g360-cli 1.3.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 +209 -5
- package/package.json +15 -8
- 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 +112 -0
- package/src/assets/config/project-types.json +16 -0
- package/src/assets/config/skills.json +12 -0
- package/src/assets/snippets/snippets.json +293 -24
- package/src/assets/templates/lit-web/src/core/skill.json +12 -5
- package/src/assets/templates/python-cli/build-portable.bat +43 -0
- package/src/assets/templates/python-cli/src/core/skill.json +25 -6
- package/src/assets/templates/python-cli/src/main.py +107 -3
- package/src/assets/templates/python-customtkinter/README.md +48 -0
- 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 +20 -0
- package/src/assets/templates/python-customtkinter/src/core/g360_theme.py +101 -0
- package/src/assets/templates/python-customtkinter/src/core/skill.json +35 -0
- package/src/assets/templates/python-customtkinter/src/main.py +103 -0
- package/src/assets/templates/python-flet/README.md +89 -0
- 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 +20 -0
- 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 +41 -0
- package/src/assets/templates/python-flet/src/export/__init__.py +0 -0
- package/src/assets/templates/python-flet/src/main.py +146 -0
- package/src/assets/templates/python-flet/src/test_app.py +107 -0
- 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 +97 -0
- package/src/assets/templates/python-flet-migrate/src/migrate_tkinter.py +56 -0
- 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 +8 -4
- package/src/commands/bring.js +81 -6
- package/src/commands/clean.js +51 -4
- package/src/commands/init.js +60 -8
- package/src/commands/list.js +79 -9
- package/src/commands/signature.js +12 -8
- 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/src/assets/templates/web-pwa/app.js +0 -1
- package/src/assets/templates/web-pwa/styles.css +0 -28
|
@@ -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
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import base64
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class G360Theme:
|
|
7
|
+
def __init__(self, skill_path=None):
|
|
8
|
+
self._search_paths(skill_path)
|
|
9
|
+
self._load_colors()
|
|
10
|
+
self._load_effects()
|
|
11
|
+
self._load_logo()
|
|
12
|
+
|
|
13
|
+
def _search_paths(self, skill_path):
|
|
14
|
+
if skill_path and Path(skill_path).exists():
|
|
15
|
+
self.config_path = Path(skill_path)
|
|
16
|
+
return
|
|
17
|
+
candidates = [
|
|
18
|
+
Path("skill.json"),
|
|
19
|
+
Path("src/core/skill.json"),
|
|
20
|
+
Path(__file__).resolve().parent.parent.parent / "skill.json",
|
|
21
|
+
Path(__file__).resolve().parent / "skill.json",
|
|
22
|
+
Path(__file__).resolve().parent.parent / "g360" / "skills" / "flet-desktop.json",
|
|
23
|
+
]
|
|
24
|
+
for c in candidates:
|
|
25
|
+
if c.exists():
|
|
26
|
+
self.config_path = c
|
|
27
|
+
return
|
|
28
|
+
raise FileNotFoundError("skill.json not found. Run: g360 init <name> --skill flet-desktop")
|
|
29
|
+
|
|
30
|
+
def _load_colors(self):
|
|
31
|
+
with open(self.config_path, encoding="utf-8") as f:
|
|
32
|
+
self.config = json.load(f)
|
|
33
|
+
colors = self.config.get("colors", {})
|
|
34
|
+
self.bg = colors.get("bg", "#0b1220")
|
|
35
|
+
self.surface = colors.get("surface", "#1a2332")
|
|
36
|
+
self.accent = colors.get("accent", "#00d084")
|
|
37
|
+
self.text = colors.get("text", "#f0f4f8")
|
|
38
|
+
self.muted = colors.get("muted", "#94a3b8")
|
|
39
|
+
self.success = colors.get("success", "#22c55e")
|
|
40
|
+
self.warning = colors.get("warning", "#f59e0b")
|
|
41
|
+
self.error = colors.get("error", "#ef4444")
|
|
42
|
+
self.brand = self.config.get("brand", "g360")
|
|
43
|
+
|
|
44
|
+
def _load_effects(self):
|
|
45
|
+
effects = self.config.get("effects", {})
|
|
46
|
+
self.glassmorphism = effects.get("glassmorphism", True)
|
|
47
|
+
self.blur = effects.get("blur", "12px")
|
|
48
|
+
self.rounded = int(effects.get("rounded", "12px").replace("px", ""))
|
|
49
|
+
|
|
50
|
+
def _load_logo(self):
|
|
51
|
+
logo_name = None
|
|
52
|
+
guidelines = self.config.get("guidelines", {})
|
|
53
|
+
if guidelines.get("logo"):
|
|
54
|
+
logo_name = guidelines["logo"]
|
|
55
|
+
if not logo_name:
|
|
56
|
+
logo_name = "logo-g360-dark.svg"
|
|
57
|
+
paths = [
|
|
58
|
+
Path("assets/images") / logo_name,
|
|
59
|
+
Path(__file__).resolve().parent.parent.parent / "assets" / "images" / logo_name,
|
|
60
|
+
]
|
|
61
|
+
self._logo_path = None
|
|
62
|
+
for p in paths:
|
|
63
|
+
if p.exists():
|
|
64
|
+
self._logo_path = p
|
|
65
|
+
break
|
|
66
|
+
self._logo_b64 = None
|
|
67
|
+
|
|
68
|
+
def logo_src(self, page=None):
|
|
69
|
+
if self._logo_path and self._logo_path.exists():
|
|
70
|
+
return str(self._logo_path)
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
def logo_base64(self):
|
|
74
|
+
if self._logo_b64:
|
|
75
|
+
return self._logo_b64
|
|
76
|
+
if self._logo_path and self._logo_path.exists():
|
|
77
|
+
raw = self._logo_path.read_bytes()
|
|
78
|
+
ext = self._logo_path.suffix.lower()
|
|
79
|
+
mime = "image/svg+xml" if ext == ".svg" else f"image/{ext[1:]}"
|
|
80
|
+
self._logo_b64 = f"data:{mime};base64,{base64.b64encode(raw).decode()}"
|
|
81
|
+
return self._logo_b64
|
|
82
|
+
brand_dir = Path(__file__).resolve().parent.parent.parent / "assets" / "images"
|
|
83
|
+
fallback = brand_dir / "logo-g360-dark.svg"
|
|
84
|
+
if fallback.exists():
|
|
85
|
+
raw = fallback.read_bytes()
|
|
86
|
+
self._logo_b64 = f"data:image/svg+xml;base64,{base64.b64encode(raw).decode()}"
|
|
87
|
+
return self._logo_b64
|
|
88
|
+
return None
|
|
89
|
+
|
|
90
|
+
def build_name(self):
|
|
91
|
+
build_cfg = self.config.get("build", {})
|
|
92
|
+
return build_cfg.get("name", "G360-App")
|
|
93
|
+
|
|
94
|
+
def logo_component(self, height=40):
|
|
95
|
+
import flet as ft
|
|
96
|
+
src = self.logo_base64()
|
|
97
|
+
if src:
|
|
98
|
+
return ft.Image(src_base64=src, height=height, fit=ft.ImageFit.CONTAIN)
|
|
99
|
+
return ft.Text(self.build_name(), size=18, weight=ft.FontWeight.BOLD, color=self.accent)
|
|
100
|
+
|
|
101
|
+
def container(self, content=None, **kwargs):
|
|
102
|
+
kwargs.setdefault("bgcolor", self.surface)
|
|
103
|
+
kwargs.setdefault("border_radius", self.rounded)
|
|
104
|
+
kwargs.setdefault("padding", 15)
|
|
105
|
+
if self.glassmorphism and "shadow" not in kwargs:
|
|
106
|
+
import flet as ft
|
|
107
|
+
kwargs["shadow"] = ft.BoxShadow(
|
|
108
|
+
spread_radius=1,
|
|
109
|
+
blur_radius=20,
|
|
110
|
+
color=f"{self.accent}20",
|
|
111
|
+
)
|
|
112
|
+
import flet as ft
|
|
113
|
+
return ft.Container(content=content, **kwargs)
|
|
114
|
+
|
|
115
|
+
def accent_button(self, text="", on_click=None, **kwargs):
|
|
116
|
+
import flet as ft
|
|
117
|
+
return ft.ElevatedButton(
|
|
118
|
+
text=text,
|
|
119
|
+
on_click=on_click,
|
|
120
|
+
style=ft.ButtonStyle(
|
|
121
|
+
bgcolor=self.accent,
|
|
122
|
+
color=self.bg,
|
|
123
|
+
shape=ft.RoundedRectangleBorder(radius=8),
|
|
124
|
+
padding=15,
|
|
125
|
+
),
|
|
126
|
+
**kwargs,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
def styled_text(self, value="", size=14, color=None, weight=None, **kwargs):
|
|
130
|
+
import flet as ft
|
|
131
|
+
return ft.Text(
|
|
132
|
+
value=value,
|
|
133
|
+
size=size,
|
|
134
|
+
color=color or self.text,
|
|
135
|
+
weight=weight,
|
|
136
|
+
**kwargs,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
def loading_overlay(self, message="Cargando..."):
|
|
140
|
+
import flet as ft
|
|
141
|
+
return ft.Container(
|
|
142
|
+
content=ft.Column(
|
|
143
|
+
[
|
|
144
|
+
ft.ProgressRing(width=48, height=48, color=self.accent),
|
|
145
|
+
ft.Container(height=16),
|
|
146
|
+
ft.Text(message, size=16, color=self.text),
|
|
147
|
+
],
|
|
148
|
+
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
|
|
149
|
+
alignment=ft.MainAxisAlignment.CENTER,
|
|
150
|
+
),
|
|
151
|
+
bgcolor=f"{self.bg}E0",
|
|
152
|
+
expand=True,
|
|
153
|
+
alignment=ft.alignment.center,
|
|
154
|
+
visible=False,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
def footer_signature(self):
|
|
158
|
+
import flet as ft
|
|
159
|
+
mode = self.config.get("signature", {}).get("mode", "powered")
|
|
160
|
+
text = self.config.get("signature", {}).get("text", "powered by G360")
|
|
161
|
+
return ft.Container(
|
|
162
|
+
content=ft.Row(
|
|
163
|
+
[
|
|
164
|
+
self.logo_component(height=16),
|
|
165
|
+
ft.Container(width=8),
|
|
166
|
+
ft.Text(text, size=10, color=self.muted),
|
|
167
|
+
],
|
|
168
|
+
alignment=ft.MainAxisAlignment.CENTER,
|
|
169
|
+
),
|
|
170
|
+
padding=8,
|
|
171
|
+
bgcolor=self.surface,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def as_dict(self):
|
|
176
|
+
return {
|
|
177
|
+
"bg": self.bg,
|
|
178
|
+
"surface": self.surface,
|
|
179
|
+
"accent": self.accent,
|
|
180
|
+
"text": self.text,
|
|
181
|
+
"muted": self.muted,
|
|
182
|
+
"success": self.success,
|
|
183
|
+
"warning": self.warning,
|
|
184
|
+
"error": self.error,
|
|
185
|
+
"brand": self.brand,
|
|
186
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "flet-desktop",
|
|
3
|
+
"description": "G360 Flet Migration Application",
|
|
4
|
+
"framework": "flet",
|
|
5
|
+
"version": "1.2.0",
|
|
6
|
+
"python": ">=3.11,<4.0",
|
|
7
|
+
"colors": {
|
|
8
|
+
"bg": "#0b1220",
|
|
9
|
+
"surface": "#1a2332",
|
|
10
|
+
"accent": "#00d084",
|
|
11
|
+
"text": "#f0f4f8",
|
|
12
|
+
"muted": "#94a3b8",
|
|
13
|
+
"success": "#22c55e",
|
|
14
|
+
"warning": "#f59e0b",
|
|
15
|
+
"error": "#ef4444"
|
|
16
|
+
},
|
|
17
|
+
"effects": {
|
|
18
|
+
"glassmorphism": true,
|
|
19
|
+
"blur": "12px",
|
|
20
|
+
"rounded": "12px"
|
|
21
|
+
},
|
|
22
|
+
"signature": {
|
|
23
|
+
"mode": "powered",
|
|
24
|
+
"text": "powered by G360"
|
|
25
|
+
},
|
|
26
|
+
"build": {
|
|
27
|
+
"tool": "flet",
|
|
28
|
+
"target": "windows",
|
|
29
|
+
"name": "G360-App"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"flet": ">=0.25.0"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
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))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class MigratedApp:
|
|
12
|
+
def __init__(self, page: ft.Page):
|
|
13
|
+
self.page = page
|
|
14
|
+
self.theme = G360Theme()
|
|
15
|
+
self._setup_page()
|
|
16
|
+
self._build_ui()
|
|
17
|
+
|
|
18
|
+
def _setup_page(self):
|
|
19
|
+
self.page.title = self.theme.build_name()
|
|
20
|
+
self.page.theme_mode = ft.ThemeMode.DARK
|
|
21
|
+
self.page.bgcolor = self.theme.bg
|
|
22
|
+
self.page.padding = 0
|
|
23
|
+
self.page.window_width = 900
|
|
24
|
+
self.page.window_height = 700
|
|
25
|
+
self.page.window_resizable = True
|
|
26
|
+
self.page.window_center()
|
|
27
|
+
|
|
28
|
+
def _build_ui(self):
|
|
29
|
+
self.page.add(
|
|
30
|
+
ft.Column([
|
|
31
|
+
self._build_header(),
|
|
32
|
+
ft.Container(
|
|
33
|
+
content=self._build_content(),
|
|
34
|
+
expand=True,
|
|
35
|
+
padding=20,
|
|
36
|
+
),
|
|
37
|
+
self.theme.footer_signature(),
|
|
38
|
+
], spacing=0, expand=True)
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
def _build_header(self):
|
|
42
|
+
return self.theme.container(
|
|
43
|
+
content=ft.Row([
|
|
44
|
+
self.theme.logo_component(height=32),
|
|
45
|
+
ft.Container(width=8),
|
|
46
|
+
self.theme.styled_text("Migrated App", size=20, color=self.theme.muted),
|
|
47
|
+
ft.Container(expand=True),
|
|
48
|
+
ft.Text("from tkinter/ctkinter", size=14, color=self.theme.muted),
|
|
49
|
+
]),
|
|
50
|
+
padding=20,
|
|
51
|
+
bgcolor=self.theme.surface,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def _build_content(self):
|
|
55
|
+
return ft.Column([
|
|
56
|
+
self.theme.styled_text(
|
|
57
|
+
"Panel de Controles (antes tk.Button)",
|
|
58
|
+
size=20, weight=ft.FontWeight.BOLD,
|
|
59
|
+
),
|
|
60
|
+
ft.Row([
|
|
61
|
+
self.theme.accent_button("Aceptar"),
|
|
62
|
+
ft.ElevatedButton("Cancelar", bgcolor=self.theme.error, color="#ffffff"),
|
|
63
|
+
ft.ElevatedButton("Guardar", bgcolor="#00796B", color="#ffffff"),
|
|
64
|
+
], spacing=15),
|
|
65
|
+
ft.Container(height=30),
|
|
66
|
+
self.theme.styled_text(
|
|
67
|
+
"Campos de Entrada (antes tk.Entry)",
|
|
68
|
+
size=20, weight=ft.FontWeight.BOLD,
|
|
69
|
+
),
|
|
70
|
+
ft.Column([
|
|
71
|
+
ft.TextField(label="Usuario", hint_text="Ingrese usuario", width=300),
|
|
72
|
+
ft.TextField(label="Contraseña", hint_text="Ingrese contraseña", password=True, width=300),
|
|
73
|
+
], spacing=15),
|
|
74
|
+
ft.Container(height=30),
|
|
75
|
+
self.theme.styled_text(
|
|
76
|
+
"Casillas y Opciones (antes tk.Checkbutton/tk.Radiobutton)",
|
|
77
|
+
size=20, weight=ft.FontWeight.BOLD,
|
|
78
|
+
),
|
|
79
|
+
ft.Column([
|
|
80
|
+
ft.Checkbox(label="Recordarme"),
|
|
81
|
+
ft.Checkbox(label="Aceptar términos"),
|
|
82
|
+
], spacing=10),
|
|
83
|
+
], scroll=ft.ScrollMode.AUTO)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def main(page: ft.Page):
|
|
87
|
+
MigratedApp(page)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
if __name__ == "__main__":
|
|
91
|
+
try:
|
|
92
|
+
ft.run(main)
|
|
93
|
+
except Exception as e:
|
|
94
|
+
print(f"\n[FATAL] Error al iniciar la aplicacion: {e}", flush=True)
|
|
95
|
+
import traceback
|
|
96
|
+
traceback.print_exc()
|
|
97
|
+
input("\nPresione Enter para salir...")
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Migración de tkinter/ctkinter a Flet
|
|
3
|
+
Script de ayuda para convertir código existente
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
MAPPING = {
|
|
7
|
+
'tk.Label': 'ft.Text',
|
|
8
|
+
'tk.Button': 'ft.ElevatedButton',
|
|
9
|
+
'tk.Entry': 'ft.TextField',
|
|
10
|
+
'tk.Checkbutton': 'ft.Checkbox',
|
|
11
|
+
'tk.Radiobutton': 'ft.Radio',
|
|
12
|
+
'tk.Listbox': 'ft.ListView',
|
|
13
|
+
'tk.Frame': 'ft.Container',
|
|
14
|
+
'tk.LabelFrame': 'ft.Container with border',
|
|
15
|
+
'tk.Canvas': 'ft.Canvas',
|
|
16
|
+
'tk.Menu': 'ft.AppBar with actions',
|
|
17
|
+
'ctk.CTkButton': 'ft.ElevatedButton',
|
|
18
|
+
'ctk.CTkLabel': 'ft.Text',
|
|
19
|
+
'ctk.CTkEntry': 'ft.TextField',
|
|
20
|
+
'ctk.CTkFrame': 'ft.Container',
|
|
21
|
+
'ctk.CTkCheckBox': 'ft.Checkbox',
|
|
22
|
+
'ctk.CTkRadioButton': 'ft.Radio',
|
|
23
|
+
'ctk.CTkProgressBar': 'ft.ProgressBar',
|
|
24
|
+
'ctk.CTkSlider': 'ft.Slider',
|
|
25
|
+
'ctk.CTkSwitch': 'ft.Switch',
|
|
26
|
+
'ctk.CTkComboBox': 'ft.Dropdown',
|
|
27
|
+
'ctk.CTkTextbox': 'ft.TextField multiline',
|
|
28
|
+
'ctk.CTkTabview': 'ft.Tabs',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
LAYOUT_MAPPING = {
|
|
32
|
+
'pack()': 'page.add()',
|
|
33
|
+
'pack(fill=..., expand=...)': 'expand=True, alignment=...',
|
|
34
|
+
'grid(row=..., column=...)': 'use Column with Row for grid-like',
|
|
35
|
+
'place(x=..., y=...)': 'position in Container',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
THEME_MAPPING = {
|
|
39
|
+
'bg': 'bgcolor',
|
|
40
|
+
'fg': 'color',
|
|
41
|
+
'font': 'size + weight',
|
|
42
|
+
'relief': 'border_style',
|
|
43
|
+
'padx/pady': 'padding',
|
|
44
|
+
'width': 'width',
|
|
45
|
+
'height': 'height',
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
def convert_tkinter_to_flet(code: str) -> str:
|
|
49
|
+
result = code
|
|
50
|
+
for tk_widget, flet_widget in MAPPING.items():
|
|
51
|
+
result = result.replace(tk_widget, flet_widget)
|
|
52
|
+
return result
|
|
53
|
+
|
|
54
|
+
print("Mapeo de tkinter/ctkinter a Flet cargado")
|
|
55
|
+
print("Usa: from migrate_tkinter import convert_tkinter_to_flet")
|
|
56
|
+
print("Para convertir código existente a Flet")
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
"
|
|
2
|
+
"name": "solid-web",
|
|
3
|
+
"description": "G360 SolidJS Application",
|
|
4
|
+
"framework": "solid",
|
|
5
5
|
"version": "1.0.0",
|
|
6
|
-
"createdAt": "2024-01-01T00:00:00.000Z",
|
|
7
6
|
"colors": {
|
|
8
7
|
"bg": "#0b1220",
|
|
9
8
|
"surface": "#151e2e",
|
|
10
9
|
"accent": "#00d084",
|
|
11
10
|
"text": "#f0f4f8",
|
|
12
|
-
"muted": "#94a3b8"
|
|
11
|
+
"muted": "#94a3b8",
|
|
12
|
+
"success": "#22c55e",
|
|
13
|
+
"warning": "#f59e0b",
|
|
14
|
+
"error": "#ef4444"
|
|
15
|
+
},
|
|
16
|
+
"effects": {
|
|
17
|
+
"glassmorphism": true,
|
|
18
|
+
"blur": "12px",
|
|
19
|
+
"rounded": "12px"
|
|
13
20
|
},
|
|
14
21
|
"signature": {
|
|
15
22
|
"mode": "powered",
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"
|
|
4
|
-
"
|
|
2
|
+
"name": "svelte-web",
|
|
3
|
+
"description": "G360 SvelteKit Application",
|
|
4
|
+
"framework": "svelte",
|
|
5
5
|
"version": "1.0.0",
|
|
6
|
-
"createdAt": "2024-01-01T00:00:00.000Z",
|
|
7
6
|
"colors": {
|
|
8
7
|
"bg": "#0b1220",
|
|
9
8
|
"surface": "#151e2e",
|
|
10
9
|
"accent": "#00d084",
|
|
11
10
|
"text": "#f0f4f8",
|
|
12
|
-
"muted": "#94a3b8"
|
|
11
|
+
"muted": "#94a3b8",
|
|
12
|
+
"success": "#22c55e",
|
|
13
|
+
"warning": "#f59e0b",
|
|
14
|
+
"error": "#ef4444"
|
|
15
|
+
},
|
|
16
|
+
"effects": {
|
|
17
|
+
"glassmorphism": true,
|
|
18
|
+
"blur": "12px",
|
|
19
|
+
"rounded": "12px"
|
|
13
20
|
},
|
|
14
21
|
"signature": {
|
|
15
22
|
"mode": "powered",
|
|
@@ -9,15 +9,10 @@
|
|
|
9
9
|
<title>Mi Proyecto G360</title>
|
|
10
10
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
11
11
|
<link rel="manifest" href="/manifest.json" />
|
|
12
|
-
<link rel="stylesheet" href="/styles.css" />
|
|
12
|
+
<link rel="stylesheet" href="/src/styles/main.css" />
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
15
|
<div id="root"></div>
|
|
16
|
-
|
|
17
|
-
<!-- Firma G360 -->
|
|
18
|
-
<g360-signature mode="powered" style="position: fixed; bottom: 16px; right: 16px; z-index: 100;"></g360-signature>
|
|
19
|
-
|
|
20
|
-
<script type="module" src="https://unpkg.com/g360-signature@1.0.0/index.js"></script>
|
|
21
|
-
<script type="module" src="/app.js"></script>
|
|
16
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
22
17
|
</body>
|
|
23
18
|
</html>
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<circle cx="16" cy="16" r="14" fill="#0b1220" stroke="#00d084" stroke-width="2"/>
|
|
3
|
+
<text x="16" y="22" text-anchor="middle" font-family="Arial Black,sans-serif" font-size="16" font-weight="bold" fill="#00d084">G</text>
|
|
4
|
+
</svg>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import Header from './components/Header';
|
|
3
|
+
import LoadingOverlay from './components/LoadingOverlay';
|
|
4
|
+
import FooterSignature from './components/FooterSignature';
|
|
5
|
+
|
|
6
|
+
function App() {
|
|
7
|
+
const [loading, setLoading] = useState(false);
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<div className="app">
|
|
11
|
+
<Header />
|
|
12
|
+
<main className="container">
|
|
13
|
+
<h1>Bienvenido a G360</h1>
|
|
14
|
+
<p className="muted">Proyecto creado con React + Vite</p>
|
|
15
|
+
</main>
|
|
16
|
+
<FooterSignature />
|
|
17
|
+
{loading && <LoadingOverlay message="Cargando..." />}
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default App;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "corporativo-movil",
|
|
3
|
+
"description": "G360 React + Vite Application",
|
|
4
|
+
"framework": "react",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"colors": {
|
|
7
|
+
"bg": "#0b1220",
|
|
8
|
+
"surface": "#151e2e",
|
|
9
|
+
"accent": "#00d084",
|
|
10
|
+
"text": "#f0f4f8",
|
|
11
|
+
"muted": "#94a3b8",
|
|
12
|
+
"success": "#22c55e",
|
|
13
|
+
"warning": "#f59e0b",
|
|
14
|
+
"error": "#ef4444"
|
|
15
|
+
},
|
|
16
|
+
"effects": {
|
|
17
|
+
"glassmorphism": true,
|
|
18
|
+
"blur": "16px",
|
|
19
|
+
"rounded": "16px"
|
|
20
|
+
},
|
|
21
|
+
"signature": {
|
|
22
|
+
"mode": "powered",
|
|
23
|
+
"text": "powered by G360"
|
|
24
|
+
}
|
|
25
|
+
}
|