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.
@@ -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.24" # last public release: 15.00.22 (15.00.12)
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/23/2024 - 15.00.24: Tech Preview: als genai-app w/ sra provider+model, import fix, bug [96] \n"\
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: OpenAI): # TODO: type??
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 fix_source(raw_source: str) -> str:
101
- ''' Remove code occasional begin/end code markers <br>
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 = ["import React from 'react';",
106
- "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"]
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 "from 'react-admin'" in each_line: # sigh: missing imports 20% of the time - override
116
- found_from_react_admin = True
117
- continue
118
- if found_from_react_admin == True:
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
- # image moves app gen time from 70 -> 130 secs
127
- example_image_content_unused = [
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": self.admin_app_resource_learning},
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 = fix_source(response_dict['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
- # fixes here
170
- result_lines.append(each_line)
171
- return "\n".join(result_lines) # return source_lines as a string
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 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
-
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
- For each resource (`Customer`, `Order` etc):
9
+ Sample code (follow these guidelines EXACTLY):
12
10
 
13
- * Create a source file under `src/`, e.g., `Customer.js`
14
- * Each file must **fully** implement:
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
- * Always start with `<SimpleShowLayout>`, followed by a `<TabbedShowLayout>` for related data
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ApiLogicServer
3
- Version: 15.0.24
3
+ Version: 15.0.26
4
4
  Author-email: Val Huber <apilogicserver@gmail.com>
5
5
  License: BSD-3-Clause
6
6
  Project-URL: Homepage, https://www.genai-logic.com
@@ -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=8PUYlFjepKJ0p4nhLuApaJt5G0lQsoumpbveCeTH-DI,96379
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=NHQ-As5HJ8ubqUKVwUOJQSqdHhl2v4TMlN63zmYCyTc,9672
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=VzsqOAnN6cOCWmPtVObNy9VgptJIy88sfOFIa5bgcqw,3562
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.24.dist-info/licenses/LICENSE,sha256=67BS7VC-Z8GpaR3wijngQJkHWV04qJrwQArVgn9ldoI,1485
2278
- apilogicserver-15.0.24.dist-info/METADATA,sha256=5bLdbdURiMLJJlmu8ACYemGmIME-cu5Cgn8Z9wy3g6c,6553
2279
- apilogicserver-15.0.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
2280
- apilogicserver-15.0.24.dist-info/entry_points.txt,sha256=KiLloZJ3c_RW-nIDqBtoE0WEsQTnZ3dELwHLWi23LMA,103
2281
- apilogicserver-15.0.24.dist-info/top_level.txt,sha256=-r0AT_GEApleihg-jIh0OMvzzc0BO1RuhhOpE91H5qI,21
2282
- apilogicserver-15.0.24.dist-info/RECORD,,
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,,