ApiLogicServer 15.0.24__py3-none-any.whl → 15.0.26__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.
- api_logic_server_cli/api_logic_server.py +2 -2
- api_logic_server_cli/genai/genai_admin_app.py +47 -33
- api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-App-Resource-Learning-Prompt copy.md +203 -0
- api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-App-Resource-Learning-Prompt.md +184 -77
- {apilogicserver-15.0.24.dist-info → apilogicserver-15.0.26.dist-info}/METADATA +1 -1
- {apilogicserver-15.0.24.dist-info → apilogicserver-15.0.26.dist-info}/RECORD +10 -9
- {apilogicserver-15.0.24.dist-info → apilogicserver-15.0.26.dist-info}/WHEEL +0 -0
- {apilogicserver-15.0.24.dist-info → apilogicserver-15.0.26.dist-info}/entry_points.txt +0 -0
- {apilogicserver-15.0.24.dist-info → apilogicserver-15.0.26.dist-info}/licenses/LICENSE +0 -0
- {apilogicserver-15.0.24.dist-info → apilogicserver-15.0.26.dist-info}/top_level.txt +0 -0
|
@@ -12,10 +12,10 @@ ApiLogicServer CLI: given a database url, create [and run] customizable ApiLogic
|
|
|
12
12
|
Called from api_logic_server_cli.py, by instantiating the ProjectRun object.
|
|
13
13
|
'''
|
|
14
14
|
|
|
15
|
-
__version__ = "15.00.
|
|
15
|
+
__version__ = "15.00.26" # last public release: 15.00.25 (15.00.12)
|
|
16
16
|
recent_changes = \
|
|
17
17
|
f'\n\nRecent Changes:\n' +\
|
|
18
|
-
"\t06/
|
|
18
|
+
"\t06/25/2024 - 15.00.26: Tech Preview: als genai-app w/ sra provider+model+grid_cascadeAdd, import fix, bug [96] \n"\
|
|
19
19
|
"\t06/10/2024 - 15.00.12: MCP Security, win fixes for readme, graphics quotes \n"\
|
|
20
20
|
"\t06/08/2024 - 15.00.10: MCP, optional shortening of stacktrace lines, bugfix[92] \n"\
|
|
21
21
|
"\t05/16/2024 - 14.05.00: safrs 3.1.7, running mcp preview \n"\
|
|
@@ -38,7 +38,7 @@ class JSResponseFormat(BaseModel): # must match system/genai/prompt_inserts/res
|
|
|
38
38
|
|
|
39
39
|
class GenAIAdminApp:
|
|
40
40
|
|
|
41
|
-
def __init__(self, project: Project, app_name: str, schema: str, genai_version:
|
|
41
|
+
def __init__(self, project: Project, app_name: str, schema: str, genai_version: str):
|
|
42
42
|
self.start_time = time.time()
|
|
43
43
|
|
|
44
44
|
self.api_version = genai_version
|
|
@@ -82,6 +82,7 @@ class GenAIAdminApp:
|
|
|
82
82
|
shutil.copytree(self.react_admin_template_path, self.ui_project_path, dirs_exist_ok=True)
|
|
83
83
|
|
|
84
84
|
# self.parse_resources()
|
|
85
|
+
self.standard_imports = self.read_standard_imports()
|
|
85
86
|
self.a_generate_resource_files()
|
|
86
87
|
self.b_generate_app_js()
|
|
87
88
|
# comes from copytree, above -- self.c_generate_data_provider()
|
|
@@ -94,17 +95,39 @@ class GenAIAdminApp:
|
|
|
94
95
|
log.info('> npm install')
|
|
95
96
|
log.info('> npm start')
|
|
96
97
|
|
|
98
|
+
def read_standard_imports(self) -> List[str]:
|
|
99
|
+
'''grr
|
|
100
|
+
|
|
101
|
+
openAI very often ignores the EXACTLY imports,<br>
|
|
102
|
+
so read them manually for later resource creation
|
|
103
|
+
'''
|
|
104
|
+
learning = self.admin_app_resource_learning.splitlines()
|
|
105
|
+
result_lines = []
|
|
106
|
+
preamble_done = False
|
|
107
|
+
for each_line in learning:
|
|
108
|
+
if '<sample-code' in each_line:
|
|
109
|
+
preamble_done = True
|
|
110
|
+
continue
|
|
111
|
+
if 'end mandatory imports' in each_line:
|
|
112
|
+
result_lines.append(each_line)
|
|
113
|
+
result_lines.append("")
|
|
114
|
+
break
|
|
115
|
+
if preamble_done:
|
|
116
|
+
result_lines.append(each_line)
|
|
117
|
+
return result_lines
|
|
118
|
+
|
|
97
119
|
|
|
98
120
|
def a_generate_resource_files(self):
|
|
99
121
|
|
|
100
|
-
def
|
|
101
|
-
''' Remove
|
|
122
|
+
def fix_resource(genai_app: GenAIAdminApp, raw_source: str) -> str:
|
|
123
|
+
''' Remove occasional begin/end code markers <br>
|
|
124
|
+
And horrific override of ChatGPT refusal to generate imports AS DIRECTED!<br>
|
|
102
125
|
ToDo: lint, and repeat generation if errors detected
|
|
103
126
|
'''
|
|
127
|
+
|
|
104
128
|
source_lines = raw_source.splitlines()
|
|
105
|
-
result_lines = [
|
|
106
|
-
|
|
107
|
-
found_from_react_admin = False
|
|
129
|
+
result_lines = []
|
|
130
|
+
imports_done = False
|
|
108
131
|
for each_line in source_lines:
|
|
109
132
|
if each_line.startswith("```"):
|
|
110
133
|
if each_line.startswith("```jsx") or each_line.startswith("```javascript"):
|
|
@@ -112,34 +135,20 @@ class GenAIAdminApp:
|
|
|
112
135
|
continue
|
|
113
136
|
else:
|
|
114
137
|
break
|
|
115
|
-
if
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
result_lines.append(each_line)
|
|
120
|
-
|
|
138
|
+
if do_mandatory_imports := True and not imports_done and '= (props) =>' in each_line:
|
|
139
|
+
result_lines = list(genai_app.standard_imports)
|
|
140
|
+
imports_done = True
|
|
141
|
+
result_lines.append(each_line)
|
|
121
142
|
# return source_lines as a string
|
|
122
143
|
return "\n".join(result_lines)
|
|
123
144
|
|
|
124
145
|
|
|
125
146
|
for each_resource_name, each_resource in self.resources.items():
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
{
|
|
129
|
-
"type": "text",
|
|
130
|
-
"text": "Here is a screenshot of the desired admin app layout. Use this as a visual guide to generate a React-Admin app that mimics the layout, structure, and joins."
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
"type": "image_url",
|
|
134
|
-
"image_url": {
|
|
135
|
-
"url": "https://apilogicserver.github.io/Docs/images/ui-admin/Order-Page-Learning.png"
|
|
136
|
-
# "url": f"attachment:/{str(self.image_url)}"
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
]
|
|
147
|
+
learning = self.admin_app_resource_learning
|
|
148
|
+
learning = learning.replace('{{resource.js}}', f'{each_resource_name}.js')
|
|
140
149
|
messages = [
|
|
141
150
|
{"role": "user", "content": "You are a helpful expert in react and JavaScript"},
|
|
142
|
-
{"role": "user", "content":
|
|
151
|
+
{"role": "user", "content": learning},
|
|
143
152
|
# {"role": "user", "content": example_image_content},
|
|
144
153
|
# {"role": "user", "content": f'Schema:\n{self.schema_yaml}'},
|
|
145
154
|
{"role": "user", "content": f'Schema:\n{self.schema}'},
|
|
@@ -151,7 +160,7 @@ class GenAIAdminApp:
|
|
|
151
160
|
response_as=JSResponseFormat)
|
|
152
161
|
response_dict = json.loads(output)
|
|
153
162
|
target_file = self.ui_src_path / f"{each_resource_name}.js"
|
|
154
|
-
source_code =
|
|
163
|
+
source_code = fix_resource(self, response_dict['code'])
|
|
155
164
|
utils.write_file(target_file, source_code)
|
|
156
165
|
log.info(f"\n✅ Wrote: {target_file}")
|
|
157
166
|
|
|
@@ -163,12 +172,17 @@ class GenAIAdminApp:
|
|
|
163
172
|
'''
|
|
164
173
|
source_lines = raw_source.splitlines()
|
|
165
174
|
result_lines = []
|
|
166
|
-
data_provider_import = False
|
|
167
|
-
do_fixup = False
|
|
168
175
|
for each_line in source_lines:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
176
|
+
if each_line.startswith("```"):
|
|
177
|
+
if each_line.startswith("```jsx") or each_line.startswith("```javascript"):
|
|
178
|
+
result_lines = []
|
|
179
|
+
continue
|
|
180
|
+
else:
|
|
181
|
+
break
|
|
182
|
+
result_lines.append(each_line)
|
|
183
|
+
|
|
184
|
+
# return source_lines as a string
|
|
185
|
+
return "\n".join(result_lines)
|
|
172
186
|
|
|
173
187
|
messages = []
|
|
174
188
|
messages = [
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
## Context
|
|
2
|
+
|
|
3
|
+
Generate a per-resource file for a React Admin application using the following instructions.
|
|
4
|
+
The result must be a runnable React app (`npm start`) that connects to the supplied JSON:API, with fully implemented components (no placeholders or empty files).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
### Per-Resource Files (Required)
|
|
9
|
+
|
|
10
|
+
For each resource (`Customer`, `Order` etc):
|
|
11
|
+
|
|
12
|
+
* Create a source file under `src/`, e.g., `Customer.js`
|
|
13
|
+
* Each file must **fully** implement:
|
|
14
|
+
* `CustomerList`
|
|
15
|
+
* `CustomerShow`
|
|
16
|
+
* `CustomerCreate`
|
|
17
|
+
* `CustomerEdit`
|
|
18
|
+
|
|
19
|
+
Use:
|
|
20
|
+
|
|
21
|
+
- `<ReferenceField>` for foreign key displays
|
|
22
|
+
- `<ReferenceInput>` for foreign key input
|
|
23
|
+
- `<ReferenceManyField>` for tabbed child lists
|
|
24
|
+
- For show pages
|
|
25
|
+
|
|
26
|
+
* Always start with `<SimpleShowLayout>`, followed by a `<TabbedShowLayout>` for related data
|
|
27
|
+
* DO NOT start with `<TabbedShowLayout>`
|
|
28
|
+
|
|
29
|
+
Use the attribute order from the schema.
|
|
30
|
+
|
|
31
|
+
You may add other imports, but be sure imports below are included.
|
|
32
|
+
|
|
33
|
+
DO NOT use `<EmailInput>` - use `<TextInput>`.
|
|
34
|
+
|
|
35
|
+
DO NOT put `<ReferenceField>` in `<Datagrid>`.
|
|
36
|
+
|
|
37
|
+
Do **not leave any file empty**.
|
|
38
|
+
|
|
39
|
+
Sample code for each resource (follow these guidelines EXACTLY):
|
|
40
|
+
|
|
41
|
+
```jsx
|
|
42
|
+
import React from 'react';
|
|
43
|
+
import { List, FunctionField, Datagrid, TextField, DateField, NumberField, ReferenceField, ReferenceManyField, Show, TabbedShowLayout, Tab, SimpleShowLayout, TextInput, NumberInput, DateTimeInput, ReferenceInput, SelectInput, Create, SimpleForm, Edit, Filter, Pagination, BooleanField, BooleanInput, Labeled } from 'react-admin'; // mandatory imports
|
|
44
|
+
|
|
45
|
+
import { Grid, Typography, Box, Divider } from '@mui/material';
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
// Filter for Customer List
|
|
49
|
+
const CustomerFilter = (props) => (
|
|
50
|
+
<Filter {...props}>
|
|
51
|
+
<TextInput label="Search" source="name" alwaysOn />
|
|
52
|
+
<BooleanInput label="Email Opt Out" source="email_opt_out" />
|
|
53
|
+
</Filter>
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// Customer List
|
|
57
|
+
export const CustomerList = (props) => {
|
|
58
|
+
return (
|
|
59
|
+
<List filters={<CustomerFilter />} {...props} sort={{ field: 'name', order: 'ASC' }} pagination={<Pagination rowsPerPageOptions={[5, 10, 25]} showFirstLastButtons />}>
|
|
60
|
+
<Datagrid rowClick="show">
|
|
61
|
+
<TextField source="name" label="Name" />
|
|
62
|
+
<NumberField source="balance" label="Balance" />
|
|
63
|
+
...
|
|
64
|
+
</Datagrid>
|
|
65
|
+
</List>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
// Customer Show
|
|
71
|
+
export const CustomerShow = (props) => {
|
|
72
|
+
return (
|
|
73
|
+
<Show {...props}>
|
|
74
|
+
<SimpleShowLayout>
|
|
75
|
+
<Box sx={{ mb: 3 }}>
|
|
76
|
+
<Typography variant="h5" component="h2" sx={{ mb: 2, fontWeight: 'bold' }}>
|
|
77
|
+
Customer Information
|
|
78
|
+
</Typography>
|
|
79
|
+
<Grid container spacing={3} sx={{ mb: 2 }}>
|
|
80
|
+
<Grid item xs={12} sm={6} md={3}>
|
|
81
|
+
<Box sx={{ p: 1 }}>
|
|
82
|
+
<Labeled label="Name">
|
|
83
|
+
<TextField source="name" />
|
|
84
|
+
</Labeled>
|
|
85
|
+
</Box>
|
|
86
|
+
</Grid>
|
|
87
|
+
<Grid item xs={12} sm={6} md={3}>
|
|
88
|
+
<Box sx={{ p: 1 }}>
|
|
89
|
+
<Labeled label="Balance">
|
|
90
|
+
<NumberField source="balance" options={{ style: 'currency', currency: 'USD' }} />
|
|
91
|
+
</Labeled>
|
|
92
|
+
</Box>
|
|
93
|
+
</Grid>
|
|
94
|
+
</Grid>
|
|
95
|
+
...
|
|
96
|
+
<Divider sx={{ my: 2 }} />
|
|
97
|
+
</Box>
|
|
98
|
+
</SimpleShowLayout>
|
|
99
|
+
<TabbedShowLayout>
|
|
100
|
+
<Tab label="Orders">
|
|
101
|
+
<ReferenceManyField reference="Order" target="customer_id" addLabel={false} pagination={<Pagination />}>
|
|
102
|
+
<Datagrid rowClick="show">
|
|
103
|
+
<TextField source="id" label="Order ID" />
|
|
104
|
+
<TextField source="notes" label="Notes" />
|
|
105
|
+
<DateField source="CreatedOn" label="Created On" />
|
|
106
|
+
<NumberField source="amount_total" label="Amount Total" options={{ style: 'currency', currency: 'USD' }} />
|
|
107
|
+
<DateField source="date_shipped" label="Date Shipped" />
|
|
108
|
+
</Datagrid>
|
|
109
|
+
</ReferenceManyField>
|
|
110
|
+
</Tab>
|
|
111
|
+
...
|
|
112
|
+
</TabbedShowLayout>
|
|
113
|
+
</Show>
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// generate similar multi-column blocks (e.g., box) for edit and create, using <Edit {...props} redirect={false}>
|
|
118
|
+
|
|
119
|
+
export default {
|
|
120
|
+
list: CustomerList,
|
|
121
|
+
show: CustomerShow,
|
|
122
|
+
create: CustomerCreate,
|
|
123
|
+
edit: CustomerEdit,
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## App Features
|
|
131
|
+
|
|
132
|
+
### Multi-Page
|
|
133
|
+
|
|
134
|
+
For each resource:
|
|
135
|
+
|
|
136
|
+
- Create a **List page** showing 7 user-friendly columns
|
|
137
|
+
- Add **pagination**, **sorting**, and **filtering**
|
|
138
|
+
- Link each row to a **Display (Show) page**
|
|
139
|
+
|
|
140
|
+
### Multi-Resource
|
|
141
|
+
|
|
142
|
+
Each **Display Page** should:
|
|
143
|
+
|
|
144
|
+
- Show all fields in a **multi-column layout**
|
|
145
|
+
- Include a **tab sheet** (`<TabbedShowLayout>`) for each related resource using `<ReferenceManyField>`
|
|
146
|
+
- Link child rows to their own display page
|
|
147
|
+
|
|
148
|
+
Example:
|
|
149
|
+
|
|
150
|
+
- Customer Display has tab for OrderList
|
|
151
|
+
|
|
152
|
+
- The tab (with OrderList) is shown *below* all the Customer fields.
|
|
153
|
+
- Each Order in the tab links to Order Display
|
|
154
|
+
|
|
155
|
+
### Automatic Joins
|
|
156
|
+
|
|
157
|
+
For foreign keys:
|
|
158
|
+
|
|
159
|
+
- Display joined value (e.g., `product.name` instead of `product_id`)
|
|
160
|
+
- Use first string field from parent table containing `name`, `title`, or `description`
|
|
161
|
+
|
|
162
|
+
Numeric Primary key fields:
|
|
163
|
+
|
|
164
|
+
- Display at the end of forms/lists
|
|
165
|
+
|
|
166
|
+
### Lookups (Foreign Keys)
|
|
167
|
+
|
|
168
|
+
For foreign key fields:
|
|
169
|
+
|
|
170
|
+
- Provide auto-complete dropdown (`<ReferenceInput>`)
|
|
171
|
+
- For numeric foreign keys, use the joined string field as lookup text
|
|
172
|
+
|
|
173
|
+
### Cascade Add
|
|
174
|
+
|
|
175
|
+
When adding a child row as a detail in a Master / Detail,
|
|
176
|
+
default the Foreign Key to the Parent (Master) Primary Key.
|
|
177
|
+
|
|
178
|
+
## Implementation
|
|
179
|
+
|
|
180
|
+
### Architecture
|
|
181
|
+
|
|
182
|
+
- **Framework**: React 18 + react-admin 4.x
|
|
183
|
+
- **Data Provider**: Custom pre-built in src/rav4-jsonapi-client
|
|
184
|
+
- **CORS**: Ensure API allows `http://localhost:3000`
|
|
185
|
+
|
|
186
|
+
```py
|
|
187
|
+
from flask_cors import CORS
|
|
188
|
+
CORS(app, origins='*') # or restrict to localhost:3000
|
|
189
|
+
```
|
|
190
|
+
- **Project Setup**:
|
|
191
|
+
|
|
192
|
+
- Use `create-react-app`
|
|
193
|
+
- Include: `react-admin`, `@mui/material`, `@emotion/react`, `@emotion/styled`, `react-router-dom`
|
|
194
|
+
- Do not use any deprecated or unmaintained libraries
|
|
195
|
+
- Include complete and correct `App.js`, `index.js`, `dataProvider.js`, and `index.html`
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Response Format
|
|
199
|
+
|
|
200
|
+
Format the response as a JSResponseFormat:
|
|
201
|
+
|
|
202
|
+
class JSResponseFormat(BaseModel): # must match system/genai/prompt_inserts/response_format.prompt
|
|
203
|
+
code : str # generated javascript code (only)
|
|
@@ -1,17 +1,188 @@
|
|
|
1
1
|
## Context
|
|
2
2
|
|
|
3
|
-
Generate
|
|
4
|
-
The result must be a runnable React app (`npm start`) that connects to the supplied JSON:API, with fully implemented components (no placeholders or empty files).
|
|
5
|
-
|
|
3
|
+
Generate the {{resource.js}} file for a React Admin application using the following instructions.
|
|
6
4
|
|
|
7
5
|
---
|
|
8
6
|
|
|
9
7
|
### Per-Resource Files (Required)
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
Sample code (follow these guidelines EXACTLY):
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
<sample-code>
|
|
12
|
+
// begin MANDATORY imports (always generated EXACTLY)
|
|
13
|
+
import React from 'react';
|
|
14
|
+
import { List, FunctionField, Datagrid, TextField, DateField, NumberField } from 'react-admin';
|
|
15
|
+
import { ReferenceField, ReferenceManyField } from 'react-admin';
|
|
16
|
+
import { TabbedShowLayout, Tab, SimpleShowLayout, TextInput, NumberInput, DateTimeInput } from 'react-admin';
|
|
17
|
+
import { ReferenceInput, SelectInput, SimpleForm, Show, Edit, Create } from 'react-admin';
|
|
18
|
+
import { Filter, Pagination, BooleanField, BooleanInput, Labeled } from 'react-admin';
|
|
19
|
+
import { EditButton, DeleteButton, CreateButton } from 'react-admin';
|
|
20
|
+
import { Grid, Typography, Box, Divider, Button } from '@mui/material';
|
|
21
|
+
import { useRecordContext, useRedirect, Link, required } from 'react-admin';
|
|
22
|
+
import AddIcon from '@mui/icons-material/Add';
|
|
23
|
+
// end mandatory imports
|
|
24
|
+
|
|
25
|
+
// Filter for Customer List
|
|
26
|
+
const CustomerFilter = (props) => (
|
|
27
|
+
<Filter {...props}>
|
|
28
|
+
<TextInput label="Search" source="name" alwaysOn />
|
|
29
|
+
<BooleanInput label="Email Opt Out" source="email_opt_out" />
|
|
30
|
+
</Filter>
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// Customer List
|
|
34
|
+
export const CustomerList = (props) => {
|
|
35
|
+
return (
|
|
36
|
+
<List filters={<CustomerFilter />} {...props} sort={{ field: 'name', order: 'ASC' }} pagination={<Pagination rowsPerPageOptions={[5, 10, 25]} showFirstLastButtons />}>
|
|
37
|
+
<Datagrid rowClick="show">
|
|
38
|
+
<TextField source="name" label="Name" />
|
|
39
|
+
<NumberField source="balance" label="Balance" />
|
|
40
|
+
...
|
|
41
|
+
</Datagrid>
|
|
42
|
+
</List>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
// Customer Show
|
|
48
|
+
export const CustomerShow = (props) => {
|
|
49
|
+
return (
|
|
50
|
+
<Show {...props}>
|
|
51
|
+
<SimpleShowLayout>
|
|
52
|
+
<Box sx={{ mb: 3 }}>
|
|
53
|
+
<Typography variant="h5" component="h2" sx={{ mb: 2, fontWeight: 'bold' }}>
|
|
54
|
+
Customer Information
|
|
55
|
+
</Typography>
|
|
56
|
+
<Grid container spacing={3} sx={{ mb: 2 }}>
|
|
57
|
+
<Grid item xs={12} sm={6} md={3}>
|
|
58
|
+
<Box sx={{ p: 1 }}>
|
|
59
|
+
<Labeled label="Name">
|
|
60
|
+
<TextField source="name" />
|
|
61
|
+
</Labeled>
|
|
62
|
+
</Box>
|
|
63
|
+
</Grid>
|
|
64
|
+
<Grid item xs={12} sm={6} md={3}>
|
|
65
|
+
<Box sx={{ p: 1 }}>
|
|
66
|
+
<Labeled label="Balance">
|
|
67
|
+
<NumberField source="balance" options={{ style: 'currency', currency: 'USD' }} />
|
|
68
|
+
</Labeled>
|
|
69
|
+
</Box>
|
|
70
|
+
</Grid>
|
|
71
|
+
</Grid>
|
|
72
|
+
...
|
|
73
|
+
<Divider sx={{ my: 2 }} />
|
|
74
|
+
</Box>
|
|
75
|
+
</SimpleShowLayout>
|
|
76
|
+
<TabbedShowLayout>
|
|
77
|
+
<Tab label="Orders">
|
|
78
|
+
<ReferenceManyField reference="Order" target="customer_id" addLabel={false} pagination={<Pagination />}>
|
|
79
|
+
<Datagrid rowClick="show">
|
|
80
|
+
<TextField source="id" label="Order ID" />
|
|
81
|
+
<TextField source="notes" label="Notes" />
|
|
82
|
+
<DateField source="CreatedOn" label="Created On" />
|
|
83
|
+
<NumberField source="amount_total" label="Amount Total" options={{ style: 'currency', currency: 'USD' }} />
|
|
84
|
+
<DateField source="date_shipped" label="Date Shipped" />
|
|
85
|
+
<EditButton />
|
|
86
|
+
<DeleteButton />
|
|
87
|
+
</Datagrid>
|
|
88
|
+
</ReferenceManyField>
|
|
89
|
+
<AddOrderButton />
|
|
90
|
+
</Tab>
|
|
91
|
+
...
|
|
92
|
+
</TabbedShowLayout>
|
|
93
|
+
</Show>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// Custom Add Order Button
|
|
98
|
+
const AddOrderButton = () => {
|
|
99
|
+
const record = useRecordContext();
|
|
100
|
+
const redirect = useRedirect();
|
|
101
|
+
|
|
102
|
+
const handleClick = () => {
|
|
103
|
+
// Use the newer React Admin approach for pre-filling forms
|
|
104
|
+
redirect(`/Order/create?source=${encodeURIComponent(JSON.stringify({ customer_id: record?.id }))}`);
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<Button
|
|
109
|
+
variant="contained"
|
|
110
|
+
color="primary"
|
|
111
|
+
startIcon={<AddIcon />}
|
|
112
|
+
onClick={handleClick}
|
|
113
|
+
sx={{ mt: 2 }}
|
|
114
|
+
>
|
|
115
|
+
Add New Order
|
|
116
|
+
</Button>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// Customer Create
|
|
121
|
+
export const CustomerCreate = (props) => {
|
|
122
|
+
return (
|
|
123
|
+
<Create {...props}>
|
|
124
|
+
<SimpleForm>
|
|
125
|
+
<Box sx={{ mb: 3 }}>
|
|
126
|
+
<Typography variant="h5" component="h2" sx={{ mb: 2, fontWeight: 'bold' }}>
|
|
127
|
+
Create New Customer
|
|
128
|
+
</Typography>
|
|
129
|
+
<Grid container spacing={3} sx={{ mb: 2 }}>
|
|
130
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
131
|
+
<Box sx={{ p: 1 }}>
|
|
132
|
+
<TextInput source="name" label="Name" fullWidth />
|
|
133
|
+
</Box>
|
|
134
|
+
</Grid>
|
|
135
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
136
|
+
<Box sx={{ p: 1 }}>
|
|
137
|
+
<NumberInput source="balance" label="Balance" fullWidth />
|
|
138
|
+
</Box>
|
|
139
|
+
</Grid>
|
|
140
|
+
...
|
|
141
|
+
</Grid>
|
|
142
|
+
</Box>
|
|
143
|
+
</SimpleForm>
|
|
144
|
+
</Create>
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// Customer Edit
|
|
149
|
+
export const CustomerEdit = (props) => {
|
|
150
|
+
return (
|
|
151
|
+
<Edit {...props} redirect={false}>
|
|
152
|
+
<SimpleForm>
|
|
153
|
+
<Box sx={{ mb: 3 }}>
|
|
154
|
+
<Typography variant="h5" component="h2" sx={{ mb: 2, fontWeight: 'bold' }}>
|
|
155
|
+
Edit Customer
|
|
156
|
+
</Typography>
|
|
157
|
+
<Grid container spacing={3} sx={{ mb: 2 }}>
|
|
158
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
159
|
+
<Box sx={{ p: 1 }}>
|
|
160
|
+
<TextInput source="name" label="Name" fullWidth />
|
|
161
|
+
</Box>
|
|
162
|
+
</Grid>
|
|
163
|
+
<Grid item xs={12} sm={6} md={4}>
|
|
164
|
+
<Box sx={{ p: 1 }}>
|
|
165
|
+
<NumberInput source="balance" label="Balance" fullWidth />
|
|
166
|
+
</Box>
|
|
167
|
+
</Grid>
|
|
168
|
+
...
|
|
169
|
+
</Grid>
|
|
170
|
+
</Box>
|
|
171
|
+
</SimpleForm>
|
|
172
|
+
</Edit>
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export default {
|
|
177
|
+
list: CustomerList,
|
|
178
|
+
show: CustomerShow,
|
|
179
|
+
create: CustomerCreate,
|
|
180
|
+
edit: CustomerEdit,
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
</sample-code>
|
|
184
|
+
|
|
185
|
+
For each resource (`Customer`, `Order` etc) and **fully** implement:
|
|
15
186
|
* `CustomerList`
|
|
16
187
|
* `CustomerShow`
|
|
17
188
|
* `CustomerCreate`
|
|
@@ -20,79 +191,22 @@ For each resource (`Customer`, `Order` etc):
|
|
|
20
191
|
Use:
|
|
21
192
|
|
|
22
193
|
- `<ReferenceField>` for foreign key displays
|
|
23
|
-
- `<ReferenceInput>` for foreign key input
|
|
194
|
+
- `<ReferenceInput>` for foreign key input, like this (IMPORTANT: validate is on SelectInput, NEVER ReferenceInput )
|
|
195
|
+
```
|
|
196
|
+
<ReferenceInput source="customer_id" reference="Customer" fullWidth>
|
|
197
|
+
<SelectInput optionText="name" validate={required()} />
|
|
198
|
+
</ReferenceInput>
|
|
199
|
+
```
|
|
24
200
|
- `<ReferenceManyField>` for tabbed child lists
|
|
25
|
-
- For show pages
|
|
26
201
|
|
|
27
|
-
|
|
28
|
-
* DO NOT start with `<TabbedShowLayout>`
|
|
29
|
-
|
|
30
|
-
ALWAYS include these 2 imports at the top of the file, with this EXACT formatting, whether or not they are used:
|
|
31
|
-
|
|
32
|
-
```jsx
|
|
33
|
-
import React from 'react';
|
|
34
|
-
import { List, FunctionField, Datagrid, TextField, DateField, NumberField, ReferenceField, ReferenceManyField, Show, TabbedShowLayout, Tab, SimpleShowLayout, TextInput, NumberInput, DateTimeInput, ReferenceInput, SelectInput, Create, SimpleForm, Edit, Filter, Pagination, BooleanField, BooleanInput } from 'react-admin'; // mandatory import
|
|
35
|
-
```
|
|
36
|
-
You may add other imports, but be sure all those are included.
|
|
202
|
+
Use the attribute order from the schema.
|
|
37
203
|
|
|
38
204
|
DO NOT use `<EmailInput>` - use `<TextInput>`.
|
|
39
205
|
|
|
40
206
|
DO NOT put `<ReferenceField>` in `<Datagrid>`.
|
|
41
207
|
|
|
42
|
-
Do **not leave any file empty**.
|
|
43
|
-
|
|
44
208
|
---
|
|
45
209
|
|
|
46
|
-
## App Features
|
|
47
|
-
|
|
48
|
-
### Multi-Page
|
|
49
|
-
|
|
50
|
-
For each resource:
|
|
51
|
-
|
|
52
|
-
- Create a **List page** showing 7 user-friendly columns
|
|
53
|
-
- Add **pagination**, **sorting**, and **filtering**
|
|
54
|
-
- Link each row to a **Display (Show) page**
|
|
55
|
-
|
|
56
|
-
### Multi-Resource
|
|
57
|
-
|
|
58
|
-
Each **Display Page** should:
|
|
59
|
-
|
|
60
|
-
- Show all fields in a **multi-column layout**
|
|
61
|
-
- Include a **tab sheet** (`<TabbedShowLayout>`) for each related resource using `<ReferenceManyField>`
|
|
62
|
-
- Link child rows to their own display page
|
|
63
|
-
|
|
64
|
-
Example:
|
|
65
|
-
|
|
66
|
-
- Customer Display has tab for OrderList
|
|
67
|
-
|
|
68
|
-
- The tab (with OrderList) is shown *below* all the Customer fields.
|
|
69
|
-
- Each Order in the tab links to Order Display
|
|
70
|
-
|
|
71
|
-
### Automatic Joins
|
|
72
|
-
|
|
73
|
-
For foreign keys:
|
|
74
|
-
|
|
75
|
-
- Display joined value (e.g., `product.name` instead of `product_id`)
|
|
76
|
-
- Use first string field from parent table containing `name`, `title`, or `description`
|
|
77
|
-
|
|
78
|
-
Numeric Primary key fields:
|
|
79
|
-
|
|
80
|
-
- Display at the end of forms/lists
|
|
81
|
-
|
|
82
|
-
### Lookups (Foreign Keys)
|
|
83
|
-
|
|
84
|
-
For foreign key fields:
|
|
85
|
-
|
|
86
|
-
- Provide auto-complete dropdown (`<ReferenceInput>`)
|
|
87
|
-
- For numeric foreign keys, use the joined string field as lookup text
|
|
88
|
-
|
|
89
|
-
### Cascade Add
|
|
90
|
-
|
|
91
|
-
When adding a child row as a detail in a Master / Detail,
|
|
92
|
-
default the Foreign Key to the Parent (Master) Primary Key.
|
|
93
|
-
|
|
94
|
-
## Implementation
|
|
95
|
-
|
|
96
210
|
### Architecture
|
|
97
211
|
|
|
98
212
|
- **Framework**: React 18 + react-admin 4.x
|
|
@@ -103,13 +217,6 @@ default the Foreign Key to the Parent (Master) Primary Key.
|
|
|
103
217
|
from flask_cors import CORS
|
|
104
218
|
CORS(app, origins='*') # or restrict to localhost:3000
|
|
105
219
|
```
|
|
106
|
-
- **Project Setup**:
|
|
107
|
-
|
|
108
|
-
- Use `create-react-app`
|
|
109
|
-
- Include: `react-admin`, `@mui/material`, `@emotion/react`, `@emotion/styled`, `react-router-dom`
|
|
110
|
-
- Do not use any deprecated or unmaintained libraries
|
|
111
|
-
- Include complete and correct `App.js`, `index.js`, `dataProvider.js`, and `index.html`
|
|
112
|
-
---
|
|
113
220
|
|
|
114
221
|
## Response Format
|
|
115
222
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
api_logic_server_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
api_logic_server_cli/api_logic_server.py,sha256=
|
|
2
|
+
api_logic_server_cli/api_logic_server.py,sha256=3u1SUUCgh3cRxHuhflye-1IMuzwrJp3QONSz1o04tZw,96395
|
|
3
3
|
api_logic_server_cli/api_logic_server_info.yaml,sha256=Rmy2DSMNBLtlV9PP_hqmn2FojD2AAinPVOfnTbwu6oE,128
|
|
4
4
|
api_logic_server_cli/cli.py,sha256=bSc3sj9df94pIx0HyRYKOojOv3M360UNQgieJAgg9IM,85002
|
|
5
5
|
api_logic_server_cli/cli_args_base.py,sha256=lr27KkOB7_WpZwTs7LgiK8LKDIHMKQkoZCTnE99BFxw,3280
|
|
@@ -476,7 +476,7 @@ api_logic_server_cli/genai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJ
|
|
|
476
476
|
api_logic_server_cli/genai/client.py,sha256=36gyz-dqxj4dJj1SGtO9NZsy9-cfnf4d7uahHimwqHk,772
|
|
477
477
|
api_logic_server_cli/genai/genai.py,sha256=rt4XW_xmo-D5fLD8DQBHMjrU7Teflw43S8lR-tJd4KU,47014
|
|
478
478
|
api_logic_server_cli/genai/genai_admin_app copy.py,sha256=d1E6kNVhq-xqhUh2j52V4cOTJxEiZgWhja1_kLJXKX8,4665
|
|
479
|
-
api_logic_server_cli/genai/genai_admin_app.py,sha256=
|
|
479
|
+
api_logic_server_cli/genai/genai_admin_app.py,sha256=IO9aSvOXmY5wiJl74awPo3PxE1ibKjqtUDbpik46NkE,9754
|
|
480
480
|
api_logic_server_cli/genai/genai_fatal_excp.py,sha256=1FmDVcXVRqmG0JMVZ7l4KqMOdpff3KGZ2LPAGtw304Q,179
|
|
481
481
|
api_logic_server_cli/genai/genai_graphics.py,sha256=9ao0os6rUKY5u2caeLtgyDsNEuVQXq4KcKV575fNC58,20610
|
|
482
482
|
api_logic_server_cli/genai/genai_logic_builder.py,sha256=u_89UtrALIfcMtW6p0SZ78lCmwRqerA5igyY2hDvjlk,26150
|
|
@@ -1210,7 +1210,8 @@ api_logic_server_cli/prototypes/manager/system/app_model_editor/venv_setup/venv-
|
|
|
1210
1210
|
api_logic_server_cli/prototypes/manager/system/app_model_editor/venv_setup/venv.ps1,sha256=_-LfKkLw5HOkZsF59BGCqM9Zsk3n1oDIyDb4emy0O08,698
|
|
1211
1211
|
api_logic_server_cli/prototypes/manager/system/app_model_editor/venv_setup/venv.sh,sha256=aWX9fa8fe6aO9ifBIZEgGY5UGh4I0arOoCwBzDsxgU8,893
|
|
1212
1212
|
api_logic_server_cli/prototypes/manager/system/genai/.DS_Store,sha256=ndrcwHjeXXcVbvjdiQNuyCtmI6m-kvDLoEnr0fFJsuY,6148
|
|
1213
|
-
api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-App-Resource-Learning-Prompt.md,sha256=
|
|
1213
|
+
api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-App-Resource-Learning-Prompt copy.md,sha256=cDkLjSRPZxfmgDZhObilm1K67ZweOv9TkGT6cTpZNOM,6741
|
|
1214
|
+
api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-App-Resource-Learning-Prompt.md,sha256=L2nPSDJ3NzGHwQziN2d6z2PoH4RKGo6tuCGEGgLyhOE,8063
|
|
1214
1215
|
api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-App-js-Learning-Prompt.md,sha256=75FA3txqJ1viIyqt9O6nGpi17As7aSgVyUJ1rImriKc,2054
|
|
1215
1216
|
api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-config-prompt.md,sha256=fyP8X1q9tM3i6bTVioa7ieM_aTUfk4GPo08aOWZ60-0,932
|
|
1216
1217
|
api_logic_server_cli/prototypes/manager/system/genai/app_templates/app_learning/Admin-json-api-model-prompt.md,sha256=5Zp9q_lpY225qceQ3UhF4Fyd-85hDKkD-r3BWYmcs6Y,2890
|
|
@@ -2274,9 +2275,9 @@ api_logic_server_cli/tools/mini_skel/database/system/SAFRSBaseX.py,sha256=p8C7AF
|
|
|
2274
2275
|
api_logic_server_cli/tools/mini_skel/database/system/TestDataBase.py,sha256=U02SYqThsbY5g3DX7XGaiMxjZBuOpzvtPS6RfI1WQFg,371
|
|
2275
2276
|
api_logic_server_cli/tools/mini_skel/logic/declare_logic.py,sha256=fTrlHyqMeZsw_TyEXFa1VlYBL7fzjZab5ONSXO7aApo,175
|
|
2276
2277
|
api_logic_server_cli/tools/mini_skel/logic/load_verify_rules.py,sha256=Rr5bySJpYCZmNPF2h-phcPJ53nAOPcT_ohZpCD93-a0,7530
|
|
2277
|
-
apilogicserver-15.0.
|
|
2278
|
-
apilogicserver-15.0.
|
|
2279
|
-
apilogicserver-15.0.
|
|
2280
|
-
apilogicserver-15.0.
|
|
2281
|
-
apilogicserver-15.0.
|
|
2282
|
-
apilogicserver-15.0.
|
|
2278
|
+
apilogicserver-15.0.26.dist-info/licenses/LICENSE,sha256=67BS7VC-Z8GpaR3wijngQJkHWV04qJrwQArVgn9ldoI,1485
|
|
2279
|
+
apilogicserver-15.0.26.dist-info/METADATA,sha256=38bB2lGjbj1sZM1OjXOJsv8EsfcgbRW4HLOKFEibN6g,6553
|
|
2280
|
+
apilogicserver-15.0.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
2281
|
+
apilogicserver-15.0.26.dist-info/entry_points.txt,sha256=KiLloZJ3c_RW-nIDqBtoE0WEsQTnZ3dELwHLWi23LMA,103
|
|
2282
|
+
apilogicserver-15.0.26.dist-info/top_level.txt,sha256=-r0AT_GEApleihg-jIh0OMvzzc0BO1RuhhOpE91H5qI,21
|
|
2283
|
+
apilogicserver-15.0.26.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|