Skip to content

Commit 6b52990

Browse files
committed
graphics checkin
1 parent 016615d commit 6b52990

File tree

22 files changed

+696
-53
lines changed

22 files changed

+696
-53
lines changed

Diff for: api_logic_server_cli/genai/genai_graphics.py

+33-13
Original file line numberDiff line numberDiff line change
@@ -139,23 +139,45 @@ def create_data_class_methods(self, graphics_response_path: Path):
139139
def create_graphics_dashboard_service(self, graphics_response_path: Path):
140140
""" Process graphics response from ChatGPT graphics_response_path """
141141

142-
shutil.copy(self.manager_path.joinpath('system/genai/graphics_templates/dashboard_services.jinja'),
143-
self.project.project_directory_path.joinpath('api/api_discovery/dashboard_services.py') ) # all the api methods are created in this file
144-
145142
# open and read the graphics_response_path json file
146143
assert graphics_response_path.exists(), f'Graphics response file not found: {graphics_response_path}'
147144
with open(graphics_response_path, 'r') as file:
148145
graphics_response = json.load(file)
146+
if 'graphics' not in graphics_response:
147+
log.error(f'No graphics found in {graphics_response_path}')
148+
return
149149
graphics = graphics_response['graphics']
150+
151+
env = Environment(loader=FileSystemLoader(self.manager_path.joinpath('system/genai/graphics_templates')))
152+
iframe_templates= []
153+
has_iframe = False
154+
iframe_links = []
155+
dashboards = []
156+
cnt = 0
157+
template = env.get_template('dashboard_services.jinja')
150158
for each_graphic in graphics: # add each service to api/api_discovery
159+
cnt += 1
160+
server = '{server}'
161+
iframe = f'iframe_{cnt} = iframe_template.format(url=f"{server}chart_graphics/{each_graphic['name']}")\n'
162+
iframe_templates.append(iframe)
163+
link = "{"+ f'iframe_{cnt}' + "}"
164+
iframe_links.append(f'{link}')
165+
sqlalchemy_query = each_graphic['sqlalchemy_query'].split("session.query(")[1].split(',')[0].split(".")[0].replace('\n', '').strip()
166+
db = f"""
167+
results = models.{sqlalchemy_query}.{each_graphic['name']}(None)
168+
color = 'rgba(75, 192, 192, 0.2)'
169+
dashboard{cnt} = template.render(result=results, color=color)
170+
dashboard_result['{each_graphic['name']}']= dashboard{cnt}
171+
"""
172+
dashboards.append(db)
173+
174+
rendered_result = template.render(iframe_templates=iframe_templates, iframe_links=" ".join(iframe_links), has_iframe=cnt > 0 , dashboards= dashboards)
175+
with open(self.project.project_directory_path.joinpath(f'api/api_discovery/dashboard_services.py'), 'a') as out_file:
176+
out_file.write(rendered_result)
177+
log.info(f'.. added dashboard service to api_discovery')
178+
179+
for each_graphic in graphics:
151180
self.fix_sqlalchemy_query(each_graphic)
152-
env = Environment(loader=FileSystemLoader(self.manager_path.joinpath('system/genai/graphics_templates')))
153-
154-
template = env.get_template('dashboard_services_each_method.jinja')
155-
rendered_result = template.render( **each_graphic )
156-
with open(self.project.project_directory_path.joinpath(f'api/api_discovery/dashboard_services.py'), 'a') as out_file:
157-
out_file.write(rendered_result)
158-
159181
template = env.get_template('html_template.jinja')
160182
rendered_result = template.render( **each_graphic )
161183
with open(self.project.project_directory_path.joinpath(f'api/api_discovery/{each_graphic['name']}.html'), 'w') as out_file:
@@ -168,9 +190,7 @@ def create_graphics_dashboard_service(self, graphics_response_path: Path):
168190
out_file.write(sql_query)
169191

170192
log.info(f'.. added dashboard query: {each_graphic['name']} to api_discovery')
171-
return_result = '\n return jsonify(dashboard_result)\n'
172-
with open(self.project.project_directory_path.joinpath(f'api/api_discovery/dashboard_services.py'), 'a') as out_file:
173-
out_file.write(return_result)
193+
174194
pass
175195

176196
def fix_sqlalchemy_query(self, graphic: Dict):

Diff for: api_logic_server_cli/prototypes/base/ui/admin/home.js

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ const sla_doc =
77
'creates <i>customizable</i> model-driven systems, instantly from your ' +
88
'database:' +
99
'</h3>' +
10+
'<div class="dashboard-iframe">' +
11+
'<iframe id="iframeTargetDashboard" src="http://localhost:5656/dashboard" style="flex: 1; border: none; width: 100%; height: 200px;"></iframe>' +
12+
'</div>' +
1013
'<h4>1. Automatic Admin App</h4>' +
1114
'<ul>' +
1215
' <li>For instant collaboration and Back Office data maintenance</li>' +
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Sales by Region</title>
7+
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
8+
<style>
9+
body {
10+
margin: 0;
11+
padding: 0;
12+
display: flex;
13+
overflow: hidden;
14+
justify-content: center;
15+
align-items: center;
16+
height: 100%;
17+
box-sizing: border-box;
18+
}
19+
canvas {
20+
display: block;
21+
}
22+
</style>
23+
</head>
24+
<body>
25+
<canvas id="salesChart" width="200" height="200"></canvas>
26+
<script>
27+
const labels = [];
28+
const data = [];
29+
result = {{ result | tojson }};
30+
console.log(result);
31+
const type = result.chart_type;
32+
const title = result.title;
33+
const columns = result.columns;
34+
console.log(JSON.stringify(result));
35+
result.results.forEach(item => {
36+
labels.push(item[columns[0]]);
37+
data.push(parseFloat(item[columns[1]]));
38+
});
39+
const ctx = document.getElementById('salesChart').getContext('2d');
40+
const salesChart = new Chart(ctx, {
41+
type: type,
42+
data: {
43+
labels: labels,
44+
datasets: [{
45+
label: title,
46+
data: data,
47+
backgroundColor: {{ color | tojson }},
48+
borderColor: 'rgba(75, 192, 192, 1)',
49+
borderWidth: 1
50+
}]
51+
},
52+
options: {
53+
responsive: true,
54+
maintainAspectRatio: false,
55+
scales: {
56+
y: {
57+
beginAtZero: true
58+
}
59+
}
60+
}
61+
});
62+
</script>
63+
</body>
64+
</html>

Diff for: api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/dashboard_services.jinja

+45-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import decimal as decimal
77
from sqlalchemy import extract, func
88
from flask import request, jsonify
99
from safrs import jsonapi_rpc, SAFRSAPI
10+
from database.models import models
1011
import safrs
1112

1213
"""
@@ -21,18 +22,58 @@ You typically do not alter this file.
2122
"""
2223

2324
app_logger = logging.getLogger(__name__)
24-
25-
dashboard_result = {'dashboard': []}
25+
dashboard_result = {}
2626

2727

2828
def add_service(app, api, project_dir, swagger_host: str, PORT: str, method_decorators = []):
2929
pass
3030

31-
@app.route('/dashboard')
31+
@app.route('/dashboard', methods=['GET','OPTIONS'])
3232
def dashboard():
3333

34+
35+
if request.method == 'OPTIONS':
36+
return jsonify({"result": "ok"})
37+
38+
server = request.host_url
39+
40+
iframe_template = '<div class="dashboard-iframe"><iframe src="{url}" style="flex: 1; border: none; width: 90%; height: 200px;"></iframe></div>'
41+
{% for iframe in iframe_templates %}
42+
{{iframe}}
43+
{% endfor %}
44+
45+
{% if has_iframe %}
46+
return f'<div style="display: flex; flex-direction: row; gap: 10px; border: none; ">{{ iframe_links }}</div>'
47+
{% endif %}
48+
{% if has_iframe == false %}
49+
return jsonify({})
50+
{% endif %}
51+
52+
@app.route('/chart_graphics/<path:path>', methods=['GET','OPTIONS'])
53+
def chart_graphics(path):
54+
if request.method == 'OPTIONS':
55+
return jsonify({"result": "ok"})
56+
57+
dashboards = get_dashboards()
58+
if len(dashboards) == 0:
59+
return jsonify({"result": "No dashboards Found"}), 404
60+
if path in dashboards:
61+
return dashboards[path]
62+
return jsonify({"result": "not found"}), 404
3463
##############################
3564
# generated queries follow
3665
##############################
3766

38-
67+
def get_dashboards():
68+
if len(dashboard_result) > 0:
69+
return dashboard_result
70+
71+
from jinja2 import Environment, FileSystemLoader
72+
env = Environment(loader = FileSystemLoader('ui/templates'))
73+
template = env.get_template('bar_chart.jinja')
74+
75+
{% for dashboard in dashboards %}
76+
{{dashboard}}
77+
{% endfor %}
78+
79+
return dashboard_result

Diff for: api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/dashboard_services_each_method.jinja

-30
This file was deleted.

Diff for: api_logic_server_cli/prototypes/manager/system/genai/graphics_templates/graphics_services_db_each_method.jinja

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
@classmethod
23
@add_method(models.{{class_x_axis}})
34
@jsonapi_rpc(http_methods=['GET', 'OPTIONS'])
@@ -15,19 +16,19 @@ def {{name}}(*args, **kwargs):
1516
# Security.set_user_sa() # an endpoint that requires no auth header (see also @bypass_security)
1617

1718
# SQLAlchemy query
18-
query = {{sqlalchemy_query}}
19+
query = {{ sqlalchemy_query }}
1920
# Execute query and fetch results
2021
results = query.all()
2122
from decimal import Decimal
22-
columns = ['RegionDescription', 'TotalSales'] # {{ xAxis }} {{ yAxis }}
23-
results = [{columns[0]: row[0], columns[1]: str(Decimal(row[1]).quantize(Decimal('0.01')))} for row in results]
24-
title = "Sales by Region" # {{ title }}
25-
chart_type = 'bar' # {{ chart_type }}
23+
columns = ['{{ xAxis }}' , '{{ yAxis }}']
24+
results = [{columns[0]: row[0], columns[1]: row[1]} for row in results]
25+
title = '{{ title }}'
26+
graph_type = '{{ graph_type }}'
2627
json_results = {
2728
"results": results,
2829
"columns": columns,
2930
"title": title,
30-
"chart_type": "bar",
31+
"chart_type": graph_type,
3132
"xAxis": columns[0],
3233
"yAxis": columns[1],
3334
}

Diff for: apilogicserver-14.3.14/api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/wg_demo_no_logic_fixed/system/genai/examples/genai_demo/wg_dev_merge/base_genai_demo_no_logic/ui/app/.dockerignore

+34
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,40 @@ README.md
3838
# For more help, visit the .dockerignore file reference guide at
3939
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
4040

41+
**/.DS_Store
42+
**/__pycache__
43+
**/.venv
44+
**/.classpath
45+
**/.dockerignore
46+
**/.env
47+
**/.git
48+
**/.gitignore
49+
**/.project
50+
**/.settings
51+
**/.toolstarget
52+
**/.vs
53+
**/.vscode
54+
**/*.*proj.user
55+
**/*.dbmdl
56+
**/*.jfm
57+
**/bin
58+
**/charts
59+
**/docker-compose*
60+
**/compose*
61+
**/Dockerfile*
62+
**/node_modules
63+
**/npm-debug.log
64+
**/obj
65+
**/secrets.dev.yaml
66+
**/values.dev.yaml
67+
LICENSE
68+
README.md
69+
# Include any files or directories that you don't want to be copied to your
70+
# container here (e.g., local build artifacts, temporary files, etc.).
71+
#
72+
# For more help, visit the .dockerignore file reference guide at
73+
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
74+
4175
**/.DS_Store
4276
**/__pycache__
4377
**/.venv

Diff for: apilogicserver-14.3.14/api_logic_server_cli/prototypes/manager/system/genai/examples/genai_demo/wg_dev_merge/wg_demo_no_logic_fixed/system/genai/examples/genai_demo/wg_dev_merge/dev_demo_no_logic_fixed/ui/app/.dockerignore

+34
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,40 @@ README.md
3838
# For more help, visit the .dockerignore file reference guide at
3939
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
4040

41+
**/.DS_Store
42+
**/__pycache__
43+
**/.venv
44+
**/.classpath
45+
**/.dockerignore
46+
**/.env
47+
**/.git
48+
**/.gitignore
49+
**/.project
50+
**/.settings
51+
**/.toolstarget
52+
**/.vs
53+
**/.vscode
54+
**/*.*proj.user
55+
**/*.dbmdl
56+
**/*.jfm
57+
**/bin
58+
**/charts
59+
**/docker-compose*
60+
**/compose*
61+
**/Dockerfile*
62+
**/node_modules
63+
**/npm-debug.log
64+
**/obj
65+
**/secrets.dev.yaml
66+
**/values.dev.yaml
67+
LICENSE
68+
README.md
69+
# Include any files or directories that you don't want to be copied to your
70+
# container here (e.g., local build artifacts, temporary files, etc.).
71+
#
72+
# For more help, visit the .dockerignore file reference guide at
73+
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
74+
4175
**/.DS_Store
4276
**/__pycache__
4377
**/.venv

Diff for: apilogicserver-14.3.14/api_logic_server_cli/prototypes/ont_app/ontimize_seed/.dockerignore

+34
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,40 @@ README.md
3838
# For more help, visit the .dockerignore file reference guide at
3939
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
4040

41+
**/.DS_Store
42+
**/__pycache__
43+
**/.venv
44+
**/.classpath
45+
**/.dockerignore
46+
**/.env
47+
**/.git
48+
**/.gitignore
49+
**/.project
50+
**/.settings
51+
**/.toolstarget
52+
**/.vs
53+
**/.vscode
54+
**/*.*proj.user
55+
**/*.dbmdl
56+
**/*.jfm
57+
**/bin
58+
**/charts
59+
**/docker-compose*
60+
**/compose*
61+
**/Dockerfile*
62+
**/node_modules
63+
**/npm-debug.log
64+
**/obj
65+
**/secrets.dev.yaml
66+
**/values.dev.yaml
67+
LICENSE
68+
README.md
69+
# Include any files or directories that you don't want to be copied to your
70+
# container here (e.g., local build artifacts, temporary files, etc.).
71+
#
72+
# For more help, visit the .dockerignore file reference guide at
73+
# https://docs.docker.com/engine/reference/builder/#dockerignore-file
74+
4175
**/.DS_Store
4276
**/__pycache__
4377
**/.venv

0 commit comments

Comments
 (0)