Dive into the realm of Power Apps and Dataverse with a focused chapter that unveils a sophisticated collection of code snippets designed to enhance referral management systems.
From deploying dynamic icons based on referral status, mapping status codes to user-friendly text, to implementing comprehensive search, sort, and filter functionalities, this chapter covers essential techniques to refine your Power Apps development skills. Whether you're looking to automate referral mail flows, validate email inputs efficiently, generate unique referral codes, or reset and update data seamlessly, each snippet is meticulously explained and ready to be integrated into your projects.
This guide not only serves as a practical resource for developers seeking to leverage Power Apps and Dataverse capabilities but also as a beacon for those aspiring to create more engaging, responsive, and efficient applications.
Code Snippet #1
For referral status icons
This code snippet display different icons based on the referral status
Switch(
ThisItem.'Referral Status',
'Referral Status (Referrals)'.'Referral bonus settled',
Icon.Money,
'Referral Status (Referrals)'.'Admission team support needed',
Icon.Support,
'Referral Status (Referrals)'.'Referral bonus unlocked',
Icon.Unlock,
'Referral Status (Referrals)'.'Referral code shared',
Icon.Key,
Icon.LogJournal
)
Explanation
This code snippet uses the Switch
function, which is a way to handle multiple conditional cases. This function is typically used to evaluate an expression and return different results based on the value of that expression.
-
Switch Function:- The
Switch
function evaluates an expression and then returns a result depending on the value of that expression. It works similarly to a series ofIf
statements, but is often more concise and easier to read. -
ThisItem.'Referral Status':- This
ThisItem.'Referral Status'
expression evaluates referral status.ThisItem
refers to the current item in a collection or data source, particularly when used in a gallery, form, or other data-bound control.'Referral Status'
is a field in the current item. -
Cases in the Switch Function:- The
Switch
function then checks the value ofThisItem.'Referral Status'
against several possible values. Each case is a value that'Referral Status'
might have, followed by the result that should be returned if that case matches.- If the status is
'Referral Status (Referrals)'.'Referral bonus settled'
, it returnsIcon.Money
. - If the status is
'Referral Status (Referrals)'.'Admission team support needed'
, it returnsIcon.Support
. - If the status is
'Referral Status (Referrals)'.'Referral bonus unlocked'
, it returnsIcon.Unlock
. - If the status is
'Referral Status (Referrals)'.'Referral code shared'
, it returnsIcon.Key
.
- If the status is
-
Default Case:- The last value in the
Switch
function (Icon.LogJournal
) is the default case. IfThisItem.'Referral Status'
does not match any of the specified cases, the function returnsIcon.LogJournal
.
In summary, this code snippet is used to display different icons based on the referral status of the current item in a data set. It's a concise and effective way to handle multiple conditions, making it easier to manage and read compared to multiple nested If
statements. This is particularly useful in user interface scenarios where you want to visually represent the status of items in a list or gallery.
Code Snippet #2
Maps status codes with text
This code snippet uses the Switch
function, which is a powerful tool for handling multiple conditional cases. It is designed to evaluate an expression and return different results based on the value of that expression.
Switch(
ThisItem.'Referral Status',
'Referral Status (Referrals)'.'Referral bonus settled',
"Referral bonus settled",
'Referral Status (Referrals)'.'Admission team support needed',
"Admission team support needed",
'Referral Status (Referrals)'.'Referral bonus unlocked',
"Referral bonus unlocked",
'Referral Status (Referrals)'.'Referral code shared',
"Referral code shared",
"Application submitted"
)
Explanation
-
Switch Function:- The
Switch
function evaluates an expression (ThisItem.'Referral Status'
in this case) and then returns a result depending on the value of that expression. It's a more streamlined alternative to a series ofIf
statements, often resulting in clearer and more concise code. -
Expression to Evaluate:-
ThisItem.'Referral Status'
: This expression refers to the 'Referral Status' field of the current item (ThisItem
) in a collection or data source. In the context of Power Apps,ThisItem
typically refers to the current item in a gallery, form, or other data-bound control. -
Cases in the Switch Function:- The function checks the value of
ThisItem.'Referral Status'
against several specified cases. Each case consists of a possible value for'Referral Status'
, followed by the corresponding result to return if that case matches:- If the status is
'Referral Status (Referrals)'.'Referral bonus settled'
, it returns the text"Referral bonus settled"
. - If the status is
'Referral Status (Referrals)'.'Admission team support needed'
, it returns"Admission team support needed"
. - If the status is
'Referral Status (Referrals)'.'Referral bonus unlocked'
, it returns"Referral bonus unlocked"
. - If the status is
'Referral Status (Referrals)'.'Referral code shared'
, it returns"Referral code shared"
.
- If the status is
-
Default Case:- The last value in the
Switch
function ("Application submitted"
) serves as the default case. IfThisItem.'Referral Status'
does not match any of the earlier cases, the function returns"Application submitted"
.
In summary, this code snippet is used to determine a text description based on the 'Referral Status' of the current item in a data set. It's a typical use case in scenarios where you want to convert status codes or technical terms into more user-friendly, readable text in a UI, such as in a list, gallery, or data table.
Code Snippet #3
For send a referral mail flow
This code snippet performs a series of operations involving data validation, database updates, and running a Power Automate flow to send an email. It uses conditional logic, collection filtering, data patching, and context variable updates.
UpdateContext({varErrorCode: 0});
If(
IsEmpty(
(Filter(
'Referral Codes',
'Referral Codes (Views)'.'Active Referral Codes'
))
),
Patch(
'Referral Codes',
Defaults('Referral Codes'),
{Code: lblReferralCode.Text}
);
UpdateContext({varErrorCode: 1});
,
UpdateContext({varErrorCode: 2})
);
If(
IsEmpty(
Filter (
Referrals,
ThisRecord.'Referral Email' = txtFriendEmail.Value
)
),
Patch(
Referrals,
Defaults(Referrals),
{
Name: txtFriendName.Value,
'Referral Email': txtFriendEmail.Value,
'Referral Notes': "The Referral code shared is shared with a friend.",
'Referral Status': 'Referral Status (Referrals)'.'Referral code shared'
}
);
UpdateContext({varErrorCode: 1});
,
UpdateContext({varErrorCode: 2});
);
If(
varErrorCode = 1,
UpdateContext({varEmailSubject: "Referral Instructions"}),
UpdateContext({varEmailSubject: "Resending-Referral Instructions"});
);
If(
'Send-a-email-to-friend-with-referral-code'.Run(
txtFriendEmail.Value,
varEmailSubject,
lblReferralCode.Text,
User().FullName,
txtFriendName.Value
),
Notify(
"Email sent to " & txtFriendEmail.Value,
NotificationType.Success
);
Reset(txtFriendEmail);
Reset(txtFriendName);
,
Notify(
"Error, We are not able to send mail!",
NotificationType.Error
)
);
Explanation
-
Initializing a Context Variable:-
UpdateContext({varErrorCode: 0});
: This initializes a context variablevarErrorCode
with the value0
. Context variables in Power Apps are used to store data that can be accessed across different screens and controls within the same app. -
First Conditional Block - Checking and Updating 'Referral Codes':- This block checks if there are any active referral codes using
IsEmpty
and aFilter
on the 'Referral Codes' data source. If no active referral codes are found, it performs aPatch
operation to add a new referral code (fromlblReferralCode.Text
) to the 'Referral Codes' database. If an active referral code exists, it setsvarErrorCode
to2
. -
Second Conditional Block - Checking and Updating 'Referrals':- This block checks if the referral email (from
txtFriendEmail.Value
) already exists in the 'Referrals' data source. If it doesn't, a new record is added to the 'Referrals' database with details from the form, andvarErrorCode
is set to1
. If the email exists,varErrorCode
is set to2
. -
Third Conditional Block - Setting Email Subject Based on ErrorCode:- Depending on the value of
varErrorCode
, this block updates another context variablevarEmailSubject
. IfvarErrorCode
is1
, indicating a new referral or code, the subject is set to "Referral Instructions". Otherwise, it's set to "Resending-Referral Instructions". -
Fourth Conditional Block - Sending an Email via Power Automate:- This block runs a Power Automate flow named 'Send-a-email-to-friend-with-referral-code', passing the friend's email, the email subject, the referral code, and user details as parameters. If the flow runs successfully, it displays a success notification and resets the email and name input fields. If it fails, an error notification is displayed.
In summary, this code snippet handles the process of checking for existing referral codes and referrals, updating databases accordingly, setting email subjects based on certain conditions, and finally sending an email through Power Automate. It employs a systematic approach to managing the referral process, ensuring data integrity and providing user feedback throughout the process.
Code Snippet #4
For Email validation
This code snippet is designed to dynamically set the display mode of a control (such as a button) based on the validity of an email address entered in a text input control (txtFriendEmail
). It comes in two versions: the first one with a specific validation criteria, and the second one with a more general approach.
If(
IsMatch(
txtFriendEmail.Value,
"^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$"
) && Last(
ForAll(
Split(
txtFriendEmail.Value,
"@"
),
{Result: ThisRecord.Result}
)
).Result in [
"gmail.com",
"outlook.com"
],
DisplayMode.Edit,
DisplayMode.Disabled
)
// or simply use, if you do not want to limit gmail.com or outlook.com
// If(IsMatch(txtFriendEmail.Text, Match.Email), DisplayMode.Edit,DisplayMode.Disabled)
Explanation
Version 1: Specific Email Validation
-
Email Format Validation:-
IsMatch(txtFriendEmail.Value, "^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$")
: This function checks if the email entered intxtFriendEmail
matches a regular expression pattern. The pattern validates the email format, ensuring it consists of:- User name part with alphanumeric characters, dots, underscores, or hyphens.
- An
@
symbol. - Domain name with alphanumeric characters or hyphens, followed by a dot.
- A domain extension of 2 to 4 characters.
-
Domain Specific Validation:- The
Last(ForAll(Split(txtFriendEmail.Value, "@"), {Result: ThisRecord.Result})).Result in ["gmail.com", "outlook.com"]
part further checks if the domain of the email address (the part after@
) is eithergmail.com
oroutlook.com
. -
This is achieved by splitting the email address at
@
, iterating through the resulting parts withForAll
, and then checking if the last part (the domain) is one of the specified domains. -
Setting Display Mode:-
If(..., DisplayMode.Edit, DisplayMode.Disabled)
: This sets the display mode of the control. If both conditions are true (the email is in the correct format and the domain is eithergmail.com
oroutlook.com
), the mode is set toDisplayMode.Edit
, making the control editable or interactive. If not, the mode isDisplayMode.Disabled
, making it non-interactive.
Version 2: General Email Validation
If(IsMatch(txtFriendEmail.Text, Match.Email), DisplayMode.Edit, DisplayMode.Disabled)
: This is a simplified version using Power Fx's built-inMatch.Email
pattern to validate the email format. If the email format is valid, it sets the control toDisplayMode.Edit
; otherwise, it sets it toDisplayMode.Disabled
.
Summary
The first version is useful when you want to restrict valid email addresses to specific domains (gmail.com
and outlook.com
in this case) and ensure they adhere to a specific format. The second version is a more general approach, suitable when any valid email format is acceptable, regardless of the domain. Both methods are used to control the interactivity of an element in the app based on the validity of the email address input.
Code Snippet #5
For generate or retrieve existing referral code
This code snippet is designed to generate or retrieve a referral code based on certain conditions. It employs a combination of conditional checks, data filtering, and string manipulation.
If(
IsEmpty(
Filter(
'Referral Codes',
'Referral Codes (Views)'.'Active Referral Codes'
)
),
Concat(
FirstN(
Shuffle(
ForAll(
Split(
"abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789",
""
),
{Result: ThisRecord.Result}.Result
)
),
8
),
ThisRecord.Value
)
,
First(
Filter(
'Referral Codes',
'Referral Codes (Views)'.'Active Referral Codes'
)
).Code
)
Explanation
-
Conditional Check Using
IsEmpty
andFilter
:-IsEmpty(Filter('Referral Codes', 'Referral Codes (Views)'.'Active Referral Codes'))
: This part checks whether there are any active referral codes in the 'Referral Codes' data source. TheIsEmpty
function returnstrue
if the filtered list is empty (i.e., there are no active referral codes). -
Generating a New Referral Code:- If there are no active referral codes, the
Concat
function is used to generate a new referral code:- The
Split
function splits a long string of lowercase letters and numbers into individual characters. ForAll
iterates over each character, creating a table with each character as a separate record.Shuffle
randomly rearranges these records.FirstN
selects the first 8 characters from this shuffled list.Concat
then concatenates these characters to form a new 8-character referral code.
- The
-
Retrieving an Existing Referral Code:- If there are active referral codes, the
First(Filter(...)).Code
part retrieves the code of the first active referral code found. It filters the 'Referral Codes' data source for active codes and returns the 'Code' field of the first record.
In summary, this code snippet checks for the existence of active referral codes. If none are found, it generates a new, random 8-character code. If active referral codes are available, it retrieves the first one. This logic can be useful in scenarios where unique referral codes need to be assigned, either by generating new ones or reusing existing active codes.
Code Snippet #6
For toggle a filter functionality
This code snippet is designed to toggle a filter on a collection of referral data based on a context variable (locFiltered
). It updates another context variable (tabReferrals
) with a filtered subset of the Referrals
data source, based on the value of locFiltered
.
UpdateContext({locFiltered: !locFiltered});
If(
locFiltered,
UpdateContext(
{
tabReferrals: Filter(
Referrals,
'Referrals (Views)'.'My Referrals',
ThisRecord.'Referral Status' = 'Referral Status (Referrals)'.'Application submitted'
)
}
),
UpdateContext(
{
tabReferrals: Filter(
Referrals,
'Referrals (Views)'.'My Referrals'
)
}
);
);
Explanation
-
Toggling the Filter State:-
UpdateContext({locFiltered: !locFiltered});
: This line toggles the value of the context variablelocFiltered
. IflocFiltered
is currentlytrue
, it becomesfalse
, and vice versa. This variable is likely used to track whether a specific filter is applied to the referral data. -
Conditional Filtering of Referrals:- The
If
statement checks the state oflocFiltered
:- If
locFiltered
istrue
, it applies a specific filter to theReferrals
data source: UpdateContext({ tabReferrals: Filter(Referrals, 'Referrals (Views)'.'My Referrals', ThisRecord.'Referral Status' = 'Referral Status (Referrals)'.'Application submitted') })
: This updates thetabReferrals
context variable with referral records where the status is 'Application submitted'. It assumes that 'Referrals (Views)'.'My Referrals' is a predefined view or condition within theReferrals
data source.- If
locFiltered
isfalse
, it applies a more general filter: UpdateContext({ tabReferrals: Filter(Referrals, 'Referrals (Views)'.'My Referrals') })
: This updatestabReferrals
with all referral records that meet the 'My Referrals' condition or view, regardless of their referral status.
- If
-
Usage of UpdateContext: This
UpdateContext
function is used to create or update a context variable within the current screen of a Power Apps application. Context variables are temporary and local to the screen they are set in.
In summary, this code snippet is used to toggle between two states of a filtered list of referrals: one where only referrals with the status 'Application submitted' are shown, and another where all referrals under 'My Referrals' are shown. This functionality is useful in scenarios where users need to switch views or filters in a list, such as in dashboards or data management interfaces.
Code Snippet #7
For filter and sort functionality
This code snippet is designed to update a context variable (tabReferrals
) with a filtered and sorted list of referral data from a data source (Referrals
). It also toggles the sorting order between ascending and descending.
UpdateContext({locSortOrder: !locSortOrder});
UpdateContext(
{
tabReferrals: Filter(
SortByColumns(
Search(
Referrals,
txtSearch.Value,
"nledu_name",
"nledu_referralemail",
"nledu_referralnotes"
),
"nledu_referralstatus",
If(
locSortOrder,
SortOrder.Ascending,
SortOrder.Descending
)
),
'Referrals (Views)'.'My Referrals'
)
}
);
Explanation
-
Toggling Sorting Order:-
UpdateContext({locSortOrder: !locSortOrder});
: This line toggles the value of the context variablelocSortOrder
. IflocSortOrder
is currentlytrue
, it becomesfalse
, and vice versa. This is used to switch between ascending and descending sorting orders. -
Updating
tabReferrals
with Filtered and Sorted Data:-UpdateContext({ tabReferrals: Filter(SortByColumns(Search(...), "nledu_referralstatus", If(locSortOrder, SortOrder.Ascending, SortOrder.Descending)), 'Referrals (Views)'.'My Referrals') })
: This complex line updates thetabReferrals
context variable. It performs several operations on theReferrals
data:Search(Referrals, txtSearch.Value, "nledu_name", "nledu_referralemail", "nledu_referralnotes")
: It searches theReferrals
data source for records where the search query (txtSearch.Value
) matches any of the specified fields (nledu_name
,nledu_referralemail
,nledu_referralnotes
).SortByColumns(..., "nledu_referralstatus", If(locSortOrder, SortOrder.Ascending, SortOrder.Descending))
: The search results are then sorted by the columnnledu_referralstatus
. The sorting order is determined bylocSortOrder
– ascending iflocSortOrder
istrue
, and descending iffalse
.Filter(..., 'Referrals (Views)'.'My Referrals')
: Finally, the sorted results are filtered based on a condition or view defined as'Referrals (Views)'.'My Referrals'
.
-
Usage of UpdateContext:-
UpdateContext
is used to create or update context variables within the current screen. Context variables are local to the screen they are set in and are used to store data temporarily.
In summary, this code snippet is used for dynamic data handling in a Power Apps application. It allows for searching within the Referrals
data source, sorting the search results based on a toggleable order, and applying an additional filter. This kind of functionality is typically used in scenarios where users need to interact with and manipulate large sets of data, such as in data management interfaces or search features within an application.
Code Snippet #8
For resetting and updating the data
This code snippet performs several operations to reset certain controls and context variables, refresh a data source, and update a context variable with a filtered set of data from that data source.
Reset(txtSearch);
UpdateContext(
{
locSortOrder: false,
locFiltered: false
}
);
Refresh(Referrals);
UpdateContext(
{
tabReferrals: Filter(
Referrals,
'Referrals (Views)'.'My Referrals'
)
}
);
Explanation
-
Resetting a Text Input Control:-
Reset(txtSearch);
: Resets thetxtSearch
text input control. This typically means clearing any text the user might have entered in the search box. -
Updating Context Variables:-
UpdateContext({ locSortOrder: false, locFiltered: false });
: This line updates two context variables,locSortOrder
andlocFiltered
, setting both tofalse
. These variables are likely used to track the state of sorting and filtering in the app. -
Refreshing the Data Source:-
Refresh(Referrals);
: Refreshes theReferrals
data source. This is often used to ensure that the app is working with the latest data, especially if the data might have been changed elsewhere (like in a different user session or outside of the app). -
Filtering Data and Updating Context Variable:-
UpdateContext({ tabReferrals: Filter(Referrals, 'Referrals (Views)'.'My Referrals') });
: This updates thetabReferrals
context variable with a filtered subset of theReferrals
data source. TheFilter
function is applied to select only those records fromReferrals
that meet the criteria defined by'Referrals (Views)'.'My Referrals'
. This could be a specific view or condition within theReferrals
data source.
In summary, this code snippet is designed to reset and update the state of an application interface, particularly for features related to searching, sorting, and displaying referral data. It clears a search input, resets sorting and filtering states, refreshes the data source to ensure up-to-date data, and then applies a predefined filter to the data to update a context variable. This functionality is useful for scenarios like clearing user input and returning to a default or initial view of data in an application.
Code Snippet #9
For filter, sort along with search functionality
This code snippet combines several functions to update a context variable (tabReferrals
) with a list of referrals that have been filtered, sorted, and searched based on certain criteria.
UpdateContext(
{
tabReferrals: Filter(
SortByColumns(
Search(
Referrals,
txtSearch.Value,
"nledu_name",
"nledu_referralemail",
"nledu_referralnotes"
),
"nledu_referralstatus",
If(
locSortOrder,
SortOrder.Ascending,
SortOrder.Descending
)
),
'Referrals (Views)'.'My Referrals'
)
}
);
Explanation
-
Search Function:-
Search(Referrals, txtSearch.Value, "nledu_name", "nledu_referralemail", "nledu_referralnotes")
: This function searches through theReferrals
data source (Microsoft Dataverse in this case) for records where the search string entered intxtSearch.Value
matches any of the fieldsnledu_name
,nledu_referralemail
, ornledu_referralnotes
. -
SortByColumns Function:-
SortByColumns(..., "nledu_referralstatus", If(locSortOrder, SortOrder.Ascending, SortOrder.Descending))
: The results from theSearch
function are then sorted by thenledu_referralstatus
field. The sort order (ascending or descending) is determined by the value of thelocSortOrder
context variable. -
Filter Function:-
Filter(..., 'Referrals (Views)'.'My Referrals')
: The sorted list is further filtered to include only those records that meet the criteria defined by'Referrals (Views)'.'My Referrals'
. This might refer to a specific view or subset of theReferrals
data, such as referrals belonging to the current user. -
UpdateContext Function:-
UpdateContext({ tabReferrals: ... })
: This function updates thetabReferrals
context variable with the results of the search, sort, and filter operations. Context variables are used in Power Apps to store and manage data locally on a screen.
In summary, this code snippet is performing a multi-step data manipulation process. It starts by searching the Referrals
data source based on user input, sorts the results based on a specified field and order, filters these results based on a predefined condition, and finally stores this curated list of referrals in the tabReferrals
context variable. This is a common pattern in Power Apps for creating dynamic, responsive user interfaces where the displayed data depends on user interactions such as search input and sorting preferences.
Code Snippet #10
For reset update
This code snippet performs a series of operations to reset and update the state of a user interface related to the display and management of referral data. The operations include resetting context variables, refreshing a data source, and filtering data for display.
UpdateContext(
{
locSortOrder: false,
locFiltered: false
}
);
Reset(txtSearch);
UpdateContext(
{
locSortOrder: false,
locFiltered: false
}
);
Refresh(Referrals);
UpdateContext(
{
tabReferrals: Filter(
Referrals,
'Referrals (Views)'.'My Referrals'
)
}
);
Explanation
-
Setting Initial Context Variables:-
UpdateContext({ locSortOrder: false, locFiltered: false });
: This line initializes or updates two context variables:locSortOrder
andlocFiltered
, setting both tofalse
. These variables likely control the sorting and filtering state of data displayed in the app. -
Resetting the Search Text Input Control:-
Reset(txtSearch);
: This function resets thetxtSearch
control, which is likely a text input field. This action clears any text the user might have entered. -
Reiterating Context Variable Updates:- The code again updates the same context variables
locSortOrder
andlocFiltered
tofalse
. This appears to be redundant, as these variables were already set tofalse
in the previous step. -
Refreshing the Data Source:-
Refresh(Referrals);
: This function refreshes theReferrals
data source. It ensures that the app is working with the most up-to-date data, reflecting any changes that might have occurred outside of the app or in other user sessions. -
Updating Context Variable with Filtered Data:-
UpdateContext({ tabReferrals: Filter(Referrals, 'Referrals (Views)'.'My Referrals') });
: This updates thetabReferrals
context variable with data filtered from theReferrals
data source. TheFilter
function is used to select only those records that meet the criteria defined by'Referrals (Views)'.'My Referrals'
, which is likely a specific view or subset within theReferrals
data source.
In summary, this code snippet is designed to reset certain user interface elements and states, refresh the data source to ensure current data is being used, and update a context variable with a filtered set of referral data. This type of functionality is common in applications where data needs to be reset or reloaded based on user interactions or other application events, ensuring that users are always presented with the most relevant and current information.
Concluding this exploration of Power Apps and Dataverse through practical code snippets, we've traversed from the basics of dynamic UI adjustments to the complexities of data manipulation and integration with Power Automate. Each snippet not only serves as a standalone solution but also as a building block towards creating more sophisticated, responsive, and user-friendly applications. This journey underscores the power of low-code platforms in transforming ideas into reality, enabling developers and business professionals alike to craft solutions that are not just efficient but also scalable and adaptable to evolving business needs. As you integrate these snippets into your projects, remember that the essence of technology is to simplify, automate, and enhance — principles that Power Apps and Dataverse embody with excellence. Happy coding, and may your path in leveraging these tools be as rewarding as it is innovative.
Happy #low-code learning