Skip to content
Developerhome

Example - New Department Screens

  Less than to read

Welcome to the guide on API usage for custom Department screens and creating custom BaseSelect functionality for departments.

Before diving into this guide, it is highly recommended to have previously setup the “New Department” and “Amend Department” screens. This example relies on the existence of those screens, and without them, the guide will not work as intended. If you haven’t completed the setup yet, please follow the New Screen Guide.

:

Note: This guide primarily focuses on Sage 200 Professional. However, the information in the schema file can still be valuable for Sage 200 Standard customizations. Please note that modifications will be required as Sage 200 Standard does not allow the creation of new screens.

This guide will provide you with step-by-step instructions and explanations for the following topics:

  • How to use the API for items on standalone custom forms, both for new and amend forms.
  • Creating a custom BaseSelect component for departments.
  • Understanding how the select’s confirmFormDirty feature clears the form when the value is changed.
  • Utilising the apiGetMetadata, apiGet, and apiPut functions for single item operations without a prefix.
  • Resetting the form using the resetState function.

By the end of this guide, you will have a solid understanding of these concepts and be able to effectively utilise them in your application development.

Overview of Departments Schema

Pages

The “pages” section defines the screens that you require your component to be included on. In this case, there are two pages: “extensions/new-department” and “extensions/amend-department”. These are not default screens and will require adding, if you have not already done so please follow the New Screen Guide.

JSON:

{
  ...
"pages": [
  "extensions/new-department",
  "extensions/amend-department"
],
  ...
}

UI Extensions

The “uiExtensions” section defines the UI extensions used in the schema. Each UI extension has an “id” and a “component” array that contains different UI elements.

  • “NewDeptExt” UI extension: It has an ID of “NewDeptExt” and consists of four “Textbox” elements. Each “Textbox” has its own ID and a label specifying its unique identifier and display label.
{
  ...
"uiExtensions": [
  {
    "id": "NewDeptExt",
    "component": [
      {
        "Textbox": {
          "id": "code",
          "label": "Code"
        }
      },
      {
        "Textbox": {
          "id": "name",
          "label": "Name"
        }
      },
      {
        "Textbox": {
          "id": "contact_name",
          "label": "Contact name"
        }
      },
      {
        "Textbox": {
          "id": "contact_details",
          "label": "Contact details"
        }
      }
    ]
  },
...
  • “AmendDeptExt” UI extension: It has an ID of “AmendDeptExt” and consists of five UI elements. The first element is a “BaseSelect” dropdown, followed by four “Textbox” elements similar to the “NewDeptExt” UI extension.

The BaseSelect component provides a foundation for creating custom dropdowns with various options. When using a BaseSelect, you can define its properties such as the ID, label, endpoint, keyFields and its columns. It allows you to select a single option from the available choices. In this example we shall GET all department data to populate the BaseSelect. The BaseSelect component is commonly used in forms or user interfaces where users need to choose a value from a predefined set of options.

...
  {
    "id": "AmendDeptExt",
    "component": [
      {
        "BaseSelect": {
          "id": "dept_id",
          "label": "Department",
          "isClientSide": false,
          "confirmFormDirty": true,
          "endpoint": "v1/departments",
          "keyFields": [ "code", "id" ],
          "columns": [
            {
              "field": "code",
              "headerName": "Code"
            },
            {
              "field": "name",
              "headerName": "Name"
            }
          ]
        }
      },
      {
        "Textbox": {
          "id": "code",
          "label": "Code"
        }
      },
      {
        "Textbox": {
          "id": "name",
          "label": "Name"
        }
      },
      {
        "Textbox": {
          "id": "contact_name",
          "label": "Contact name"
        }
      },
      {
        "Textbox": {
          "id": "contact_details",
          "label": "Contact details"
        }
      }
    ]
  }
]
  ...
}

Actions

The “actions” section defines different actions that can be triggered within the schema.

  • “deptLoad”: This action is responsible for loading the department metadata from the API. It uses the apiGetMetadata action to retrieve information about “v1/departments” endpoint.

The “apiGetMetadata” function is used to retrieve metadata information from an API endpoint. It is a built-in function that allows you to fetch metadata specifically related to the specified endpoint.

When you call the “apiGetMetadata” function, you provide the endpoint URL as a parameter. The function then makes a GET request to that endpoint and retrieves the metadata associated with it. The metadata typically includes information about the structure, fields, and properties of the data that the endpoint provides.

  • Requests Metadata: The function sends a GET request to the specified endpoint URL, asking for metadata information rather than the actual data.

  • Retrieves Metadata: The API server responds with metadata related to the endpoint. This metadata may include details such as the available fields, data types, validation rules, relationships, and other relevant information about the endpoint’s data structure.

  • Consumes Metadata: Once the metadata is received, the application can use it to understand the structure of the data, generate forms dynamically, perform validations, and make informed decisions about how to interact with the endpoint.

The “apiGetMetadata” function allows you to obtain detailed information about this structure, including the fields and properties of the data.

apiGetMetadata parameters:

  • Endpoint Property: The “endpoint” property specifies the URL or path of the API endpoint from which the metadata is retrieved. It identifies the specific endpoint that provides the desired metadata. For example, it can be set to “v1/departments” to retrieve metadata related to the “departments” endpoint. NEED TO ADD: Query parameters are automatically applied

  • Prefix Property: The “prefix” property allows you to add a prefix to the endpoint URL. This is useful in scenarios where you need to keep data separate or handle different versions or variations of the endpoint. NEED TO ADD: to separate data in redux store

key: key for grid(collection), if present, manipulates differently for use by collection.

Type of information included in the metadata:

  • Structure: The metadata provides details about the overall structure of the data returned by the API endpoint. It may specify if the data is returned as a single object or an array of objects, or if it is nested within other objects.

  • Fields: The metadata describes the individual fields or attributes that make up the data. It includes the names of the fields and their corresponding data types, such as string, number, boolean, or date. Additionally, it may indicate whether certain fields are required or optional.

  • Properties: The metadata provides additional properties or characteristics associated with each field. This can include information like the maximum length of a string field, the range of values for a numeric field, or any specific formatting requirements for a date field.

"actions": {
		"deptLoad": [{
			"apiGetMetadata": {
				"endpoint": "v1/departments",
				"prefix": ""
			}
		}],
  ...
}
  • “deptClear”: It contains a “resetState” action that clears the state.
...
"deptClear": [{
  "resetState": {}
}],
...
  • “deptPut”: It consists of a “tryCatch” action. The “try” array contains two actions:
    • “apiPut” makes a PUT request to the “v1/departments” endpoint using the “dept_id” retrieved from the screen’s state
    • “resetState” clears the screen’s state. The “catch” array has a “set” action that sets the “error_message” which get’s the state of the “CURRENT_ERROR”.
...
"deptPut": [{
  "tryCatch": {
    "try": [{
        "apiPut": {
          "endpoint": "v1/departments",
          "prefix": "",
          "id": {
            "get": {
              "state": "dept_id"
            }
          }
        }
      },
      {
        "set": {
          "success_message": "Department updated successfully"
        }
      },
      {
        "resetState": {}
      }
    ],
    "catch": [
      {
        "set": {
          "error_message": {
            "title": "Error updating Department",
            "message": {
              "get": {
                "state": "CURRENT_ERROR"
              }
            }
          }
        }
      }
    ]
  }
}],
...
  • “deptPost”: It also includes a “tryCatch” action. The “try” array contains three actions:
    • “apiPost” makes a POST request to the “v1/departments” endpoint
    • “sets” the success_message.
    • “resetState” clears the state. The “catch” array is similar to the “deptPut” action’s “catch” array. The “finally” array has a “set” action that sets the state with a “finally” string value.
"deptPost": [{
  "tryCatch": {
    "try": [{
        "apiPost": {
          "endpoint": "v1/departments",
          "prefix": ""
        }
      },
      {
        "set": {
          "success_message": "Department created successfully"
        }
      },
      {
        "resetState": {}
      }
    ],
    "catch": [{
      "set": {
        "error_message": {
          "title": "Error creating Department",
          "message": {
            "get": {
              "state": "CURRENT_ERROR"
            }
          }
        }
      }
    }],
    "finally": [{
      "set": {
        "state": {
          "finally": "myFinally"
        }
      }
    }]
  }
}]

Validations

The “validations” section is empty, indicating that no specific validations are defined in this area.

Events

The “events” section defines the events associated with each page.

“extensions/new-department” page events:

  • “onSubmit”: This event triggers the “deptPost” action when the screen is submitted.
  • “onClear”: This event triggers the “resetState” action when the screen is cleared.
  • “onLoad”: This event is triggered when the “extensions/new-department” page is loaded. It performs the following actions:
    • “apiGetMetadata”: Retrieves the department metadata using the apiGetMetadata action. The endpoint is set to “v1/departments”, and the prefix is empty.
    • “pageExtension”: It sets the “NewDeptExt” UI extension within the “ExtensionMainPod” component to appear at the bottom panel.

“extensions/amend-department” page events:

  • “onStateChange”: This event triggers the “apiGet” action to get data from the “v1/departments” endpoint when the state changes.
  • “onSubmit”: This event triggers the “deptPut” action when the screen is submitted.
  • “onClear”: This event triggers the “resetState” action when the screen is cleared.
  • “onLoad”: This event triggers the same actions as the “extensions/new-department” page.
	"events": [{
			"pages": [
				"extensions/new-department"
			],
			"onSubmit": [{
				"action": "deptPost"
			}],
			"onClear": [{
				"resetState": {}
			}],
			"onLoad": [{
					"apiGetMetadata": {
						"endpoint": "v1/departments",
						"prefix": ""
					}
				},
				{
					"set": {
						"pageExtension": {
							"componentId": "ExtensionMainPod",
							"panel": "bottom",
							"uiExtension": "NewDeptExt"
						}
					}
				}
			]
		},
		{
			"pages": [
				"extensions/amend-department"
			],
			"onStateChange": [{
				"watchTarget": "dept_id",
				"onChange": [{
					"if": {
						"ne": [{
								"get": {
									"state": "dept_id"
								}
							},
							{
								"string": {
									"value": ""
								}
							}
						],
						"then": [{
							"apiGet": {
								"endpoint": "v1/departments",
								"prefix": "",
								"id": {
									"get": {
										"state": "dept_id"
									}
								},
								"queryParams": {
									"$expandall": "true"
								}
							}
						}]
					}
				}]
			}],
			"onSubmit": [{
				"action": "deptPut"
			}],
			"onClear": [{
				"resetState": {}
			}],
			"onLoad": [{
					"apiGetMetadata": {
						"endpoint": "v1/departments",
						"prefix": ""
					}
				},
				{
					"set": {
						"pageExtension": {
							"componentId": "ExtensionMainPod",
							"panel": "bottom",
							"uiExtension": "AmendDeptExt"
						}
					}
				}
			]
		}
	]