@flowtomic/logic 0.1.0 → 0.1.2
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/hooks/useAnimatedIndicator/index.d.ts +3 -0
- package/dist/hooks/useAnimatedIndicator/index.d.ts.map +1 -0
- package/dist/hooks/useAnimatedIndicator/index.js +1 -0
- package/dist/hooks/useAnimatedIndicator/useAnimatedIndicator.d.ts +94 -0
- package/dist/hooks/useAnimatedIndicator/useAnimatedIndicator.d.ts.map +1 -0
- package/dist/hooks/useAnimatedIndicator/useAnimatedIndicator.js +228 -0
- package/dist/hooks/useGenealogy/index.d.ts +3 -0
- package/dist/hooks/useGenealogy/index.d.ts.map +1 -0
- package/dist/hooks/useGenealogy/index.js +1 -0
- package/dist/hooks/useGenealogy/useGenealogy.d.ts +96 -0
- package/dist/hooks/useGenealogy/useGenealogy.d.ts.map +1 -0
- package/dist/hooks/useGenealogy/useGenealogy.js +335 -0
- package/dist/hooks/useMoblile/index.js +1 -868
- package/dist/hooks/useProjectProgress/index.d.ts +3 -0
- package/dist/hooks/useProjectProgress/index.d.ts.map +1 -0
- package/dist/hooks/useProjectProgress/index.js +1 -0
- package/dist/hooks/useProjectProgress/useProjectProgress.d.ts +103 -0
- package/dist/hooks/useProjectProgress/useProjectProgress.d.ts.map +1 -0
- package/dist/hooks/useProjectProgress/useProjectProgress.js +124 -0
- package/dist/hooks/useProjectStats/index.d.ts +3 -0
- package/dist/hooks/useProjectStats/index.d.ts.map +1 -0
- package/dist/hooks/useProjectStats/index.js +1 -0
- package/dist/hooks/useProjectStats/useProjectStats.d.ts +130 -0
- package/dist/hooks/useProjectStats/useProjectStats.d.ts.map +1 -0
- package/dist/hooks/useProjectStats/useProjectStats.js +87 -0
- package/dist/hooks/useResizable/index.d.ts +1 -1
- package/dist/hooks/useResizable/index.d.ts.map +1 -1
- package/dist/hooks/useScriptEditor/index.d.ts +3 -0
- package/dist/hooks/useScriptEditor/index.d.ts.map +1 -0
- package/dist/hooks/useScriptEditor/index.js +1 -0
- package/dist/hooks/useScriptEditor/useScriptEditor.d.ts +147 -0
- package/dist/hooks/useScriptEditor/useScriptEditor.d.ts.map +1 -0
- package/dist/hooks/useScriptEditor/useScriptEditor.js +247 -0
- package/dist/hooks/useStatCard/useStatCard.d.ts +44 -5
- package/dist/hooks/useStatCard/useStatCard.d.ts.map +1 -1
- package/dist/hooks/useStatCard/useStatCard.js +81 -20
- package/dist/hooks/useTimeTracker/index.d.ts +3 -0
- package/dist/hooks/useTimeTracker/index.d.ts.map +1 -0
- package/dist/hooks/useTimeTracker/index.js +1 -0
- package/dist/hooks/useTimeTracker/useTimeTracker.d.ts +106 -0
- package/dist/hooks/useTimeTracker/useTimeTracker.d.ts.map +1 -0
- package/dist/hooks/useTimeTracker/useTimeTracker.js +143 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProjectProgress/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,2BAA2B,EAC3B,qBAAqB,EACrB,mBAAmB,EACnB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useProjectProgress } from "./useProjectProgress";
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProjectProgress - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function MyProjectProgress() {
|
|
12
|
+
* const { percentage, status, distribution } = useProjectProgress({
|
|
13
|
+
* projects: [
|
|
14
|
+
* { id: '1', status: 'completed', ... },
|
|
15
|
+
* { id: '2', status: 'in-progress', ... },
|
|
16
|
+
* { id: '3', status: 'pending', ... },
|
|
17
|
+
* ],
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* return (
|
|
21
|
+
* <div>
|
|
22
|
+
* <div>Progress: {percentage}%</div>
|
|
23
|
+
* <div>Status: {status}</div>
|
|
24
|
+
* </div>
|
|
25
|
+
* )
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export type ProjectProgressStatus = "completed" | "in-progress" | "pending" | "on-hold";
|
|
30
|
+
export interface ProjectWithProgress {
|
|
31
|
+
id: string;
|
|
32
|
+
status: ProjectProgressStatus;
|
|
33
|
+
progress?: number;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
export interface UseProjectProgressOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Lista de projetos com progresso
|
|
39
|
+
*/
|
|
40
|
+
projects: ProjectWithProgress[];
|
|
41
|
+
/**
|
|
42
|
+
* Função customizada para calcular progresso de um projeto
|
|
43
|
+
* Se não fornecido, usa progress do projeto ou calcula baseado no status
|
|
44
|
+
*/
|
|
45
|
+
calculateProgress?: (project: ProjectWithProgress) => number;
|
|
46
|
+
}
|
|
47
|
+
export interface ProjectProgressDistribution {
|
|
48
|
+
/**
|
|
49
|
+
* Número de projetos completados
|
|
50
|
+
*/
|
|
51
|
+
completed: number;
|
|
52
|
+
/**
|
|
53
|
+
* Número de projetos em progresso
|
|
54
|
+
*/
|
|
55
|
+
inProgress: number;
|
|
56
|
+
/**
|
|
57
|
+
* Número de projetos pendentes
|
|
58
|
+
*/
|
|
59
|
+
pending: number;
|
|
60
|
+
/**
|
|
61
|
+
* Número de projetos em espera
|
|
62
|
+
*/
|
|
63
|
+
onHold: number;
|
|
64
|
+
}
|
|
65
|
+
export interface UseProjectProgressReturn {
|
|
66
|
+
/**
|
|
67
|
+
* Porcentagem total de progresso (0-100)
|
|
68
|
+
*/
|
|
69
|
+
percentage: number;
|
|
70
|
+
/**
|
|
71
|
+
* Status geral do progresso
|
|
72
|
+
*/
|
|
73
|
+
status: "completed" | "in-progress" | "pending" | "on-hold";
|
|
74
|
+
/**
|
|
75
|
+
* Distribuição de projetos por status
|
|
76
|
+
*/
|
|
77
|
+
distribution: ProjectProgressDistribution;
|
|
78
|
+
/**
|
|
79
|
+
* Total de projetos
|
|
80
|
+
*/
|
|
81
|
+
total: number;
|
|
82
|
+
/**
|
|
83
|
+
* Projetos completados
|
|
84
|
+
*/
|
|
85
|
+
completed: number;
|
|
86
|
+
/**
|
|
87
|
+
* Projetos em progresso
|
|
88
|
+
*/
|
|
89
|
+
inProgress: number;
|
|
90
|
+
/**
|
|
91
|
+
* Projetos pendentes
|
|
92
|
+
*/
|
|
93
|
+
pending: number;
|
|
94
|
+
/**
|
|
95
|
+
* Projetos em espera
|
|
96
|
+
*/
|
|
97
|
+
onHold: number;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Hook headless para calcular progresso de projetos
|
|
101
|
+
*/
|
|
102
|
+
export declare function useProjectProgress(options: UseProjectProgressOptions): UseProjectProgressReturn;
|
|
103
|
+
//# sourceMappingURL=useProjectProgress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProjectProgress.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProjectProgress/useProjectProgress.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,MAAM,MAAM,qBAAqB,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;AAExF,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,qBAAqB,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAEhC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,MAAM,CAAC;CAC9D;AAED,MAAM,WAAW,2BAA2B;IAC1C;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,CAAC;IAE5D;;OAEG;IACH,YAAY,EAAE,2BAA2B,CAAC;IAE1C;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAwBD;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,wBAAwB,CA8E/F"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProjectProgress - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function MyProjectProgress() {
|
|
12
|
+
* const { percentage, status, distribution } = useProjectProgress({
|
|
13
|
+
* projects: [
|
|
14
|
+
* { id: '1', status: 'completed', ... },
|
|
15
|
+
* { id: '2', status: 'in-progress', ... },
|
|
16
|
+
* { id: '3', status: 'pending', ... },
|
|
17
|
+
* ],
|
|
18
|
+
* })
|
|
19
|
+
*
|
|
20
|
+
* return (
|
|
21
|
+
* <div>
|
|
22
|
+
* <div>Progress: {percentage}%</div>
|
|
23
|
+
* <div>Status: {status}</div>
|
|
24
|
+
* </div>
|
|
25
|
+
* )
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
import { useMemo } from "react";
|
|
30
|
+
/**
|
|
31
|
+
* Calcula progresso padrão baseado no status
|
|
32
|
+
*/
|
|
33
|
+
function getDefaultProgress(project) {
|
|
34
|
+
if (project.progress !== undefined) {
|
|
35
|
+
return project.progress;
|
|
36
|
+
}
|
|
37
|
+
switch (project.status) {
|
|
38
|
+
case "completed":
|
|
39
|
+
return 100;
|
|
40
|
+
case "in-progress":
|
|
41
|
+
return 50; // Valor padrão para projetos em progresso
|
|
42
|
+
case "pending":
|
|
43
|
+
return 0;
|
|
44
|
+
case "on-hold":
|
|
45
|
+
return 0;
|
|
46
|
+
default:
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Hook headless para calcular progresso de projetos
|
|
52
|
+
*/
|
|
53
|
+
export function useProjectProgress(options) {
|
|
54
|
+
const { projects, calculateProgress = getDefaultProgress } = options;
|
|
55
|
+
const result = useMemo(() => {
|
|
56
|
+
if (projects.length === 0) {
|
|
57
|
+
return {
|
|
58
|
+
percentage: 0,
|
|
59
|
+
status: "pending",
|
|
60
|
+
distribution: {
|
|
61
|
+
completed: 0,
|
|
62
|
+
inProgress: 0,
|
|
63
|
+
pending: 0,
|
|
64
|
+
onHold: 0,
|
|
65
|
+
},
|
|
66
|
+
total: 0,
|
|
67
|
+
completed: 0,
|
|
68
|
+
inProgress: 0,
|
|
69
|
+
pending: 0,
|
|
70
|
+
onHold: 0,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// Calcular distribuição
|
|
74
|
+
const distribution = {
|
|
75
|
+
completed: 0,
|
|
76
|
+
inProgress: 0,
|
|
77
|
+
pending: 0,
|
|
78
|
+
onHold: 0,
|
|
79
|
+
};
|
|
80
|
+
let totalProgress = 0;
|
|
81
|
+
projects.forEach((project) => {
|
|
82
|
+
const progress = calculateProgress(project);
|
|
83
|
+
totalProgress += progress;
|
|
84
|
+
switch (project.status) {
|
|
85
|
+
case "completed":
|
|
86
|
+
distribution.completed++;
|
|
87
|
+
break;
|
|
88
|
+
case "in-progress":
|
|
89
|
+
distribution.inProgress++;
|
|
90
|
+
break;
|
|
91
|
+
case "pending":
|
|
92
|
+
distribution.pending++;
|
|
93
|
+
break;
|
|
94
|
+
case "on-hold":
|
|
95
|
+
distribution.onHold++;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Calcular porcentagem média
|
|
100
|
+
const percentage = Math.round(totalProgress / projects.length);
|
|
101
|
+
// Determinar status geral
|
|
102
|
+
let status = "pending";
|
|
103
|
+
if (distribution.completed === projects.length) {
|
|
104
|
+
status = "completed";
|
|
105
|
+
}
|
|
106
|
+
else if (distribution.inProgress > 0 || distribution.completed > 0) {
|
|
107
|
+
status = "in-progress";
|
|
108
|
+
}
|
|
109
|
+
else if (distribution.onHold > 0) {
|
|
110
|
+
status = "on-hold";
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
percentage,
|
|
114
|
+
status,
|
|
115
|
+
distribution,
|
|
116
|
+
total: projects.length,
|
|
117
|
+
completed: distribution.completed,
|
|
118
|
+
inProgress: distribution.inProgress,
|
|
119
|
+
pending: distribution.pending,
|
|
120
|
+
onHold: distribution.onHold,
|
|
121
|
+
};
|
|
122
|
+
}, [projects, calculateProgress]);
|
|
123
|
+
return result;
|
|
124
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProjectStats/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,OAAO,EACP,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useProjectStats } from "./useProjectStats";
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProjectStats - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function MyProjectStats() {
|
|
12
|
+
* const { total, ended, running, pending, stats } = useProjectStats({
|
|
13
|
+
* projects: [
|
|
14
|
+
* { id: '1', status: 'running', ... },
|
|
15
|
+
* { id: '2', status: 'ended', ... },
|
|
16
|
+
* ],
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* return (
|
|
20
|
+
* <div>
|
|
21
|
+
* <div>Total: {total}</div>
|
|
22
|
+
* <div>Running: {running}</div>
|
|
23
|
+
* <div>Ended: {ended}</div>
|
|
24
|
+
* <div>Pending: {pending}</div>
|
|
25
|
+
* </div>
|
|
26
|
+
* )
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export type ProjectStatus = "running" | "ended" | "pending" | "on-hold" | "cancelled";
|
|
31
|
+
export interface Project {
|
|
32
|
+
id: string;
|
|
33
|
+
status: ProjectStatus;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
export interface UseProjectStatsOptions {
|
|
37
|
+
/**
|
|
38
|
+
* Lista de projetos
|
|
39
|
+
*/
|
|
40
|
+
projects: Project[];
|
|
41
|
+
/**
|
|
42
|
+
* Função customizada para filtrar projetos
|
|
43
|
+
*/
|
|
44
|
+
filter?: (project: Project) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Função customizada para agrupar projetos
|
|
47
|
+
*/
|
|
48
|
+
groupBy?: (project: Project) => string;
|
|
49
|
+
}
|
|
50
|
+
export interface ProjectStats {
|
|
51
|
+
/**
|
|
52
|
+
* Total de projetos
|
|
53
|
+
*/
|
|
54
|
+
total: number;
|
|
55
|
+
/**
|
|
56
|
+
* Projetos finalizados
|
|
57
|
+
*/
|
|
58
|
+
ended: number;
|
|
59
|
+
/**
|
|
60
|
+
* Projetos em execução
|
|
61
|
+
*/
|
|
62
|
+
running: number;
|
|
63
|
+
/**
|
|
64
|
+
* Projetos pendentes
|
|
65
|
+
*/
|
|
66
|
+
pending: number;
|
|
67
|
+
/**
|
|
68
|
+
* Projetos em espera
|
|
69
|
+
*/
|
|
70
|
+
onHold: number;
|
|
71
|
+
/**
|
|
72
|
+
* Projetos cancelados
|
|
73
|
+
*/
|
|
74
|
+
cancelled: number;
|
|
75
|
+
/**
|
|
76
|
+
* Distribuição por status
|
|
77
|
+
*/
|
|
78
|
+
byStatus: Record<ProjectStatus, number>;
|
|
79
|
+
/**
|
|
80
|
+
* Projetos filtrados (se filter foi fornecido)
|
|
81
|
+
*/
|
|
82
|
+
filtered: Project[];
|
|
83
|
+
/**
|
|
84
|
+
* Projetos agrupados (se groupBy foi fornecido)
|
|
85
|
+
*/
|
|
86
|
+
grouped?: Record<string, Project[]>;
|
|
87
|
+
}
|
|
88
|
+
export interface UseProjectStatsReturn {
|
|
89
|
+
/**
|
|
90
|
+
* Estatísticas calculadas
|
|
91
|
+
*/
|
|
92
|
+
stats: ProjectStats;
|
|
93
|
+
/**
|
|
94
|
+
* Total de projetos
|
|
95
|
+
*/
|
|
96
|
+
total: number;
|
|
97
|
+
/**
|
|
98
|
+
* Projetos finalizados
|
|
99
|
+
*/
|
|
100
|
+
ended: number;
|
|
101
|
+
/**
|
|
102
|
+
* Projetos em execução
|
|
103
|
+
*/
|
|
104
|
+
running: number;
|
|
105
|
+
/**
|
|
106
|
+
* Projetos pendentes
|
|
107
|
+
*/
|
|
108
|
+
pending: number;
|
|
109
|
+
/**
|
|
110
|
+
* Projetos em espera
|
|
111
|
+
*/
|
|
112
|
+
onHold: number;
|
|
113
|
+
/**
|
|
114
|
+
* Projetos cancelados
|
|
115
|
+
*/
|
|
116
|
+
cancelled: number;
|
|
117
|
+
/**
|
|
118
|
+
* Projetos filtrados
|
|
119
|
+
*/
|
|
120
|
+
filtered: Project[];
|
|
121
|
+
/**
|
|
122
|
+
* Projetos agrupados
|
|
123
|
+
*/
|
|
124
|
+
grouped?: Record<string, Project[]>;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Hook headless para calcular estatísticas de projetos
|
|
128
|
+
*/
|
|
129
|
+
export declare function useProjectStats(options: UseProjectStatsOptions): UseProjectStatsReturn;
|
|
130
|
+
//# sourceMappingURL=useProjectStats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProjectStats.d.ts","sourceRoot":"","sources":["../../../src/hooks/useProjectStats/useProjectStats.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAEtF,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,aAAa,CAAC;IACtB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAC;IAEpB;;OAEG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;IAEvC;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAExC;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,KAAK,EAAE,YAAY,CAAC;IAEpB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,OAAO,EAAE,CAAC;IAEpB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;CACrC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CA8DtF"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useProjectStats - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function MyProjectStats() {
|
|
12
|
+
* const { total, ended, running, pending, stats } = useProjectStats({
|
|
13
|
+
* projects: [
|
|
14
|
+
* { id: '1', status: 'running', ... },
|
|
15
|
+
* { id: '2', status: 'ended', ... },
|
|
16
|
+
* ],
|
|
17
|
+
* })
|
|
18
|
+
*
|
|
19
|
+
* return (
|
|
20
|
+
* <div>
|
|
21
|
+
* <div>Total: {total}</div>
|
|
22
|
+
* <div>Running: {running}</div>
|
|
23
|
+
* <div>Ended: {ended}</div>
|
|
24
|
+
* <div>Pending: {pending}</div>
|
|
25
|
+
* </div>
|
|
26
|
+
* )
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
import { useMemo } from "react";
|
|
31
|
+
/**
|
|
32
|
+
* Hook headless para calcular estatísticas de projetos
|
|
33
|
+
*/
|
|
34
|
+
export function useProjectStats(options) {
|
|
35
|
+
const { projects, filter, groupBy } = options;
|
|
36
|
+
const stats = useMemo(() => {
|
|
37
|
+
// Aplicar filtro se fornecido
|
|
38
|
+
const filtered = filter ? projects.filter(filter) : projects;
|
|
39
|
+
// Calcular contagens por status
|
|
40
|
+
const byStatus = {
|
|
41
|
+
running: 0,
|
|
42
|
+
ended: 0,
|
|
43
|
+
pending: 0,
|
|
44
|
+
"on-hold": 0,
|
|
45
|
+
cancelled: 0,
|
|
46
|
+
};
|
|
47
|
+
filtered.forEach((project) => {
|
|
48
|
+
const status = project.status || "pending";
|
|
49
|
+
if (status in byStatus) {
|
|
50
|
+
byStatus[status]++;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// Agrupar se groupBy foi fornecido
|
|
54
|
+
const grouped = groupBy
|
|
55
|
+
? filtered.reduce((acc, project) => {
|
|
56
|
+
const key = groupBy(project);
|
|
57
|
+
if (!acc[key]) {
|
|
58
|
+
acc[key] = [];
|
|
59
|
+
}
|
|
60
|
+
acc[key].push(project);
|
|
61
|
+
return acc;
|
|
62
|
+
}, {})
|
|
63
|
+
: undefined;
|
|
64
|
+
return {
|
|
65
|
+
total: filtered.length,
|
|
66
|
+
ended: byStatus.ended,
|
|
67
|
+
running: byStatus.running,
|
|
68
|
+
pending: byStatus.pending,
|
|
69
|
+
onHold: byStatus["on-hold"],
|
|
70
|
+
cancelled: byStatus.cancelled,
|
|
71
|
+
byStatus,
|
|
72
|
+
filtered,
|
|
73
|
+
grouped,
|
|
74
|
+
};
|
|
75
|
+
}, [projects, filter, groupBy]);
|
|
76
|
+
return {
|
|
77
|
+
stats,
|
|
78
|
+
total: stats.total,
|
|
79
|
+
ended: stats.ended,
|
|
80
|
+
running: stats.running,
|
|
81
|
+
pending: stats.pending,
|
|
82
|
+
onHold: stats.onHold,
|
|
83
|
+
cancelled: stats.cancelled,
|
|
84
|
+
filtered: stats.filtered,
|
|
85
|
+
grouped: stats.grouped,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useResizable/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useResizable/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC9E,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/useScriptEditor/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,YAAY,EACZ,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useScriptEditor } from "./useScriptEditor";
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useScriptEditor - Headless UI Hook
|
|
3
|
+
*
|
|
4
|
+
* Fornece apenas: lógica, estado, processamento e API
|
|
5
|
+
* NÃO fornece: markup, styles ou implementações pré-construídas
|
|
6
|
+
*
|
|
7
|
+
* Padrão Headless UI: você controla o markup e styles
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```tsx
|
|
11
|
+
* function MyScriptEditor() {
|
|
12
|
+
* const {
|
|
13
|
+
* script,
|
|
14
|
+
* setScript,
|
|
15
|
+
* terminalLines,
|
|
16
|
+
* preview,
|
|
17
|
+
* isRunning,
|
|
18
|
+
* isConnected,
|
|
19
|
+
* executeScript,
|
|
20
|
+
* stopExecution,
|
|
21
|
+
* clearTerminal,
|
|
22
|
+
* } = useScriptEditor({
|
|
23
|
+
* wsUrl: "ws://localhost:8080/ws/terminal",
|
|
24
|
+
* executeScript: async (script) => {
|
|
25
|
+
* const response = await fetch("/api/scripts/execute", {
|
|
26
|
+
* method: "POST",
|
|
27
|
+
* body: JSON.stringify({ script }),
|
|
28
|
+
* });
|
|
29
|
+
* return response.json();
|
|
30
|
+
* },
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* return (
|
|
34
|
+
* <div>
|
|
35
|
+
* <textarea value={script} onChange={(e) => setScript(e.target.value)} />
|
|
36
|
+
* <button onClick={executeScript}>Executar</button>
|
|
37
|
+
* <div>
|
|
38
|
+
* {terminalLines.map((line) => (
|
|
39
|
+
* <div key={line.id}>{line.content}</div>
|
|
40
|
+
* ))}
|
|
41
|
+
* </div>
|
|
42
|
+
* </div>
|
|
43
|
+
* );
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export interface TerminalLine {
|
|
48
|
+
id: string;
|
|
49
|
+
type: "input" | "output" | "error" | "system";
|
|
50
|
+
content: string;
|
|
51
|
+
timestamp: Date;
|
|
52
|
+
}
|
|
53
|
+
export interface ExecuteScriptResponse {
|
|
54
|
+
output?: string;
|
|
55
|
+
error?: string;
|
|
56
|
+
result?: unknown;
|
|
57
|
+
}
|
|
58
|
+
export interface UseScriptEditorOptions {
|
|
59
|
+
/**
|
|
60
|
+
* URL do WebSocket para conexão em tempo real
|
|
61
|
+
* @default undefined
|
|
62
|
+
*/
|
|
63
|
+
wsUrl?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Função para executar script via HTTP (fallback quando WebSocket não está disponível)
|
|
66
|
+
* @default undefined
|
|
67
|
+
*/
|
|
68
|
+
executeScript?: (script: string) => Promise<ExecuteScriptResponse>;
|
|
69
|
+
/**
|
|
70
|
+
* Callback quando uma linha é adicionada ao terminal
|
|
71
|
+
*/
|
|
72
|
+
onOutput?: (line: TerminalLine) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Callback quando ocorre um erro
|
|
75
|
+
*/
|
|
76
|
+
onError?: (error: Error) => void;
|
|
77
|
+
/**
|
|
78
|
+
* Se deve conectar automaticamente ao WebSocket
|
|
79
|
+
* @default true
|
|
80
|
+
*/
|
|
81
|
+
autoConnect?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Número máximo de tentativas de reconexão
|
|
84
|
+
* @default 3
|
|
85
|
+
*/
|
|
86
|
+
maxReconnectAttempts?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Script inicial
|
|
89
|
+
* @default ""
|
|
90
|
+
*/
|
|
91
|
+
defaultScript?: string;
|
|
92
|
+
}
|
|
93
|
+
export interface UseScriptEditorReturn {
|
|
94
|
+
/**
|
|
95
|
+
* Script atual
|
|
96
|
+
*/
|
|
97
|
+
script: string;
|
|
98
|
+
/**
|
|
99
|
+
* Atualizar script
|
|
100
|
+
*/
|
|
101
|
+
setScript: (script: string) => void;
|
|
102
|
+
/**
|
|
103
|
+
* Linhas do terminal
|
|
104
|
+
*/
|
|
105
|
+
terminalLines: TerminalLine[];
|
|
106
|
+
/**
|
|
107
|
+
* Preview formatado (JSON)
|
|
108
|
+
*/
|
|
109
|
+
preview: string;
|
|
110
|
+
/**
|
|
111
|
+
* Aba ativa (terminal ou preview)
|
|
112
|
+
*/
|
|
113
|
+
activeTab: "terminal" | "preview";
|
|
114
|
+
/**
|
|
115
|
+
* Mudar aba ativa
|
|
116
|
+
*/
|
|
117
|
+
setActiveTab: (tab: "terminal" | "preview") => void;
|
|
118
|
+
/**
|
|
119
|
+
* Se o script está sendo executado
|
|
120
|
+
*/
|
|
121
|
+
isRunning: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Se o WebSocket está conectado
|
|
124
|
+
*/
|
|
125
|
+
isConnected: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* Executar script
|
|
128
|
+
*/
|
|
129
|
+
executeScript: () => Promise<void>;
|
|
130
|
+
/**
|
|
131
|
+
* Parar execução
|
|
132
|
+
*/
|
|
133
|
+
stopExecution: () => void;
|
|
134
|
+
/**
|
|
135
|
+
* Limpar terminal e preview
|
|
136
|
+
*/
|
|
137
|
+
clearTerminal: () => void;
|
|
138
|
+
/**
|
|
139
|
+
* Adicionar linha ao terminal manualmente
|
|
140
|
+
*/
|
|
141
|
+
addTerminalLine: (type: TerminalLine["type"], content: string) => void;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Hook headless para gerenciar editor de scripts com terminal interativo
|
|
145
|
+
*/
|
|
146
|
+
export declare function useScriptEditor(options?: UseScriptEditorOptions): UseScriptEditorReturn;
|
|
147
|
+
//# sourceMappingURL=useScriptEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useScriptEditor.d.ts","sourceRoot":"","sources":["../../../src/hooks/useScriptEditor/useScriptEditor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAIH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAEnE;;OAEG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IAExC;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAEpC;;OAEG;IACH,aAAa,EAAE,YAAY,EAAE,CAAC;IAE9B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,EAAE,UAAU,GAAG,SAAS,CAAC;IAElC;;OAEG;IACH,YAAY,EAAE,CAAC,GAAG,EAAE,UAAU,GAAG,SAAS,KAAK,IAAI,CAAC;IAEpD;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IAErB;;OAEG;IACH,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnC;;OAEG;IACH,aAAa,EAAE,MAAM,IAAI,CAAC;IAE1B;;OAEG;IACH,aAAa,EAAE,MAAM,IAAI,CAAC;IAE1B;;OAEG;IACH,eAAe,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,qBAAqB,CAoO3F"}
|