ApiLogicServer 15.0.37__py3-none-any.whl → 15.0.40__py3-none-any.whl

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.
Files changed (55) hide show
  1. api_logic_server_cli/api_logic_server.py +2 -2
  2. api_logic_server_cli/api_logic_server_info.yaml +2 -2
  3. api_logic_server_cli/genai/genai_svcs.py +4 -3
  4. api_logic_server_cli/prototypes/base/.copilot-instructions.md +10 -0
  5. api_logic_server_cli/prototypes/base/.vscode/.copilot-instructions.md +178 -0
  6. api_logic_server_cli/prototypes/base/README_PROJECT.md +43 -0
  7. api_logic_server_cli/prototypes/base/api_logic_server_run.py +20 -8
  8. api_logic_server_cli/prototypes/base/docs/training/react_map.prompt.md +13 -0
  9. api_logic_server_cli/prototypes/base/docs/training/react_tree.prompt.md +10 -0
  10. api_logic_server_cli/prototypes/base/integration/mcp/readme-mcp.md +9 -0
  11. api_logic_server_cli/prototypes/base/logic/logic_discovery/readme_logic_discovery.md +9 -0
  12. api_logic_server_cli/prototypes/base/logic/logic_discovery/use_case.py +27 -0
  13. api_logic_server_cli/prototypes/base/logic/{readme_declare_logic.md → readme_logic.md} +70 -1
  14. api_logic_server_cli/prototypes/base/readme.md +30 -5
  15. api_logic_server_cli/prototypes/base/security/readme_security.md +17 -0
  16. api_logic_server_cli/prototypes/manager/.copilot-instructions.md +13 -0
  17. api_logic_server_cli/prototypes/manager/.vscode/.copilot-instructions.md +58 -0
  18. api_logic_server_cli/prototypes/manager/.vscode/ApiLogicServer.code-workspace +2 -2
  19. api_logic_server_cli/prototypes/manager/README.md +13 -1
  20. api_logic_server_cli/prototypes/manager/system/Manager_workspace.code-workspace +3 -3
  21. api_logic_server_cli/prototypes/nw/api/api_discovery/authentication_expose_api_models.py +53 -0
  22. api_logic_server_cli/prototypes/nw/api/api_discovery/auto_discovery.py +27 -0
  23. api_logic_server_cli/prototypes/nw/api/api_discovery/count_orders_by_month.html +76 -0
  24. api_logic_server_cli/prototypes/nw/api/api_discovery/count_orders_by_month.sql +1 -0
  25. api_logic_server_cli/prototypes/nw/api/api_discovery/dashboard_services.py +143 -0
  26. api_logic_server_cli/prototypes/nw/api/api_discovery/mcp_discovery.py +97 -0
  27. api_logic_server_cli/prototypes/nw/api/api_discovery/new_service.py +21 -0
  28. api_logic_server_cli/prototypes/nw/api/api_discovery/newer_service.py +21 -0
  29. api_logic_server_cli/prototypes/nw/api/api_discovery/number_of_sales_per_category.html +76 -0
  30. api_logic_server_cli/prototypes/nw/api/api_discovery/number_of_sales_per_category.sql +1 -0
  31. api_logic_server_cli/prototypes/nw/api/api_discovery/ontimize_api.py +495 -0
  32. api_logic_server_cli/prototypes/nw/api/api_discovery/sales_by_category.html +76 -0
  33. api_logic_server_cli/prototypes/nw/api/api_discovery/sales_by_category.sql +1 -0
  34. api_logic_server_cli/prototypes/nw/api/api_discovery/system.py +77 -0
  35. api_logic_server_cli/prototypes/nw/database/database_discovery/graphics_services.py +173 -0
  36. api_logic_server_cli/prototypes/nw/ui/admin/home.js +5 -0
  37. api_logic_server_cli/prototypes/nw/ui/reference_react_app/DEPARTMENT_TREE_VIEW.md +66 -0
  38. api_logic_server_cli/prototypes/nw/ui/reference_react_app/README.md +21 -4
  39. api_logic_server_cli/prototypes/nw/ui/reference_react_app/package.json +4 -0
  40. api_logic_server_cli/prototypes/nw/ui/reference_react_app/public/index.html +3 -0
  41. api_logic_server_cli/prototypes/nw/ui/reference_react_app/src/App.js +8 -1
  42. api_logic_server_cli/prototypes/nw/ui/reference_react_app/src/CustomLayout.js +20 -0
  43. api_logic_server_cli/prototypes/nw/ui/reference_react_app/src/Department.js +511 -24
  44. api_logic_server_cli/prototypes/nw/ui/reference_react_app/src/DepartmentTree.js +147 -0
  45. api_logic_server_cli/prototypes/nw/ui/reference_react_app/src/Employee.js +230 -18
  46. api_logic_server_cli/prototypes/nw/ui/reference_react_app/src/LandingPage.js +264 -0
  47. api_logic_server_cli/prototypes/nw/ui/reference_react_app/src/Supplier.js +359 -121
  48. api_logic_server_cli/prototypes/nw/ui/reference_react_app/src/index.js +1 -0
  49. {apilogicserver-15.0.37.dist-info → apilogicserver-15.0.40.dist-info}/METADATA +1 -1
  50. {apilogicserver-15.0.37.dist-info → apilogicserver-15.0.40.dist-info}/RECORD +54 -25
  51. api_logic_server_cli/prototypes/base/docs/training/admin_app_unused.md +0 -156
  52. {apilogicserver-15.0.37.dist-info → apilogicserver-15.0.40.dist-info}/WHEEL +0 -0
  53. {apilogicserver-15.0.37.dist-info → apilogicserver-15.0.40.dist-info}/entry_points.txt +0 -0
  54. {apilogicserver-15.0.37.dist-info → apilogicserver-15.0.40.dist-info}/licenses/LICENSE +0 -0
  55. {apilogicserver-15.0.37.dist-info → apilogicserver-15.0.40.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,173 @@
1
+ from database import models
2
+ import logging
3
+ from safrs import jsonapi_attr
4
+ from sqlalchemy.orm import relationship, remote, foreign
5
+ from functools import wraps # This convenience func preserves name and docstring
6
+ import decimal as decimal
7
+ from sqlalchemy import extract, func
8
+ from flask import request, jsonify
9
+ from safrs import jsonapi_rpc, SAFRSAPI
10
+ import safrs
11
+
12
+ """
13
+ Graphics methods for database classes, created when:
14
+ * `als genai create` contains prompts like: 'Graph Sales by Category', etc.
15
+ * `als add-graphics` --using the docs/graphics directory
16
+
17
+ Called by api/api_discovery/dashboard_services.py when admin app loaded
18
+
19
+ You typically do not alter this file - rebuilt on als genai--graphics.
20
+
21
+ """
22
+
23
+ app_logger = logging.getLogger(__name__)
24
+
25
+
26
+ def add_method(cls):
27
+ """
28
+ Decorator to add method to class, e.g., db class group by query method
29
+
30
+ Thanks to: https://mgarod.medium.com/dynamically-add-a-method-to-a-class-in-python-c49204b85bd6
31
+ """
32
+ def decorator(func):
33
+ @wraps(func)
34
+ def wrapper(self, *args, **kwargs):
35
+ return func(*args, **kwargs)
36
+
37
+ setattr(cls, func.__name__, wrapper)
38
+ # Note we are not binding func, but wrapper which accepts self but does exactly the same as func
39
+ return func # returning func means func can still be used normally
40
+ return decorator
41
+
42
+ ##############################
43
+ # generated services follow
44
+ ##############################
45
+
46
+
47
+
48
+ @classmethod
49
+ @add_method(models.Category)
50
+ @jsonapi_rpc(http_methods=['GET', 'OPTIONS'])
51
+ def sales_by_category(*args, **kwargs):
52
+ """
53
+ Complex query with multiple joins, for graphics, from 'Graph Sales by Category', etc.
54
+ Test with Swagger.
55
+ """
56
+ if request.method == 'OPTIONS':
57
+ return jsonify({ "result": "ok" })
58
+
59
+ from database.models import Category, Product, OrderDetail, Order
60
+ db = safrs.DB
61
+ session = db.session # sqlalchemy.orm.scoping.scoped_session
62
+ # Security.set_user_sa() # an endpoint that requires no auth header (see also @bypass_security)
63
+
64
+ # SQLAlchemy query
65
+ query = sales_by_category = ((session.query(Category.CategoryName, func.sum(OrderDetail.Quantity * OrderDetail.UnitPrice * (1 - OrderDetail.Discount))
66
+ .label("TotalSales"))
67
+ .join(Product, Category.Id == Product.CategoryId)
68
+ .join(OrderDetail, Product.Id == OrderDetail.ProductId)
69
+ .join(Order, OrderDetail.OrderId == Order.Id)
70
+ .filter(Order.ShippedDate.is_not(None))
71
+ .group_by(Category.CategoryName)
72
+ .order_by(func.sum(OrderDetail.Quantity * OrderDetail.UnitPrice * (1 - OrderDetail.Discount))
73
+ .desc())))
74
+ # Execute query and fetch results
75
+ results = query.all()
76
+ from decimal import Decimal
77
+ columns = ['Category Name' , 'Total Sales']
78
+ results = [{columns[0]: row[0], columns[1]: round(float(row[1]), 2)} for row in results]
79
+ title = 'Sales by Category'
80
+ graph_type = 'Bar'.lower()
81
+ json_results = {
82
+ "results": results,
83
+ "columns": columns,
84
+ "title": title,
85
+ "chart_type": graph_type,
86
+ "xAxis": columns[0],
87
+ "yAxis": columns[1],
88
+ }
89
+
90
+ return json_results
91
+ @classmethod
92
+ @add_method(models.Category)
93
+ @jsonapi_rpc(http_methods=['GET', 'OPTIONS'])
94
+ def number_of_sales_per_category(*args, **kwargs):
95
+ """
96
+ Complex query with multiple joins, for graphics, from 'Graph Sales by Category', etc.
97
+ Test with Swagger.
98
+ """
99
+ if request.method == 'OPTIONS':
100
+ return jsonify({ "result": "ok" })
101
+
102
+ from database.models import Category, Product, OrderDetail, Order
103
+ db = safrs.DB
104
+ session = db.session # sqlalchemy.orm.scoping.scoped_session
105
+ # Security.set_user_sa() # an endpoint that requires no auth header (see also @bypass_security)
106
+
107
+ # SQLAlchemy query
108
+ query = number_of_sales_per_category = ((session.query(Category.CategoryName, func.count(Order.Id)
109
+ .label("NumberOfSales"))
110
+ .join(Product, Product.CategoryId == Category.Id)
111
+ .join(OrderDetail, OrderDetail.ProductId == Product.Id)
112
+ .join(Order, Order.Id == OrderDetail.OrderId)
113
+ .filter(Order.ShippedDate.is_not(None))
114
+ .group_by(Category.CategoryName)
115
+ .order_by(func.count(Order.Id)
116
+ .desc())))
117
+ # Execute query and fetch results
118
+ results = query.all()
119
+ from decimal import Decimal
120
+ columns = ['Category Name' , 'Number of Sales']
121
+ results = [{columns[0]: row[0], columns[1]: round(float(row[1]), 2)} for row in results]
122
+ title = 'Number of Sales Per Category'
123
+ graph_type = 'Bar'.lower()
124
+ json_results = {
125
+ "results": results,
126
+ "columns": columns,
127
+ "title": title,
128
+ "chart_type": graph_type,
129
+ "xAxis": columns[0],
130
+ "yAxis": columns[1],
131
+ }
132
+
133
+ return json_results
134
+ @classmethod
135
+ @add_method(models.Order)
136
+ @jsonapi_rpc(http_methods=['GET', 'OPTIONS'])
137
+ def count_orders_by_month(*args, **kwargs):
138
+ """
139
+ Complex query with multiple joins, for graphics, from 'Graph Sales by Category', etc.
140
+ Test with Swagger.
141
+ """
142
+ if request.method == 'OPTIONS':
143
+ return jsonify({ "result": "ok" })
144
+
145
+ from database.models import Order
146
+ db = safrs.DB
147
+ session = db.session # sqlalchemy.orm.scoping.scoped_session
148
+ # Security.set_user_sa() # an endpoint that requires no auth header (see also @bypass_security)
149
+
150
+ # SQLAlchemy query
151
+ query = count_orders_by_month = ((session.query(func.strftime('%Y-%m', func.date(Order.OrderDate))
152
+ .label("OrderMonth"), func.count(Order.Id)
153
+ .label("OrderCount"))
154
+ .filter(Order.OrderDate.is_not(None))
155
+ .group_by(func.strftime('%Y-%m', func.date(Order.OrderDate)))
156
+ .order_by(func.strftime('%Y-%m', func.date(Order.OrderDate)))))
157
+ # Execute query and fetch results
158
+ results = query.all()
159
+ from decimal import Decimal
160
+ columns = ['Month' , 'Order Count']
161
+ results = [{columns[0]: row[0], columns[1]: round(float(row[1]), 2)} for row in results]
162
+ title = 'Order Count by Month'
163
+ graph_type = 'Line'.lower()
164
+ json_results = {
165
+ "results": results,
166
+ "columns": columns,
167
+ "title": title,
168
+ "chart_type": graph_type,
169
+ "xAxis": columns[0],
170
+ "yAxis": columns[1],
171
+ }
172
+
173
+ return json_results
@@ -1,6 +1,11 @@
1
1
  const sla_doc =
2
2
  '<div class="MuiTypography-root jss4" style="color: rgba(0, 0, 0, 0.66)">' +
3
3
  '<div style="text-align:center">' +
4
+ '<div class="dashboard-iframe">' +
5
+
6
+ '<iframe id="iframeTargetDashboard" src="http://localhost:5656/dashboard" style="flex: 1; border: none; width: 100%; height: 200px;"></iframe>' +
7
+
8
+ '</div>' +
4
9
  '<h2>Welcome to GenAI-Logic/API Logic Server - Sample</h2>' +
5
10
  '</div><br>' +
6
11
  '<h3><a class="custom" style="color: #3f51b5;" rel="nofollow" href="https://www.genai-logic.com" target="_blank">GenAI-Logic</a> ' +
@@ -0,0 +1,66 @@
1
+ # Department Tree View Feature
2
+
3
+ ## Overview
4
+ The Department component now supports two view modes:
5
+ 1. **List View** - Traditional table view showing all departments
6
+ 2. **Tree View** - Hierarchical view showing department relationships
7
+
8
+ ## Features
9
+
10
+ ### View Toggle
11
+ - Switch between List and Tree views using the toggle buttons in the top-right corner
12
+ - List view shows departments in a traditional table format
13
+ - Tree view shows departments in a hierarchical structure
14
+
15
+ ### Tree View Functionality
16
+ - **Hierarchical Display**: Shows parent-child relationships between departments
17
+ - **Expandable Nodes**: Click the expand/collapse icons to show/hide sub-departments
18
+ - **Clickable Department Names**: Click on any department name to view its details
19
+ - **Split View**: When a department is selected, its details appear in a panel to the right
20
+ - **Security Level Display**: Shows security level next to each department name
21
+
22
+ ### Split View Details Panel
23
+ When a department is clicked in tree view, the right panel shows:
24
+ - Department basic information (Security Level, ID)
25
+ - List of sub-departments (if any)
26
+ - List of employees in that department (up to 5, with count if more)
27
+ - Close button to hide the details panel
28
+
29
+ ### Enhanced Forms
30
+ - **Create Department**: Now includes parent department selection
31
+ - **Edit Department**: Can change parent department relationships
32
+ - **Show Department**: Displays parent department information and has tabs for:
33
+ - Sub-Departments: Shows child departments with add button
34
+ - Employee List: Shows employees in this department
35
+
36
+ ## Technical Implementation
37
+
38
+ ### Dependencies Added
39
+ - `@mui/x-tree-view`: Provides TreeView and TreeItem components
40
+ - Enhanced MUI components for better UI
41
+
42
+ ### Key Components
43
+ - `DepartmentTreeView`: Main tree component
44
+ - `DepartmentTreeItem`: Recursive tree item for hierarchy
45
+ - `DepartmentDetails`: Details panel for split view
46
+ - `AddSubDepartmentButton`: Button to create sub-departments
47
+
48
+ ### API Integration
49
+ - Uses `useGetList` hook to fetch department hierarchies
50
+ - Filters departments by `DepartmentId` to build tree structure
51
+ - Supports real-time data updates
52
+
53
+ ## Usage
54
+ 1. Navigate to the Departments section
55
+ 2. Use the toggle buttons to switch between List and Tree views
56
+ 3. In Tree view:
57
+ - Expand/collapse departments to explore hierarchy
58
+ - Click department names to view details
59
+ - Use the split view to see department information
60
+ - Create sub-departments using the "Add Sub-Department" button
61
+
62
+ ## Benefits
63
+ - **Better Organization**: Visualize department hierarchy clearly
64
+ - **Improved Navigation**: Quick access to related departments
65
+ - **Enhanced UX**: Split view allows comparing departments
66
+ - **Efficient Management**: Easy creation of sub-departments
@@ -2,10 +2,26 @@
2
2
 
3
3
  GenAI-Logic (`genai-logic genai-add-app`) [docs here](https://apilogicserver.github.io/Docs/Admin-Vibe/), from `ui/admin/admin.yaml`.
4
4
 
5
- We then *Vibed it* to add cards:
5
+ We then *Vibed it* to add dashboards, cards, trees and maps:
6
6
 
7
- ```bash
8
- Update the Customer list to provide users an option to see results in a list, or in cards
7
+ ```text
8
+ Please customize the react-app as follows:
9
+
10
+ create a landing page that summarizes the architecture, and iFrame to "http://localhost:5656/dashboard"
11
+
12
+ Add an option on the Employee List page to show results as cards, and
13
+ show the employee image in the card.
14
+
15
+ Create a Department tree view component for the existing Department list page.
16
+ Make it collapsible/expandable and integrate it into the existing Department.js file.
17
+ The tree should show just the Department Name as a link;
18
+ clicking the link opens an Information panel to the right.
19
+ The panel is equivalent to Department Show: all the fields, plus tab sheets for related data.
20
+ The tab sheets should provide transitions to the related data show pages (eg, the Employee page).
21
+
22
+ Enhance supplier list page to include a toggle for a professional, interactive world map view.
23
+ The map should display supplier icons on a real map with proper geography.
24
+ Click a supplier icon should open the Supplier show page.
9
25
  ```
10
26
 
11
27
  <br>
@@ -20,4 +36,5 @@ npm install
20
36
  npm start
21
37
  ```
22
38
 
23
- Open your browser at [http://localhost:3000](http://localhost:3000).
39
+ Open your browser at [http://localhost:3000](http://localhost:3000).
40
+
@@ -5,16 +5,20 @@
5
5
  "dependencies": {
6
6
  "@emotion/react": "^11.14.0",
7
7
  "@emotion/styled": "^11.14.0",
8
+ "@mui/icons-material": "^7.1.1",
8
9
  "@mui/material": "^7.1.1",
10
+ "@mui/x-tree-view": "^8.7.0",
9
11
  "@testing-library/dom": "^10.4.0",
10
12
  "@testing-library/jest-dom": "^6.6.3",
11
13
  "@testing-library/react": "^16.3.0",
12
14
  "@testing-library/user-event": "^13.5.0",
13
15
  "compare-versions": "^6.1.1",
14
16
  "keycloak-js": "^26.2.0",
17
+ "leaflet": "^1.9.4",
15
18
  "react": "^19.1.0",
16
19
  "react-admin": "^5.8.3",
17
20
  "react-dom": "^19.1.0",
21
+ "react-leaflet": "^5.0.0",
18
22
  "react-router-dom": "^7.6.2",
19
23
  "react-scripts": "5.0.1",
20
24
  "url-join": "^5.0.0",
@@ -15,6 +15,9 @@
15
15
  user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
16
16
  -->
17
17
  <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
18
+ <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
19
+ integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
20
+ crossorigin=""/>
18
21
  <!--
19
22
  Notice the use of %PUBLIC_URL% in the tags above.
20
23
  It will be replaced with the URL of the `public` folder during the build.
@@ -4,6 +4,8 @@ import { Admin, Resource, Loading } from 'react-admin';
4
4
  import { jsonapiClient } from './rav4-jsonapi-client/ra-jsonapi-client';
5
5
  import { createTheme } from '@mui/material/styles';
6
6
  import { useConf, loadHomeConf } from './Config';
7
+ import LandingPage from './LandingPage';
8
+ import CustomLayout from './CustomLayout';
7
9
  // End constant imports
8
10
 
9
11
  // Import each resource
@@ -55,7 +57,12 @@ const App = () => {
55
57
  const dataProvider = jsonapiClient(conf.api_root, { conf: {} }, null);
56
58
 
57
59
  return (
58
- <Admin dataProvider={dataProvider} theme={theme}>
60
+ <Admin
61
+ dataProvider={dataProvider}
62
+ theme={theme}
63
+ dashboard={LandingPage}
64
+ layout={CustomLayout}
65
+ >
59
66
  <Resource
60
67
  name="Customer"
61
68
  list={CustomerList}
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ import { Layout, AppBar } from 'react-admin';
3
+ import { Typography } from '@mui/material';
4
+
5
+ const CustomAppBar = (props) => (
6
+ <AppBar {...props}>
7
+ <Typography variant="h6" color="inherit" sx={{ flex: 1 }}>
8
+ API Logic Server - Northwind Sample
9
+ </Typography>
10
+ </AppBar>
11
+ );
12
+
13
+ const CustomLayout = (props) => (
14
+ <Layout
15
+ {...props}
16
+ appBar={CustomAppBar}
17
+ />
18
+ );
19
+
20
+ export default CustomLayout;