diff --git a/website/docs/training/day-1-agenda.md b/website/docs/training/day-1-agenda.md new file mode 100644 index 0000000000..87ca718351 --- /dev/null +++ b/website/docs/training/day-1-agenda.md @@ -0,0 +1,60 @@ +--- +title: "Agenda" +hide_title: false +--- + +# Day 1: Appsmith Training Agenda +## Introduction and Core Concepts +
+ +Discover what Appsmith is, its key features, and how it empowers you to build applications quickly. + +
+ +### [1. Connecting and Managing Datasources](/training/session-1#connecting-and-managing-datasources) +
+ +- **Datasource Setup:** Learn to connect various datasources such as REST APIs and databases. +- **Hands-On:** Follow step-by-step instructions to add and configure your datasource. + +
+ +### [2. Widget Essentials and Displaying Data](/training/session-1#widget-essentials-and-displaying-data) +
+ +- **Core Widgets:** Explore essential widgets like Table, Text, Button, Select, and Container. +- **Data Binding:** Understand how to bind data to widgets for dynamic display and interactivity. + +
+ +### [3. Customizing and Enhancing Functionality with Code](/training/session-2#customizing-and-enhancing-functionality-with-code) +
+ +- **Custom Code Integration:** Use JavaScript to extend widget functionality and manipulate data. +- **Interactive Demo:** Practice by writing custom code snippets to modify widget behaviors and data output. + +
+ +### [4. Building CRUD Interfaces and Interactive Dashboards](/training/session-2#building-crud-interfaces-and-interactive-dashboards) +
+ +- **CRUD Operations:** Implement functionalities to Create or Update data with Forms +- **Dashboard Assembly:** Combine multiple widgets like Chart and Statbox to create an interactive Dashboard + +
+ +### [5. Task: Create a Basic App](https://training.app.appsmith.com/app/task-1/home-67bdd31349bf245ac087e8fe) +
+ +- **Hands-On Challenge:** Build a basic application integrating datasources, widgets, and custom code. +- **Objective:** Apply all the concepts learned to create a functional app from scratch. + +
+ +### 6. Get a sneak peek into Day 2 Agenda +
+ + - **Git Integration:** Understand version control for collaborative development. + - **Custom Widgets:** Learn how to create your own widget + +
diff --git a/website/docs/training/day-2-agenda.md b/website/docs/training/day-2-agenda.md new file mode 100644 index 0000000000..06763fd042 --- /dev/null +++ b/website/docs/training/day-2-agenda.md @@ -0,0 +1,72 @@ +--- +title: "Agenda" +hide_title: false +--- + +# Day 2: Appsmith Training Agenda +## Advanced Development and Collaboration +
+ +Enhance your Appsmith skills by exploring version control, CI/CD, advanced integrations, and custom widgets. + +
+ +### [1. Version Control: Development Process and Collaboration](/training/session-3#version-control-development-process-and-collaboration) +
+ +- **Git Integration:** Learn how to integrate Appsmith with Git for version control. +- **Branching & Merging:** Understand how to create branches, commit changes, and merge updates. +- **Collaborative Development:** Work with teams using Appsmith’s built-in collaboration features. + +
+ +### [2. Configuring Multiple Environments and Setting Up CI/CD Pipelines](/training/session-3#configuring-multiple-environments-and-setting-up-cicd-pipelines) +
+ +- **Environment Variables:** Learn how to configure multiple environments like Development, Staging, and Production. +- **CI/CD Pipelines:** Automate deployments and manage changes across different environments. + +
+ +### [3. Advanced JavaScript and API Integrations](/training/session-4#advanced-javascript-and-api-integrations) +
+ +- **JS Libraries:** Extend Appsmith’s capabilities with custom JavaScript libraries. +- **API Chaining & Transformations:** Use JavaScript to modify API responses before displaying data. +- **Error Handling & Debugging:** Learn best practices for handling API failures and debugging in Appsmith. + +
+ +### [4. Embedding Appsmith Applications and Facilitating Communication](/training/session-4#embedding-appsmith-applications-and-facilitating-communication) +
+ +- **Embedding Apps:** Learn how to embed Appsmith apps into external platforms or other web apps. +- **Cross-App Communication:** Enable seamless data sharing between different Appsmith applications. + +
+ +### [5. Creating Custom Widgets](/training/session-4#creating-custom-widgets) +
+ +- **Understanding Custom Widgets:** Learn how to build custom widgets using JavaScript and Appsmith’s widget APIs. +- **Data Models & Events:** Send actions and trigger events to enhance widget behavior. + +
+ +### [6. Hands-On Task](https://community.appsmith.com/tutorial/how-create-your-own-custom-navigation-bar-nested-items-and-icons) +
+ +* **Objective:** Build an advanced app using custom widgets and version control it with GIT. +* **Challenge:** Create a custom navigation bar that is dynamic based on the data model. When an item is clicked, the app should navigate to the corresponding Appsmith page. +* Share us the applications that you create and we will publish them in our [community](https://community.appsmith.com) + +
+ +### 7. Get a sneak peek into Day 3 Agenda +
+ +- **Workflows & Automation:** Learn how to design and manage complex workflows. +- **Reusable Code with Appsmith Packages:** Explore how to reuse code across multiple applications. +- **Granular Access Control:** Understand how to set up role-based access, programmatic permissions, and secure your applications. + +
diff --git a/website/docs/training/day-3-agenda.md b/website/docs/training/day-3-agenda.md new file mode 100644 index 0000000000..0b5f6aa539 --- /dev/null +++ b/website/docs/training/day-3-agenda.md @@ -0,0 +1,46 @@ +--- +title: "Agenda" +hide_title: false +--- + +# Day 3: Appsmith Training Agenda +## Enterprise Features +
+ +Enhance your Appsmith expertise by exploring **reusability**, **workflow automation**, **access control**, and **audit logging** to build secure, scalable applications. + +
+ +### [1. Reusability with Appsmith Packages](/training/session-5#reusability-with-appsmith-packages) +
+ +* **Introduction to Appsmith Packages:** Learn how to create and use reusable JS Objects and Queries. +* **Best Practices:** Understand how to structure your apps efficiently using reusable components. +* **Hands-On:** Create a package and integrate it into multiple applications. + +
+ +### [2. Designing and Managing Complex Workflows](/training/session-5#designing-and-managing-complex-workflows) +
+ +* **Human-in-the-Loop Workflows:** Implement workflows where manual approvals or interventions are required before proceeding. +* **Automating Tasks with CronJobs:** Schedule recurring tasks like data refreshes, report generation, or background processing by triggering APIs or database queries at set intervals + +
+ +### [3. Implementing Granular Access Control and Programmatic Permissions](/training/session-6#implementing-granular-access-control-and-programmatic-permissions) +
+ +* **Role-Based Access Control (RBAC):** Configure user roles and permissions for better security. +* **Programmatic Permissions:** Use dynamic access control based on user roles and conditions + +
+ +### [4. Utilizing Audit Logs for Monitoring and Compliance](/training/session-6#utilizing-audit-logs-for-monitoring-and-compliance) +
+ +* **Understanding Audit Logs:** Track user activities and changes made within the application. +* **Compliance & Security:** Maintain logs for audits, troubleshooting, and security monitoring. +* **Hands-On Task:** View, filter, and analyze logs to investigate user actions. + +
diff --git a/website/docs/training/day-5-agenda.md b/website/docs/training/day-5-agenda.md new file mode 100644 index 0000000000..b926a8a379 --- /dev/null +++ b/website/docs/training/day-5-agenda.md @@ -0,0 +1,58 @@ +--- +title: "Agenda" +hide_title: false +--- + +# Day 5: Appsmith Training Agenda +## Application Support +
+ +Learn essential debugging and troubleshooting techniques for Appsmith applications, including console debugging, server-side log analysis, and support workflows. + +
+ +### [1. Debugging with Consoles & Browser Tools](/training/session-8#debugging-with-consoles--browser-tools) +
+ +- **Appsmith In-App Console:** Master the editor console for real-time debugging of queries, JS objects, and bindings. +- **Browser Developer Tools:** Learn when and how to use Chrome DevTools for deeper investigation. +- **Network Tab Deep Dive:** Export HAR files and analyze API requests/responses. +- **Application Tab:** Inspect local storage and session data for state-related issues. + +
+ +### [2. Accessing Server-Side Logs & Instance Health](/training/session-8#accessing-server-side-logs--instance-health) +
+ +- **Quick Instance Checks:** Use built-in endpoints like `/info`, `/api/v1/health`, and consolidated API views. +- **Container Log Collection:** Follow best practices for gathering server-side logs. +- **Log Analysis:** Identify error patterns, timestamps, and service context in logs. + +
+ +### [3. Checking for Existing Issues](/training/session-8#checking-for-existing-issues) +
+ +- **GitHub Issues Search:** Efficiently search Appsmith's issue tracker before escalating problems. +- **Filtering Techniques:** Use labels, status, and keywords to find relevant discussions. +- **Finding Workarounds:** Locate temporary solutions and status updates for known issues. + +
+ +### [4. Connecting with Appsmith Support](/training/session-8#connecting-with-appsmith-support) +
+ +- **Support Channels:** Understand available support options and escalation paths. +- **Information Gathering:** Learn what details to include for effective support requests. +- **Best Practices:** Follow proper procedures for timely assistance. + +
+ +### [5. Using Audit Logs](/training/session-8#using-audit-logs-for-debugging) +
+ +- **Audit Log Access:** Navigate to Settings → Audit Logs and understand permission requirements. +- **Filtering Strategies:** Use Event Type, User ID, Time Range, and Resource ID filters effectively. +- **Troubleshooting with Logs:** Identify failed calls, high latency, and unauthorized attempts. + +
diff --git a/website/docs/training/session-1.md b/website/docs/training/session-1.md new file mode 100755 index 0000000000..7b956ddaf3 --- /dev/null +++ b/website/docs/training/session-1.md @@ -0,0 +1,159 @@ +--- +title: Session 1 +hide_title: false +--- + + + +## Getting Started + +1. Sign up on this instance: [Training Instance](https://training.app.appsmith.com/user/signup) (Ignore if already done) + +2. Now you will be guided through the Onboarding. Select your profiency with Appsmith. + +3. Click on **Skip this step** so that we can head to the editor of your Application + + +## Connecting and Managing Datasources +1. **REST API** +
+ +* Click on the Datasoure icon, located third from the bottom of the left sidebar, and then click on the button **Bring your data** and select Datasource **REST API**. +* Enter **https://mock-api.appsmith.com** in the field +* Click **Save URL** and you will be taken to the Datasource configuration page +* Name the Datasource as **Mock API** and go ahead and click Save. +* Now rename the API as **getUsers** and append the path **/users** to the url +* Click on Run and see the results below on the page +* Great!! You have successfully created an REST API Datasource and ran an API on top of it + +
+ +2. **PostgreSQL** +
+ +* Now go back to Data on the sidebar and Click on the **+** symbol on the top, next to **Datasources in your workspace** +* Select **PostgreSQL** and you will be taken to the configuration page +* Now fill in the follow credentials as seen below + ```jsx + Host: mockdb.internal.appsmith.com + Port: 5432 + Database: users + User: users + Password: new-users-db-pass + ``` +* Click on **Test configuration** to verify if the credentials are valid to successfully connect to the datasource. +* Rename this Datasource as **Postgres DB** and go ahead and click Save. +* You will be able to see the schema of your table, and also preview of the data on right side for each table. +* Now select the table name **public.users** click on the button **New Query** on the top right +* There will be a default query already filled in. You can go ahead and click on Run and see the results below on the page +* On the bottom right side, you will also be able to see the Schema of each table in detail, like Column type, Primary key, etc. +* Great!! You have successfully created a Postgres Datasource and a Query on top of it + +
+ +## Workspaces and Sharing Access + +
+ +1. In the Editor mode, on the top, you will see your App name as **My First Application**. Click on it and Rename it as **Activity 1**. +2. Now click on the Appsmith Logo on the top left corner of the page, and it will take you back to the Appsmith Workspaces page. +3. You will be able to see your Workspaces and Applications and what other workspaces you have access to. +4. On the top-rightmost, next to the **Create new** button, you will see a three-dot menu. Click on it and you will see your workspace name. +5. Click on the Edit icon next to it and rename your workspace as **\-Training-Workspace** +6. Also you can share access to your workspace by clicking on the **Share** button. Type in **Training Admin** and select the Administrator role and click Invite. This will allow us to view your Applications and help you in the case of any issue you face during the training. +7. On the top right of the workspace, there is an info icon. From that click on **Chat with us**. This is our support assistant that can help you on any issues. Go ahead and send a test message + +
+ +## Widget Essentials and Displaying Data + +1. **Table Widget** + +
+ +* Introduce a Table widget from the Widget pane on the left. +* Connect data from the table settings on the right, and select the datasource **Postgres DB** which we just created. +* Select the table **public.users** and the searchable column as **name**, and click **Connect data** +* Now go to the **Queries** Tab on the left and check out the automatically generated CRUD queries for your database +* Customise the columns like setting visibility, re-ordering the columns and even changing the column type +* See how the table is connected to your Data and that it supports Server Side Pagination +* Play around with the inline editing and add row to table + +
+ +2. **Text Widget** + +
+ +* Drag and drop a text widget on to the canvas +* Edit the Text from its settings on the right, and set the value it as **My User Database** +* From its Style tab, you can customise many things like the size or the color of the Text widget +* Set the Font size as **L** (Large) and select the Text color as the first **Theme color** + +
+ +3. **Button Widget** + +
+ +* Introduce a Button widget on to the canvas +* Set the button value as Refresh, and possibly find an icon from the Style tab to suit this Action +* You can also set the type of the button between Primary, Secondary and Teritary options +* Finally connect the onClick of the widget to the Table’s **Select_public_users1** query + +
+ +4. **Select Widget** + +
+ +* Create an SQL query named **getGenderValues** that retrieves all the distinct values of the table from the “gender“ column +
+ Show Hint +
+ ```jsx + Select DISTINCT(gender) from public.users + ``` +
+
+ +* Click on **Display on UI** and choose Select widget to bind the data and it to the UI. +* Now update the Table’s **Select_public_users1** query and append to the Where clause to filter based on gender +
+ Show Hint +
+ ```jsx + WHERE “name” ilike ‘%{{Table1.searchText}}%’ + AND “gender” ilike '{{Select1.selectedOptionValue}}%' + ``` +
+
+ +* Connect the onOptionChange event of the Select Widget to trigger the Table’s **Select_public_users1** query + +
+ +5. **Container Widget** + +
+ +* Drag and place the 4 widgets Table, Text, Button and Select on the canvas however you want +* You can also drag and highlight all the widgets to select them, and you will see a minibar pop up +* Select the last option, to group these widgets inside a container +* Now you can easily move it around the canvas and align it based on your need +* Like other widgets, you can also configure its height either as **Fixed** or **Auto Height** + +
+ +## Theming + +
+ +* Go to the bottom left Corner and click on the **:gear:** button that will take you to the App Settings +* Click on Theme and explore changing the primary color, app border radius and shadow +* Notice how you will see the changes happening across your widgets in real time based on your theming changes + +
+ +## Deploy App +Go ahead and click on the Deploy button on the top right and see your App in deployed mode \ No newline at end of file diff --git a/website/docs/training/session-2.md b/website/docs/training/session-2.md new file mode 100755 index 0000000000..ab8c932358 --- /dev/null +++ b/website/docs/training/session-2.md @@ -0,0 +1,147 @@ +--- +title: Session 2 +hide_title: false +--- + + + +## Getting Started + +**Ignore this if you were able to attend the previous Session.** + +1. Sign up on this instance: [Training Instance](https://training.app.appsmith.com/user/signup) + +2. Create a workspace of your own and name it as **\-Training-Workspace** + +3. Share access to your workspace to **Training Admin** as an Administrator + +4. From the workspace, click on the top-right **info icon**, then select **Chat with us**. This is Appsmith’s support assistant that can help you with any issues. Send a test message to familiarize yourself with the support feature. + +## Customizing and Enhancing Functionality with Code + +1. **Inline JS** + +
+ +* You can write javascript code inside any widget's fields that has **JS** symbol next to it, by using the `Moustache {{}}` operator +* This allows you to logically customise a widget's functionality and styling based on some conditions +* Introduce a checkbox and rename the Label as **Allow Filters** +* Now go to the settings of the Select widget, and click on **JS** next to the Visible field +* Bind the status of the Checkbox to that field like this `{{Checkbox1.isChecked}}` +* Click on the Preview symbol next to the Share button on the top +* Now toggle the checkbox to see the Select widget's visibility changing based on your selection + +
+ +2. **JSObjects** + +
+ +* You can also write functions and create variables to bind it to a widget's Data or an Event +* From the left sidebar, click on **JS** and create a **New JS object** and name it as **Utils** +* Introduce a variable with some initial value inside it +```jsx +currentDate: new Date(), +``` +* Introduce a function to get **Select_public_users1** data +```jsx +getUserData() { + return Select_public_users1.data +}, +``` +* Introduce a function to get current age from date of birth +
+ Show Hint +
+ ```jsx + getUserAge(dob) { + return moment(this.currentDate).diff(moment(dob), ‘years’) + } + ``` +
+
+ +* Add new column in table widget and name it **Age** +* Connect the value of the column to the getUserAge function +`{{Utils.getUserAge(currentRow.dob)}}` + +
+ +## Building CRUD Interfaces and Interactive Dashboards + +1. **Forms** + +
+ +* Introduce a Form onto the canvas and align it on the right side of the Table +* Add input and select widgets for all the relevant Table columns you would want to update for like +```jsx +Name, Gender, Date of Birth, Phone, Email and Country +``` +* Rename the widgets inside the Form for better reference +* You can set which all fields that are required for Form submittion, and even add validations to it. +* Change the existing **Update_public_users1** Query to use the Form data instead +
+ Show Hint +
+ ```jsx + UPDATE public.users SET + "gender"= '{{Form1.data.gender}}', + "dob"= '{{Form1.data.dob}}', + "phone"= '{{Form1.data.phone}}', + "email"= '{{Form1.data.email}}', + "country"= '{{Form1.data.country}}', + "name"= '{{Form1.data.name}}', + "updated_at"= '{{new Date()}}' + WHERE "id"= {{Table1.selectedRow.id}}; + ``` + The above is just a sample solution. Ensure you correctly refer to the widgets' names you had renamed in the Form, within this **Query** when you copy pasting it. +
+
+ +* Rename the button label inside the Form to `Update Details` +* Connect the onClick of the button to the **Update_public_users1** Query +* Inside the success of the onClick, connect it to the **Select_public_users1** Query + +
+ +2. **Charts** + +
+ +* Create a new Page +* Introduce a Chart on the canvas +* Write an SQL query **getGenderRatioQuery** to show all the males and females distribution of users in the database +
+ Show Hint +
+ ```jsx + SELECT gender, COUNT(*) FROM public."users" group by gender; + ``` +
+
+ +* Notice that chart that takes values only in x,y format. +* Create a JSObject and call it **Utils**. Introduce a function called **getChartDataByGender** that formats the Query’s data in x & y format +
+ Show Hint +
+ ```jsx + getChartDataByGender: () => { + return getGenderRatioQuery.data.map(item => { + return { + x: item.gender, + y: item.count + }; + ) + } + ``` +
+
+ +* Connect the JS Object function directly to the Chart’s source data `{{Utils.getChartDataByGender()}}` + +
+ +## Deploy the App +Go ahead and click on the Deploy button on the top right and redeploy your App and view it with the new changes you have made \ No newline at end of file diff --git a/website/docs/training/session-3.md b/website/docs/training/session-3.md new file mode 100755 index 0000000000..a80ac6aa89 --- /dev/null +++ b/website/docs/training/session-3.md @@ -0,0 +1,141 @@ +--- +title: Session 3 +hide_title: false +--- + + + +## Getting Started + +**Ignore this if you were able to attend the previous Session.** + +1. Sign up on this instance: + [Training Instance](https://training.app.appsmith.com/user/signup) + +2. Create a workspace of your own and name it as **\-Training-Workspace** + +3. Share access to your workspace to **Training Admin** as an Administrator + +4. From the workspace, click on the top-right **info icon**, then select **Chat + with us**. This is Appsmith’s support assistant that can help you with any + issues. Send a test message to familiarize yourself with the support feature. + +## Version Control: Development Process and Collaboration + +1. **Setting up your GIT branches** + +
+ +- Open the **Git-connected App** in your workspace and click **Edit** to enter + the Editor mode. +- Look at the **bottom-left corner**; you will see that you are currently on the + **master** branch. +- Click on the branch name, and a popover will appear listing all branches (both + local and remote). +- Create a new branch: + - Enter **\-prod** as the branch name. + - This will create a **production branch** from the master branch. +- After switching to the **prod** branch: + - Click the **Cog icon ⚙️** on the bottom bar to open Git settings. + - Under the **Branch tab**, set **\-prod** as the default branch. +- Now, create another branch: + - Open the branch list, type **\-dev**, and create a **development + branch** from your production branch. + +
+ +2. **Making changes and commiting to GIT** + +
+ +- Make some changes in your app: + - Add new widgets, update styling, or create a new page. +- Once you are done, Click the **+ button** next to the branch name and a modal + will pop up. +- In the modal, go to the **Deploy Tab**: + - Review the changes. + - Add a commit message to describe your changes. + - Click **Commit & Push** to push changes to your remote branch. +- Great, you have successfully commited your changes to your very own dev branch + of this Application. +- You can preview the deployed version by + - Click on **Deploy > Latest deployed preview** + - By changing value of branch to `?branch=` in your app's URL. + +
+ +3. **Merging your changes** + +
+ +- Click the **+ button** again to open the modal. +- Navigate to the **Merge Tab**. +- Select **\-prod** as the target branch to merge your **dev** branch + changes. +- Check for merge conflicts before proceeding. +- After merging: + - Switch to the **prod** branch from the GIT branches list. + - Click the **down arrow** (⬇) next to the branch name to pull the latest + changes. + - Click **Deploy > Latest deployed preview** to see the updated app in + production. + +
+ +## Configuring Multiple Environments and Setting Up CI/CD Pipelines + +### 1. Creating and Managing Multiple Environments + +
+ +- Open your **Application** and navigate to the **Datasources** page + (bottom-left corner). +- Click on any **existing datasource** and select **Edit**. +- On the right panel, you will notice: + - **Production Environment** is already configured as the default. + - **Staging Environment** can be configured manually. +- Click on **Manage Environments** at the bottom. +- Here, you can: + - Create new environments (e.g., **Development, QA, UAT**). + - View how many datasources are already configured for each environment across + your workspace. + +
+ +### 2. Automating Deployments with CI/CD + +
+ +- Open the **Application** for which you want to set up CI/CD, preferably the + one in the production instance/workspace. +- Click the **⚙️ (Cog icon)** to open **Git Settings** and go to the + **Continuous Delivery** tab. +- Here, you'll see setup instructions along with a **cURL command** for the + master branch. +- Click **Generate Bearer Token** to create an authentication token. +- Open the + [Appsmith CI/CD documentation](https://docs.appsmith.com/advanced-concepts/version-control-with-git/cd-with-git) + and choose a deployment tool (e.g., **GitHub Actions**). +- Follow the instructions to create a **GitHub Action** and copy-paste the YAML + code. +- Replace the cURL command in the YAML file with: + - The command generated for your application. + - The **Bearer Token** from Appsmith. +- **Best Practice:** Store the **Bearer Token** as a **GitHub Secret** and + reference it in your YAML file instead of hardcoding it. +- After saving the changes to your YAML file, check the confirmation box and + click **Finish Setup**. +- Now, any time changes are merged, pushed, or committed to the **master + branch**, the application will automatically redeploy with the latest updates. + +
+ +## Best practices + +When you are working as team and collaborating using Version Control, some best +practices need to be followed to ensure consistency and synchronisation across +your org. + +Here is a +[documentation](https://www.appsmith.com/blog/appsmith-git-internal-tools-3) +stating some of these practices that you can follow. diff --git a/website/docs/training/session-4.md b/website/docs/training/session-4.md new file mode 100755 index 0000000000..28cc88e669 --- /dev/null +++ b/website/docs/training/session-4.md @@ -0,0 +1,165 @@ +--- +title: Session 4 +hide_title: false +--- + + + +## Getting Started + +**Ignore this if you were able to attend the previous Session.** + +1. Sign up on this instance: [Training Instance](https://training.app.appsmith.com/user/signup) + +2. Create a workspace of your own and name it as **\-Training-Workspace** + +3. Share access to your workspace to **Training Admin** as an Administrator + +4. From the workspace, click on the top-right **info icon**, then select **Chat with us**. This is Appsmith’s support assistant that can help you with any issues. Send a test message to familiarize yourself with the support feature. + +## Advanced JavaScript and API Integrations + +1. **Custom JS Libraries** + +
+ +* Click on the Libraries icon, second last from the bottom on the left pane +* Here, you will find pre-installed libraries like **lodash** and **moment.js**, along with an option to **Add new libraries**. +* Browse through the **Recommended Libraries** or search for other libraries via [jsDelivr](https://www.jsdelivr.com). +* You will also see an option to add other libraries from the site [jsDelivr](https://www.jsdelivr.com) +* Search for **currency.js** and select it. +* Copy the URL from the **src** tag or use the direct link below: + +
+ Show library url +
+ ```https://cdn.jsdelivr.net/npm/currency.js@2.0.4/dist/currency.min.js``` +
+
+ +* Paste the copied link into the Add JS Library input field and click Install. +* Once installed, you can now use the currency.js functions anywhere in your Appsmith app. +* Example: + - Drag and drop a Text widget. + - Enter a large numeric value with moustache brackets `{{}}` + - Surround the value with the currency function to display the amount in a properly formatted currency. + ```jsx currency(10899.99, { symbol: "$", precision: 0 }).format()``` + +
+ +2. **API Chaining and Error handling with Javascript** + +
+ +* Use async/await to chain multiple API calls and queries in a controlled sequence. +* Implement try/catch or .then/.catch for error handling to manage failures gracefully. +* Utilize Promises to run multiple actions in parallel while maintaining control over their execution flow. + +
+ +3. **Debugger** + +
+ +* Click the Debug button at the bottom-right corner of the Editor to open the Debugger Console +* The Logs section displays: + - Actions triggered by widgets (e.g., button clicks). + - API requests and responses, including success/failure status. +* The Linter tab highlights widgets with issues and clicking on an error will navigate directly to the affected widget for quick fixes +* Open the Network Tab in the Developer tool of the Browser. Whenever an API/Query is triggered, the tab shows the follow details + - API requests wrapped in executeAction (in Edit mode). + - Sent parameters and the endpoint being called in the requests + - In View mode, the API request is seen but additional details like endpoint and parameters are hidden for security reasons. + +
+ +## Embedding Appsmith Applications and Facilitating Communication + +1. **Embedding applications** + +
+ +* Click on the **Share** button in the top-right corner to open the **Share Modal**. +* Navigate to the **Embed** tab to view the **Embed URL** and a **Preview embedded app** option. +* Configure embed settings based on access requirements: + - **Public Embed:** Making the App public allows anyone to access the embedded app. + - **Private Embed:** Requires authentication to access the embedded content. +* For **private embeds**, you can also pass an **SSO method** in the embed URL to authenticate users seamlessly. + +
+ +2. **Communicating between Appsmith Embeds and Parent page** + +
+ +* Appsmith provides methods to enable two-way communication between the **embedded app** and the **parent page** +* Use `postWindowMessage()` to send data or events from Appsmith to the parent page. + ```postWindowMessage("Appsmith Ready", { status: "initialized" });``` +* Use `windowMessageListener()` in Appsmith to listen for messages from the parent page and trigger actions accordingly. + ```jsx + windowMessageListener((message) => { + if (message.data === "refresh") { + getData.run(); // Trigger an action inside Appsmith + } + }); + ``` +
+ +## Creating Custom Widgets + +1. **Configuring Custom Widget** + +
+ +* Drag and drop a **Custom Widget** from the **Widgets pane** onto the canvas. +* In the widget settings, click **Go to Source Editor** to open the **Custom Widget Editor**. +* The editor provides three coding tabs: **HTML, CSS, and JS**, along with an **AI tab** where our AI Copilot helps you generate code. +* Click on **Editable Data Grid Widget** in the **AI Copilot**, and it will auto-generate code across the tabs for the custom widget. +* Review the generated code to understand how it works. + +
+ +2. **Connecting data model** + +
+ +* Return to the **Main Editor** and select the **Custom Widget** to open its settings. +* Locate the **Default Model** section, which contains dummy data. +* Modify the **Default Model** to fetch data from one of your existing queries. Below is an example for a query named as getUsers.data + ```jsx + {{ + { + data: getUsers.data + } + }} + ``` +* The widget will automatically re-render when the data updates, thanks to the onModelChange event in the Custom widget. +* The onModelChange event ensures that the component updates whenever the Data Model changes + ```jsx + appsmith.onModelChange((model, prevModel) => { + if (JSON.stringify(model.data) !== JSON.stringify(prevModel?.data)) { + setData(model.data && Array.isArray(model.data) ? model.data : fallbackData); + } + }); + ``` + +
+ +3. **Configuring Custom Events** + +
+ +* Inside the Settings panel, navigate to Events and add a new event named onCellEdit. +* Configure the action to Show Alert, and set the message as ```{{`Cell to Update: Column ${column}, Row: ${rowIndex}, Value: ${value}`}}``` +* Now, go back to the Custom Widget Editor and locate the following line of code like ```appsmith.triggerEvent```. This will trigger any event that you have configured if you pass the event name, and the data as an object. Below it calls the onCellEdit and passes the column, rowIndex and value +```appsmith.triggerEvent("onCellEdit", { column: columList[col], rowIndex: row, value: newValue.data });``` +* Ensure that the event name matches the one you created in the settings. If different, update either the event name or the custom widget code accordingly. + +
+ +Congratulations :tada: You have successfully configured a Custom Widget and linked it with your app's data. + - Experiment with additional functionalities and customization options. + - For more details, refer to the [documentation](https://docs.appsmith.com/reference/widgets/custom) + +## Deploy the App +Go ahead and click on the Deploy button on the top right. This time you will have to commit your changes. Post that you can view the App with the latest changes you have made. \ No newline at end of file diff --git a/website/docs/training/session-5.md b/website/docs/training/session-5.md new file mode 100755 index 0000000000..7165155c86 --- /dev/null +++ b/website/docs/training/session-5.md @@ -0,0 +1,183 @@ +--- +title: Session 5 +hide_title: false +--- + + + +## Getting Started + +**Ignore this if you were able to attend the previous Session.** + +1. Sign up on this instance: [Training Instance](https://training.app.appsmith.com/user/signup) + +2. Create a workspace of your own and name it as **\-Training-Workspace** + +3. Share access to your workspace to **Training Admin** as Administrator + +4. From the workspace, click on the top-right **info icon**, then select **Chat with us**. This is Appsmith’s support assistant that can help you with any issues. Send a test message to familiarize yourself with the support feature. + +## Reusability with Appsmith Packages + +1. **Creating a Package** + +
+ +* On the workspace page, Click on **Create New** button and select New Package. +* Once inside the package, name this package from the top as **My Package**. +* Then click on **New Module** and select JS Module. +* Now you will see a JSObject created. Name this as **DateFns**. +* Inside that introduce a function called **getUserAge** that takes an argument **dateString**, and returns the age +```jsx +getUserAge: (dateString) => { + return moment().diff(moment(dateString), 'years'); +} +``` +* Now publish this package by clicking the button on the top right. + +
+ +2. **Connecting a package to your App** + +
+ +* Now go to the edit mode of your App, and clicking on the JS tab on left sidebar. +* Click on new JS Object, and you will be able to add your module **DateFns** to your App. +* Now head to your Table widget which is connected to user data. Go to the age column you had created before, else create a custom column +* In the settings of this column, inside the Computed value field, surround it with your module's function. +Example below +```jsx +DateFns1.getUserAge(currentRow.dob) +``` +* Now you should be seeing the column on Table having ages for all users. +* Go ahead and click on the Deploy button on the top right to deploy your App and view it with the new changes you have made. + +
+ +3. **Republishing a package** + +
+ +* Let us also try making some changes inside the package and see how the changes are reflected across in your Apps. +* Head back to the workspace and click on edit on package named **My Package**. +* Inside the main file of your **DateFns** module, lets update the function to show the text **years** along with the age. +```return moment().diff(moment(dateString, 'years')) + " years";``` +* Now lets publish and head back to the Edit mode of your Application, and you will already see your changes being reflected inside the Editor in your Table widget. +* Click on deploy button again to start seeing your changes. +* Great, you have successfully created a package with a module and reused it across multiple pages of your App. + +
+ +4. **Converting a Query/JSObject into a Package** + +
+ +* We showed how to create a module inside a package, now lets explore how to add a query to a package. +* Now lets go to the editor page of the App, and head to the queries in the page. +* You will see the Query **Select_public_users1** or the equivalent of it in your App. Hover over it and click on the 3 dots next to it. +* Now click on the **Create a Module** and select **Add to My Package**. +* You will see that your query has been automatically added to your existing Package and its reference is being used in the Page. You will also notice that it is auto filled with the arguments needed. +* And thats it, you have successfully converted your Query as a module + +
+ +## Designing and Managing Complex Workflows + +1. Creating a Basic Workflow + +
+ +* On the **Workspace** page, click **Create new** and select **Workflow**. +* You will be directed to the **Workflow Editor**. Name the workflow **My Workflow**. +* The editor contains a main file with a predefined function `executeWorkflow(data)`, where `data` is the input argument. +* Create a query named **getUsers** to fetch users from the database, filtering by name: +```Select * from public.users Where name ilike '{{this.params.name}}'``` +* Call the query inside executeWorkflow, passing an object with the name parameter: +```await getUsers.run({ name: data.name });``` +* Add a console statement like ```console.log('getUsers response', getUsers.data)``` and also ensure that the last line of the function is ```return true``` +* Run the function directly from the Workflow Editor: + - In the input field, enter the test object: +```{ "name": "Rose" }``` + - Observe the execution steps and responses on the right panel. Expand each step for details. +* Click Deploy (top-right), then navigate to a new application within the same workspace. +* Add a Query from the sidebar and select Workflows Query. +* Choose the workflow name from the list and set the Request Type to Trigger Workflow. +* Pass the same input object as before and click Run. You can also bind this query to a Button Widget to trigger it. +* Return to the Workflow Editor, go to Run History, and verify if the workflow execution was triggered successfully. + +
+ +2. Creating an Approval Workflow + +
+ +* Create a new workflow and name it **My Approval Workflow** +* In the workflow editor, assign an approval request inside the function using the below snippet of code: + ```jsx + let response = await appsmith.workflows.assignRequest({ + requestName: "Approval Process", + message: "Testing Approval Process", + requestToUsers: "", + requestToGroups: "", + metadata: data, + resolutions: ["Approve", "Reject"] + }) + ``` +* This creates an approval request with the specified resolutions and assigns it to the respective users or groups. +* The data argument is passed as metadata to the approval request. +* Next, handle the resolution when a user approves or rejects the request: + ```jsx + if ( response.resolution === "Approve" ) { + console.log("The request was approved"); + } else if ( response.resolution === "Reject" ) { + console.log("The request was rejected"); + } + ``` +* Click Deploy, and proceed to set up the application for this workflow. + +
+ +3. Creating an Approval Request from the App + +
+ +* Create a new Application and add a JSONForm Widget. +* Click on JS next to the Source Data and insert a JSON object with attributes: + ```firstName, lastName, address, email and department``` +* Navigate to the Query Tab, add a **Workflow Query** named ```submitRequest```, and select the workflow created earlier. +* Set the Request Type to **Trigger Request** +* Inside the Metadata field, pass the entire form data: + ```{{JSONForm1.formData}}``` +* In the JSONForm settings, set the **onSubmit** event to run this query. +* Fill out the form and click Submit to initiate a workflow request. +* To verify, go back to the **Workflow Editor -> Run History** to see the latest request in a pending state. + +
+ +4. Resolving the Request from the App + +
+ +* Go back to the Application and create a new Page. +* Add a new Workflow Query named ```getPendingRequests```, select the Workflow, and use Request Type: **Get Requests** +* Run the query to retrieve the pending approval requests +* Click **Display on UI** and bind the data to a Table Widget. +* The table will display request details like name, message, created time, and metadata containing the form details. +* Add a Custom Column, name it Action, and set the Column Type to Button. +* Configure the **onClick** event of this column to **Show Modal**, then click **+ New Modal**. +* Inside the modal: + - Add an Input Field with the label and name Comment. + - Add two buttons named Approve and Reject. +* Next, create a Workflow Query named ```resolveRequest``` and set the following fields as below: + - Request Type: Resolve Request + - Request Id: ```{{Table1.triggeredRow.id}}``` + - Resolution: ```{{this.params.resolution}}``` + - Metadata (for comments): ```{{Comment.text}}``` +* Bind this query to both Approve and Reject buttons, ensuring the Params field sends: + - For Approve button: ```{ resolution: "Approve" }``` + - For Reject button: ```{ resolution: "Reject" }``` +* Set onSuccess of this query to run **getPendingRequests** and onFailure to show an alert message. +* Now, go to the UI, click the **Action** button to open the **Modal**, enter a comment, and click Approve or Reject. +* Return to the **Workflow Editor -> Run History**, and verify that the workflow is completed with the selected resolution and console message. + +
\ No newline at end of file diff --git a/website/docs/training/session-6.md b/website/docs/training/session-6.md new file mode 100644 index 0000000000..554947108c --- /dev/null +++ b/website/docs/training/session-6.md @@ -0,0 +1,93 @@ +--- +title: Session 6 +hide_title: false +--- + + + +## Getting Started + +**Ignore this if you were able to attend the previous Session.** + +1. Sign up on this instance: [Training Instance](https://training.app.appsmith.com/user/signup) + +2. Create a workspace of your own and name it as **\-Training-Workspace** + +3. Share access to your workspace to **Training Admin** as Administrator + +4. From the workspace, click on the top-right **info icon**, then select **Chat with us**. This is Appsmith’s support assistant that can help you with any issues. Send a test message to familiarize yourself with the support feature. + +## Implementing Granular Access Control and Programmatic Permissions + +1. **Role-Based Access Control** + +
+ +* Every workspace comes with three default roles: **Administrator, Developer, and App Viewer**. +* Custom **Groups** and **Roles** can also be created to define access more precisely. +* Here is an example of how to set Custom Groups and Roles: + - Navigate to **Admin Settings → Groups** under **Access Control**. + - Click **Create Group**, name it **Agents**, and assign users to this group. + - Switch to the **Roles** tab and create a new role named **Agent Role**. + - Configure the role by assigning specific permissions. +* Here are the main permissions you can assign to a Role + - **Workspace Access** – Define who can access or modify workspace settings. + - **App Access** – Control view and edit rights for applications. + - **Page Access** – Restrict or grant access to specific pages within an app. + - **JSObjects & Queries** – Allow or deny execution/edit permissions on queries and JavaScript objects. + - **Datasource & Workflow Access** – Set permissions on which datasources and workflows users can interact with. +* Below are some of the additional permission you can assign as well + - Who can **create workspaces**. + - Who can **invite users** to a workspace or application. + - Who can **create Groups and Roles**. + - Who can **view Audit Logs** for tracking user activity. +* Finally after saving the changes made to your new Role, go back to the Group and assign this Role. +* You can assign the Role either to a Group of users or at a user level as well + +
+ +2. **Programmatic Permissions** + +
+ +* Ensure that **Programmatic Access Control** is enabled in **Admin Settings**. +* Once enabled, you can dynamically manage user access within your application using logic based on user groups. +* **Examples of Programmatic Access:** + - **Show or hide UI elements** based on user groups: + ```appsmith.user.groups.includes("")``` + *(User this to control visibility of tables, forms, buttons, etc dynamically)* + - **Conditionally execute actions** based on user roles: + ```jsx + if (appsmith.user.groups.includes("Agents")) { + submitData.run(); + } else { + showAlert("You do not have permission to perform this action."); + } + ``` + +
+ +## Utilizing Audit Logs for Monitoring and Compliance + +1. **Viewing Audit Logs** + +
+ +* Navigate to **Admin Settings → Audit Logs**. + *(Ensure you have the necessary permissions granted by your instance administrator.)* +* Here you can view: + - **User Activity:** Logins, sign-ups, and invitations. + - **Application Modifications:** Changes in queries, deployments, and settings. + - **Access Logs:** Identify who viewed, edited, modified the application or triggered some actions. + +
+ +2. **Filtering and Analyzing Logs** +
+ +* Use filters such as **Events**, **Users**, or **Date Range** to refine log records. +* Example: + - Find logs where a specific query was executed by multiple users within a selected time period. +* Click the **three-dot menu** (top-right) to **⬇ Download** the audit logs for further analysis or compliance review. + +
\ No newline at end of file diff --git a/website/docs/training/session-8.md b/website/docs/training/session-8.md new file mode 100644 index 0000000000..c2586243fa --- /dev/null +++ b/website/docs/training/session-8.md @@ -0,0 +1,176 @@ +--- +title: Session 8 +hide_title: false +--- + + + +## Debugging with Consoles & Browser Tools + +1. **Appsmith In-App Console (Editor Console)** + +
+ +* The **Appsmith Console** inside the editor is the first stop when debugging an app: + - Open the Appsmith editor → bottom panel → **Console** tab. +* **What it shows:** + - Logs generated by `showAlert()` or `console.log()` calls inside queries and JS objects. + - API & DB query responses (success, failure, latency). + - Evaluation errors for bindings (e.g., "Cannot read property of undefined"). +* **How to use it effectively:** + - Reproduce the issue and watch for red errors in real time. + - Use the **filter** controls to narrow logs by severity. + - Expand query responses to inspect returned JSON. +* **Best practice:** Always check the Appsmith Console first — it often surfaces the error without needing browser DevTools. + +
+ +2. **Browser Developer Tools — When to Go Deeper** + +
+ +* If the Appsmith Console doesn't provide enough detail, move to **browser DevTools**. +* **Steps to gather HAR & Console logs:** + - Navigate to the app and stop just before reproducing the issue. + - Open Chrome Developer Tools: Right-click → **Inspect** or **Ctrl+Shift+I** (Win/Linux) / **Cmd+Opt+I** (Mac). + - **Network Tab:** Check **"Preserve log"** at the top, reproduce the issue, export the HAR file (⬇ icon). + - **Console Tab:** Right-click → **Save as…** to export console logs. +* **Network Tab Deep Dive:** + - Focus on **XHR / Fetch** requests and filter for **`execute`** to isolate API calls made by the app. + - Inspect: request URL, status codes, response body, headers, timings. + - **Note:** Request body inspection is only available in **Edit mode**, not in **View mode**. +* **Console Tab Deep Dive:** + - Look for red errors (critical) and yellow warnings. + - Expand logs for context and use search to filter logs. + +
+ +3. **Application Tab — Local Storage** + +
+ +* Inspect **Local Storage** for persisted state (`appsmith.store`) and **Session Storage** for transient state. +* **Identify which app data belongs to:** + - Grab the `applicationId`: Open the app → **Network** pane from debugger tools → Refresh page → Search for **`applicationId`** → Copy ID from payload. + - Filter Local Storage keys with that `applicationId`. +* Useful when debugging why certain stored values aren't loading or persisting correctly. + +
+ +## Accessing Server-Side Logs & Instance Health + +1. **Quick Instance Checks** + +
+ +* Before diving into container logs, use Appsmith's built-in endpoints: + - **`/info`** — Shows the **Appsmith version** the instance is running. Helps confirm if the issue could be version-specific. + - **`/api/v1/health`** — Monitor the availability and status of a self-hosted Appsmith instance. Helps detect downtime early and ensures the system is running as expected. + - **`/api/v1/consolidated-api/view`** — Provides insights into API response times, user session details, feature flag statuses, and system configuration. +* These endpoints are especially helpful when debugging **customer environments** before escalating to support. + +
+ +2. **Getting Container Logs** + +
+ +* Follow the documentation: [Get Container Logs](https://docs.appsmith.com/getting-started/setup/instance-management/how-to-get-container-logs) +* **What to Look For in Logs:** + - **Timestamp alignment:** correlate logs with when the issue occurred. + - **Error-related keywords:** e.g., `Exception`, `Timeout`, `Connection refused`, Out‑of‑memory, or container restarts. + - **Service context:** Identify which log (backend, editor, rts, etc.) is relevant to the failure. + +
+ +## Checking for Existing Issues + +1. **GitHub Issues Search Strategy** + +
+ +* Before spending time reproducing or escalating an issue, check the **Appsmith GitHub Issues** page: + - Go to: [https://github.com/appsmithorg/appsmith/issues](https://github.com/appsmithorg/appsmith/issues) +* **Use the Search bar to look for:** + - Error messages from your logs + - Feature name (e.g., "PostgreSQL plugin") + - Keywords related to the problem (e.g., "timeout", "deploy", "login") +* **Filter by:** + - **Open** issues (current bugs) + - **Closed** issues (to see if it was recently fixed) + - **Label** for categorization +* **Review the discussion for:** + - Workarounds + - Status updates + - Links to fixes in upcoming releases + +
+ +## Connecting with Appsmith Support + +1. **Support Channels and Best Practices** + +
+ +* When users need help with Appsmith, prompt access to support is crucial. +* Follow the documentation: [Appsmith Support](https://docs.appsmith.com/product/support) +* **Information to include for effective support requests:** + - Clear description of the issue and steps to reproduce + - Appsmith version and deployment type + - Browser console logs and HAR files (when applicable) + - Server-side logs (for self-hosted instances) + - Screenshots or screen recordings demonstrating the issue + +
+ +## Using Audit Logs for Debugging + +1. **Accessing and Filtering Audit Logs** + +
+ +* Navigate to **Settings → Audit Logs** + *(Note: While typically accessed by Admins, **users/developers can also be granted audit log access only** without needing full admin rights.)* +* **Key Filters for Debugging:** + - **Event Type** = API Call + - **User ID** = End user affected + - **Time Range** = When issue happened + - **Resource ID** = The specific API/Query ID (found in the **URL** when the query/API page is open in **Edit mode**) + +
+ +2. **Analyzing Audit Logs for Issues** + +
+ +* **Look for:** + - Failed calls + - High latency + - Unauthorized attempts +* **Documentation:** [Audit Logs Guide](https://docs.appsmith.com/advanced-concepts/audit-logs) +* Use audit logs in combination with other debugging techniques for comprehensive troubleshooting. + +
+ +## Debugging Flow Recommendation + +1. **Systematic Debugging Approach** + +
+ +* **Step 1: Start with Appsmith Console (in-App Editor)** + - Quickest method with app-context logs +* **Step 2: If unresolved → Browser DevTools Console** + - For runtime JS errors outside Appsmith logs +* **Step 3: If API/data issues → Browser Network tab** + - For request/response details, HAR export +* **Step 4: If state issues → Application tab** + - Inspect local storage for `appsmith.store` entries +* **Step 5: Check GitHub Issues** + - Search for known issues before escalating +* **Step 6: Gather server logs if needed** + - Use health endpoints and container logs +* **Step 7: Use Audit Logs for user activity** + - When debugging user-specific or permission-related issues + +
diff --git a/website/sidebars.js b/website/sidebars.js old mode 100644 new mode 100755 index a1e1ebf77c..0effb15644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -1,802 +1,45 @@ - const sidebars = { tutorialSidebar: [ + //training start { - //getting started section start - type: 'category', + type: "category", + label: "Appsmith Training Day 1", collapsed: false, - label: 'Get Started', items: [ - 'intro', - { - type: 'category', - label: 'Tutorial', - link: { type: 'doc', id: 'getting-started/tutorials/start-building' }, - items: [ - 'getting-started/tutorials/the-basics/connect-query-display-data', - 'getting-started/tutorials/the-basics/work-with-data-in-ui', - 'getting-started/tutorials/the-basics/write-js-code', - ], - }, - - { - type: 'category', - label: 'Self Hosting', - link: { type: 'doc', id: 'getting-started/setup/README' }, - items: [ - { - type: 'category', - label: 'Install Appsmith', - link: { - type: 'doc', - id: 'getting-started/setup/installation-guides/README', - }, - items: [ - { - type: 'category', - label: 'Docker', - link: { - type: 'doc', - id: 'getting-started/setup/installation-guides/docker/README', - }, - items: [ - 'getting-started/setup/installation-guides/docker/migrate', - ], - }, - { - type: 'category', - label: 'Kubernetes', - link: { - type: 'doc', - id: 'getting-started/setup/installation-guides/kubernetes/README', - }, - items: [ - 'getting-started/setup/installation-guides/kubernetes/configure-high-availability', - 'getting-started/setup/installation-guides/kubernetes/publish-appsmith-online', - 'getting-started/setup/installation-guides/kubernetes/migrate-to-be-chart', - 'getting-started/setup/installation-guides/kubernetes/migrate-to-helm-chart-v2-ce', - 'getting-started/setup/installation-guides/kubernetes/migrate-k8s', - ], - }, - 'getting-started/setup/installation-guides/aws-ami', - { - type: 'category', - label: 'AWS ECS', - link: { - type: 'doc', - id: 'getting-started/setup/installation-guides/aws-ecs/README', - }, - items: [ - 'getting-started/setup/installation-guides/aws-ecs/aws-ecs-on-ec2', - 'getting-started/setup/installation-guides/aws-ecs-on-fargate', - 'getting-started/setup/installation-guides/aws-ecs/setup-postgresql-aws-ecs', - 'getting-started/setup/installation-guides/aws-ecs/set-up-high-availability', - 'getting-started/setup/installation-guides/aws-ecs/migrate-bind-mount-to-efs', - ], - }, - 'getting-started/setup/installation-guides/azure-aci', - { - type: 'category', - label: 'Google Cloud Run', - link: { - type: 'doc', - id: 'getting-started/setup/installation-guides/google-cloud-run', - }, - items: [ - 'getting-started/setup/installation-guides/google-cloud-run/manage-traffic', - 'getting-started/setup/installation-guides/google-cloud-run/setup-to-integrate-sso', - ], - }, - 'getting-started/setup/installation-guides/digitalocean', - 'getting-started/setup/installation-guides/heroku', - 'getting-started/setup/installation-guides/ansible', - 'getting-started/setup/installation-guides/air-gapped', - ], - }, - { - type: 'category', - label: 'Configure Instance', - link: { - type: 'doc', - id: 'getting-started/setup/instance-configuration/README', - }, - items: [ - { - type: 'category', - label: 'Authentication', - link: { - type: 'doc', - id: 'getting-started/setup/instance-configuration/authentication/README', - }, - items: [ - 'getting-started/setup/instance-configuration/authentication/google-login', - 'getting-started/setup/instance-configuration/authentication/github-login', - { - type: 'category', - label: 'SAML SSO', - link: { - type: 'doc', - id: 'getting-started/setup/instance-configuration/authentication/security-assertion-markup-language-saml/README', - }, - items: [ - 'getting-started/setup/instance-configuration/authentication/security-assertion-markup-language-saml/active-directory', - 'getting-started/setup/instance-configuration/authentication/security-assertion-markup-language-saml/auth0', - 'getting-started/setup/instance-configuration/authentication/security-assertion-markup-language-saml/okta', - 'getting-started/setup/instance-configuration/authentication/security-assertion-markup-language-saml/ping-identity', - ], - }, - { - type: 'category', - label: 'OpenID Connect SSO', - link: { - type: 'doc', - id: 'getting-started/setup/instance-configuration/authentication/openid-connect-oidc/README', - }, - items: [ - 'getting-started/setup/instance-configuration/authentication/openid-connect-oidc/active-directory', - 'getting-started/setup/instance-configuration/authentication/openid-connect-oidc/aws-cognito', - 'getting-started/setup/instance-configuration/authentication/openid-connect-oidc/auth0', - 'getting-started/setup/instance-configuration/authentication/openid-connect-oidc/okta', - 'getting-started/setup/instance-configuration/authentication/openid-connect-oidc/ping-identity', - ], - }, - 'getting-started/setup/instance-configuration/authentication/json-web-tokens-jwt', - ], - }, - { - type: 'category', - label: 'Email', - link: { - type: 'doc', - id: 'getting-started/setup/instance-configuration/email/README', - }, - items: [ - 'getting-started/setup/instance-configuration/email/gmail', - 'getting-started/setup/instance-configuration/email/amazon-ses', - 'getting-started/setup/instance-configuration/email/sendgrid', - ], - }, - 'getting-started/setup/instance-configuration/custom-mongodb-redis', - 'getting-started/setup/instance-configuration/disable-intercom', - 'getting-started/setup/instance-configuration/google-maps', - 'getting-started/setup/instance-configuration/disable-user-signup', - { - type: 'category', - label: 'Custom Domain and SSL', - link: { - type: 'doc', - id: 'getting-started/setup/instance-configuration/custom-domain/README', - }, - items: [ - 'getting-started/setup/instance-configuration/custom-domain/configure-tls', - 'getting-started/setup/instance-configuration/custom-domain/custom-ca-root-certificate', - ], - }, - 'getting-started/setup/instance-configuration/http-proxy', - 'getting-started/setup/instance-configuration/frame-ancestors', - 'getting-started/setup/environment-variables', - ], - }, - { - type: 'category', - label: 'Manage Instance', - link: { - type: 'doc', - id: 'getting-started/setup/instance-management/README', - }, - items: [ - { - type: 'category', - label: 'Update Appsmith', - link: { - type: 'doc', - id: 'getting-started/setup/instance-management/update-appsmith', - }, - items: [ - 'getting-started/setup/instance-management/upgrade-to-checkpoint-version' - ] - }, - 'getting-started/setup/instance-management/maintenance-window', - 'getting-started/setup/instance-management/appsmithctl', - 'getting-started/setup/instance-management/supervisor', - 'getting-started/setup/instance-management/how-to-get-container-logs', - ], - }, - { - type: 'category', - label: 'Manage Editions', - link: { - type: 'doc', - id: 'getting-started/setup/manage-editions/README', - }, - items: [ - 'getting-started/setup/manage-plans/upgrade-plan', - 'getting-started/setup/manage-plans/downgrade-plan', - { - type: 'category', - label: 'Upgrade from Community Edition', - link: { - type: 'doc', - id: 'getting-started/setup/upgrade-from-community-edition/README', - - }, - items: [ - 'getting-started/setup/upgrade-from-community-edition/docker', - 'getting-started/setup/upgrade-from-community-edition/kubernetes', - ] - }, - ], - }, - `getting-started/setup/best-practices`, - 'getting-started/setup/deployment-architecture', - ], - } + "training/day-1-agenda", + "training/session-1", + "training/session-2", ], - }, //getting started section end - { - //Data start - type: 'category', - collapsed: false, - label: 'Connect Data', - items: [ - 'connect-data/overview', - { - type: 'category', - collapsed: true, - label: 'How-to Guides', - link: { type: 'doc', id: 'connect-data/how-to-guides/README' }, - items: [ - 'connect-data/how-to-guides/how-to-work-with-local-apis-on-appsmith', - 'connect-data/how-to-guides/setup-datasource-environments', - 'connect-data/how-to-guides/how-to-pass-params-to-an-api', - 'connect-data/how-to-guides/fetch-and-filter-data-in-sql', - 'connect-data/how-to-guides/insert-and-update-data-in-sql', - 'connect-data/how-to-guides/filter-data-google-sheet', - 'connect-data/how-to-guides/insert-and-update-data-in-google-sheets', - 'connect-data/integrations', - ] - }, - { - //Reference start - type: 'category', - collapsed: false, - label: 'Reference', - link: { type: 'doc', id: 'connect-data/reference/overview' }, - items: [ - { - type: 'category', - collapsed: true, - label: 'Datasources', - link: { type: 'doc', id: 'connect-data/reference/README' }, - items: [ - //category- Api - { - type: 'category', - label: 'APIs', - items: [ - 'connect-data/reference/authenticated-api', - 'connect-data/reference/curl-import', - 'connect-data/reference/graphql', - 'connect-data/reference/rest-api' - ], - }, - //category- Databases - { - type: 'category', - label: 'Databases', - items: [ - 'connect-data/reference/querying-arango-db', - 'connect-data/reference/databricks', - 'connect-data/reference/querying-dynamodb', - 'connect-data/reference/querying-elasticsearch', - 'connect-data/reference/querying-firestore', - { - type: 'category', - label: 'MongoDB', - link: { - type: 'doc', - id: 'connect-data/reference/querying-mongodb/README', - }, - items: [ - 'connect-data/reference/querying-mongodb/mongo-syntax' - ], - }, - 'connect-data/reference/querying-mssql', - 'connect-data/reference/querying-mysql', - 'connect-data/reference/querying-oracle', - 'connect-data/reference/querying-postgres', - 'connect-data/reference/querying-redis', - 'connect-data/reference/querying-redshift', - 'connect-data/reference/querying-amazon-s3', - 'connect-data/reference/querying-snowflake-db', - 'connect-data/reference/using-smtp' - ], - }, - //category- SaaS Integrations - { - type: 'category', - label: 'SaaS Integrations', - items: [ - 'connect-data/reference/airtable', - 'connect-data/reference/aws-lambda', - 'connect-data/reference/querying-google-sheets', - 'connect-data/reference/hubspot', - 'connect-data/reference/twilio' - ], - }, - //category- AI Integrations - { - type: 'category', - label: 'AI Integrations', - items: [ - 'connect-data/reference/anthropic', - 'connect-data/reference/appsmith-ai', - 'connect-data/reference/google-ai', - 'connect-data/reference/open-ai' - ], - }, - ], - }, - 'connect-data/reference/query-settings', - ], - }, //Reference End - { - type: 'category', - collapsed: true, - label: 'Concepts', - link: { type: 'doc', id: 'connect-data/concepts/README' }, - items: [ - 'connect-data/concepts/dynamic-queries', - 'connect-data/concepts/dynamic-binding-in-queries', - 'connect-data/concepts/connection-pooling', - 'connect-data/concepts/Datasource-Environments', - ] - }, - ] - }, //Data end - - // Build App Start - - { // UI start - type: 'category', - collapsed: false, - label: 'Build Apps', - items: [ - 'build-apps/overview', - { - type: 'category', - collapsed: true, - label: 'How-to Guides', - link: { type: 'doc', id: 'build-apps/how-to-guides/README' }, - items: [ - //'core-concepts/building-ui/dynamic-ui/README', - { - type: 'category', - label: 'Display and Filter Data in Table', - items: [ - `build-apps/how-to-guides/display-search-and-filter-table-data`, - 'build-apps/how-to-guides/create-drill-down-view', - 'build-apps/how-to-guides/Server-side-pagination-in-table', - 'build-apps/how-to-guides/search-and-filter-table-data' - ], - }, - { - type: 'category', - label: 'Display and Filter Data in List', - items: [ - 'build-apps/how-to-guides/display-search-and-filter-list-data', - 'build-apps/how-to-guides/Setup-Server-side-Pagination-on-List' - ], - }, - { - type: 'category', - label: 'Insert Data', - link: { type: 'doc', id: 'build-apps/how-to-guides/insert-data' }, - items: [ - 'build-apps/how-to-guides/Upload-CSV-Data-to-Table', - ], - }, - { - type: 'category', - label: 'Update or Delete Data', - link: { type: 'doc', id: 'build-apps/how-to-guides/submit-form-data' }, - items: [ - 'reference/widgets/table/inline-editing', - 'build-apps/how-to-guides/update-list-data' - ], - }, - { - type: 'category', - label: 'Plot Charts', - items: [ - `build-apps/how-to-guides/Display-and-filter-chart-data`, - `build-apps/how-to-guides/create-custom-charts` - ], - }, - { - type: 'category', - label: 'Upload Files', - items: [ - 'build-apps/how-to-guides/Send-Filepicker-Data-with-API-Requests', - 'connect-data/how-to-guides/how-to-upload-to-s3' - - ], - }, - { - type: 'category', - label: 'Create Custom Widgets', - link: { type: 'doc', id: 'build-apps/how-to-guides/Create-Custom-Widgets-Using-Iframe' }, - items: [ - 'build-apps/how-to-guides/custom-widget-using-vanillajs' - ], - }, - 'connect-data/how-to-guides/how-to-download-files-using-api', - `core-concepts/writing-code/workflows`, - 'connect-data/how-to-guides/send-emails-using-the-SMTP-plugin', - `build-apps/how-to-guides/display-select-options-dynamically`, - 'build-apps/how-to-guides/add-remove-inputs-in-list', - `build-apps/how-to-guides/navigate-between-pages`, - `build-apps/how-to-guides/create-custom-nav-bar`, - 'build-apps/how-to-guides/Communicate-Between-an-App-and-Iframe', - 'advanced-concepts/custom-authentication', - 'build-apps/how-to-guides/display-map-markers', - `build-apps/how-to-guides/set-up-websockets`, - `build-apps/how-to-guides/setup-polling`, - `build-apps/how-to-guides/browse-and-display-documents`, - 'build-apps/how-to-guides/Multi-step-Form-or-Wizard-Using-Tabs' - ] - }, - { - //Reference start - type: 'category', - label: 'Reference', - collapsed: false, - link: { type: 'doc', id: 'build-apps/reference/README' }, - items: [ - { - type: 'category', - label: 'Widgets', - link: { type: 'doc', id: 'reference/widgets/README' }, - items: [ - 'reference/widgets/audio', - 'reference/widgets/audio-recorder', - { - type: 'category', - label: 'Button', - link: { type: 'doc', id: 'reference/widgets/button/README' }, - items: ['reference/widgets/button/google-recaptcha'], - }, - { - type: 'category', - label: 'Button Group', - link: { type: 'doc', id: 'reference/widgets/button-group/README' }, - items: [ - 'reference/widgets/button-group/buttons' - ], - }, - 'reference/widgets/camera', - 'reference/widgets/category-slider', - 'reference/widgets/chart', - 'reference/widgets/checkbox', - 'reference/widgets/checkbox-group', - 'reference/widgets/code-scanner', - 'reference/widgets/container', - 'reference/widgets/currency-input', - 'reference/widgets/custom', - 'reference/widgets/datepicker', - 'reference/widgets/divider', - 'reference/widgets/document-viewer', - 'reference/widgets/form', - 'reference/widgets/filepicker', - 'reference/widgets/icon-button', - 'reference/widgets/iframe', - 'reference/widgets/image', - 'reference/widgets/input', - 'reference/widgets/json-form', - 'reference/widgets/list', - 'reference/widgets/maps', - 'reference/widgets/map-chart', - { - type: 'category', - label: 'Menu Button', - link: { type: 'doc', id: 'reference/widgets/menu/README' }, - items: [ - 'reference/widgets/menu/menu-items' - ], - }, - 'reference/widgets/modal', - 'reference/widgets/multiselect', - 'reference/widgets/multi-tree-select', - 'reference/widgets/number-slider', - 'reference/widgets/phone-input', - 'reference/widgets/progress', - 'reference/widgets/radio-group', - 'reference/widgets/range-slider', - 'reference/widgets/rating', - 'reference/widgets/rich-text-editor', - 'reference/widgets/select', - 'reference/widgets/stat-box', - 'reference/widgets/switch', - 'reference/widgets/switch-group', - 'reference/widgets/tabs', - { - type: 'category', - label: 'Table', - link: { type: 'doc', id: 'reference/widgets/table/README' }, - items: [ - 'reference/widgets/table/column-settings' - ], - }, - 'reference/widgets/text', - 'reference/widgets/tree-select', - 'reference/widgets/video', - ], - }, - - 'core-concepts/building-ui/designing-an-application/app-theming', - 'learning-and-resources/sample-apps' - ], - }, //Reference End - ] - }, //Build Apps end - - { // WRITE CODE start - type: 'category', - collapsed: false, - label: 'Write Code', - items: [ - 'write-code/overview', - { - type: 'category', - collapsed: true, - label: 'How-to Guides', - link: { type: 'doc', id: 'write-code/how-to-guides/README' }, - items: [ - 'core-concepts/writing-code/javascript-promises', - 'advanced-concepts/sharing-data-across-pages', - 'core-concepts/writing-code/ext-libraries' - ] - }, - { - //Reference start - type: 'category', - collapsed: false, - label: 'Reference', - link: { type: 'doc', id: 'write-code/reference/overview' }, - items: [{ - type: 'category', - collapsed: true, - label: 'Global Objects', - link: { type: 'doc', id: 'write-code/reference/README' }, - items: [ - 'reference/appsmith-framework/query-object', - 'reference/appsmith-framework/context-object', - 'reference/appsmith-framework/console-object', - ], - }, - { - type: 'category', - label: 'Global Functions', - link: { - type: 'doc', - id: 'reference/appsmith-framework/widget-actions/README', - }, - items: [ - 'reference/appsmith-framework/widget-actions/navigate-to', - 'reference/appsmith-framework/widget-actions/show-alert', - 'reference/appsmith-framework/widget-actions/show-modal', - 'reference/appsmith-framework/widget-actions/close-modal', - 'reference/appsmith-framework/widget-actions/store-value', - 'reference/appsmith-framework/widget-actions/remove-value', - 'reference/appsmith-framework/widget-actions/clear-store', - 'reference/appsmith-framework/widget-actions/download', - 'reference/appsmith-framework/widget-actions/copy-to-clipboard', - 'reference/appsmith-framework/widget-actions/reset-widget', - 'reference/appsmith-framework/widget-actions/intervals-time-events', - 'reference/appsmith-framework/widget-actions/clear-interval', - 'reference/appsmith-framework/widget-actions/set-timeout', - 'reference/appsmith-framework/widget-actions/post-message', - 'reference/appsmith-framework/widget-actions/window-message-listener', - 'reference/appsmith-framework/widget-actions/unlisten-window-message' - ] - }, - 'write-code/reference/Built-in-JS-Libraries', - 'write-code/reference/Fetch-API' - ], - }, //Reference End - { - type: 'category', - collapsed: true, - label: 'Concepts', - link: { - type: 'doc', - id: 'write-code/concepts/overview', - }, - items: [ - 'core-concepts/writing-code/javascript-editor-beta/README', - 'write-code/concepts/execute-onpageload', - ], - }, - `write-code/best-practices`, - ] - }, //CODE end - //module start - { - type: 'category', - collapsed: false, - label: 'Packages (Beta)', - items: [ - 'packages/overview', - - { - type: 'category', - label: 'Tutorial', - items: [ - 'packages/tutorial/query-module', - 'packages/tutorial/js-module' - ], - }, - ] - }, //module end - //Workflows start - { - type: 'category', - collapsed: false, - label: 'Workflows (Beta)', - items: [ - 'workflows/README', - //category- Api - { - type: 'category', - label: 'Tutorial', - link: { - type: 'doc', - id: 'workflows/tutorials/create-workflow', - }, - items: [ - ], - }, - { - type: 'category', - label: 'How-to Guides', - link: { - type: 'doc', - id: 'workflows/how-to-guides/README', - }, - items: [ - 'workflows/how-to-guides/create-approval-workflow', - 'workflows/how-to-guides/trigger-workflow-from-appsmith-app', - 'workflows/how-to-guides/set-up-automatic-processing', - ], - }, - { - type: 'category', - collapsed: false, - label: 'Reference', - items: [ - 'workflows/reference/workflow-queries', - 'workflows/reference/workflow-functions' - ], - } - ] - - }, //Workflows end + }, { - //Advanced Concepts Start - type: 'category', + type: "category", + label: "Appsmith Training Day 2", collapsed: false, - label: 'Manage Apps and Users', items: [ - { - type: 'category', - label: 'Embed Appsmith', - link: { type: 'doc', id: 'advanced-concepts/embed-appsmith-into-existing-application', }, - items: [ - 'build-apps/how-to-guides/send-messages-between-your-app-and-appsmith', - ] - }, - 'advanced-concepts/invite-users', - { - type: 'category', - label: 'Granular Access Control', - link: { type: 'doc', id: 'advanced-concepts/granular-access-control/README', }, - items: [ - 'advanced-concepts/granular-access-control/roles', - ] - }, - `advanced-concepts/user-provisioning-group-sync`, - { - type: 'category', - label: 'Version Control with Git', - link: { - type: 'doc', - id: 'advanced-concepts/version-control-with-git/README', - }, - items: [ - { - type: 'category', - label: 'Connect to a Git Repository', - link: { - type: 'doc', - id: 'advanced-concepts/version-control-with-git/connecting-to-git-repository', - }, - items: ['advanced-concepts/version-control-with-git/updating-local-file-path',], - }, - 'advanced-concepts/version-control-with-git/working-with-branches', - 'advanced-concepts/version-control-with-git/commit-and-push', - 'advanced-concepts/version-control-with-git/merging-branches', - 'advanced-concepts/version-control-with-git/revert-changes', - 'advanced-concepts/version-control-with-git/import-from-repository', - 'advanced-concepts/version-control-with-git/environments-with-git', - ], - }, - - 'advanced-concepts/more/backup-restore', - 'advanced-concepts/audit-logs', - 'advanced-concepts/branding', + "training/day-2-agenda", + "training/session-3", + "training/session-4", ], - }, //Advanced Concepts end + }, { - // Help & Support start - type: 'category', + type: "category", + label: "Appsmith Training Day 3", collapsed: false, - label: 'Troubleshooting', items: [ - 'help-and-support/troubleshooting-guide/README', - { - // Help & Support start - type: 'category', - label: 'Self-hosting Errors', - link: { - type: 'doc', - id: 'help-and-support/troubleshooting-guide/deployment-errors', - }, - items: [ - "help-and-support/troubleshooting-guide/deployment-error-guides/mongodb-startup-error-postv5", - "help-and-support/troubleshooting-guide/deployment-error-guides/schema-mismatch-error", - "help-and-support/troubleshooting-guide/deployment-error-guides/k8s-helm3.0.4-upgrade-error", - "help-and-support/troubleshooting-guide/backup-restore-errors" - ], - }, - { - // Help & Support start - type: 'category', - label: 'Application Errors', - link: { - type: 'doc', - id: 'help-and-support/troubleshooting-guide/application-errors', - }, - items: [ - 'help-and-support/troubleshooting-guide/action-errors/datasource-errors', - 'help-and-support/troubleshooting-guide/action-errors/README' - ], - }, - // 'help-and-support/troubleshooting-guide/js-errors', - // 'help-and-support/troubleshooting-guide/query-errors', - // 'help-and-support/troubleshooting-guide/widget-errors', + "training/day-3-agenda", + "training/session-5", + "training/session-6", ], - }, // Help & Support end + }, { - // Product Start - type: 'category', + type: "category", + label: "Appsmith Training Day 5", collapsed: false, - label: 'Product', items: [ - 'getting-started/faq', - 'product/security', - 'product/telemetry', - { - type: 'link', - label: 'Release Notes', // The link label - href: 'https://github.com/appsmithorg/appsmith/releases', // The external URL - }, - { - type: 'link', - label: 'Contribute', // The link label - href: 'https://github.com/appsmithorg/appsmith/blob/release/CONTRIBUTING.md', // The external URL - }, + "training/day-5-agenda", + "training/session-8", ], - }, // Product End + }, //training end ], }; diff --git a/website/src/theme/DocItem/Footer/index.js b/website/src/theme/DocItem/Footer/index.js old mode 100644 new mode 100755 index 4d32797b8a..141b0520c4 --- a/website/src/theme/DocItem/Footer/index.js +++ b/website/src/theme/DocItem/Footer/index.js @@ -6,8 +6,6 @@ export default function FooterWrapper(props) { return ( <>
- -
); diff --git a/website/src/theme/SearchBar.js b/website/src/theme/SearchBar.js old mode 100644 new mode 100755 index 508e6b3b46..0ef3d57a28 --- a/website/src/theme/SearchBar.js +++ b/website/src/theme/SearchBar.js @@ -4,7 +4,7 @@ import CustomSearchBar from '../components/custom-search/CustomSearchBar'; export default function SearchBarWrapper(props) { return ( <> - + ); }