g360-cli 1.4.0 → 1.5.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/README.md +122 -0
- package/package.json +11 -4
- package/src/assets/brand/brand.json +43 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.png +0 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_borde.svg +9 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.png +0 -0
- package/src/assets/brand/cipsa/logotypes/Logo_cipsa_solid.svg +9 -0
- package/src/assets/brand/g360/logotypes/logo-g360-dark.svg +19 -0
- package/src/assets/brand/g360/logotypes/logo-g360-light.svg +19 -0
- package/src/assets/brand/g360/logotypes/logo_g360_dark_b64.txt +1 -0
- package/src/assets/brand/g360/logotypes/logo_g360_light_b64.txt +1 -0
- package/src/assets/config/g360-skills.json +60 -0
- package/src/assets/snippets/snippets.json +293 -101
- package/src/assets/templates/lit-web/src/core/skill.json +12 -5
- package/src/assets/templates/python-cli/build-portable.bat +19 -9
- package/src/assets/templates/python-cli/src/core/skill.json +25 -6
- package/src/assets/templates/python-customtkinter/README.md +32 -31
- package/src/assets/templates/python-customtkinter/assets/images/logo-g360-dark.svg +19 -0
- package/src/assets/templates/python-customtkinter/assets/images/logo-g360-light.svg +19 -0
- package/src/assets/templates/python-customtkinter/build.bat +50 -0
- package/src/assets/templates/python-customtkinter/pyproject.toml +26 -0
- package/src/assets/templates/python-customtkinter/run.bat +11 -20
- package/src/assets/templates/python-customtkinter/src/core/g360_theme.py +101 -0
- package/src/assets/templates/python-customtkinter/src/core/skill.json +23 -10
- package/src/assets/templates/python-customtkinter/src/main.py +61 -81
- package/src/assets/templates/python-flet/README.md +52 -93
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.png +0 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_borde.svg +9 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.png +0 -0
- package/src/assets/templates/python-flet/assets/images/Logo_cipsa_solid.svg +9 -0
- package/src/assets/templates/python-flet/assets/images/logo-g360-dark.svg +19 -0
- package/src/assets/templates/python-flet/assets/images/logo-g360-light.svg +19 -0
- package/src/assets/templates/python-flet/build.bat +36 -0
- package/src/assets/templates/python-flet/pyproject.toml +26 -0
- package/src/assets/templates/python-flet/run.bat +11 -72
- package/src/assets/templates/python-flet/src/core/__init__.py +0 -0
- package/src/assets/templates/python-flet/src/core/g360_theme.py +186 -0
- package/src/assets/templates/python-flet/src/core/skill.json +28 -8
- package/src/assets/templates/python-flet/src/export/__init__.py +0 -0
- package/src/assets/templates/python-flet/src/main.py +113 -68
- package/src/assets/templates/python-flet/src/test_app.py +41 -37
- package/src/assets/templates/python-flet/src/ui/__init__.py +0 -0
- package/src/assets/templates/python-flet-migrate/README.md +70 -0
- package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-dark.svg +19 -0
- package/src/assets/templates/python-flet-migrate/assets/images/logo-g360-light.svg +19 -0
- package/src/assets/templates/python-flet-migrate/build.bat +36 -0
- package/src/assets/templates/python-flet-migrate/pyproject.toml +26 -0
- package/src/assets/templates/python-flet-migrate/run.bat +20 -0
- package/src/assets/templates/python-flet-migrate/src/core/__init__.py +0 -0
- package/src/assets/templates/python-flet-migrate/src/core/g360_theme.py +186 -0
- package/src/assets/templates/python-flet-migrate/src/core/skill.json +34 -0
- package/src/assets/templates/python-flet-migrate/src/main.py +71 -42
- package/src/assets/templates/solid-web/src/core/skill.json +12 -5
- package/src/assets/templates/svelte-web/src/core/skill.json +12 -5
- package/src/assets/templates/web-pwa/index.html +2 -7
- package/src/assets/templates/web-pwa/public/favicon.svg +4 -0
- package/src/assets/templates/web-pwa/public/manifest.json +11 -0
- package/src/assets/templates/web-pwa/src/App.jsx +22 -0
- package/src/assets/templates/web-pwa/src/components/FooterSignature.jsx +9 -0
- package/src/assets/templates/web-pwa/src/components/Header.jsx +12 -0
- package/src/assets/templates/web-pwa/src/components/LoadingOverlay.jsx +10 -0
- package/src/assets/templates/web-pwa/src/core/skill.json +25 -0
- package/src/assets/templates/web-pwa/src/main.jsx +9 -0
- package/src/assets/templates/web-pwa/src/styles/main.css +133 -0
- package/src/assets/templates/web-pwa/vite.config.js +12 -0
- package/src/cli.js +4 -4
- package/src/commands/bring.js +81 -6
- package/src/commands/list.js +79 -9
- package/src/lib/asset-validator.js +145 -0
- package/src/lib/auditor.js +48 -0
- package/src/lib/global-config.js +260 -0
- package/src/lib/i18n.js +238 -0
- package/src/lib/logger.js +100 -0
- package/src/lib/manifest.js +70 -1
- package/src/lib/validator.js +39 -0
- package/src/schemas/skills-schema.json +1 -0
- package/src/schemas/snippets-schema.json +1 -0
- package/dist/g360.exe +0 -0
- package/src/assets/templates/python-customtkinter/build-portable.bat +0 -28
- package/src/assets/templates/python-customtkinter/requirements.txt +0 -1
- package/src/assets/templates/python-flet/build-portable.bat +0 -42
- package/src/assets/templates/python-flet/create_shortcut.vbs +0 -35
- package/src/assets/templates/python-flet/requirements.txt +0 -3
- package/src/assets/templates/web-pwa/app.js +0 -1
- package/src/assets/templates/web-pwa/styles.css +0 -28
|
@@ -1,101 +1,146 @@
|
|
|
1
|
-
import flet as ft
|
|
2
1
|
import sys
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import flet as ft
|
|
4
|
+
from core.g360_theme import G360Theme
|
|
5
|
+
|
|
6
|
+
BASE_DIR = Path(__file__).resolve().parent.parent
|
|
7
|
+
if str(BASE_DIR) not in sys.path:
|
|
8
|
+
sys.path.insert(0, str(BASE_DIR))
|
|
3
9
|
|
|
4
10
|
|
|
5
11
|
class G360App:
|
|
6
12
|
def __init__(self, page: ft.Page):
|
|
7
13
|
self.page = page
|
|
8
|
-
self.
|
|
9
|
-
self.
|
|
14
|
+
self.theme = G360Theme()
|
|
15
|
+
self._setup_page()
|
|
16
|
+
self._build_ui()
|
|
10
17
|
|
|
11
|
-
def
|
|
12
|
-
self.page.title =
|
|
18
|
+
def _setup_page(self):
|
|
19
|
+
self.page.title = self.theme.build_name()
|
|
13
20
|
self.page.theme_mode = ft.ThemeMode.DARK
|
|
14
|
-
self.page.
|
|
15
|
-
self.page.
|
|
16
|
-
self.page.window_width =
|
|
17
|
-
self.page.window_height =
|
|
21
|
+
self.page.bgcolor = self.theme.bg
|
|
22
|
+
self.page.padding = 0
|
|
23
|
+
self.page.window_width = 1350
|
|
24
|
+
self.page.window_height = 900
|
|
18
25
|
self.page.window_resizable = True
|
|
19
26
|
self.page.window_center()
|
|
20
27
|
|
|
21
|
-
def
|
|
28
|
+
def _build_ui(self):
|
|
29
|
+
self.loading = self.theme.loading_overlay()
|
|
22
30
|
self.page.add(
|
|
23
|
-
ft.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
ft.Stack(
|
|
32
|
+
controls=[
|
|
33
|
+
ft.Column(
|
|
34
|
+
controls=[
|
|
35
|
+
self._build_header(),
|
|
36
|
+
ft.Container(
|
|
37
|
+
content=self._build_content(),
|
|
38
|
+
expand=True,
|
|
39
|
+
padding=20,
|
|
40
|
+
),
|
|
41
|
+
self.theme.footer_signature(),
|
|
42
|
+
],
|
|
43
|
+
spacing=0,
|
|
44
|
+
expand=True,
|
|
45
|
+
),
|
|
46
|
+
self.loading,
|
|
47
|
+
],
|
|
28
48
|
expand=True,
|
|
29
|
-
spacing=20
|
|
30
49
|
)
|
|
31
50
|
)
|
|
32
51
|
|
|
33
|
-
def
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
def show_loading(self, message="Procesando..."):
|
|
53
|
+
self.loading.content.controls[2].value = message
|
|
54
|
+
self.loading.visible = True
|
|
55
|
+
self.page.update()
|
|
56
|
+
|
|
57
|
+
def hide_loading(self):
|
|
58
|
+
self.loading.visible = False
|
|
59
|
+
self.page.update()
|
|
60
|
+
|
|
61
|
+
def _build_header(self):
|
|
62
|
+
return self.theme.container(
|
|
63
|
+
content=ft.Row(
|
|
64
|
+
controls=[
|
|
65
|
+
ft.Row(
|
|
66
|
+
controls=[
|
|
67
|
+
self.theme.logo_component(height=32),
|
|
68
|
+
ft.Container(width=8),
|
|
69
|
+
self.theme.styled_text(
|
|
70
|
+
"Desktop App", size=20, color=self.theme.muted
|
|
71
|
+
),
|
|
72
|
+
],
|
|
73
|
+
spacing=0,
|
|
74
|
+
),
|
|
75
|
+
ft.Container(expand=True),
|
|
76
|
+
ft.IconButton(
|
|
77
|
+
icon=ft.icons.SETTINGS,
|
|
78
|
+
on_click=lambda _: print("Settings"),
|
|
79
|
+
),
|
|
80
|
+
],
|
|
81
|
+
alignment=ft.MainAxisAlignment.START,
|
|
82
|
+
),
|
|
53
83
|
padding=20,
|
|
54
|
-
bgcolor=
|
|
55
|
-
border_radius=12
|
|
84
|
+
bgcolor=self.theme.surface,
|
|
56
85
|
)
|
|
57
86
|
|
|
58
|
-
def
|
|
59
|
-
return ft.
|
|
60
|
-
|
|
61
|
-
|
|
87
|
+
def _build_content(self):
|
|
88
|
+
return ft.Column(
|
|
89
|
+
controls=[
|
|
90
|
+
self.theme.styled_text(
|
|
62
91
|
"Bienvenido a G360 Desktop",
|
|
63
92
|
size=24,
|
|
64
|
-
|
|
93
|
+
weight=ft.FontWeight.BOLD,
|
|
65
94
|
),
|
|
66
95
|
ft.Container(height=20),
|
|
67
|
-
ft.Row(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
96
|
+
ft.Row(
|
|
97
|
+
controls=[
|
|
98
|
+
self._build_card(
|
|
99
|
+
"Usuarios", "Gestión de usuarios", ft.icons.PEOPLE
|
|
100
|
+
),
|
|
101
|
+
self._build_card(
|
|
102
|
+
"Reportes", "Ver reportes", ft.icons.ANALYTICS
|
|
103
|
+
),
|
|
104
|
+
self._build_card(
|
|
105
|
+
"Configuración", "Ajustes del sistema", ft.icons.SETTINGS
|
|
106
|
+
),
|
|
107
|
+
],
|
|
108
|
+
spacing=20,
|
|
109
|
+
),
|
|
110
|
+
],
|
|
111
|
+
scroll=ft.ScrollMode.AUTO,
|
|
75
112
|
)
|
|
76
113
|
|
|
77
|
-
def
|
|
78
|
-
return
|
|
79
|
-
content=ft.Column(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
114
|
+
def _build_card(self, title, subtitle, icon):
|
|
115
|
+
return self.theme.container(
|
|
116
|
+
content=ft.Column(
|
|
117
|
+
controls=[
|
|
118
|
+
ft.Icon(icon, size=48, color=self.theme.accent),
|
|
119
|
+
self.theme.styled_text(
|
|
120
|
+
title, size=18, weight=ft.FontWeight.BOLD
|
|
121
|
+
),
|
|
122
|
+
self.theme.styled_text(
|
|
123
|
+
subtitle, size=14, color=self.theme.muted
|
|
124
|
+
),
|
|
125
|
+
],
|
|
126
|
+
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
|
127
|
+
spacing=10,
|
|
128
|
+
),
|
|
129
|
+
width=220,
|
|
130
|
+
height=190,
|
|
131
|
+
alignment=ft.alignment.center,
|
|
90
132
|
)
|
|
91
133
|
|
|
92
|
-
def on_settings(self, e):
|
|
93
|
-
print("Settings clicked")
|
|
94
|
-
|
|
95
134
|
|
|
96
135
|
def main(page: ft.Page):
|
|
97
136
|
G360App(page)
|
|
98
137
|
|
|
99
138
|
|
|
100
139
|
if __name__ == "__main__":
|
|
101
|
-
|
|
140
|
+
try:
|
|
141
|
+
ft.run(main)
|
|
142
|
+
except Exception as e:
|
|
143
|
+
print(f"\n[FATAL] Error al iniciar la aplicacion: {e}", flush=True)
|
|
144
|
+
import traceback
|
|
145
|
+
traceback.print_exc()
|
|
146
|
+
input("\nPresione Enter para salir...")
|
|
@@ -1,21 +1,42 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Tests para la aplicación G360 Flet
|
|
3
|
-
Usa: pytest test_app.py -v
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
1
|
import unittest
|
|
7
2
|
from unittest.mock import Mock, patch
|
|
3
|
+
import json
|
|
4
|
+
from pathlib import Path
|
|
8
5
|
import flet as ft
|
|
6
|
+
from core.g360_theme import G360Theme
|
|
9
7
|
|
|
10
8
|
|
|
11
|
-
class
|
|
12
|
-
|
|
9
|
+
class TestG360Theme(unittest.TestCase):
|
|
10
|
+
def setUp(self):
|
|
11
|
+
self.theme = G360Theme(skill_path=Path(__file__).parent / "core" / "skill.json")
|
|
12
|
+
|
|
13
|
+
def test_default_colors(self):
|
|
14
|
+
self.assertEqual(self.theme.bg, "#0b1220")
|
|
15
|
+
self.assertEqual(self.theme.surface, "#1a2332")
|
|
16
|
+
self.assertEqual(self.theme.accent, "#00d084")
|
|
17
|
+
self.assertEqual(self.theme.text, "#f0f4f8")
|
|
18
|
+
self.assertEqual(self.theme.muted, "#94a3b8")
|
|
19
|
+
self.assertEqual(self.theme.success, "#22c55e")
|
|
20
|
+
self.assertEqual(self.theme.warning, "#f59e0b")
|
|
21
|
+
self.assertEqual(self.theme.error, "#ef4444")
|
|
22
|
+
|
|
23
|
+
def test_as_dict(self):
|
|
24
|
+
d = self.theme.as_dict
|
|
25
|
+
self.assertEqual(d["bg"], "#0b1220")
|
|
26
|
+
self.assertEqual(d["surface"], "#1a2332")
|
|
27
|
+
self.assertEqual(d["accent"], "#00d084")
|
|
28
|
+
|
|
29
|
+
def test_effects(self):
|
|
30
|
+
self.assertTrue(self.theme.glassmorphism)
|
|
31
|
+
self.assertEqual(self.theme.blur, "12px")
|
|
32
|
+
self.assertEqual(self.theme.rounded, "12px")
|
|
13
33
|
|
|
34
|
+
|
|
35
|
+
class TestG360App(unittest.TestCase):
|
|
14
36
|
def setUp(self):
|
|
15
37
|
self.mock_page = Mock(spec=ft.Page)
|
|
16
38
|
|
|
17
39
|
def test_page_theme_setup(self):
|
|
18
|
-
"""Verifica que la página se configura con el tema correcto"""
|
|
19
40
|
self.mock_page.title = "G360 Desktop App"
|
|
20
41
|
self.mock_page.theme_mode = ft.ThemeMode.DARK
|
|
21
42
|
self.mock_page.bgcolor = "#0b1220"
|
|
@@ -25,79 +46,62 @@ class TestG360App(unittest.TestCase):
|
|
|
25
46
|
self.assertEqual(self.mock_page.bgcolor, "#0b1220")
|
|
26
47
|
|
|
27
48
|
def test_colors_g360(self):
|
|
28
|
-
"""Verifica los colores del tema G360"""
|
|
29
49
|
colors = {
|
|
30
50
|
"bg": "#0b1220",
|
|
31
|
-
"surface": "#
|
|
51
|
+
"surface": "#1a2332",
|
|
32
52
|
"accent": "#00d084",
|
|
33
53
|
"text": "#f0f4f8",
|
|
34
|
-
"muted": "#94a3b8"
|
|
54
|
+
"muted": "#94a3b8",
|
|
35
55
|
}
|
|
36
|
-
|
|
37
56
|
for key, value in colors.items():
|
|
38
57
|
self.assertIsNotNone(value)
|
|
39
58
|
|
|
40
59
|
def test_button_styles(self):
|
|
41
|
-
"""Verifica estilos de botones G360"""
|
|
42
60
|
button = ft.ElevatedButton(
|
|
43
61
|
text="Test",
|
|
44
62
|
bgcolor="#00d084",
|
|
45
|
-
color="#0b1220"
|
|
63
|
+
color="#0b1220",
|
|
46
64
|
)
|
|
47
|
-
|
|
48
65
|
self.assertIsNotNone(button)
|
|
49
66
|
|
|
50
67
|
def test_container_styles(self):
|
|
51
|
-
"""Verifica estilos de contenedores G360"""
|
|
52
68
|
container = ft.Container(
|
|
53
|
-
bgcolor="#
|
|
69
|
+
bgcolor="#1a2332",
|
|
54
70
|
border_radius=12,
|
|
55
|
-
padding=20
|
|
71
|
+
padding=20,
|
|
56
72
|
)
|
|
57
|
-
|
|
58
73
|
self.assertIsNotNone(container)
|
|
59
|
-
self.assertEqual(container.bgcolor, "#
|
|
74
|
+
self.assertEqual(container.bgcolor, "#1a2332")
|
|
60
75
|
self.assertEqual(container.border_radius, 12)
|
|
61
76
|
|
|
62
77
|
|
|
63
78
|
class TestMigration(unittest.TestCase):
|
|
64
|
-
"""Tests para migración desde tkinter/ctkinter"""
|
|
65
|
-
|
|
66
79
|
def test_convert_tkinter_widgets(self):
|
|
67
|
-
"""Verifica mapeo de widgets tkinter a Flet"""
|
|
68
80
|
mapping = {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
81
|
+
"tk.Label": "ft.Text",
|
|
82
|
+
"tk.Button": "ft.ElevatedButton",
|
|
83
|
+
"tk.Entry": "ft.TextField",
|
|
84
|
+
"tk.Frame": "ft.Container",
|
|
73
85
|
}
|
|
74
|
-
|
|
75
86
|
for tk, flet in mapping.items():
|
|
76
87
|
self.assertIsNotNone(tk)
|
|
77
88
|
self.assertIsNotNone(flet)
|
|
78
89
|
|
|
79
90
|
|
|
80
91
|
class TestCalculations(unittest.TestCase):
|
|
81
|
-
"""Tests para cálculos y procesamiento de datos"""
|
|
82
|
-
|
|
83
92
|
def test_sum_basic(self):
|
|
84
|
-
|
|
85
|
-
result = 2 + 2
|
|
86
|
-
self.assertEqual(result, 4)
|
|
93
|
+
self.assertEqual(2 + 2, 4)
|
|
87
94
|
|
|
88
95
|
def test_list_operations(self):
|
|
89
|
-
"""Test operaciones con listas"""
|
|
90
96
|
items = [1, 2, 3, 4, 5]
|
|
91
97
|
self.assertEqual(sum(items), 15)
|
|
92
98
|
self.assertEqual(len(items), 5)
|
|
93
|
-
self.assertEqual(max(items), 5)
|
|
94
99
|
|
|
95
100
|
def test_dict_operations(self):
|
|
96
|
-
"""Test operaciones con diccionarios"""
|
|
97
101
|
data = {"sku": "ABC001", "cantidad": 10, "precio": 50.0}
|
|
98
102
|
self.assertIn("sku", data)
|
|
99
103
|
self.assertEqual(data["cantidad"] * data["precio"], 500.0)
|
|
100
104
|
|
|
101
105
|
|
|
102
|
-
if __name__ ==
|
|
106
|
+
if __name__ == "__main__":
|
|
103
107
|
unittest.main()
|
|
File without changes
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# G360 Python Flet Migration App
|
|
2
|
+
|
|
3
|
+
Template para migrar aplicaciones de **tkinter/CustomTkinter a Flet** con el ecosistema G360.
|
|
4
|
+
|
|
5
|
+
## Estructura del Proyecto
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
mi-proyecto/
|
|
9
|
+
├── src/
|
|
10
|
+
│ ├── main.py # Entry point: ft.run(main)
|
|
11
|
+
│ ├── migrate_tkinter.py # Asistente de migracion
|
|
12
|
+
│ ├── core/
|
|
13
|
+
│ │ ├── skill.json # Configuracion del skill G360
|
|
14
|
+
│ │ └── g360_theme.py # Theme engine
|
|
15
|
+
├── assets/
|
|
16
|
+
│ └── images/
|
|
17
|
+
├── skill.json # Skill G360 aplicado
|
|
18
|
+
├── pyproject.toml # Dependencias
|
|
19
|
+
├── run.bat # Ejecutar app
|
|
20
|
+
├── build.bat # Build EXE standalone
|
|
21
|
+
└── README.md
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Migracion de tkinter/CustomTkinter
|
|
25
|
+
|
|
26
|
+
### Paso 1: Reemplazar imports
|
|
27
|
+
```python
|
|
28
|
+
# Antes (tkinter)
|
|
29
|
+
import tkinter as tk
|
|
30
|
+
from tkinter import ttk, messagebox
|
|
31
|
+
|
|
32
|
+
# Despues (Flet)
|
|
33
|
+
import flet as ft
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Paso 2: Convertir widgets
|
|
37
|
+
| tkinter | Flet |
|
|
38
|
+
|---------|------|
|
|
39
|
+
| `tk.Button` | `ft.ElevatedButton` |
|
|
40
|
+
| `tk.Entry` | `ft.TextField` |
|
|
41
|
+
| `tk.Label` | `ft.Text` |
|
|
42
|
+
| `tk.Frame` | `ft.Container` |
|
|
43
|
+
| `ttk.Treeview` | `ft.DataTable` |
|
|
44
|
+
| `messagebox` | `ft.AlertDialog` |
|
|
45
|
+
|
|
46
|
+
### Paso 3: Aplicar tema G360
|
|
47
|
+
```python
|
|
48
|
+
class MigratedApp:
|
|
49
|
+
def __init__(self, page: ft.Page):
|
|
50
|
+
self.theme = G360Theme()
|
|
51
|
+
self.page = page
|
|
52
|
+
self._setup_page()
|
|
53
|
+
|
|
54
|
+
def _setup_page(self):
|
|
55
|
+
self.page.title = self.theme.build_name()
|
|
56
|
+
self.page.theme_mode = ft.ThemeMode.DARK
|
|
57
|
+
self.page.bgcolor = self.theme.bg
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Ejecucion
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
run.bat
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Build Windows
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
build.bat
|
|
70
|
+
```
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<svg viewBox="0 0 280 70" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="glow-dark" x="-40%" y="-40%" width="180%" height="180%">
|
|
4
|
+
<feGaussianBlur stdDeviation="3" result="blur" />
|
|
5
|
+
<feFlood flood-color="#22c55e" flood-opacity="0.8" result="glowColor"/>
|
|
6
|
+
<feComposite in="glowColor" in2="blur" operator="in" result="softGlow"/>
|
|
7
|
+
<feMerge>
|
|
8
|
+
<feMergeNode in="softGlow"/>
|
|
9
|
+
<feMergeNode in="SourceGraphic"/>
|
|
10
|
+
</feMerge>
|
|
11
|
+
</filter>
|
|
12
|
+
</defs>
|
|
13
|
+
<circle cx="20" cy="20" r="5" fill="#94a3b8" />
|
|
14
|
+
<circle cx="20" cy="40" r="5" fill="#22c55e" filter="url(#glow-dark)" />
|
|
15
|
+
<circle cx="20" cy="60" r="5" fill="#94a3b8" />
|
|
16
|
+
<path d="M45 20 L 65 40 L 45 60" fill="none" stroke="#22c55e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" filter="url(#glow-dark)"/>
|
|
17
|
+
<text x="85" y="45" font-family="Arial Black, sans-serif" font-weight="bold" font-size="38" fill="#f8fafc">G360</text>
|
|
18
|
+
<text x="85" y="65" font-family="monospace" font-size="12" fill="#94a3b8" letter-spacing="4">BY CCUSI</text>
|
|
19
|
+
</svg>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<svg viewBox="0 0 280 70" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="glow-light" x="-30%" y="-30%" width="160%" height="160%">
|
|
4
|
+
<feGaussianBlur stdDeviation="2.5" result="blur" />
|
|
5
|
+
<feFlood flood-color="#22c55e" flood-opacity="0.6" result="glowColor"/>
|
|
6
|
+
<feComposite in="glowColor" in2="blur" operator="in" result="softGlow"/>
|
|
7
|
+
<feMerge>
|
|
8
|
+
<feMergeNode in="softGlow"/>
|
|
9
|
+
<feMergeNode in="SourceGraphic"/>
|
|
10
|
+
</feMerge>
|
|
11
|
+
</filter>
|
|
12
|
+
</defs>
|
|
13
|
+
<circle cx="20" cy="20" r="5" fill="#475569" />
|
|
14
|
+
<circle cx="20" cy="40" r="5" fill="#22c55e" filter="url(#glow-light)" />
|
|
15
|
+
<circle cx="20" cy="60" r="5" fill="#475569" />
|
|
16
|
+
<path d="M45 20 L 65 40 L 45 60" fill="none" stroke="#22c55e" stroke-width="6" stroke-linecap="round" stroke-linejoin="round" filter="url(#glow-light)"/>
|
|
17
|
+
<text x="85" y="45" font-family="Arial Black, sans-serif" font-weight="bold" font-size="38" fill="#1e293b">G360</text>
|
|
18
|
+
<text x="85" y="65" font-family="monospace" font-size="12" fill="#64748b" letter-spacing="4">BY CCUSI</text>
|
|
19
|
+
</svg>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
chcp 65001 >nul
|
|
3
|
+
cd /d "%~dp0"
|
|
4
|
+
|
|
5
|
+
echo.
|
|
6
|
+
echo ========================================
|
|
7
|
+
echo G360 - Build Windows App
|
|
8
|
+
echo Genera ejecutable standalone
|
|
9
|
+
echo ========================================
|
|
10
|
+
echo.
|
|
11
|
+
|
|
12
|
+
REM Verificar uv
|
|
13
|
+
where uv >nul 2>&1
|
|
14
|
+
if errorlevel 1 (
|
|
15
|
+
echo Instalando uv...
|
|
16
|
+
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
REM Build con flet (maneja dependencias automaticamente)
|
|
20
|
+
echo [BUILD] Generando ejecutable...
|
|
21
|
+
uv run flet build windows --name "G360-App" --icon assets/images/app.ico
|
|
22
|
+
|
|
23
|
+
if errorlevel 1 (
|
|
24
|
+
echo.
|
|
25
|
+
echo ERROR: Fallo la generacion del ejecutable.
|
|
26
|
+
pause
|
|
27
|
+
exit /b 1
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
echo.
|
|
31
|
+
echo ========================================
|
|
32
|
+
echo BUILD EXITOSO
|
|
33
|
+
echo Ejecutable en: build/windows/
|
|
34
|
+
echo ========================================
|
|
35
|
+
echo.
|
|
36
|
+
pause
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "g360-app"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "G360 Desktop Application (Flet Migration)"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "ccusi", email = "ccusi@cipsa.com.pe" },
|
|
7
|
+
]
|
|
8
|
+
requires-python = ">=3.11,<4.0"
|
|
9
|
+
dependencies = [
|
|
10
|
+
"flet>=0.25.0",
|
|
11
|
+
"openpyxl>=3.1.0",
|
|
12
|
+
"pandas>=2.0.0",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.optional-dependencies]
|
|
16
|
+
dev = [
|
|
17
|
+
"pytest>=8.0.0",
|
|
18
|
+
"pytest-cov>=5.0.0",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[build-system]
|
|
22
|
+
requires = ["hatchling"]
|
|
23
|
+
build-backend = "hatchling.build"
|
|
24
|
+
|
|
25
|
+
[tool.hatch.build.targets.wheel]
|
|
26
|
+
packages = ["src"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
chcp 65001 >nul
|
|
3
|
+
cd /d "%~dp0"
|
|
4
|
+
|
|
5
|
+
echo.
|
|
6
|
+
echo ========================================
|
|
7
|
+
echo G360 Flet Migration App
|
|
8
|
+
echo powered by G360
|
|
9
|
+
echo ========================================
|
|
10
|
+
echo.
|
|
11
|
+
|
|
12
|
+
REM uv run detecta/instala Python y dependencias automaticamente
|
|
13
|
+
uv run python src/main.py
|
|
14
|
+
|
|
15
|
+
if errorlevel 1 (
|
|
16
|
+
echo.
|
|
17
|
+
echo ERROR: La aplicacion fallo.
|
|
18
|
+
echo Verifique que uv este instalado: https://docs.astral.sh/uv/
|
|
19
|
+
pause
|
|
20
|
+
)
|
|
File without changes
|