@fickou/quasar-workflow 1.0.0
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/LICENSE +21 -0
- package/README.md +535 -0
- package/dist/composables/useWorkflow.d.ts +108 -0
- package/dist/composables/useWorkflow.js +183 -0
- package/dist/composables/useWorkflow.js.map +1 -0
- package/dist/composables/useWorkflowAdmin.d.ts +51 -0
- package/dist/composables/useWorkflowAdmin.js +140 -0
- package/dist/composables/useWorkflowAdmin.js.map +1 -0
- package/dist/composables/useWorkflowDashboard.d.ts +72 -0
- package/dist/composables/useWorkflowDashboard.js +40 -0
- package/dist/composables/useWorkflowDashboard.js.map +1 -0
- package/dist/composables/useWorkflowDelegation.d.ts +76 -0
- package/dist/composables/useWorkflowDelegation.js +87 -0
- package/dist/composables/useWorkflowDelegation.js.map +1 -0
- package/dist/composables/useWorkflowFieldControl.d.ts +19 -0
- package/dist/composables/useWorkflowFieldControl.js +111 -0
- package/dist/composables/useWorkflowFieldControl.js.map +1 -0
- package/dist/composables/useWorkflowStats.d.ts +21 -0
- package/dist/composables/useWorkflowStats.js +87 -0
- package/dist/composables/useWorkflowStats.js.map +1 -0
- package/dist/composables/useWorkflowWebSocket.d.ts +26 -0
- package/dist/composables/useWorkflowWebSocket.js +140 -0
- package/dist/composables/useWorkflowWebSocket.js.map +1 -0
- package/dist/directives/vWorkflowField.d.ts +2 -0
- package/dist/directives/vWorkflowField.js +59 -0
- package/dist/directives/vWorkflowField.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/WorkflowPlugin.d.ts +6 -0
- package/dist/plugins/WorkflowPlugin.js +36 -0
- package/dist/plugins/WorkflowPlugin.js.map +1 -0
- package/dist/types/index.d.ts +47 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { ref, computed, watch, inject } from 'vue';
|
|
2
|
+
import axios, { AxiosError } from 'axios';
|
|
3
|
+
import { useWorkflowWebSocket } from './useWorkflowWebSocket';
|
|
4
|
+
export function useWorkflow(entityType, entityId, options) {
|
|
5
|
+
const instance = ref(null);
|
|
6
|
+
const definition = ref(null);
|
|
7
|
+
const loading = ref(false);
|
|
8
|
+
const error = ref(null);
|
|
9
|
+
const hookRejectionReason = ref(null);
|
|
10
|
+
// Résolution de l'apiBase : options locales → inject plugin → défaut
|
|
11
|
+
const injectedApiBase = inject('workflowApiBase', '/api/workflow');
|
|
12
|
+
const apiBase = options?.apiBase ?? injectedApiBase;
|
|
13
|
+
const injectedWsUrl = inject('workflowWsUrl', 'ws://localhost:3333');
|
|
14
|
+
const wsUrl = options?.wsUrl ?? injectedWsUrl;
|
|
15
|
+
// Chargement de la définition et de l'instance courante
|
|
16
|
+
const fetchInstanceAndDefinition = async () => {
|
|
17
|
+
error.value = null;
|
|
18
|
+
hookRejectionReason.value = null;
|
|
19
|
+
if (!entityId.value) {
|
|
20
|
+
instance.value = null;
|
|
21
|
+
definition.value = null;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
loading.value = true;
|
|
25
|
+
try {
|
|
26
|
+
// 1. Récupération de la définition active pour ce type d'entité
|
|
27
|
+
try {
|
|
28
|
+
const defResponse = await axios.get(`${apiBase}/definitions/by-type/${entityType}`);
|
|
29
|
+
definition.value = defResponse.data;
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
if (axios.isAxiosError(e) && e.response?.status === 404) {
|
|
33
|
+
definition.value = null;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
throw e;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// 2. Récupération de l'instance active (si elle existe)
|
|
40
|
+
try {
|
|
41
|
+
const instResponse = await axios.get(`${apiBase}/instances/by-entity?entityType=${entityType}&entityId=${entityId.value}`);
|
|
42
|
+
instance.value = instResponse.data;
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
if (axios.isAxiosError(e) && e.response?.status === 404) {
|
|
46
|
+
instance.value = null;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
throw e;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
const msg = err instanceof AxiosError
|
|
55
|
+
? err.response?.data?.message || err.message
|
|
56
|
+
: String(err);
|
|
57
|
+
error.value = msg;
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
loading.value = false;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
// Exécution d'une action avec transmission de la version pour le verrouillage optimiste
|
|
64
|
+
const executeAction = async (action, payload = {}) => {
|
|
65
|
+
if (!instance.value)
|
|
66
|
+
return;
|
|
67
|
+
error.value = null;
|
|
68
|
+
hookRejectionReason.value = null;
|
|
69
|
+
loading.value = true;
|
|
70
|
+
try {
|
|
71
|
+
const activeStep = instance.value.steps?.find((s) => s.status === 'active');
|
|
72
|
+
const version = activeStep?.version ?? 1;
|
|
73
|
+
await axios.post(`${apiBase}/instances/${instance.value.id}/actions`, {
|
|
74
|
+
action,
|
|
75
|
+
version,
|
|
76
|
+
...payload,
|
|
77
|
+
});
|
|
78
|
+
// Rechargement de l'état après l'action
|
|
79
|
+
await fetchInstanceAndDefinition();
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
if (axios.isAxiosError(err)) {
|
|
83
|
+
const data = err.response?.data;
|
|
84
|
+
const code = data?.code || data?.error_code;
|
|
85
|
+
// Traitement spécifique du refus par un ActionHook
|
|
86
|
+
if (code === 'HOOK_REJECTED') {
|
|
87
|
+
hookRejectionReason.value = data?.message || 'Action refusée par la logique métier.';
|
|
88
|
+
}
|
|
89
|
+
else if (code === 'CONCURRENT_MODIFICATION') {
|
|
90
|
+
// Conflit de version : rafraîchissement automatique
|
|
91
|
+
await fetchInstanceAndDefinition();
|
|
92
|
+
error.value = 'Le workflow a été modifié par un autre utilisateur. Les données ont été rafraîchies.';
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
error.value = data?.message || err.message;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
error.value = String(err);
|
|
100
|
+
}
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
loading.value = false;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
// Soumission du document (auto_start = false)
|
|
108
|
+
const submitWorkflow = async () => {
|
|
109
|
+
if (!entityId.value)
|
|
110
|
+
return;
|
|
111
|
+
loading.value = true;
|
|
112
|
+
error.value = null;
|
|
113
|
+
try {
|
|
114
|
+
const response = await axios.post(`${apiBase}/instances`, {
|
|
115
|
+
entityType,
|
|
116
|
+
entityId: entityId.value,
|
|
117
|
+
});
|
|
118
|
+
instance.value = response.data;
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
const msg = err instanceof AxiosError ? err.response?.data?.message || err.message : String(err);
|
|
122
|
+
error.value = msg;
|
|
123
|
+
throw err;
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
loading.value = false;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
// Resoumission après correction
|
|
130
|
+
const resubmit = async () => {
|
|
131
|
+
if (!instance.value)
|
|
132
|
+
return;
|
|
133
|
+
loading.value = true;
|
|
134
|
+
error.value = null;
|
|
135
|
+
try {
|
|
136
|
+
await axios.post(`${apiBase}/instances/${instance.value.id}/resubmit`);
|
|
137
|
+
await fetchInstanceAndDefinition();
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
const msg = err instanceof AxiosError ? err.response?.data?.message || err.message : String(err);
|
|
141
|
+
error.value = msg;
|
|
142
|
+
throw err;
|
|
143
|
+
}
|
|
144
|
+
finally {
|
|
145
|
+
loading.value = false;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
// Récupération de l'historique des actions
|
|
149
|
+
const fetchHistory = async () => {
|
|
150
|
+
if (!instance.value)
|
|
151
|
+
return [];
|
|
152
|
+
const response = await axios.get(`${apiBase}/instances/${instance.value.id}/history`);
|
|
153
|
+
return response.data;
|
|
154
|
+
};
|
|
155
|
+
// WebSocket : abonnement temps réel au channel de l'instance
|
|
156
|
+
const instanceId = computed(() => instance.value?.id ?? null);
|
|
157
|
+
const { onConflict, onStepChanged, onActionExecuted, isConnected } = useWorkflowWebSocket(instanceId, { wsUrl });
|
|
158
|
+
// Conflit de version détecté par WebSocket → rafraîchissement + message
|
|
159
|
+
onConflict(async () => {
|
|
160
|
+
await fetchInstanceAndDefinition();
|
|
161
|
+
error.value = 'Le workflow a été modifié par un autre utilisateur. Les données ont été rafraîchies.';
|
|
162
|
+
});
|
|
163
|
+
// Nouvelle étape détectée → rafraîchissement de l'état
|
|
164
|
+
onStepChanged(async () => {
|
|
165
|
+
await fetchInstanceAndDefinition();
|
|
166
|
+
});
|
|
167
|
+
// Observation de l'entityId : rechargement si l'entité change
|
|
168
|
+
watch(entityId, fetchInstanceAndDefinition, { immediate: true });
|
|
169
|
+
return {
|
|
170
|
+
instance,
|
|
171
|
+
definition,
|
|
172
|
+
loading,
|
|
173
|
+
error,
|
|
174
|
+
hookRejectionReason,
|
|
175
|
+
isWsConnected: isConnected,
|
|
176
|
+
fetchInstance: fetchInstanceAndDefinition,
|
|
177
|
+
executeAction,
|
|
178
|
+
submitWorkflow,
|
|
179
|
+
resubmit,
|
|
180
|
+
fetchHistory,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=useWorkflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkflow.js","sourceRoot":"","sources":["../../composables/useWorkflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { WorkflowDefinitionDTO } from '../types';
|
|
2
|
+
export declare function useWorkflowAdmin(options?: {
|
|
3
|
+
apiBase?: string;
|
|
4
|
+
}): {
|
|
5
|
+
definitions: import("vue").Ref<{
|
|
6
|
+
id: string;
|
|
7
|
+
entity_type: string;
|
|
8
|
+
auto_start: boolean;
|
|
9
|
+
steps: {
|
|
10
|
+
id: string;
|
|
11
|
+
order: number;
|
|
12
|
+
step_type: import("../types").StepType;
|
|
13
|
+
validation_threshold: number;
|
|
14
|
+
name: string;
|
|
15
|
+
description?: string | undefined;
|
|
16
|
+
editable_fields?: string[] | undefined;
|
|
17
|
+
}[];
|
|
18
|
+
}[], WorkflowDefinitionDTO[] | {
|
|
19
|
+
id: string;
|
|
20
|
+
entity_type: string;
|
|
21
|
+
auto_start: boolean;
|
|
22
|
+
steps: {
|
|
23
|
+
id: string;
|
|
24
|
+
order: number;
|
|
25
|
+
step_type: import("../types").StepType;
|
|
26
|
+
validation_threshold: number;
|
|
27
|
+
name: string;
|
|
28
|
+
description?: string | undefined;
|
|
29
|
+
editable_fields?: string[] | undefined;
|
|
30
|
+
}[];
|
|
31
|
+
}[]>;
|
|
32
|
+
loading: import("vue").Ref<boolean, boolean>;
|
|
33
|
+
error: import("vue").Ref<string | null, string | null>;
|
|
34
|
+
fetchDefinitions: () => Promise<void>;
|
|
35
|
+
fetchDefinition: (id: string) => Promise<any>;
|
|
36
|
+
createDefinition: (data: Partial<WorkflowDefinitionDTO>) => Promise<any>;
|
|
37
|
+
updateDefinition: (id: string, data: Partial<WorkflowDefinitionDTO>) => Promise<any>;
|
|
38
|
+
deleteDefinition: (id: string) => Promise<void>;
|
|
39
|
+
toggleDefinitionActive: (id: string, activate: boolean) => Promise<any>;
|
|
40
|
+
createStep: (definitionId: string, data: Record<string, unknown>) => Promise<any>;
|
|
41
|
+
updateStep: (definitionId: string, stepId: string, data: Record<string, unknown>) => Promise<any>;
|
|
42
|
+
deleteStep: (definitionId: string, stepId: string) => Promise<void>;
|
|
43
|
+
createTransition: (definitionId: string, data: Record<string, unknown>) => Promise<any>;
|
|
44
|
+
updateTransition: (definitionId: string, transitionId: string, data: Record<string, unknown>) => Promise<any>;
|
|
45
|
+
deleteTransition: (definitionId: string, transitionId: string) => Promise<void>;
|
|
46
|
+
addValidator: (definitionId: string, stepId: string, data: {
|
|
47
|
+
type: string;
|
|
48
|
+
reference_id: string;
|
|
49
|
+
}) => Promise<any>;
|
|
50
|
+
removeValidator: (definitionId: string, stepId: string, validatorId: string) => Promise<void>;
|
|
51
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { ref, inject } from 'vue';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
// Composable pour les opérations d'administration des définitions de workflow
|
|
4
|
+
export function useWorkflowAdmin(options) {
|
|
5
|
+
const injectedApiBase = inject('workflowApiBase', '/api/workflow');
|
|
6
|
+
const apiBase = options?.apiBase ?? injectedApiBase;
|
|
7
|
+
const definitions = ref([]);
|
|
8
|
+
const loading = ref(false);
|
|
9
|
+
const error = ref(null);
|
|
10
|
+
const fetchDefinitions = async () => {
|
|
11
|
+
loading.value = true;
|
|
12
|
+
error.value = null;
|
|
13
|
+
try {
|
|
14
|
+
const res = await axios.get(`${apiBase}/definitions`);
|
|
15
|
+
definitions.value = res.data;
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
error.value = String(err);
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
loading.value = false;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const fetchDefinition = async (id) => {
|
|
25
|
+
loading.value = true;
|
|
26
|
+
error.value = null;
|
|
27
|
+
try {
|
|
28
|
+
const res = await axios.get(`${apiBase}/definitions/${id}`);
|
|
29
|
+
return res.data;
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
error.value = String(err);
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
loading.value = false;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const createDefinition = async (data) => {
|
|
40
|
+
loading.value = true;
|
|
41
|
+
error.value = null;
|
|
42
|
+
try {
|
|
43
|
+
const res = await axios.post(`${apiBase}/definitions`, data);
|
|
44
|
+
return res.data;
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
error.value = String(err);
|
|
48
|
+
throw err;
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
loading.value = false;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const updateDefinition = async (id, data) => {
|
|
55
|
+
loading.value = true;
|
|
56
|
+
error.value = null;
|
|
57
|
+
try {
|
|
58
|
+
const res = await axios.put(`${apiBase}/definitions/${id}`, data);
|
|
59
|
+
return res.data;
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
error.value = String(err);
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
loading.value = false;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const deleteDefinition = async (id) => {
|
|
70
|
+
loading.value = true;
|
|
71
|
+
error.value = null;
|
|
72
|
+
try {
|
|
73
|
+
await axios.delete(`${apiBase}/definitions/${id}`);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
error.value = String(err);
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
loading.value = false;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const toggleDefinitionActive = async (id, activate) => {
|
|
84
|
+
const endpoint = activate ? 'activate' : 'deactivate';
|
|
85
|
+
const res = await axios.patch(`${apiBase}/definitions/${id}/${endpoint}`);
|
|
86
|
+
return res.data;
|
|
87
|
+
};
|
|
88
|
+
// CRUD Étapes
|
|
89
|
+
const createStep = async (definitionId, data) => {
|
|
90
|
+
const res = await axios.post(`${apiBase}/definitions/${definitionId}/steps`, data);
|
|
91
|
+
return res.data;
|
|
92
|
+
};
|
|
93
|
+
const updateStep = async (definitionId, stepId, data) => {
|
|
94
|
+
const res = await axios.put(`${apiBase}/definitions/${definitionId}/steps/${stepId}`, data);
|
|
95
|
+
return res.data;
|
|
96
|
+
};
|
|
97
|
+
const deleteStep = async (definitionId, stepId) => {
|
|
98
|
+
await axios.delete(`${apiBase}/definitions/${definitionId}/steps/${stepId}`);
|
|
99
|
+
};
|
|
100
|
+
// CRUD Transitions
|
|
101
|
+
const createTransition = async (definitionId, data) => {
|
|
102
|
+
const res = await axios.post(`${apiBase}/definitions/${definitionId}/transitions`, data);
|
|
103
|
+
return res.data;
|
|
104
|
+
};
|
|
105
|
+
const updateTransition = async (definitionId, transitionId, data) => {
|
|
106
|
+
const res = await axios.put(`${apiBase}/definitions/${definitionId}/transitions/${transitionId}`, data);
|
|
107
|
+
return res.data;
|
|
108
|
+
};
|
|
109
|
+
const deleteTransition = async (definitionId, transitionId) => {
|
|
110
|
+
await axios.delete(`${apiBase}/definitions/${definitionId}/transitions/${transitionId}`);
|
|
111
|
+
};
|
|
112
|
+
// CRUD Validators
|
|
113
|
+
const addValidator = async (definitionId, stepId, data) => {
|
|
114
|
+
const res = await axios.post(`${apiBase}/definitions/${definitionId}/steps/${stepId}/validators`, data);
|
|
115
|
+
return res.data;
|
|
116
|
+
};
|
|
117
|
+
const removeValidator = async (definitionId, stepId, validatorId) => {
|
|
118
|
+
await axios.delete(`${apiBase}/definitions/${definitionId}/steps/${stepId}/validators/${validatorId}`);
|
|
119
|
+
};
|
|
120
|
+
return {
|
|
121
|
+
definitions,
|
|
122
|
+
loading,
|
|
123
|
+
error,
|
|
124
|
+
fetchDefinitions,
|
|
125
|
+
fetchDefinition,
|
|
126
|
+
createDefinition,
|
|
127
|
+
updateDefinition,
|
|
128
|
+
deleteDefinition,
|
|
129
|
+
toggleDefinitionActive,
|
|
130
|
+
createStep,
|
|
131
|
+
updateStep,
|
|
132
|
+
deleteStep,
|
|
133
|
+
createTransition,
|
|
134
|
+
updateTransition,
|
|
135
|
+
deleteTransition,
|
|
136
|
+
addValidator,
|
|
137
|
+
removeValidator,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=useWorkflowAdmin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkflowAdmin.js","sourceRoot":"","sources":["../../composables/useWorkflowAdmin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AACjC,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,OAA8B;IAC7D,MAAM,eAAe,GAAG,MAAM,CAAS,iBAAiB,EAAE,eAAe,CAAC,CAAA;IAC1E,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,eAAe,CAAA;IAEnD,MAAM,WAAW,GAAG,GAAG,CAA0B,EAAE,CAAC,CAAA;IACpD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,KAAK,GAAG,GAAG,CAAgB,IAAI,CAAC,CAAA;IAEtC,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;QAClC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAA;QACpB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,cAAc,CAAC,CAAA;YACrD,WAAW,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,CAAA;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;QAC3B,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,KAAK,EAAE,EAAU,EAAE,EAAE;QAC3C,OAAO,CAAC,KAAK,GAAG,IAAI,CAAA;QACpB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,gBAAgB,EAAE,EAAE,CAAC,CAAA;YAC3D,OAAO,GAAG,CAAC,IAAI,CAAA;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;YACzB,OAAO,IAAI,CAAA;QACb,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAoC,EAAE,EAAE;QACtE,OAAO,CAAC,KAAK,GAAG,IAAI,CAAA;QACpB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,cAAc,EAAE,IAAI,CAAC,CAAA;YAC5D,OAAO,GAAG,CAAC,IAAI,CAAA;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,GAAG,CAAA;QACX,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,KAAK,EAAE,EAAU,EAAE,IAAoC,EAAE,EAAE;QAClF,OAAO,CAAC,KAAK,GAAG,IAAI,CAAA;QACpB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,gBAAgB,EAAE,EAAE,EAAE,IAAI,CAAC,CAAA;YACjE,OAAO,GAAG,CAAC,IAAI,CAAA;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,GAAG,CAAA;QACX,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,KAAK,EAAE,EAAU,EAAE,EAAE;QAC5C,OAAO,CAAC,KAAK,GAAG,IAAI,CAAA;QACpB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,gBAAgB,EAAE,EAAE,CAAC,CAAA;QACpD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;YACzB,MAAM,GAAG,CAAA;QACX,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,sBAAsB,GAAG,KAAK,EAAE,EAAU,EAAE,QAAiB,EAAE,EAAE;QACrE,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAA;QACrD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,gBAAgB,EAAE,IAAI,QAAQ,EAAE,CAAC,CAAA;QACzE,OAAO,GAAG,CAAC,IAAI,CAAA;IACjB,CAAC,CAAA;IAED,cAAc;IACd,MAAM,UAAU,GAAG,KAAK,EAAE,YAAoB,EAAE,IAA6B,EAAE,EAAE;QAC/E,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,gBAAgB,YAAY,QAAQ,EAAE,IAAI,CAAC,CAAA;QAClF,OAAO,GAAG,CAAC,IAAI,CAAA;IACjB,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,KAAK,EAAE,YAAoB,EAAE,MAAc,EAAE,IAA6B,EAAE,EAAE;QAC/F,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,gBAAgB,YAAY,UAAU,MAAM,EAAE,EAAE,IAAI,CAAC,CAAA;QAC3F,OAAO,GAAG,CAAC,IAAI,CAAA;IACjB,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,KAAK,EAAE,YAAoB,EAAE,MAAc,EAAE,EAAE;QAChE,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,gBAAgB,YAAY,UAAU,MAAM,EAAE,CAAC,CAAA;IAC9E,CAAC,CAAA;IAED,mBAAmB;IACnB,MAAM,gBAAgB,GAAG,KAAK,EAAE,YAAoB,EAAE,IAA6B,EAAE,EAAE;QACrF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,gBAAgB,YAAY,cAAc,EAAE,IAAI,CAAC,CAAA;QACxF,OAAO,GAAG,CAAC,IAAI,CAAA;IACjB,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,KAAK,EAC5B,YAAoB,EACpB,YAAoB,EACpB,IAA6B,EAC7B,EAAE;QACF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CACzB,GAAG,OAAO,gBAAgB,YAAY,gBAAgB,YAAY,EAAE,EACpE,IAAI,CACL,CAAA;QACD,OAAO,GAAG,CAAC,IAAI,CAAA;IACjB,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,KAAK,EAAE,YAAoB,EAAE,YAAoB,EAAE,EAAE;QAC5E,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,gBAAgB,YAAY,gBAAgB,YAAY,EAAE,CAAC,CAAA;IAC1F,CAAC,CAAA;IAED,kBAAkB;IAClB,MAAM,YAAY,GAAG,KAAK,EACxB,YAAoB,EACpB,MAAc,EACd,IAA4C,EAC5C,EAAE;QACF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAC1B,GAAG,OAAO,gBAAgB,YAAY,UAAU,MAAM,aAAa,EACnE,IAAI,CACL,CAAA;QACD,OAAO,GAAG,CAAC,IAAI,CAAA;IACjB,CAAC,CAAA;IAED,MAAM,eAAe,GAAG,KAAK,EAAE,YAAoB,EAAE,MAAc,EAAE,WAAmB,EAAE,EAAE;QAC1F,MAAM,KAAK,CAAC,MAAM,CAChB,GAAG,OAAO,gBAAgB,YAAY,UAAU,MAAM,eAAe,WAAW,EAAE,CACnF,CAAA;IACH,CAAC,CAAA;IAED,OAAO;QACL,WAAW;QACX,OAAO;QACP,KAAK;QACL,gBAAgB;QAChB,eAAe;QACf,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,sBAAsB;QACtB,UAAU;QACV,UAAU;QACV,UAAU;QACV,gBAAgB;QAChB,gBAAgB;QAChB,gBAAgB;QAChB,YAAY;QACZ,eAAe;KAChB,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { WorkflowInstanceDTO } from '../types';
|
|
2
|
+
export declare function useWorkflowDashboard(options?: {
|
|
3
|
+
apiBase?: string;
|
|
4
|
+
wsUrl?: string;
|
|
5
|
+
}): {
|
|
6
|
+
pendingInstances: import("vue").Ref<{
|
|
7
|
+
id: string;
|
|
8
|
+
entity_type: string;
|
|
9
|
+
entity_id: string;
|
|
10
|
+
status: import("../types").WorkflowStatus;
|
|
11
|
+
ever_started: boolean;
|
|
12
|
+
snapshot_id: string;
|
|
13
|
+
steps: {
|
|
14
|
+
id: string;
|
|
15
|
+
instance_id: string;
|
|
16
|
+
step_id: string;
|
|
17
|
+
status: "pending" | "active" | "completed" | "skipped" | "rejected";
|
|
18
|
+
validation_count: number;
|
|
19
|
+
version: number;
|
|
20
|
+
}[];
|
|
21
|
+
snapshot?: {
|
|
22
|
+
snapshot_data: {
|
|
23
|
+
id: string;
|
|
24
|
+
entity_type: string;
|
|
25
|
+
auto_start: boolean;
|
|
26
|
+
steps: {
|
|
27
|
+
id: string;
|
|
28
|
+
order: number;
|
|
29
|
+
step_type: import("../types").StepType;
|
|
30
|
+
validation_threshold: number;
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string | undefined;
|
|
33
|
+
editable_fields?: string[] | undefined;
|
|
34
|
+
}[];
|
|
35
|
+
};
|
|
36
|
+
} | undefined;
|
|
37
|
+
}[], WorkflowInstanceDTO[] | {
|
|
38
|
+
id: string;
|
|
39
|
+
entity_type: string;
|
|
40
|
+
entity_id: string;
|
|
41
|
+
status: import("../types").WorkflowStatus;
|
|
42
|
+
ever_started: boolean;
|
|
43
|
+
snapshot_id: string;
|
|
44
|
+
steps: {
|
|
45
|
+
id: string;
|
|
46
|
+
instance_id: string;
|
|
47
|
+
step_id: string;
|
|
48
|
+
status: "pending" | "active" | "completed" | "skipped" | "rejected";
|
|
49
|
+
validation_count: number;
|
|
50
|
+
version: number;
|
|
51
|
+
}[];
|
|
52
|
+
snapshot?: {
|
|
53
|
+
snapshot_data: {
|
|
54
|
+
id: string;
|
|
55
|
+
entity_type: string;
|
|
56
|
+
auto_start: boolean;
|
|
57
|
+
steps: {
|
|
58
|
+
id: string;
|
|
59
|
+
order: number;
|
|
60
|
+
step_type: import("../types").StepType;
|
|
61
|
+
validation_threshold: number;
|
|
62
|
+
name: string;
|
|
63
|
+
description?: string | undefined;
|
|
64
|
+
editable_fields?: string[] | undefined;
|
|
65
|
+
}[];
|
|
66
|
+
};
|
|
67
|
+
} | undefined;
|
|
68
|
+
}[]>;
|
|
69
|
+
loading: import("vue").Ref<boolean, boolean>;
|
|
70
|
+
error: import("vue").Ref<string | null, string | null>;
|
|
71
|
+
fetchPending: () => Promise<void>;
|
|
72
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ref, inject, onMounted } from 'vue';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
// Composable pour le dashboard de l'utilisateur connecté
|
|
4
|
+
// Affiche les documents en attente de sa validation avec rafraîchissement temps réel
|
|
5
|
+
export function useWorkflowDashboard(options) {
|
|
6
|
+
const injectedApiBase = inject('workflowApiBase', '/api/workflow');
|
|
7
|
+
const injectedWsUrl = inject('workflowWsUrl', 'ws://localhost:3333');
|
|
8
|
+
const apiBase = options?.apiBase ?? injectedApiBase;
|
|
9
|
+
const wsUrl = options?.wsUrl ?? injectedWsUrl;
|
|
10
|
+
const pendingInstances = ref([]);
|
|
11
|
+
const loading = ref(false);
|
|
12
|
+
const error = ref(null);
|
|
13
|
+
const fetchPending = async () => {
|
|
14
|
+
loading.value = true;
|
|
15
|
+
error.value = null;
|
|
16
|
+
try {
|
|
17
|
+
const res = await axios.get(`${apiBase}/stats/pending`);
|
|
18
|
+
pendingInstances.value = res.data;
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
error.value = String(err);
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
loading.value = false;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
// Rafraîchissement sur action exécutée par n'importe quel utilisateur
|
|
28
|
+
// WebSocket sur un channel générique de notifications (EXTENSION)
|
|
29
|
+
// Pour l'instant, polling manuel via fetchPending()
|
|
30
|
+
onMounted(() => {
|
|
31
|
+
fetchPending();
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
pendingInstances,
|
|
35
|
+
loading,
|
|
36
|
+
error,
|
|
37
|
+
fetchPending,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=useWorkflowDashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useWorkflowDashboard.js","sourceRoot":"","sources":["../../composables/useWorkflowDashboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAC5C,OAAO,KAAK,MAAM,OAAO,CAAA;AAIzB,yDAAyD;AACzD,qFAAqF;AACrF,MAAM,UAAU,oBAAoB,CAAC,OAA8C;IACjF,MAAM,eAAe,GAAG,MAAM,CAAS,iBAAiB,EAAE,eAAe,CAAC,CAAA;IAC1E,MAAM,aAAa,GAAG,MAAM,CAAS,eAAe,EAAE,qBAAqB,CAAC,CAAA;IAE5E,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,eAAe,CAAA;IACnD,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,aAAa,CAAA;IAE7C,MAAM,gBAAgB,GAAG,GAAG,CAAwB,EAAE,CAAC,CAAA;IACvD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,KAAK,GAAG,GAAG,CAAgB,IAAI,CAAC,CAAA;IAEtC,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;QAC9B,OAAO,CAAC,KAAK,GAAG,IAAI,CAAA;QACpB,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,gBAAgB,CAAC,CAAA;YACvD,gBAAgB,CAAC,KAAK,GAAG,GAAG,CAAC,IAAI,CAAA;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;QAC3B,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,CAAC;IACH,CAAC,CAAA;IAED,sEAAsE;IACtE,kEAAkE;IAClE,oDAAoD;IAEpD,SAAS,CAAC,GAAG,EAAE;QACb,YAAY,EAAE,CAAA;IAChB,CAAC,CAAC,CAAA;IAEF,OAAO;QACL,gBAAgB;QAChB,OAAO;QACP,KAAK;QACL,YAAY;KACb,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export interface DelegationDTO {
|
|
2
|
+
id: string;
|
|
3
|
+
delegator_id: string;
|
|
4
|
+
delegate_id: string;
|
|
5
|
+
scope: 'global' | 'workflow' | 'step';
|
|
6
|
+
workflow_definition_id: string | null;
|
|
7
|
+
step_id: string | null;
|
|
8
|
+
valid_from: string;
|
|
9
|
+
valid_until: string;
|
|
10
|
+
type: 'delegation' | 'substitution';
|
|
11
|
+
is_active: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function useWorkflowDelegation(options?: {
|
|
14
|
+
apiBase?: string;
|
|
15
|
+
}): {
|
|
16
|
+
delegations: import("vue").Ref<{
|
|
17
|
+
id: string;
|
|
18
|
+
delegator_id: string;
|
|
19
|
+
delegate_id: string;
|
|
20
|
+
scope: "global" | "workflow" | "step";
|
|
21
|
+
workflow_definition_id: string | null;
|
|
22
|
+
step_id: string | null;
|
|
23
|
+
valid_from: string;
|
|
24
|
+
valid_until: string;
|
|
25
|
+
type: "delegation" | "substitution";
|
|
26
|
+
is_active: boolean;
|
|
27
|
+
}[], DelegationDTO[] | {
|
|
28
|
+
id: string;
|
|
29
|
+
delegator_id: string;
|
|
30
|
+
delegate_id: string;
|
|
31
|
+
scope: "global" | "workflow" | "step";
|
|
32
|
+
workflow_definition_id: string | null;
|
|
33
|
+
step_id: string | null;
|
|
34
|
+
valid_from: string;
|
|
35
|
+
valid_until: string;
|
|
36
|
+
type: "delegation" | "substitution";
|
|
37
|
+
is_active: boolean;
|
|
38
|
+
}[]>;
|
|
39
|
+
receivedDelegations: import("vue").Ref<{
|
|
40
|
+
id: string;
|
|
41
|
+
delegator_id: string;
|
|
42
|
+
delegate_id: string;
|
|
43
|
+
scope: "global" | "workflow" | "step";
|
|
44
|
+
workflow_definition_id: string | null;
|
|
45
|
+
step_id: string | null;
|
|
46
|
+
valid_from: string;
|
|
47
|
+
valid_until: string;
|
|
48
|
+
type: "delegation" | "substitution";
|
|
49
|
+
is_active: boolean;
|
|
50
|
+
}[], DelegationDTO[] | {
|
|
51
|
+
id: string;
|
|
52
|
+
delegator_id: string;
|
|
53
|
+
delegate_id: string;
|
|
54
|
+
scope: "global" | "workflow" | "step";
|
|
55
|
+
workflow_definition_id: string | null;
|
|
56
|
+
step_id: string | null;
|
|
57
|
+
valid_from: string;
|
|
58
|
+
valid_until: string;
|
|
59
|
+
type: "delegation" | "substitution";
|
|
60
|
+
is_active: boolean;
|
|
61
|
+
}[]>;
|
|
62
|
+
loading: import("vue").Ref<boolean, boolean>;
|
|
63
|
+
error: import("vue").Ref<string | null, string | null>;
|
|
64
|
+
fetchMyDelegations: () => Promise<void>;
|
|
65
|
+
fetchReceivedDelegations: () => Promise<void>;
|
|
66
|
+
createDelegation: (data: {
|
|
67
|
+
delegate_id: string;
|
|
68
|
+
scope: "global" | "workflow" | "step";
|
|
69
|
+
valid_from: string;
|
|
70
|
+
valid_until: string;
|
|
71
|
+
type: "delegation" | "substitution";
|
|
72
|
+
workflow_definition_id?: string;
|
|
73
|
+
step_id?: string;
|
|
74
|
+
}) => Promise<DelegationDTO>;
|
|
75
|
+
revokeDelegation: (delegationId: string) => Promise<void>;
|
|
76
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ref, inject } from 'vue';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
// Composable pour la gestion des délégations de l'utilisateur connecté
|
|
4
|
+
export function useWorkflowDelegation(options) {
|
|
5
|
+
const injectedApiBase = inject('workflowApiBase', '/api/workflow');
|
|
6
|
+
const apiBase = options?.apiBase ?? injectedApiBase;
|
|
7
|
+
const delegations = ref([]);
|
|
8
|
+
const receivedDelegations = ref([]);
|
|
9
|
+
const loading = ref(false);
|
|
10
|
+
const error = ref(null);
|
|
11
|
+
// Chargement des délégations émises par l'utilisateur courant
|
|
12
|
+
const fetchMyDelegations = async () => {
|
|
13
|
+
loading.value = true;
|
|
14
|
+
error.value = null;
|
|
15
|
+
try {
|
|
16
|
+
const res = await axios.get(`${apiBase}/delegations?as=delegator`);
|
|
17
|
+
delegations.value = res.data;
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
error.value = String(err);
|
|
21
|
+
}
|
|
22
|
+
finally {
|
|
23
|
+
loading.value = false;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
// Chargement des délégations reçues par l'utilisateur courant
|
|
27
|
+
const fetchReceivedDelegations = async () => {
|
|
28
|
+
loading.value = true;
|
|
29
|
+
error.value = null;
|
|
30
|
+
try {
|
|
31
|
+
const res = await axios.get(`${apiBase}/delegations?as=delegate`);
|
|
32
|
+
receivedDelegations.value = res.data;
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
error.value = String(err);
|
|
36
|
+
}
|
|
37
|
+
finally {
|
|
38
|
+
loading.value = false;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
// Création d'une délégation
|
|
42
|
+
const createDelegation = async (data) => {
|
|
43
|
+
loading.value = true;
|
|
44
|
+
error.value = null;
|
|
45
|
+
try {
|
|
46
|
+
const res = await axios.post(`${apiBase}/delegations`, data);
|
|
47
|
+
delegations.value.unshift(res.data);
|
|
48
|
+
return res.data;
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
error.value = String(err);
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
loading.value = false;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
// Révocation d'une délégation
|
|
59
|
+
const revokeDelegation = async (delegationId) => {
|
|
60
|
+
loading.value = true;
|
|
61
|
+
error.value = null;
|
|
62
|
+
try {
|
|
63
|
+
await axios.delete(`${apiBase}/delegations/${delegationId}`);
|
|
64
|
+
const idx = delegations.value.findIndex((d) => d.id === delegationId);
|
|
65
|
+
if (idx !== -1)
|
|
66
|
+
delegations.value[idx].is_active = false;
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
error.value = String(err);
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
loading.value = false;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
return {
|
|
77
|
+
delegations,
|
|
78
|
+
receivedDelegations,
|
|
79
|
+
loading,
|
|
80
|
+
error,
|
|
81
|
+
fetchMyDelegations,
|
|
82
|
+
fetchReceivedDelegations,
|
|
83
|
+
createDelegation,
|
|
84
|
+
revokeDelegation,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=useWorkflowDelegation.js.map
|