<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vihar Kurama</title>
    <description>The latest articles on DEV Community by Vihar Kurama (@vihar).</description>
    <link>https://dev.to/vihar</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F294632%2F52ee9e41-cc6f-4b52-aa2f-eb230b7d197b.png</url>
      <title>DEV Community: Vihar Kurama</title>
      <link>https://dev.to/vihar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vihar"/>
    <language>en</language>
    <item>
      <title>We built Plane ✈️ Open Source Project Management Tool (Next.js + Django)</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Fri, 05 May 2023 13:02:59 +0000</pubDate>
      <link>https://dev.to/vihar/we-built-plane-open-source-project-management-tool-nextjs-django-3hke</link>
      <guid>https://dev.to/vihar/we-built-plane-open-source-project-management-tool-nextjs-django-3hke</guid>
      <description>&lt;h2&gt;
  
  
  &lt;a href="https://github.com/makeplane/plane" rel="noopener noreferrer"&gt;Plane GitHub Repo&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Story behind Plane&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://plane.so/" rel="noopener noreferrer"&gt;Plane&lt;/a&gt; is an open-source project management tool designed to help teams from different domains including engineering, marketing, product, and design to collaborate and manage their projects more efficiently. It is an alternative to expensive and opinionated tools such as JIRA, Trello, OpenProject, etc. that often come with steep learning curves and may not be suitable for every team's unique needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk11bnqoh287zbzegzcf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuk11bnqoh287zbzegzcf.gif" alt="Plane Views"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Plane allows users to start with a basic task tracking tool and gradually adopt various project management frameworks like Agile, Waterfall, and many more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting-up Plane
&lt;/h2&gt;

&lt;p&gt;Setting up the Plane server is a breeze! You can easily do it by running a simple command using docker-compose from your terminal. Whether you prefer working on your local machine or cloud provider, Plane server is packaged as a Docker container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/makeplane/plane
&lt;span class="nb"&gt;cd &lt;/span&gt;plane
./setup.sh localhost
docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Plane is also on DockerHub and can be installed with single command, &lt;a href="https://docs.plane.so/self-hosting" rel="noopener noreferrer"&gt;read our docs&lt;/a&gt; to learn more.&lt;/p&gt;
&lt;h3&gt;
  
  
  Plane Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Issue Planning and Tracking&lt;/strong&gt;: Quickly create issues and add details using a powerful rich text editor that supports file uploads. Add sub-properties and references to issues for better organization and tracking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issue Attachments&lt;/strong&gt;: Collaborate effectively by attaching files to issues, making it easy for your team to find and share important project-related documents.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Layouts&lt;/strong&gt;: Customize your project view with your preferred layout - choose from List, Kanban, or Calendar to visualize your project in a way that makes sense to you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cycles&lt;/strong&gt;: Plan sprints with Cycles to keep your team on track and productive. Gain insights into your project's progress with burn-down charts and other useful features.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modules&lt;/strong&gt;: Break down your large projects into smaller, more manageable modules. Assign modules between teams to easily track and plan your project's progress.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Views&lt;/strong&gt;: Create custom filters to display only the issues that matter to you. Save and share your filters in just a few clicks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pages&lt;/strong&gt;: Plane pages function as an AI-powered notepad, allowing you to easily document issues, cycle plans, and module details, and then synchronize them with your issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commend Menu&lt;/strong&gt;: Enjoy a better user experience with the new Command/Control + K menu. Easily manage and navigate through your projects from one convenient location.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Sync&lt;/strong&gt;: Streamline your planning process by syncing your GitHub issues with Plane. Keep all your issues in one place for better tracking and collaboration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Demo: &lt;a href="https://app.plane.so/" rel="noopener noreferrer"&gt;Plane Cloud&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Love our project? Show us your support by leaving a star on GitHub.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/makeplane" rel="noopener noreferrer"&gt;
        makeplane
      &lt;/a&gt; / &lt;a href="https://github.com/makeplane/plane" rel="noopener noreferrer"&gt;
        plane
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🔥 🔥 🔥 Open Source JIRA, Linear, Monday, and Asana Alternative. Plane helps you track your issues, epics, and product roadmaps in the simplest way possible.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;
&lt;a href="https://plane.so" rel="nofollow noopener noreferrer"&gt;
  &lt;img src="https://camo.githubusercontent.com/82feb9c8f8212561ecebe55b26622afa2b11e9943c698d3a28789f0bed77b651/68747470733a2f2f706c616e652d6d61726b6574696e672e73332e61702d736f7574682d312e616d617a6f6e6177732e636f6d2f706c616e652d726561646d652f706c616e655f6c6f676f5f2e77656270" alt="Plane Logo" width="70"&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;&lt;b&gt;Plane&lt;/b&gt;&lt;/h3&gt;
&lt;/div&gt;

&lt;p&gt;&lt;b&gt;Open-source project management that unlocks customer value&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;
&lt;a href="https://discord.com/invite/A92xrEGCge" rel="nofollow noopener noreferrer"&gt;
&lt;img alt="Discord online members" src="https://camo.githubusercontent.com/d9f94df0c779a2bcaa6cac7565db1617384da6c40bf4b9121653159ba0d0f691/68747470733a2f2f696d672e736869656c64732e696f2f646973636f72642f313033313534373736343032303038343834363f636f6c6f723d353836354632266c6162656c3d446973636f7264267374796c653d666f722d7468652d6261646765"&gt;
&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/bedc4afbe63202c51dccb577c0baf78a14a74cdff8421a864047aa6b3c5b5b58/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f6d2f6d616b65706c616e652f706c616e653f7374796c653d666f722d7468652d6261646765"&gt;&lt;img alt="Commit activity per month" src="https://camo.githubusercontent.com/bedc4afbe63202c51dccb577c0baf78a14a74cdff8421a864047aa6b3c5b5b58/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f636f6d6d69742d61637469766974792f6d2f6d616b65706c616e652f706c616e653f7374796c653d666f722d7468652d6261646765"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
    &lt;a href="https://dub.sh/plane-website-readme" rel="nofollow noopener noreferrer"&gt;&lt;b&gt;Website&lt;/b&gt;&lt;/a&gt; •
    &lt;a href="https://git.new/releases" rel="nofollow noopener noreferrer"&gt;&lt;b&gt;Releases&lt;/b&gt;&lt;/a&gt; •
    &lt;a href="https://dub.sh/planepowershq" rel="nofollow noopener noreferrer"&gt;&lt;b&gt;Twitter&lt;/b&gt;&lt;/a&gt; •
    &lt;a href="https://dub.sh/planedocs" rel="nofollow noopener noreferrer"&gt;&lt;b&gt;Documentation&lt;/b&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
    &lt;a href="https://app.plane.so/#gh-light-mode-only" rel="nofollow noopener noreferrer"&gt;
      &lt;img src="https://camo.githubusercontent.com/059b36bc57199e55ca053e49c73470ba4ca969a3b2763ef15f64154dd73c09d8/68747470733a2f2f706c616e652d6d61726b6574696e672e73332e61702d736f7574682d312e616d617a6f6e6177732e636f6d2f706c616e652d726561646d652f706c616e655f73637265656e2e77656270" alt="Plane Screens" width="100%"&gt;
    &lt;/a&gt;
    &lt;a href="https://app.plane.so/#gh-dark-mode-only" rel="nofollow noopener noreferrer"&gt;
      &lt;img src="https://camo.githubusercontent.com/1dc804fd6e5e177361c694cb889baf1616fb9069b693d5a8cc0746485600c0ab/68747470733a2f2f706c616e652d6d61726b6574696e672e73332e61702d736f7574682d312e616d617a6f6e6177732e636f6d2f706c616e652d726561646d652f706c616e655f73637265656e735f6461726b5f6d6f64652e77656270" alt="Plane Screens" width="100%"&gt;
    &lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Meet &lt;a href="https://dub.sh/plane-website-readme" rel="nofollow noopener noreferrer"&gt;Plane&lt;/a&gt;, an open-source project management tool to track issues, run &lt;del&gt;sprints&lt;/del&gt; cycles, and manage product roadmaps without the chaos of managing the tool itself. 🧘‍♀️&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Plane is evolving every day. Your suggestions, ideas, and reported bugs help us immensely. Do not hesitate to join in the conversation on &lt;a href="https://discord.com/invite/A92xrEGCge" rel="nofollow noopener noreferrer"&gt;Discord&lt;/a&gt; or raise a GitHub issue. We read everything and respond to most.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;⚡ Installation&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;The easiest way to get started with Plane is by creating a &lt;a href="https://app.plane.so" rel="nofollow noopener noreferrer"&gt;Plane Cloud&lt;/a&gt; account.&lt;/p&gt;

&lt;p&gt;If you would like to self-host Plane, please see our &lt;a href="https://docs.plane.so/docker-compose" rel="nofollow noopener noreferrer"&gt;deployment guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Installation methods&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Docs link&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;a href="https://docs.plane.so/self-hosting/methods/docker-compose" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c9a85f6869aa992f1500dd9d4d4bdff7d405605292ca152587394c1f92552d4f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f636b65722d2532333064623765642e7376673f7374796c653d666f722d7468652d6261646765266c6f676f3d646f636b6572266c6f676f436f6c6f723d7768697465" alt="Docker"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;Kubernetes&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;&lt;a href="https://docs.plane.so/kubernetes" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/d6d8bad228e7b8393fc66fb6b2a8628b821c4e3ca736a9c765d4a97c6e0afc1d/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6b756265726e657465732d2532333332366365352e7376673f7374796c653d666f722d7468652d6261646765266c6f676f3d6b756265726e65746573266c6f676f436f6c6f723d7768697465" alt="Kubernetes"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Instance admins&lt;/code&gt; can configure instance settings with &lt;a href="https://docs.plane.so/instance-admin" rel="nofollow noopener noreferrer"&gt;God-mode&lt;/a&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Features&lt;/h2&gt;
&lt;/div&gt;


&lt;ul&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Issues&lt;/strong&gt;: Quickly create issues and add details using a powerful rich text editor that supports file uploads. Add sub-properties and references to problems for…&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/makeplane/plane" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>showdev</category>
      <category>productivity</category>
      <category>python</category>
      <category>javascript</category>
    </item>
    <item>
      <title>December Round-up: Docked Property Pane, Switch Group, Document Viewer Widgets, Admin Page Settings!</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Thu, 06 Jan 2022 14:39:23 +0000</pubDate>
      <link>https://dev.to/appsmith/december-round-up-docked-property-pane-switch-group-document-viewer-widgets-admin-page-settings-ah5</link>
      <guid>https://dev.to/appsmith/december-round-up-docked-property-pane-switch-group-document-viewer-widgets-admin-page-settings-ah5</guid>
      <description>&lt;p&gt;Happy New Year! I am back again with a quick roundup of all the things we did in the last month of 2021! We shipped many features, fixed bugs, and hosted some fun events with our community.&lt;/p&gt;

&lt;h2&gt;
  
  
  No More Floaties, We’ve Got a Docked Property Pane
&lt;/h2&gt;

&lt;p&gt;The Property Pane in Appsmith is a crucial part of the developer application building experience. It allows us to configure widgets’ data, actions, and events. Previously, this property pane would float around the application, next to the widget in use. We felt that this interface was rather cumbersome, especially when the number of widgets increased on the canvas. We re-invented the entire developer experience and came up with the new docked property pane. With this, users will have a clear view of what’s happening on the canvas while dropping widgets and will have complete control over customizing them on the docked property pane, which is fixed on the right side of the application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478383250%2FxS1ST-Q9d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478383250%2FxS1ST-Q9d.png" alt="CleanShot 2022-01-06 at 19.42.50@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  New SMTP Plugin to Easily Send Emails
&lt;/h2&gt;

&lt;p&gt;You asked for this, and we shipped it as soon as we could! 😎 Appsmith now has an in-built SMTP plugin to send emails from the applications without using third-party applications. The email service provider of choice can be selected from DropBox, Google, Outlook, etc. An email template can also be customized for the developers’ branding needs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478483359%2F-HTJdAd3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478483359%2F-HTJdAd3b.png" alt="CleanShot 2022-01-02 at 14.24.29@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The SMTP datasource expects the Email configuration to add the Host Address and Port and the authentication details. In the example above (refer to the screenshot), I used my Gmail credentials. After this, you can create different queries to send emails from the plugin based on your requirements and use cases! Cool right? Here’s a screenshot of how the query can be customized: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: To make all the data dynamic, you can use dynamic bindings &lt;code&gt;{{ }}&lt;/code&gt; anywhere across these fields. Thank me later :)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478545595%2F0h6QHWOZB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478545595%2F0h6QHWOZB.png" alt="CleanShot 2022-01-02 at 14.25.47@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  New Widgets on the Block: Document Viewer and Switch Group
&lt;/h2&gt;

&lt;p&gt;We are kicked about shipping widgets every month! It’s kind of like an unsaid rule to ship new widgets every month! Hah! In December, we added two new ones: a new document viewer widget and a switch group widget to our list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Document Viewer Widget&lt;/strong&gt;: The document viewer widget on Appsmith allows you to add PDFs inside the application. All you need to do is populate the URL of the document link property. These can be added from any datasource in which the incoming data points to a URL.&lt;/p&gt;

&lt;p&gt;The widget currently supports the following extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; .txt&lt;/li&gt;
&lt;li&gt;.pdf&lt;/li&gt;
&lt;li&gt;.ppt (not supported by base64)&lt;/li&gt;
&lt;li&gt;.pptx&lt;/li&gt;
&lt;li&gt;.docx&lt;/li&gt;
&lt;li&gt;.xlsx&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478624298%2F-pIGqcya9E.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478624298%2F-pIGqcya9E.gif" alt="CleanShot 2022-01-02 at 14.38.25.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Switch Group Widget&lt;/strong&gt;: The new switch group widget captures user inputs from a set of binary choices. These options can be populated from a data source like an API / Query by transforming the incoming data to an array of (label, value).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478652267%2F33nFHa4lD.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478652267%2F33nFHa4lD.gif" alt="CleanShot 2022-01-06 at 19.33.36.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  New JS APIs for Geo-Location
&lt;/h2&gt;

&lt;p&gt;If you’re working with maps and geo-location, we got some good news! With our new in-built geolocation APIs, you can request current user locations, and associated information This API is stored as an object containing functions to request the current user location and the coordination received from the Mozilla &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API" rel="noopener noreferrer"&gt;Geo Location API&lt;/a&gt; request.&lt;/p&gt;

&lt;p&gt;To use this in action, you can simply run &lt;code&gt;{{appsmith.geolocation.getCurrentPosition()}}&lt;/code&gt; on a button click on any action call. As soon as the API is called, the location and the timestamp will be updated on the appsmith local store variable: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;{{appsmith.geolocation.currentPosition}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478696582%2FrUZctjUiv.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478696582%2FrUZctjUiv.gif" alt="CleanShot 2022-01-02 at 16.02.54.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Easy Self-hosting on AWS-AMI and DigitalOcean
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Upgrades to AWS AMI&lt;/strong&gt;: We refactored the first-time install script of AWS AMI deployment to fetch a new docker-compose.yml that uses a new Docker image. With this, self-hosting Appsmith with AWS-AMI is faster and smoother than ever.&lt;/p&gt;

&lt;p&gt;Read more about this in our documentation &lt;a href="https://docs.appsmith.com/setup/aws-ami#step-4-deploy-appsmith-on-aws-cloud" rel="noopener noreferrer"&gt;here&lt;/a&gt;, and also on the AWS AMI &lt;a href="https://aws.amazon.com/marketplace/pp/prodview-mclslaty46ah4" rel="noopener noreferrer"&gt;marketplace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Upgrades to DigitalOcean Droplet&lt;/strong&gt;: We published a brand new DigitalOcean machine image that is easier to maintain. This image supports the new build snapshot on DigitalOcean to use the fat container deployment. &lt;/p&gt;

&lt;p&gt;Find documentation &lt;a href="https://docs.appsmith.com/setup/digitalocean" rel="noopener noreferrer"&gt;here&lt;/a&gt;, and on Digitalocean marketplace &lt;a href="https://marketplace.digitalocean.com/apps/appsmith?refcode=469c9f1431e4" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  New Admin Settings Page to Manage Self-hosted Instances
&lt;/h2&gt;

&lt;p&gt;We also shipped a new admin settings page, where you can configure all the settings on self-hosted instances/local environments when running with Docker.&lt;/p&gt;

&lt;p&gt;You can access these by clicking on the profile icon and then selecting the Admin Settings. You’ll see the following options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;General: Configure appsmith instance name and primary email address.&lt;/li&gt;
&lt;li&gt;Authentication: Setting to provide Google, GitHub authentication or user-name, password (form-based) authentication on self-hosted instances.&lt;/li&gt;
&lt;li&gt;Email: SMTP configuration for ending emails from self-hosted instances&lt;/li&gt;
&lt;li&gt;Google Maps: Configuration to allow Google Maps&lt;/li&gt;
&lt;li&gt;Version: Know your appsmith version and latest features&lt;/li&gt;
&lt;li&gt;Advanced: Database and domain settings configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478802197%2F-DFMnKuPU.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1641478802197%2F-DFMnKuPU.gif" alt="CleanShot 2022-01-02 at 19.50.04.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've got a host of other bug fixes and updates too, be sure to check out our consolidated release notes &lt;a href="https://github.com/appsmithorg/appsmith/releases" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;See you next month with more updates! Do join us on &lt;a href="https://discord.com/invite/rBTTVJp" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, follow us on &lt;a href="https://twitter.com/theappsmith" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;, &lt;a href="https://www.youtube.com/appsmith" rel="noopener noreferrer"&gt;Youtube&lt;/a&gt;, and &lt;a href="https://in.linkedin.com/company/appsmith" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt; to stay up to date.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>ux</category>
      <category>database</category>
    </item>
    <item>
      <title>Write More Code &amp; Create Reusable Functions with Our New JavaScript Editor</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Tue, 07 Dec 2021 05:36:21 +0000</pubDate>
      <link>https://dev.to/appsmith/write-more-code-create-reusable-functions-with-our-new-javascript-editor-5adh</link>
      <guid>https://dev.to/appsmith/write-more-code-create-reusable-functions-with-our-new-javascript-editor-5adh</guid>
      <description>&lt;p&gt;What’s better than some space? More space. We’ve cleared out the clutter and developed a brand new full-fledged code editor to make the coding experience on Appsmith smooth like butter. Our &lt;a href="https://github.com/appsmithorg/appsmith" rel="noopener noreferrer"&gt;Github&lt;/a&gt; repository is home to many feature requests, and whenever we ship out a new feature, it’s cause for a mini celebration 🎉. &lt;/p&gt;

&lt;p&gt;JS editor is one such feature that was in the making for a while. &lt;strong&gt;This new feature enables users to write reusable JavaScript variables and functions as JS Objects&lt;/strong&gt;. These JS Objects can be used anywhere across the Appsmith platform using the moustache bindings. &lt;/p&gt;

&lt;p&gt;In this blog post, we will discuss our efforts to ship this much-needed feature and how you can get the most out of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Story
&lt;/h3&gt;

&lt;p&gt;Appsmith is one of the most loved open-source internal tool builders for developers. Today Appsmith sits with ~9000 stars on GitHub. We are proud of the love we receive from the community. One of the main reasons for Appsmith's success is the simplicity and customization it provides while building internal tools. We can use JavaScript anywhere on the platform to handle bindings, transformations, actions, workflows, and many more using the moustache syntax. However, all this had to be done in the small input boxes on Appsmith's property pane. This was somewhat cumbersome, especially when writing larger blocks of code. Here’s a screenshot to show you how things used to be: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638782775652%2FCCI2Xnr7T.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638782775652%2FCCI2Xnr7T.png" alt="CleanShot 2021-11-23 at 18.39.03@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s hard for any developer to write code on this small property pane, and code reusability was also not possible. However, the input editor on the property pane still served its purpose well, with its excellent auto-complete, slash commands, linting, and debugging features. However, we take developer experience seriously and constantly work towards improving it. &lt;/p&gt;

&lt;p&gt;%[&lt;a href="https://github.com/appsmithorg/appsmith/issues/1751" rel="noopener noreferrer"&gt;https://github.com/appsmithorg/appsmith/issues/1751&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Our primary goal was to create a full-fledged code editor to help developers write JavaScript with access to all the supported libraries without any distractions. To achieve this goal, we broke down this problem into three ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Introduce the concept of JS Objects files where developers can define variables and functions which they could write in a full-fledged editor &lt;/li&gt;
&lt;li&gt;JS Objects should be accessed anywhere across a page, using moustache binding.&lt;/li&gt;
&lt;li&gt;JS objects should use linting and autocomplete features developers expect from a full-fledged editor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We began the shipping process for the JS Editor around mid-July 2021. As strong proponents of building in public, we posted all the design previews, issues, ideas on our community channels and took community feedback into account while making this feature. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784344448%2FoIE7hqjfN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784344448%2FoIE7hqjfN.png" alt="CleanShot 2021-11-23 at 19.18.35@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784351196%2F2Asebw4d4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784351196%2F2Asebw4d4.png" alt="CleanShot 2021-11-23 at 19.17.59@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784360489%2FFpnHSXDN3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784360489%2FFpnHSXDN3.png" alt="CleanShot 2021-11-23 at 19.17.23@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784366674%2FCeRbgA_sg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784366674%2FCeRbgA_sg.png" alt="CleanShot 2021-11-23 at 19.16.56@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How did we build this?
&lt;/h3&gt;

&lt;p&gt;Appsmith has a highly modular code-base, so adding new widgets, integrations, and custom styles are easy. But, for a new feature like the JS editor, things needed to be stitched from scratch.  Our engineers and product folk brainstormed multiple times before getting started on it to ship a scalable solution around this.&lt;/p&gt;

&lt;p&gt;Here are a few thinking points that we started with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JS Objects are a completely new entity in Appsmith. We had to lay the foundations for this feature but did not want to derail away from already established concepts. We designed these objects as “Action Collections” where each function is a different Action (integration). This enabled us to quickly build on top of existing paradigms and allow features like &lt;code&gt;onPageLoad&lt;/code&gt;, dependency calculation, and reactive coding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Like other parts of Appsmith, these code blocks are reactive, which means they will automatically re-compute when their dependent data points have been updated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You could make mistakes, and the editor would be forgiving and guide the user to the right path.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While these are strictly objects today, we have laid the groundwork to enable more freestyle “JS files” where users can organize code however they want.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Along with this, we are also working to enable true async code in Appsmith. Async code with native promise support would help users create complex workflows easily, keeping the code readable and maintainable.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This would enable us to create a robust feature that everyone would love and give the same freedom as any standard coding framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  JS Editor and Objects in Action
&lt;/h3&gt;

&lt;p&gt;Appsmith's JS editor is quick and easy to use, and it lets you create objects with a single click. Just open the application, search for JS Objects from the entity explorer (left sidebar), and click on the + icon. We will be navigated to a new file, as shown in the screenshot here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784748140%2FDsnRzLzWo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638784748140%2FDsnRzLzWo.png" alt="CleanShot 2021-11-23 at 20.50.51@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, &lt;code&gt;myVar1&lt;/code&gt;, &lt;code&gt;myVar2&lt;/code&gt; are two variables, and &lt;code&gt;myFun1&lt;/code&gt;, &lt;code&gt;myFun2&lt;/code&gt; are two functions defined in the JS Object which are exposed in default export. Currently, we don’t support exposing functions using named exports. Now, let’s define a new random variable and try to access it onto a widget, for this, update the Code contents of JSObject1 to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;myRandomNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;randomInteger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;randomInteger&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To test this function, use the run icon from the appsmith console below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638788844368%2Fc648R0-eK.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638788844368%2Fc648R0-eK.gif" alt="CleanShot 2021-11-23 at 21.17.32.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And voila! Just like that, we should see our output; in case of errors, the console will return all the instructions options that will help you debug the issue.&lt;/p&gt;

&lt;p&gt;Now, click on the + icon next to widgets and drop a new text widget onto the canvas. Open the property pane of the text widget by clicking on the widget name, and update the text property to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{JSObject1.myRandomNumber()}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now click the + icon next to widgets and add a new text widget onto the canvas. Open up the property pane of that new text widget by clicking on its name and updating the Text property to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{JSObject1.myRandomNumber()}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, we should be able to see a new random number bound onto the text widget:&lt;/p&gt;

&lt;p&gt;The next question that comes to mind is, what if there's an error in the JS object's code? Does it work the same as a JS compiler does? The answer is yes! If you make a mistake in JavaScript syntax while writing your code, the JavaScript Editor will highlight the error using a red-colored lint below the possible position of the error. Here’s a screenshot for reference:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638790446402%2FfE9pU6MjQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638790446402%2FfE9pU6MjQ.png" alt="CleanShot 2021-11-24 at 11.26.15@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not just that, we can see all the logs; we can also see the history of each update and execution of your function under the Logs tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638790496453%2F5BhLdk8N_.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1638790496453%2F5BhLdk8N_.png" alt="CleanShot 2021-11-24 at 11.37.12@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What’s Next for the JS Editor?
&lt;/h3&gt;

&lt;p&gt;Following are a few features, we will be extending to the JS Editor, keep an eye our, or join us on &lt;a href="https://discord.com/invite/rBTTVJp" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; to stay up to date :)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inspect and debug code by hovering over entities&lt;/li&gt;
&lt;li&gt;Auto format options &lt;/li&gt;
&lt;li&gt;Functions running on page load&lt;/li&gt;
&lt;li&gt;Asynchronous functions&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;We hope you’re as excited about the JS editor as we are. If you’d like to give feedback on this feature or have a say in the roadmap, join the &lt;a href="https://www.notion.so/Betasmith-Join-the-Appsmith-Beta-Community-5c288dfd57bd4c4781c3bf02ddf9aa8a" rel="noopener noreferrer"&gt;Betasmith program&lt;/a&gt; today. &lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://github.com/ApekshaBhosale" rel="noopener noreferrer"&gt;Apeksha&lt;/a&gt;, &lt;a href="https://github.com/hetunandu" rel="noopener noreferrer"&gt;Hetu&lt;/a&gt;, &lt;a href="https://github.com/ajinkyakulkarni" rel="noopener noreferrer"&gt;Ajinkya&lt;/a&gt;, &lt;a href="https://github.com/nidhi-nair" rel="noopener noreferrer"&gt;Nidhi&lt;/a&gt;, Parth, Aakash, Saptami, Prappula, &lt;a href="https://github.com/ajinkyakulkarni" rel="noopener noreferrer"&gt;Nikhil&lt;/a&gt;, who worked hard on shipping this feature out!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Modern Stack to Build Internal Tools: Supabase, Appsmith, n8n</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Mon, 08 Nov 2021 11:58:49 +0000</pubDate>
      <link>https://dev.to/appsmith/the-modern-stack-to-build-internal-tools-supabase-appsmith-n8n-1fbc</link>
      <guid>https://dev.to/appsmith/the-modern-stack-to-build-internal-tools-supabase-appsmith-n8n-1fbc</guid>
      <description>&lt;p&gt;Developers spend quite a bit of time building internal tools, admin panels, and applications for back-office tasks that help automate everyday essential business processes. These involve multiple efforts, from maintaining a special database to writing lots of frontend and backend code. But, what if we told you that you could utilize a modern stack to build such applications that can help with your backend, frontend and automation tasks? Sounds good right? It is!&lt;/p&gt;

&lt;p&gt;We’re happy to introduce a great new stack to build applications: The &lt;a href="https://supabase.io/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;, &lt;a href="https://www.appsmith.com/" rel="noopener noreferrer"&gt;Appsmith&lt;/a&gt; and &lt;a href="https://n8n.io/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt; stack (SAN Stack) for developers to build and maintain modern custom internal tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is the SAN Stack?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;SAN stands for Supabase, Appsmith and n8n, after the three emerging and notable software that makes up the stack. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://supabase.io/" rel="noopener noreferrer"&gt;Supabase&lt;/a&gt;: The open-source firebase alternative to creating a backend in minutes. Start your project with a Postgres database, authentication, instant APIs, real-time subscriptions and storage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.appsmith.com/" rel="noopener noreferrer"&gt;Appsmith&lt;/a&gt;: An open-source framework to build custom business software with pre-built UI widgets that connect to any data source, and can be controlled extensively using JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://n8n.io/" rel="noopener noreferrer"&gt;n8n&lt;/a&gt;: An extendable workflow automation tool. With a fair-code distribution model, n8n will always have visible source code, be available to self-host, and allow you to add your custom functions, logic and apps.&lt;/p&gt;

&lt;p&gt;This stack lets you build any application within minutes. You can use Supabase for the database and backend, Appsmith for UI and adding functionality, and n8n for automating background tasks.&lt;/p&gt;

&lt;p&gt;One of Appsmith’s co-founders and head of product, Nikhil Nandagopal broke down the basics of app building into three steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636350665376%2FTEPshbRIq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636350665376%2FTEPshbRIq.png" alt="CleanShot 2021-11-08 at 11.20.37@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This has gained quite some traction among developers, especially those looking to build internal tools or applications. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why Supabase, Appsmith, and n8n?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Free / Opensource&lt;/strong&gt;: Supabase and Appsmith are fully open-sourced and can be self-hosted on their servers. While n8n follows a fair-code distribution model and always has visible source code, which is available to self-host.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Low-code yet high functionality: **All three platforms follow the principles of the low-code model to help developers deploy and scale their applications in the fastest way possible. However, devs can utilize SQL, JavaScript, and data structures to customize their applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Editing Experience&lt;/strong&gt;: Supabase, Appsmith, and n8n have an excellent UI interface and provide rich editing and debugging experience for developers right from the beginning. Both Appsmith and n8n provide a drag and drop interface for building UI and automation workflows, respectively. In comparison, Supabase offers a live SQL editor to test out and play with your database and has the power to export them into APIs directly from the platform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;**Collaboration: **When working with teams, all three platforms offer great collaboration tools; you can share these applications or workflows with anyone and set specific permissions such as view-only or edit mode. They are consistently being improved in their future roadmap.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Self-hosted:&lt;/strong&gt; Developers can self-host all three platforms on their servers for free. It is useful when you want your data to be more secure, have complete control over customization, and have custom domain options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fantastic Community&lt;/strong&gt;: The community is incredible across all three platforms; they provide excellent support and a transparency roadmap. New feature requests or existing bugs are immediately taken care of based on the priority. And with a great community, content gets better and better, and they provide rich documentation and many tutorials for devs to get started.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Build a Simple Ticket Manager Using SAN Stack&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;There are so many tools and applications that can be built across the SAN stack. Here are a couple of examples: An &lt;a href="https://youtu.be/9va1dofeiFA" rel="noopener noreferrer"&gt;Employee Survey Dashboard&lt;/a&gt; and a &lt;a href="https://youtu.be/5izZ26yh_lw" rel="noopener noreferrer"&gt;Ticket Management Admin panel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using the SAN stack, you can build any dashboard in just minutes. &lt;/p&gt;

&lt;p&gt;As an example, I will show you how to create a support dashboard manager application.&lt;/p&gt;

&lt;p&gt;Using this application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users will be able to create or raise new tickets for a particular query&lt;/li&gt;
&lt;li&gt;The support team will be able to see these tickets and assign them to engineers&lt;/li&gt;
&lt;li&gt;When the tickets are resolved, we will be sending an automated email to the users&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354257607%2F3xuqi-oL3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354257607%2F3xuqi-oL3.png" alt="CleanShot 2021-11-08 at 12.20.33@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's get started!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Set up your Backend on Supabase&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The first step is to set up the backend for the application; for this, we will be using a Postgres database on Supabase.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you are new to Supabase, you can create a new account (it's free!) or sign in with your existing credentials.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You will be redirected to the Supabase dashboard; here, you can manage all your projects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new project, and set the name to Support Dashboard. Create a new table by clicking on the &lt;code&gt;Create Table&lt;/code&gt; option on the side navigation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supabase gives us many ways to add data to the tables, from writing queries to creating schemas using UI to simply uploading CSV files; developers can choose any option. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For our support dashboard, we will be creating a table by uploading a CSV file on Supabase.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354320512%2FHwDJ5hMRB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354320512%2FHwDJ5hMRB.png" alt="CleanShot 2021-11-08 at 12.21.48@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The DB is now set up; let's use Appsmith to connect this PostgresDB and build UI for the application. For this, we might need to note down the connection info from project settings on Supabase. Following is how it looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354398174%2FRCE6_GO7l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354398174%2FRCE6_GO7l.png" alt="CleanShot 2021-11-08 at 12.22.58@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Build UI on Appsmith and Writing Queries
&lt;/h3&gt;

&lt;p&gt;Our backend is ready; now, let's connect it to Appsmith to build UI and add functionalities. Follow the below steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If you are new to Appsmith, you can create a new account (it's free!) or sign in with your existing credentials.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After we sign in, we will be redirected to a dashboard to create a new application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, let's connect a new data source. To do this, click on the &lt;code&gt;+&lt;/code&gt; icon next to the Datasources from the sidebar and choose PostgresDB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, copy the database connection details from Supabase to here and click on the test button to validate the authentication.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354458427%2Fy3TZykhjN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354458427%2Fy3TZykhjN.png" alt="CleanShot 2021-11-08 at 12.23.58@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome, we now have established a connection to our data source. Next, let’s build UI using widgets on Appsmith. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the &lt;code&gt;+&lt;/code&gt; icon next to widgets and drag and drop a Tab widget. We can configure using the property pane by clicking on the cog icon on the top-right corner.&lt;/li&gt;
&lt;li&gt;As seen in the below screenshot, we have added four tabs to support the dashboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354501026%2F0NVj0poZr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354501026%2F0NVj0poZr.png" alt="CleanShot 2021-11-08 at 12.24.46@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, we will add a button that should open a modal and have a form to raise a new ticket when clicked. For this, just drag and drop a new button widget from the widgets section and move it on canvas.&lt;/li&gt;
&lt;li&gt;Add a few input widgets and a button to submit the form; this is how the form looks after the UI is complete:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354544715%2FIe7rUgNx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354544715%2FIe7rUgNx9.png" alt="CleanShot 2021-11-08 at 12.25.29@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We now have the UI to create a ticket. Let’s write two queries on Appsmith that will allow us to create tickets and list tickets. To do this, click on the + icon next to the data sources and use the Supabase connection here to create a new query.&lt;/li&gt;
&lt;li&gt;Rename the query to create_new_ticket under the query pane; here we can write SQL that can collect inputs using moustache bindings. Following is how it looks like:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="k"&gt;PUBLIC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"tickets"&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="nv"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nv"&gt;"createdAt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nv"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nv"&gt;"updatedAt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nv"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nv"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nv"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nv"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="nv"&gt;"assignedTo"&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;VALUES&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;
                        &lt;span class="s1"&gt;'{{appsmith.store.ticket.id}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'{{moment().format('&lt;/span&gt;&lt;span class="n"&gt;yyyy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ddHH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;MM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ss&lt;/span&gt;&lt;span class="s1"&gt;')}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'{{c_user.text}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'{{moment().format('&lt;/span&gt;&lt;span class="n"&gt;yyyy&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mm&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ddHH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;MM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;ss&lt;/span&gt;&lt;span class="s1"&gt;')}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'{{c_description.text}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'{{c_status.selectedOptionValue}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'{{c_proporty.selectedOptionValue}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'{{c_category.selectedOptionValue}}'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                        &lt;span class="s1"&gt;'{{c_assignee.selectedOptionValue}}'&lt;/span&gt;
            &lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;On Appsmith, we can use moustache bindings anywhere across the app to bind data or write javascript code to customize and add functionalities to your widgets.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Lastly, we now set the onClick property for the button to execute a query and select the &lt;code&gt;create_new_ticket&lt;/code&gt;. And just like that, we should be able to create new tickets on the application.&lt;/li&gt;
&lt;li&gt;Now, let’s write one more query where we could list all the tickets that users create. We will name this query &lt;strong&gt;get_tickets&lt;/strong&gt;; the following is the SQL snippet. &lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;"tickets"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Now, drag and drop a table widget onto the tab widget under the &lt;code&gt;Assigned To Me&lt;/code&gt; tab. Open the property pane and add the following snippet to bind the tickets:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;span class="nx"&gt;get_tickets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assignedTo&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;confidence@appsmith.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;closed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Fantastic, we should be able to see all the tickets assigned to the specific user! It’s that’s simple to write custom JS to configure our internal applications on Appsmith. Now let’s use a webhook and build automation that sends Emails from the ticket using n8n!&lt;/p&gt;

&lt;h3&gt;
  
  
  Building an Extendable Workflow on n8n
&lt;/h3&gt;

&lt;p&gt;If you want to build an internal tool that requires sending emails, then n8n is the way to go. n8n is a tool that can be used to automate workflows between your favorite web apps (such as Slack, Google Drive, Dropbox, etc.). However, n8n can be used to connect almost any two web apps that you use. Now, let's create a workflow and use a webhook to send requests to n8n from Appsmith. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are new to n8n, sing-up for their cloud version &lt;a href="https://n8n.io/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Next, create a new workflow by selecting &lt;code&gt;New&lt;/code&gt; under the workflow menu&lt;/li&gt;
&lt;li&gt;Now, drag and drop a Webhook node onto the canvas; you can configure the nodes by clicking on them.&lt;/li&gt;
&lt;li&gt;Now set the HTTP method to POST and copy the TEST URL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Awesome, now that we have the Webhook, let’s connect it with Appsmith by adding it as a data source.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the appsmith application, click on the &lt;code&gt;+&lt;/code&gt; icon next to the data source and create a new API. &lt;/li&gt;
&lt;li&gt;Set the API type to POST and paste the API webhook URL,&lt;/li&gt;
&lt;li&gt;Now paste the following code snippet under the body tab to collect input from the dashboard. &lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"({this. params. message})"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(this.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;params.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;email&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;",
"&lt;/span&gt;&lt;span class="err"&gt;ticket&lt;/span&gt;&lt;span class="s2"&gt;": "&lt;/span&gt;&lt;span class="err"&gt;((appsmith.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;store.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;ticket.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="s2"&gt;"
}


&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Next, connect a Gmail node to the webhook and authenticate with your Google ID.&lt;/li&gt;
&lt;li&gt;To pass the data from the webhook to the Gmail node, configure the message property by using the variable selector nodes on the left pane.&lt;/li&gt;
&lt;li&gt;Lastly, make sure you set the workflow state to active.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And just like that, we should be able to send Emails using n8n without writing any piece of code. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354736657%2FtLqSDrgue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1636354736657%2FtLqSDrgue.png" alt="CleanShot 2021-11-08 at 12.28.38@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://app.appsmith.com/applications/61143c0ea63458639e2f4540/pages/61143c0ea63458639e2f4542" rel="noopener noreferrer"&gt;Building this app&lt;/a&gt; from scratch, including writing snippets of code, is likely to take 30 minutes! Isn’t that fast?&lt;/p&gt;

&lt;p&gt;If you're looking for a modern approach to building internal applications, check out Supabase, Appsmith, and n8n! These tools are straightforward, powerful, and can help you build apps faster than ever. So what are you waiting for? Start building your next internal app today.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>javascript</category>
      <category>database</category>
    </item>
    <item>
      <title>Appsmith Roundup: Build CRUD Apps with one-click, Move Multiple Widgets, New Icon Widget and Omnibar</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Wed, 08 Sep 2021 06:03:10 +0000</pubDate>
      <link>https://dev.to/appsmith/appsmith-roundup-build-crud-apps-with-one-click-move-multiple-widgets-new-icon-widget-and-omnibar-1422</link>
      <guid>https://dev.to/appsmith/appsmith-roundup-build-crud-apps-with-one-click-move-multiple-widgets-new-icon-widget-and-omnibar-1422</guid>
      <description>&lt;p&gt;We’re back again this month with updates from the last 30 days. Apart from adding support to self-hosted Appsmith instances, we’ve got some big features we shipped last month. &lt;/p&gt;

&lt;p&gt;Here’s a low-down on what we were up to! &lt;/p&gt;

&lt;h2&gt;
  
  
  🖱️ Generate a CRUD app from any database with one click!
&lt;/h2&gt;

&lt;p&gt;We know how important CRUD applications are for internal operations. Why should something so critical to an organization's success be difficult to make? We’ve made it super easy to make one. What if we said that you can now make the entire CRUD application with all the UI, logic, and complete control in just one click? Now, it’s possible.&lt;/p&gt;

&lt;p&gt;We’re super excited to announce our new feature called the “Generate New Page from Database” With this, you can build CRUD applications within no time. To learn more about this feature check out this blog &lt;a href="https://blog.appsmith.com/generate-a-crud-app-from-any-database-with-one-click" rel="noopener noreferrer"&gt;here&lt;/a&gt; or watch a quick demo &lt;a href="https://youtu.be/zyLDJnaxlzc" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Want to create your own CRUD app on Appsmith, here’s how you can do it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630988820111%2Fcfu7u7sLjI.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630988820111%2Fcfu7u7sLjI.gif" alt="Gif.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re new to Appsmith follow the steps below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If you’re an existing user sign in to your account or you can sign-up here for free.&lt;/li&gt;
&lt;li&gt;After you sign in you’ll be redirected to the Appsmith dashboard where you can create a new application by clicking on the Create New button.&lt;/li&gt;
&lt;li&gt;This will create a new Appsmith application, now to connect a data source click on the &lt;code&gt;+&lt;/code&gt; icon next to the Datasource option on the left navigation bar.&lt;/li&gt;
&lt;li&gt;You can choose from a wide range of options here, in case if you want to test it you can use the mock-users database.&lt;/li&gt;
&lt;li&gt;Next, under the active data sources click on the &lt;code&gt;GENERATE NEW PAGE&lt;/code&gt; option.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You’ll see the following options:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630988783768%2FQ4M4OoJ21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630988783768%2FQ4M4OoJ21.png" alt="sdHNRHrKK.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, you can select the table and add a searchable column. As soon you click on the Generate Page, you’ll see the UI where all the CRUD operations can be performed.&lt;/p&gt;

&lt;p&gt;Hola, and with just one click the entire application is generated!&lt;/p&gt;

&lt;h2&gt;
  
  
  🎉 New ICON Widget
&lt;/h2&gt;

&lt;p&gt;Icons are a great way to create a better user experience! On Appsmith, buttons are widely used for performing different actions such as calling APIs, opening modals, showing alerts, and many more. Sometimes, it might be hard to find the right buttons; in such cases, our new icon widgets come in handy. You can use it to create a better user experience or perform actions similar to the button widget. &lt;/p&gt;

&lt;p&gt;We ship this icon widget with a wide range of customization, and you can choose these from 300+ icons or connect with your own. Like other widgets on Appsmith, we've added buttons like button style, button variant, border radius, box-shadow, and shadow colour to help you create the perfect application! &lt;/p&gt;

&lt;p&gt;Here's a sneak peek of some of the variants created using the icon widget. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630988949383%2Fg52pFy-nn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630988949383%2Fg52pFy-nn.gif" alt="04.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome right? What are you waiting for? Give it a try!&lt;/p&gt;

&lt;h2&gt;
  
  
  New Omnibar
&lt;/h2&gt;

&lt;p&gt;When building huge internal applications on Appsmith, sometimes it’s hard to navigate to the right widget or data source queries, to overcome this, we’ve redesigned our entire Omnibar. With this, you can navigate to any widget, or data source query at any point of time with a single click, not just that, you can search for any query from our documentation directly from inside the application using Omnibar, all you’ll need to do is use the keyboard shortcut &lt;code&gt;CMD + K&lt;/code&gt; or &lt;code&gt;CTRL + K&lt;/code&gt; and enter your query!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630989619501%2FbxBgoGZ8E.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630989619501%2FbxBgoGZ8E.gif" alt="02.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Moving multiple widgets using widget grouping!
&lt;/h2&gt;

&lt;p&gt;So far, we’ve made quite good progress with our widget grouping feature. With this, developers are able to copy and delete multiple widgets at a time. Now, we’ve added the most requested feature! Yes, it’s moving multiple widget’s when widgets are grouped. Just, select the required widgets by dragging them over them and move across the canvas to multiple widgets at one time! Cool right? You can also use this to move widget’s into containers as well. Here’s the GIF showing the same:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630988988774%2Fihv0TGy40.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1630988988774%2Fihv0TGy40.gif" alt="03.gif"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;We’ve got a host of other bug fixes and updates too, be sure to check out our release notes &lt;a href="https://github.com/appsmithorg/appsmith/releases" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>development</category>
      <category>community</category>
    </item>
    <item>
      <title>Say Hello to our New ArangoDB Integration</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Fri, 30 Jul 2021 12:37:25 +0000</pubDate>
      <link>https://dev.to/appsmith/say-hello-to-our-new-arangodb-integration-ibe</link>
      <guid>https://dev.to/appsmith/say-hello-to-our-new-arangodb-integration-ibe</guid>
      <description>&lt;p&gt;We’ve added yet another database integration to Appsmith; say hello to ArangoDB! ArangoDB is an open-source multi-model database system where you can natively store data for graph, document and search needs. And the best part? It’s free!&lt;/p&gt;

&lt;p&gt;We’ve made it super easy to build new integrations on Appsmith. This is because we've architectured each integration as an individual module. It's super handy for us and contributors to build, customize and organize any new integration. This integration feature was developed by one of our users and top contributors on Github, Mingfang! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1627477567364%2FmGNEnxmPx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1627477567364%2FmGNEnxmPx.png" alt="github.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To learn more about Appsmith's backend architecture, we recommend you watch the session about integrations by our co-founders &lt;a href="https://www.youtube.com/watch?v=hQScncyEUds" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once the PR for the ArangoDB integration was raised, Sumit, one of our engineers from the backend team reviewed it. He then made all the changes and got things into a working shape. Needless to say that our QA team will ensure that these new features are bug-free in testing and production environments. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1627478003151%2F3lQg520Xx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1627478003151%2F3lQg520Xx.png" alt="CleanShot 2021-07-28 at 18.43.09@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using ArangoDB Integration
&lt;/h3&gt;

&lt;p&gt;To start using the ArangoDB integration on Appsmith, you can sign in to your account or create one for free here and follow the steps below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;On the Appsmith dashboard, create a new application by clicking on the &lt;code&gt;Create New&lt;/code&gt; button under any organization.&lt;/li&gt;
&lt;li&gt;Find the &lt;code&gt;Datasources&lt;/code&gt; option on the left navigation pane, click on the &lt;code&gt;+&lt;/code&gt; icon next to it.&lt;/li&gt;
&lt;li&gt;Find the ArangoDB integration and select it; you’ll be redirected to a new page where you will have to add your ArangoDB configuration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: Please whitelist Appsmith IP addresses to access ArangoDB Cloud projects. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1627478079845%2FSlPwdXnPK.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1627478079845%2FSlPwdXnPK.png" alt="CleanShot 2021-07-28 at 18.44.17@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With just three simple steps, you will be able to connect the ArangoDB Datasource to Appsmith. Now, follow the steps below to utilize the data and build UI.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the &lt;code&gt;+&lt;/code&gt; icon next to the data sources on the side navigation.&lt;/li&gt;
&lt;li&gt;Find the ArangoDB data source and click on &lt;code&gt;NEW QUERY&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the query pane, write Graph Queries for performing any operations on the data source. For this example, we’ve installed the eCom Analytics example from the ArangoDB cloud. Let’s try to fetch the departments that are present in the department’s table.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Add the following query in the query pane and click the RUN button on the top-right.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FOR document IN departments
RETURN document
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will return the values from the department table. Here’s a screenshot for your reference. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1627478243439%2FoqouCvPUq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1627478243439%2FoqouCvPUq.png" alt="CleanShot 2021-07-27 at 14.14.24@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Similarly, you could run queries and connect with different widgets on Appsmith to build awesome dashboards and internal applications. If you do, don’t forget to tell us about it, we would love to feature your work! Your contributions and feedback help us make Appsmith better and we really appreciate it.&lt;/p&gt;

&lt;p&gt;Join the community! Come chat with us on &lt;a href="https://discord.com/invite/rBTTVJp" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, or jump in on &lt;a href="https://github.com/appsmithorg/appsmith" rel="noopener noreferrer"&gt;Github&lt;/a&gt; directly!&lt;br&gt;
You can also follow us on &lt;a href="https://twitter.com/theappsmith" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and &lt;a href="https://in.linkedin.com/company/appsmith" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Don’t forget to sign up for our &lt;a href="https://lu.ma/appsmith" rel="noopener noreferrer"&gt;live events&lt;/a&gt;! &lt;/p&gt;

</description>
      <category>database</category>
      <category>opensource</category>
      <category>javascript</category>
      <category>tools</category>
    </item>
    <item>
      <title>Self-host Appsmith in Just a Few Minutes on Digital Ocean</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Fri, 30 Jul 2021 12:32:21 +0000</pubDate>
      <link>https://dev.to/appsmith/self-host-appsmith-in-just-a-few-minutes-on-digital-ocean-1fib</link>
      <guid>https://dev.to/appsmith/self-host-appsmith-in-just-a-few-minutes-on-digital-ocean-1fib</guid>
      <description>&lt;p&gt;&lt;a href="https://www.appsmith.com/" rel="noopener noreferrer"&gt;Appsmith&lt;/a&gt; is a low-code open-source framework that’ll help build your internal applications, admin panels, CRUD apps, and many more 10x faster. In this tutorial, we’ll learn how to deploy Appsmith on DigitalOcean by using the Appsmith droplet from Digital Ocean’s 1-Click Apps Marketplace and host it on your custom domain.&lt;/p&gt;

&lt;p&gt;To get started, you’ll need an account on DigitalOcean; don’t worry, if you don’t currently have an account, use this &lt;a href="https://marketplace.digitalocean.com/apps/appsmith?refcode=469c9f1431e4" rel="noopener noreferrer"&gt;link&lt;/a&gt; and get $25 credit on DigitalOcean! &lt;/p&gt;

&lt;p&gt;If you’re already an existing user, use your account and follow the steps listed below:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login to your DigitalOcean account.&lt;/li&gt;
&lt;li&gt;Find Appsmith from the DigitalOcean marketplace &lt;a href="https://marketplace.digitalocean.com/apps/appsmith" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Click on the &lt;code&gt;Create Appsmith Droplet&lt;/code&gt; button; this will redirect you to a new page where you can set up all your configurations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a base configuration, use the following settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Shared CPU: Basic
CPU Options: Regular Intel with SSD (1 GB CPU / 25GB SSD / 1000GB Transfer )
Data Center Region: (Choose the nearest location to your place)
Additional Options: IPV6 Enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In the authentication section, you can either choose SSH or set up a password if you want to log in to your server.&lt;/li&gt;
&lt;li&gt;Lastly, click on Create Droplet button.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s how it should look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626879398033%2FlDCvqZbNH.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626879398033%2FlDCvqZbNH.gif" alt="CleanShot 2021-07-21 at 13.18.46.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! It will take a few minutes (approximately 3-4 minutes) to install Appsmith on the DigitalOcean droplet. After this, you’ll find the deployed droplet on your dashboard with all the details of the selected configuration. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626879429960%2Fd5V1U56bx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626879429960%2Fd5V1U56bx.png" alt="CleanShot 2021-07-21 at 13.25.34@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, to use Appsmith, you’ll need to copy the IPv4 address from the settings and open it in a new tab. This will take you to Appsmith’s login page. You’ll have to sign up for a new account on Appsmith since it’s the first time you’ll be using it. &lt;/p&gt;

&lt;p&gt;Follow the steps shown in this GIF:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626879478156%2FHFS_imQf9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626879478156%2FHFS_imQf9.gif" alt="CleanShot 2021-07-21 at 13.31.21.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hosting Appsmith DigitalOcean Droplet on Your Domain
&lt;/h3&gt;

&lt;p&gt;To host the Appsmith DigitalOcean droplet on a custom domain, you’ll need to select the &lt;code&gt;Add a domain&lt;/code&gt; option from the dashboard. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626879528509%2FE1zl_QUUV.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626879528509%2FE1zl_QUUV.png" alt="CleanShot 2021-07-21 at 13.35.19@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will redirect you to a new page, where you’ll need to add your domain name. Once that’s done, it’ll give you records of the name servers. Copy the NS (name servers) details and use the custom name server’s configuration on your domain provider. Sometimes, it might take up to 24-48 hours for this to go live! Be patient 🙃&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping Up!
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we discussed how to deploy Appsmith on DigitalOcean. However, this is not the only way to use Appsmith; you can always self-host it on different cloud platforms. You can learn more about setting up Appsmith in different environments using these &lt;a href="https://docs.appsmith.com/setup" rel="noopener noreferrer"&gt;setup guides&lt;/a&gt;. Additionally, you can always migrate your applications from one environment to another using the import-export feature. To learn more about this, read the blog post here.&lt;/p&gt;

&lt;p&gt;We hope you found this guide helpful! Your contributions and feedback help us make Appsmith better, and we really appreciate it. &lt;/p&gt;

&lt;p&gt;Join the &lt;a href="https://community.appsmith.com/?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=blog&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=feature" rel="noopener noreferrer"&gt;community&lt;/a&gt;! Come chat with us on &lt;a href="https://discord.com/invite/rBTTVJp" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, or jump in on &lt;a href="https://github.com/appsmithorg/appsmith" rel="noopener noreferrer"&gt;Github&lt;/a&gt; directly!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
      <category>digitalocean</category>
    </item>
    <item>
      <title>Make Your Own Social Media Marketing App like Hootsuite with Appsmith and n8n</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Fri, 30 Jul 2021 12:14:07 +0000</pubDate>
      <link>https://dev.to/appsmith/make-your-own-social-media-marketing-app-like-hootsuite-with-appsmith-and-n8n-1dmj</link>
      <guid>https://dev.to/appsmith/make-your-own-social-media-marketing-app-like-hootsuite-with-appsmith-and-n8n-1dmj</guid>
      <description>&lt;p&gt;For a content management team in any organization, things can get chaotic between ideating, strategizing, content creation, and distribution. Looking after multiple social media platforms can be overwhelming; this is where social media schedulers come in handy. However, for an early-stage organization, subscribing to these tools can be an expensive affair, and they do not solve the organization’s specific requirements. For example, at Appsmith, we focus our distribution through Twitter, Discord, Slack, and Linkedin, and we wanted a customizable solution more suited to our needs. Our cross-platform scheduler can send a message across four channels with just one click, and we made this using &lt;a href="https://www.appsmith.com/?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=blog&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=lowcode"&gt;Appsmith&lt;/a&gt; and automated the workflow with &lt;a href="https://n8n.io/"&gt;n8n&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;And building this is not that difficult!  &lt;/p&gt;

&lt;p&gt;This blog will take you through the different steps involved in building a workflow like this. You can extend this and customize it further to address specific requirements. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Getting Started with Appsmith&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we’ll be using the local environment of Appsmith to build the application. However, we can always export and then import Appsmith apps to different environments (cloud, self-hosted, local). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The recommended way to use Appsmith locally is to use Docker; for detailed instructions, follow the documentation &lt;a href="https://docs.appsmith.com/setup/docker"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next, create a new account or sign in with an existing account and redirect it to our dashboard. Now, let’s create a new application and build a minimalistic UI for our social broadcaster by following the steps listed below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on &lt;code&gt;Create New&lt;/code&gt; under your organization, and this will create a new Appsmith application. &lt;/li&gt;
&lt;li&gt;Rename the application to &lt;code&gt;Social Broadcaster&lt;/code&gt; by simply double-clicking on the existing one.&lt;/li&gt;
&lt;li&gt;On the left, find the entity explorer; this is where we can manage all our widgets and data sources of the entire application.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Awesome! We will build a simple UI with Appsmith widgets to broadcast messages onto different social platforms in the next section. &lt;/p&gt;

&lt;h3&gt;
  
  
  *&lt;em&gt;Building Simple UI *&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Appsmith has a great set of widget (UI Components) collections for us to build internal applications. We'll be using a few of these widgets to create a form that enables us to write messages and select options to broadcast to social platforms of choice.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the &lt;code&gt;+&lt;/code&gt; icon next to the Widgets menu on the entity explorer. Find the drag the &lt;code&gt;Container&lt;/code&gt; widget and drag and drop it onto the canvas.&lt;/li&gt;
&lt;li&gt;Resize this container widget based on our UI preferences. Next, find the &lt;code&gt;Text&lt;/code&gt; widget and drop it inside the &lt;code&gt;Container&lt;/code&gt; widget.&lt;/li&gt;
&lt;li&gt;Next, open the property pane of the Text widget when selected by clicking on the cog icon on top-right, next to its name. Now, update the label property to &lt;code&gt;Create Post&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To write the post content, let’s use a &lt;code&gt;Rich Text Editor&lt;/code&gt; Widget. Drag and drop it inside the Container &lt;code&gt;Widget&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Let’s add some &lt;code&gt;Switch&lt;/code&gt; widgets, which will let us control what to post on social platforms. Set the labels to &lt;code&gt;Discord&lt;/code&gt;, &lt;code&gt;Slack&lt;/code&gt;, &lt;code&gt;Twitter&lt;/code&gt;, and &lt;code&gt;Linkedin&lt;/code&gt; from the property pane. &lt;/li&gt;
&lt;li&gt;Lastly, add a &lt;code&gt;Button&lt;/code&gt; widget; when clicked, content gets posted from the RTE to platforms marked in the switches.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---2JhQ48s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1626780950180/VPeLzR4p_.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---2JhQ48s--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1626780950180/VPeLzR4p_.gif" alt="CleanShot 2021-07-06 at 00.50.54.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We now have the basic UI for our broadcaster. Now, let’s create an n8n workflow and integrate it with Appsmith!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Building n8n Workflow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we will be setting up n8n in our local environment using npm (node package manager). Here’s the command to install n8n globally on your machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install n8n -g
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;n8n helps you create powerful workflows by syncing data across 200+ apps. No coding is required.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Post-installation, type in &lt;code&gt;n8n&lt;/code&gt; on your terminal or command prompt; it will open n8n editor on &lt;code&gt;[http://localhost:5678/](http://localhost:5678/)&lt;/code&gt;. Here we can create workflows and save them on local env. However, you can always import-export n8n apps in different environments.&lt;/p&gt;

&lt;p&gt;Here’s a screenshot of the &lt;code&gt;n8n&lt;/code&gt; editor: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xnTthZmM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1626780943801/RDbd3oC9X.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xnTthZmM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1626780943801/RDbd3oC9X.png" alt="CleanShot 2021-07-06 at 03.59.26@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s create a workflow that’ll broadcast messages onto different social platforms. Follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a webhook trigger on n8n; for this, click on the &lt;code&gt;+&lt;/code&gt; icon and search for &lt;code&gt;Webhook&lt;/code&gt; under the &lt;code&gt;Trigger&lt;/code&gt; sections. This will open up a new modal where we can configure the properties of the Webhook.&lt;/li&gt;
&lt;li&gt;Next, find an &lt;code&gt;if&lt;/code&gt; node under the &lt;code&gt;Regular&lt;/code&gt; section and connect it with the Webhook. We’ll have four &lt;code&gt;if nodes&lt;/code&gt; to which we’ll connect all the other integrations.&lt;/li&gt;
&lt;li&gt;Lastly, find the Discord, Slack, Twitter, and Linkedin integrations and connect them with these if-nodes. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Following is a screenshot of how the workflow looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FSNDcOWc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1626781091211/Vmk4Gp1Hn7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FSNDcOWc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1626781091211/Vmk4Gp1Hn7.png" alt="CleanShot 2021-07-20 at 17.07.39@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We now have a clear picture of how our workflow looks like; let’s pass the data into n8n from Appsmith using the webhook. &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Configuring Appsmith and n8n&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Appsmith and n8n will be communicating through a webhook. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A webhook (also called a web callback or HTTP push API) is a way for an app to provide other applications with real-time information. A webhook delivers data to other applications as it happens, meaning you get data immediately.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Follow the below steps to configure this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Double click on the Webhook node on the n8n editor; this will open up a modal with all the webhook properties.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on &lt;code&gt;Webhook URLs&lt;/code&gt; and copy the &lt;code&gt;Test URL&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://localhost:5678/webhook-test/006d957e-0a8d-467e-9b01-178771e0d275
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Update the TEST URL from your n8n environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Since we’re using the local version, we’ll be replacing localhost with the connect IP:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://192.168.0.115:5678/webhook-test/006d957e-0a8d-467e-9b01-178771e0d275
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now, on Appsmith, select the &lt;code&gt;Datasource&lt;/code&gt; option on the entity explorer and click &lt;code&gt;Create New&lt;/code&gt; under the APIs section.&lt;/li&gt;
&lt;li&gt;Change the request method to POST and paste the webhook URL. Next, under the body property, paste the following code snippet:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="err"&gt;RichTextEditor&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;.text&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"medium"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;function()&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;let&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;str&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(slackSwitch.isSwitchedOn==&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;str&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;+=&lt;/span&gt;&lt;span class="s2"&gt;"slack "&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(discordSwitch.isSwitchedOn==&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;str&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;+=&lt;/span&gt;&lt;span class="s2"&gt;"discord "&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(TwitterSwitch.isSwitchedOn==&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;str&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;+=&lt;/span&gt;&lt;span class="s2"&gt;"twitter "&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(linkedinSwitch.isSwitchedOn==&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;str&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;+=&lt;/span&gt;&lt;span class="s2"&gt;"linkedin "&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;str&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;()&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we’re sending all the required information from Appsmith to n8n using webhook through the request body. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;{{ }}&lt;/code&gt; moustache operator in Appsmith helps write JS anywhere and access widget properties. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Lastly, on n8n, click &lt;code&gt;Execute Workflow&lt;/code&gt; and on Appsmith, hit &lt;code&gt;RUN&lt;/code&gt; on the API.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If the nodes are throwing any errors, you can click on the pause icon on top of them to ignore them from execution. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Awesome, this should send the data to the webhook. Let’s add validations to the workflow with the data sent from Appsmith. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Appsmith &amp;lt;&amp;gt; n8n Workflow Configurations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, add the necessary API keys to the social nodes. If you’re using the n8n.cloud account, you can directly authorize each application by logging into your social media account.&lt;/p&gt;

&lt;p&gt;After authorization, we’ll need to configure the if-nodes; here, we’ll add the expression from the Webhook, and based on the condition, we’ll be accessing the social nodes. For this, let’s use the &lt;code&gt;contains&lt;/code&gt; operation on every node. &lt;/p&gt;

&lt;p&gt;The value1 is set to &lt;code&gt;{{$node["Webhook"].json["body"]["medium"]}}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The value2 is set to &lt;code&gt;discord&lt;/code&gt;, &lt;code&gt;linkedin&lt;/code&gt;, &lt;code&gt;twitter&lt;/code&gt;, &lt;code&gt;slack&lt;/code&gt; based on the condition from the node. &lt;/p&gt;

&lt;p&gt;Lastly, we’ll need to execute the workflow and use Appsmith UI to cross-post content across selected social apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  *&lt;em&gt;Conclusion *&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we learnt how to automate content across social media by using Appsmith and n8n. In short, we used Appsmith to build UI and n8n to create automated workflows. With this combination, you could make scores of other similar internal applications that can connect to multiple services and data sources. For example, you could quickly build a CRM that can integrate with numerous email services, or you could automate code reviews and CI/CD pipelines. &lt;/p&gt;

&lt;p&gt;We hope you found this tutorial helpful! Let us know if you made an app using Appsmith, and we would love to feature you. &lt;/p&gt;

&lt;p&gt;Join the &lt;a href="https://community.appsmith.com/?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=blog&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=feature"&gt;community&lt;/a&gt;! Come chat with us on &lt;a href="https://discord.com/invite/rBTTVJp"&gt;Discord&lt;/a&gt;, or jump in on &lt;a href="https://github.com/appsmithorg/appsmith"&gt;Github&lt;/a&gt; directly!&lt;/p&gt;

&lt;p&gt;You can also follow us on &lt;a href="https://twitter.com/theappsmith"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.linkedin.com/company/appsmith/"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>opensource</category>
      <category>html</category>
    </item>
    <item>
      <title>Embed Anything! Introducing the New iFrame Widget</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Fri, 30 Jul 2021 11:33:43 +0000</pubDate>
      <link>https://dev.to/appsmith/embed-anything-introducing-the-new-iframe-widget-cme</link>
      <guid>https://dev.to/appsmith/embed-anything-introducing-the-new-iframe-widget-cme</guid>
      <description>&lt;p&gt;We’re excited to announce the new iFrame widget on Appsmith’s latest release (v1.6). With this, we can now embed content from other sources, such as web pages, videos, and scores of other content formats on Appsmith applications within no time!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/4jXTyxUhnP0" rel="noopener noreferrer"&gt;https://youtu.be/4jXTyxUhnP0&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At Appsmith, as an open-source organisation, we believe in the power of community and take member requests seriously. It’s also a part of our commitment to building in public. This iFrame feature was highly requested by our community members, prompting us to create an issue on our &lt;a href="https://github.com/appsmithorg/appsmith/issues/1726" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626687383197%2FBEDJkUTNv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626687383197%2FBEDJkUTNv.png" alt="Iframe Issue.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today, we want to talk a little bit about how we got to prototyping and then delivering this widget. &lt;/p&gt;

&lt;p&gt;First, we listed the basic requirements for an iFrame widget and the other specific functionalities we wanted to include. And yes, all the ideation and prototyping are open to the public; &lt;a href="https://www.figma.com/file/8aAbH6N9lYh4RnV37Rz4E8/Iframe-widget-design-Tue-4-May-2021?node-id=2%3A3024" rel="noopener noreferrer"&gt;you can check out the Figma files&lt;/a&gt;! One of our contributors, Paul Li, volunteered to build the widget. Li’s submissions were then thoroughly tested on our deploy previews and then pushed into production. A working example of the collaborative engineering practices we follow here at Appsmith!  🙌&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In case you’re wondering about how to set up Appsmith in the local environment and start contributing, this detailed guide will help you! &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626687616890%2FCfZXlALlb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626687616890%2FCfZXlALlb.png" alt="Iframe Peek.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the iFrame widget
&lt;/h2&gt;

&lt;p&gt;You can add the find the iFrame under the widget sections from the entity explorer inside the application. Drag and drop it onto the canvas to use it. By default, you’ll see a Wikipedia webpage, and you can change this by opening the property pane and adding a new link to the ‘Source’ property. You can also update the ‘label’ property to assign a name (title) to the content page that you wish to embed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626688425023%2FfhWG2-Xmf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626688425023%2FfhWG2-Xmf.gif" alt="Iframe GIF.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Handling Message Events on iFrame Widget&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The iFrame widget will allow you to trigger a value when a message event is received. This can be handled by configuring the &lt;code&gt;onMessageRecieved&lt;/code&gt; property.   &lt;/p&gt;

&lt;p&gt;Here’s how it works: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The iFrame widget listens to the message event of the window for catching the message from the iFrame embed. This event can be registered in the event listener.&lt;/li&gt;
&lt;li&gt;This means that the iFrame widget is ready to receive messages from the iFrame embed.&lt;/li&gt;
&lt;li&gt;In the iFrame widget, the defined ‘onMessageRecieved’, is just a function that will execute any action set on receiving a message.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the future, Appsmith will also provide an API that will let you access the message received from the iFrame embed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/11878947/auto-login-remote-site-inner-in-iframe#answer-16833828" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is another example with a similar use case. When the developer provides auto-login to another website that they have embedded inside their new website. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that the control of the embedded website is paramount here and also this approach is insecure. We have allowed this assuming that the developer understands the security issues and deals with them appropriately.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Handling URLs on IFrame Widget&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can handle certain actions when the Widget’s URL is changed using the &lt;code&gt;onURLChanged&lt;/code&gt; property. &lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;/p&gt;

&lt;p&gt;Let’s say you have loaded user data in the table and want to display details from there onto the website. When you click on a  particular row on the table, you can change the iFrame URL to show the rest of the details on your own website using the &lt;code&gt;onURLchanged&lt;/code&gt; property. We can also bound a trigger to execute an action whenever the URL is changed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626688301738%2FFIzmeJNXv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1626688301738%2FFIzmeJNXv.png" alt="Up.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you’ll build some super cool applications using the iFrame widget and Appsmith! If you do, don’t forget to tell us about it, we would love to feature your work! Your contributions and feedback help us make Appsmith better and we really appreciate it. &lt;/p&gt;

&lt;p&gt;Join the &lt;a href="https://community.appsmith.com?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=blog&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=feature" rel="noopener noreferrer"&gt;community&lt;/a&gt;! Come chat with us on &lt;a href="https://discord.com/invite/rBTTVJp" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, or jump in on &lt;a href="https://github.com/appsmithorg/appsmith" rel="noopener noreferrer"&gt;Github&lt;/a&gt; directly!&lt;/p&gt;

&lt;p&gt;You can also follow us on &lt;a href="https://twitter.com/theappsmith" rel="noopener noreferrer"&gt;&lt;strong&gt;Twitter&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://www.linkedin.com/company/appsmith/" rel="noopener noreferrer"&gt;Linkedin&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>html</category>
      <category>opensource</category>
      <category>lowcode</category>
    </item>
    <item>
      <title>Introducing the all-new SnowflakeDB Integration on Appsmith</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Fri, 30 Jul 2021 11:30:41 +0000</pubDate>
      <link>https://dev.to/appsmith/introducing-the-all-new-snowflakedb-integration-on-appsmith-31mk</link>
      <guid>https://dev.to/appsmith/introducing-the-all-new-snowflakedb-integration-on-appsmith-31mk</guid>
      <description>&lt;p&gt;Today, we are super proud to announce Snowflake DB integrations on  &lt;a href="https://appsmith.com/?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=feature&amp;amp;utm_campaign=announcements&amp;amp;utm_term=feature" rel="noopener noreferrer"&gt;Appsmith&lt;/a&gt; in our latest release (&lt;code&gt;&amp;gt;v1.5.5&lt;/code&gt;). It was one of the highly requested integrations by our community, and we've shipped this right on time. This blog is an attempt to share with you our motivation and experience in building this integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We first received a request for this SnowflakeDB integration on our GitHub Issues&lt;/strong&gt;. This was posted by one of our community members in the last week of April. We then researched SnowflakeDB's architecture and data sharing capabilities and decided to supercharge it with Appsmith for querying and building applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpdj18nm2bgcb87thf2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frpdj18nm2bgcb87thf2l.png" alt="CleanShot 2021-06-29 at 07.13.15@2x.png" width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On Appsmith, it's super fast and easy to build new Integrations. This is because we've architectured each integration as an individual module; with this, it's super handy for us and contributors to build, customise and organise any new integration.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To learn more about Appsmith's backend architecture, we recommend you watch the session about integrations by our co-founders &lt;a href="https://www.youtube.com/watch?v=hQScncyEUds" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Considering the amount of interest this integration had gathered within our community, we decided to fast-track the work on Snowflake DB Integration. It barely took us two weeks to build, test and ship it to production. Super C❄️❄️L, right?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fna3b81up24jn6vnm909f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fna3b81up24jn6vnm909f.png" alt="CleanShot 2021-06-29 at 05.43.57@2x.png" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our existing integrations helped us organise most of the code, and with Snowflake DB's JDBC driver support, we were able to establish a connection with our backend quickly. We've made a few easy-to-get-started decisions on the UX front, but we'll enhance these based on feedback from our community. &lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting Snowflake DB on Appsmith
&lt;/h3&gt;

&lt;p&gt;It is super easy to connect databases with our integrations on Appsmith. Now, let’s look at how we can connect SnowflakeDB on Appsmith to build applications. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step #1 Find Snowflake DB Integration under Datasources&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F035kni5edqvsxzd28jpe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F035kni5edqvsxzd28jpe.png" alt="CleanShot 2021-06-29 at 06.50.21@2x.png" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step #2 Add connection details for SnowflakeDB and save a data source&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwnd3ryovqoq1k0n5q6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwnd3ryovqoq1k0n5q6s.png" alt="CleanShot 2021-06-29 at 06.51.44@2x.png" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step #3 Create Queries and Build UI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fao25qjb524w5wao2xxno.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fao25qjb524w5wao2xxno.gif" alt="snowflake-min.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome, in just three steps, we're able to connect to SnowflakeDB on Appsmith! Now we can power UI widgets with queries from the created data source.&lt;/p&gt;




&lt;p&gt;Credits to &lt;strong&gt;&lt;a href="https://github.com/nidhi-nair" rel="noopener noreferrer"&gt;Nidhi Nair&lt;/a&gt;&lt;/strong&gt;, who had worked hard on getting this integration out!&lt;/p&gt;

&lt;p&gt;We appreciate each contribution and piece of feedback that you share. Join the community! Come chat with us on &lt;a href="https://discord.com/invite/rBTTVJp" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;, or jump in on &lt;a href="https://github.com/appsmithorg/appsmith?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=feature&amp;amp;utm_campaign=announcements&amp;amp;utm_term=feature" rel="noopener noreferrer"&gt;Github&lt;/a&gt; directly.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>snowflake</category>
      <category>lowcode</category>
    </item>
    <item>
      <title>Building an Internal Leave Management Dashboard using Google Sheets</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Thu, 17 Jun 2021 15:46:57 +0000</pubDate>
      <link>https://dev.to/appsmith/building-an-internal-leave-management-dashboard-using-google-sheets-537o</link>
      <guid>https://dev.to/appsmith/building-an-internal-leave-management-dashboard-using-google-sheets-537o</guid>
      <description>&lt;p&gt;Startups falter in productivity due to employees taking unplanned or just too many leaves. But sudden issues can arise with anyone, anytime, but organisations must keep a clear record of all the employees leaves to maintain proper working with constant efficiency month-by-month. But there's no time to really set a system in place for accountability, and they were forced to use Google Sheets to maintain a record of all leave records. &lt;/p&gt;

&lt;p&gt;But not everyone are comfortable using Google Sheets, anyone can make edit’s to it once given access, and the process of approving and rejecting leaves by founders or manager is out of context. Hence, we at Appsmith came up with an internal app for leave management. It’s minimal and super easy to use. &lt;/p&gt;

&lt;p&gt;Here’s a quick &lt;a href="https://app.appsmith.com/applications/60c900c73535574772b64746/pages/60c900c73535574772b64748?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=leave-management&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=leave-management" rel="noopener noreferrer"&gt;sneak peek&lt;/a&gt; of what the app looks like. This is forkable, customisable and can be shared across organisations and teams. This tutorial will walk you through building this application with Appsmith and its Google Sheet Integration. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.appsmith.com/?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=leave-management&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=leave-management" rel="noopener noreferrer"&gt;Appsmith&lt;/a&gt; is an open-source framework that lets developers build dashboards, workflows, and CRUD apps with only the necessary code. You can connect to any API or databases like MongoDB, PostgreSQL, or MYSQL and get access to multiple widgets, including charts, tables and forms, for building a UI fast.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Following are the table of contents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Getting Started with Appsmith and Gsheets &lt;/li&gt;
&lt;li&gt;Creating and listing all the leaves user has requested&lt;/li&gt;
&lt;li&gt;Building an admin page to accept or reject the leaves&lt;/li&gt;
&lt;li&gt;Listing down all the leaves that are approved and rejected&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's dive in!&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started with Appsmith and Gsheets
&lt;/h3&gt;

&lt;p&gt;In this tutorial, we’ll be using the community edition of Appsmith Cloud to build the application. However, if you want to build this on a local instance and deploy it on your server, you could set up Appsmith’s on-prem version by following through with this documentation &lt;a href="https://docs.appsmith.com/setup/docker?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=leave-management&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=leave-management" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Now let’s follow the below steps to setup Appsmith Cloud and GSheets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Firstly, you will need to create a new account on &lt;a href="//www.app.appsmith.com?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=leave-management&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=leave-management"&gt;Appsmith&lt;/a&gt; (it’s free)! If you’re already an existing user, you can sign in to your account.&lt;/li&gt;
&lt;li&gt;  Create a new application under any organisation by clicking on the &lt;code&gt;Create New&lt;/code&gt; button, and you can rename the application by simply double-clicking on the existing name. In our case, let’s name this as &lt;code&gt;Leave Management Dashboard.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Next, on the left navigation, we should see three options under your Page: Widget’s, APIs and DB Queries. Here, we can connect to data sources and build UI for these data sources using different widgets.&lt;/li&gt;
&lt;li&gt;  Now, let’s create a new API by clicking on the &lt;code&gt;+&lt;/code&gt; button next to the APIs section. Next, choose Google Sheets and select New Datasource.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;The Google Sheets integration on Appsmith helps us use Google Sheets as a backend or data source and perform multiple operations without writing any piece of code. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;  Rename the data source name to &lt;code&gt;Leave Management Data Source&lt;/code&gt; and set the scope to &lt;code&gt;Read and Write&lt;/code&gt;, and hit continue. It will redirect for authorising your Google account, choose the email you want to connect with and authorise it. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Awesome, we now have access to all your google sheets from your Google account. Now let’s create a new Google Sheet and add the necessary fields to build our leave management dashboard. &lt;/p&gt;

&lt;p&gt;Here’s a mock &lt;a href="https://docs.google.com/spreadsheets/d/1sYviKJtnYPAXbshX-lsf_ceyPSHi1O7yq6TJmwXYZOY/edit?usp=sharing" rel="noopener noreferrer"&gt;Google Sheet&lt;/a&gt; that we used to build the application. Feel free to copy the same google sheet to your account and try it out, or you could create a new one instead. &lt;/p&gt;

&lt;p&gt;Following are the Sheets and fields that we used to build the application:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sheet One: Users&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This Sheet has all the information about the company’s employees and their roles. Following are the fields:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;Name
   &lt;/td&gt;
   &lt;td&gt;Email
   &lt;/td&gt;
   &lt;td&gt;Available Leaves
   &lt;/td&gt;
   &lt;td&gt;Leaves Applied
   &lt;/td&gt;
   &lt;td&gt;Total Leaves
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Sheet Two: Leave Requests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This Sheet has information about leave requests requested by the employees and their status if they are approved. Following are the fields:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
   &lt;td&gt;Name
   &lt;/td&gt;
   &lt;td&gt;Start Date
   &lt;/td&gt;
   &lt;td&gt;End Date
   &lt;/td&gt;
   &lt;td&gt;Total Days
   &lt;/td&gt;
   &lt;td&gt;Reason
   &lt;/td&gt;
   &lt;td&gt;Other Contact
   &lt;/td&gt;
   &lt;td&gt;Status
   &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We’ll connect to this particular Google Sheet and build a UI to create and list our leave requests in the next section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating and listing all the leaves user has requested
&lt;/h3&gt;

&lt;p&gt;Firstly, let’s build a Google Sheet API using the GSheet integration Appsmith. To do this, click on the &lt;code&gt;Leave Management Data Source&lt;/code&gt; you’ve created in the previous section and hit &lt;code&gt;NEW API&lt;/code&gt;. We should see the following screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1623943111421%2FyikrPEv4P.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1623943111421%2FyikrPEv4P.png" alt="CleanShot 2021-06-17 at 20.48.03@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow the below steps to list down all our leave requests:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rename the API as &lt;code&gt;getLeavesRequested&lt;/code&gt; and copy-paste the Google Sheets URL you're working on; in this case, we'll be using the duplicated mock-sheet. (Make sure you copy it to your account cause you'll need to authorise it to perform all the operations on it).&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now set the following properties:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sheet Name: Leave Requests
Table Heading Row Index: 1
Query Format: Query Rows
Row Offset: 0
Row limit: 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lastly, hit the Run button on the top right. We should see the data that's inside the **Leave Requests **sheet. Now let's create a new table and display the data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the &lt;code&gt;+&lt;/code&gt; icon next to Widget's, drag and drop a new Table widget onto the canvas. We can configure the Table Widget by opening its property pane by clicking on the cog icon on the top right of the table widget.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now, copy-paste the following JS code snippet into the Table Data property inside the table's property pane:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;span class="nx"&gt;getLeavesRequested&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;appsmith&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;REQUESTED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome! Here, we call the &lt;code&gt;getLeavesRequested&lt;/code&gt; API and use the filter method to filter the object's based on the user_name and the leave status. In my case, the name inside the GSheet is &lt;code&gt;Iron Man&lt;/code&gt;, and I'm matching the same with my username on Appsmith. We can do that by using Appsmit's internal store. Here, &lt;code&gt;appsmith.user.name&lt;/code&gt; returns the user name &lt;code&gt;Iron Man&lt;/code&gt; in my case. Similarly, say your profile name is &lt;code&gt;Bat Man&lt;/code&gt;. Then, you should filter all the leaves that are named after Bat Man in the Google Sheet.&lt;/p&gt;

&lt;p&gt;Now let's add an option to create a new leave request and post it to the GSheets. Follow the below steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Firstly, drag and drop a new button widget on top of the table. Next, open the Button's property pane and set the onClick property to open a Modal. In the dropdown's we'll see an option to create a new Modal directly there; let's choose it.&lt;/li&gt;
&lt;li&gt;  Name the modal as &lt;code&gt;leaveApplyModal&lt;/code&gt;, and its property pane sets the modal type to Form Modal. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now drag and drop the following Widget's on the modal to create a form:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Firstly a &lt;code&gt;text widget&lt;/code&gt; and an &lt;code&gt;input widget&lt;/code&gt; to display the name of who's applying for the leave. We'll add the label to the text widget as &lt;code&gt;Name&lt;/code&gt; and rename the input widget as &lt;code&gt;appliedBy&lt;/code&gt;. Cause we'll be referring to this when we're making an API call to the Google Sheet. Also, set the &lt;code&gt;Default Text&lt;/code&gt; of &lt;code&gt;appliedBy&lt;/code&gt; input widget to &lt;code&gt;{{appsmith.user.name}}&lt;/code&gt; and disable property. So that Users can't create leaves on other's names. Cool right!&lt;/li&gt;
&lt;li&gt;Next, add another text and input widget to add a &lt;code&gt;Leave Note&lt;/code&gt; and rename the input widget to &lt;code&gt;leaveNote&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Now, let's add two more text widgets and date-picker widgets to add the start date and end date. Set the default date's date picker widget to &lt;code&gt;{{moment.now()}}&lt;/code&gt;. This will add today's date as a placeholder to the date picker widget. &lt;/li&gt;
&lt;li&gt;We'll also add one more field that'll show us the number of day's we're applying for leave. We'll set the default value of the input to &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;{{moment(DatePicker2.selectedDate).diff(DatePicker1.selectedDate, "days") +1}}&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lastly, add a select widget that set's the alternate contact. Then, we'll pull the name's of our employees from the Users sheet. For now, let's set the options property to the following:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;span class="nx"&gt;getUserDetails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;label&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our form is now ready; let's create a new API from the Gsheets data source that lets us post values from this form to the Leave Requests Sheet:&lt;/p&gt;

&lt;p&gt;Follow the below steps to list down all our leave requests:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the &lt;code&gt;Leave Management Data Source&lt;/code&gt; and hit &lt;code&gt;NEW API&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Rename the API as &lt;code&gt;requestLeave&lt;/code&gt; and copy-paste the Google Sheets URL you're working on.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now set the following properties:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Method: Insert sheet row
Sheet Name: Leave Requests
Table Heading Row Index: 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following snippet in the Row Object property:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{appliedBy.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Start Date&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{DatePicker1.formattedDate}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;End Date&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{DatePicker2.formattedDate}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Total Days&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{totalDays.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Reason&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{leaveNote.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Other Contact&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{alternateContact.selectedOptionValue}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Status&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;REQUESTED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we're setting the Status of requested leave as &lt;code&gt;REQUESTED&lt;/code&gt;. We'll be changing this to &lt;code&gt;APPROVED&lt;/code&gt; or &lt;code&gt;REJECTED&lt;/code&gt; based on the actions from the leave manager admin page in the following sections. &lt;/p&gt;

&lt;p&gt;Fantastic, now, when we add details on the form and submit it, we should see a new entry on the Gsheet. But we have one problem here, and the leaves on the table are not updated. So, for this, let's create a workflow that submits the data and refreshes the table data when the leave is requested.&lt;/p&gt;

&lt;p&gt;Now open the modal and set the onClick property of the submit button to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;span class="nx"&gt;requestLeave&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;getLeavesRequested&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;closeModal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;leaveApplyModal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;showAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Leave Status updated!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we create a workflow that does the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First, call the &lt;code&gt;requestLeave&lt;/code&gt; API and submit the form.&lt;/li&gt;
&lt;li&gt;Run's the &lt;code&gt;getLeavesRequested&lt;/code&gt; API and updates the data in the Table.&lt;/li&gt;
&lt;li&gt;Closes the &lt;code&gt;leaveApplyModal&lt;/code&gt; Modal&lt;/li&gt;
&lt;li&gt;Finally, it shows an alert saying, "Leave Status updated!"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We'll also create a new API from the Sheets data source &lt;code&gt;getUserDetails&lt;/code&gt; that fetches the names in the Users sheet. For this, just copy the &lt;code&gt;getLeavesRequested&lt;/code&gt; API to the same page and change the Sheet Name to Users. This will get all the User's that are there in our org. &lt;/p&gt;

&lt;h3&gt;
  
  
  Building an admin page to accept or reject the leaves
&lt;/h3&gt;

&lt;p&gt;In the previous section, we created a table and form to create and display all the leave requests. Now let’s build an admin dashboard where we could look at all the leaves requested by the team and accept or reject them. Let’s follow the below steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new Page by clicking on the &lt;code&gt;+&lt;/code&gt; icon next to the pages option in the side navigation.  Name it as &lt;code&gt;Leave Manager Admin&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Now drag and drop a new Table widget onto the canvas. &lt;/li&gt;
&lt;li&gt;Now copy the &lt;code&gt;getLeavesRequested&lt;/code&gt; from &lt;code&gt;Page1&lt;/code&gt; to the &lt;code&gt;Leave Manager Admin&lt;/code&gt; page.&lt;/li&gt;
&lt;li&gt;Now add the following code snippet to the Table Data property:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;span class="nx"&gt;getLeavesRequested&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;REQUESTED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, we should be filtering all the row’s from the Leave Requests sheet that has leave status set to REQUESTED. Now let’s add two buttons that will allow us to update the status to Approved or rejected. Follow the below steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the table’s property pane and click on the &lt;code&gt;ADD A NEW COLUMN&lt;/code&gt; option. This will create a new column in your table. Now set the Column type to Button and set the label as &lt;code&gt;APPROVED&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Similarly, add one more column and set the label to &lt;code&gt;Reject&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To make it more intuitive, add the background colour to the buttons. In my case, I set the background colour of the &lt;code&gt;Approve&lt;/code&gt; button to green and the background colour of the rejected colour to red. &lt;/li&gt;
&lt;li&gt;Awesome, let’s add an onClick property to both these buttons. For this, let’s create two new API’s that will handle the leave status.&lt;/li&gt;
&lt;li&gt;Now, create the new API from the GSheets data source and name it as &lt;code&gt;approveLeaveStatus&lt;/code&gt;; the method will be &lt;code&gt;Update sheet row&lt;/code&gt; as we update the google sheet.&lt;/li&gt;
&lt;li&gt;Set the Sheet Name as &lt;code&gt;Leave Requests&lt;/code&gt; and Table Heading Row Index as &lt;code&gt;1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Lastly, set the Row Object to the following:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rowIndex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{{&lt;/span&gt;&lt;span class="nx"&gt;Table1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectedRow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rowIndex&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Status&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;APPROVED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, create one more API named &lt;code&gt;rejectLeaveStatus&lt;/code&gt; and set the Row Object as following to reject the leave:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;rowIndex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{{&lt;/span&gt;&lt;span class="nx"&gt;Table1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectedRow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rowIndex&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Status&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;REJECTED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s set the Approve to button onClick property to call the &lt;code&gt;approveLeaveStatus&lt;/code&gt; API and the reject button to call the approveLeaveStatus. Additionally, &lt;code&gt;onSubmit&lt;/code&gt;, you can call the &lt;code&gt;getLeavesRequested&lt;/code&gt; API to refresh the Table data. Below is the GIF showing the same:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1623943466077%2FOi4HteKLd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1623943466077%2FOi4HteKLd.gif" alt="CleanShot 2021-06-17 at 08.28.47.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Listing down all the leaves that are approved and rejected
&lt;/h3&gt;

&lt;p&gt;This section will notify the user if the leave he applied for is accepted or rejected. For this, we’ll be using the List Widget and display all the leaves that are approved and rejected. Follow the below steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Now head back to &lt;code&gt;Page1&lt;/code&gt; and drag and drop a new List Widget onto the canvas.&lt;/li&gt;
&lt;li&gt;We already have the &lt;code&gt;getLeavesRequested&lt;/code&gt; API that has all the data of the leaves. So all we need to do is filter them based on the username and the leave status.&lt;/li&gt;
&lt;li&gt;Now, let’s bind this API onto the list widget. First, open theList Widget’s property pane and add the following code snippet under the Items property:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
&lt;span class="nx"&gt;getLeavesRequested&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;appsmith&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;APPROVED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
    &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;REJECTED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, drag and drop a few text widget’s and bind the list widget data using the &lt;code&gt;currentItem&lt;/code&gt; property.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Leave Notes: {{currentItem.Reason}}
Leave Start Date: {{currentItem["Start Date"] }}
Leave End Date: {{currentItem["End Date"] }}
Leave Status: {{currentItem.Status}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, this is how the List widget should look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1623943549279%2FyNbzHTPqa0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1623943549279%2FyNbzHTPqa0.png" alt="CleanShot 2021-06-17 at 08.51.41@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we've added some container's and added some additional information to make the app UI more beautiful. This is how the final look's like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1623943776829%2F4jn_18a6w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1623943776829%2F4jn_18a6w.png" alt="CleanShot 2021-06-17 at 20.59.19@2x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Deploy your application on the cloud and share it with others, and that's it. We're done!&lt;/p&gt;

&lt;p&gt;You've seen how easy it is to build CRUD Apps and Workflows on &lt;a href="https://appsmith.com?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=leave-management&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=leave-management" rel="noopener noreferrer"&gt;Appsmith&lt;/a&gt;. Similarly, we can integrate the number of APIs and data sources and build customised dashboards.&lt;/p&gt;

&lt;p&gt;If you like this tutorial, drop us a star on our GitHub repository &lt;a href="https://github.com/appsmithorg/appsmith?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=leave-management&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=leave-management" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>startup</category>
      <category>googlecloud</category>
    </item>
    <item>
      <title>Build an Investor CRM using Appsmith on Google Sheets</title>
      <dc:creator>Vihar Kurama</dc:creator>
      <pubDate>Tue, 11 May 2021 12:40:04 +0000</pubDate>
      <link>https://dev.to/appsmith/build-an-investor-crm-using-appsmith-on-google-sheets-179e</link>
      <guid>https://dev.to/appsmith/build-an-investor-crm-using-appsmith-on-google-sheets-179e</guid>
      <description>&lt;p&gt;Most founders talk to 10s, if not 100s of investors. Keeping track of the conversations, files shared, and specifics of each investor is hard. Most of the time, we find ourselves rummaging through our inbox for that last email received, the previous file sent or the following action steps. &lt;/p&gt;

&lt;p&gt;Many founders rely on spreadsheets (Google Sheets, usually) to list down the bare minimum of next steps, notion or google docs for the notes, and everything else on email to “streamline” the fundraising process. We know that’s not efficient from our experience, and we thought why not take a leaf out of our sales team and use a CRM to track our investor conversations.  &lt;/p&gt;

&lt;p&gt;So we went ahead and built an investor CRM that we’ve been using for our fundraising. We used Appsmith and the Google Sheets Integration to build this. Feel free to develop or fork this application and extend it to however you want. &lt;/p&gt;

&lt;p&gt;In this tutorial, we’ll build an essential Investor CRM, which will let you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build unique profiles for the fund and investor&lt;/li&gt;
&lt;li&gt;Filter saved investors by fund specifications and interests levels&lt;/li&gt;
&lt;li&gt;Track conversations, see the most recent interaction &lt;/li&gt;
&lt;li&gt;Set deadlines and reminders for action items&lt;/li&gt;
&lt;li&gt;Manage file sharing by keeping track of files shared with each investor &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's a screenshot of how the app looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620720790844%2Fj2m2Rk6v6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620720790844%2Fj2m2Rk6v6.png" alt="Investor CRM.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.appsmith.com/?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=google_sheets_crm&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=google_sheets_crm" rel="noopener noreferrer"&gt;Appsmith&lt;/a&gt; is an open-source framework that lets developers build dashboards, workflows, and CRUD apps with only the necessary code. You can connect to any API or databases like MongoDB, PostgreSQL, or MYSQL and get access to multiple widgets, including charts, tables and forms, for building a UI really fast.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s dive right in!&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting Up Google Sheets and Appsmith
&lt;/h3&gt;

&lt;p&gt;To build this application, we’ll be using Appsmith’s Google Sheet Plugin. This will allow us to use our Google Sheet as a data source and help us build a custom CRM with a beautiful UI on Appsmith. Follow the below steps to integrate Google Sheets with Appsmith:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new account on &lt;a href="https://www.appsmith.com/?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=google_sheets_crm&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=google_sheets_crm" rel="noopener noreferrer"&gt;Appsmith&lt;/a&gt; (it’s free!), if you are already an existing login to your Appsmith account.&lt;/li&gt;
&lt;li&gt;Create a new application by clicking on the “Create New” button under the Appsmith dashboard.&lt;/li&gt;
&lt;li&gt;We’ll now see a new Appsmith app with an empty canvas and a sidebar with Widgets, APIs and DB Queries.&lt;/li&gt;
&lt;li&gt;Click on the &lt;code&gt;+&lt;/code&gt; icon next to the APIs section and choose the &lt;code&gt;Google Sheets&lt;/code&gt; option. Next, click on the &lt;code&gt;New Datasource&lt;/code&gt; button and set the scope to &lt;code&gt;Read and Write&lt;/code&gt; and click Authorise.&lt;/li&gt;
&lt;li&gt;This will ask us to log in from our Google Account, choose the account we want to access Google Sheets with and log in. After successful authorisation, this will redirect back to your Appsmith account. &lt;/li&gt;
&lt;li&gt;Now, you’ll find your Google Sheets Datasource under your APIs, and you can create the necessary queries by choosing this data source.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620721060625%2Fs1gQU3T-y.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620721060625%2Fs1gQU3T-y.gif" alt="Plugin Intro Gif One.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome! Now that our Google Sheets Plugin is set up, let’s create a new Google Sheet and add the necessary fields required for Investor CRM.&lt;/p&gt;

&lt;p&gt;Let’s divide our Google Sheet into two sheets; in the first Sheet named “Investor Details”, let’s add all the information regarding the inventors and their specifics. Following are the fields we’ll be considering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name of Fund&lt;/li&gt;
&lt;li&gt;Name of Investor&lt;/li&gt;
&lt;li&gt;Designation&lt;/li&gt;
&lt;li&gt;Investor interesting portfolio companies&lt;/li&gt;
&lt;li&gt;Interest levels&lt;/li&gt;
&lt;li&gt;Size of fund&lt;/li&gt;
&lt;li&gt;Reference check names &lt;/li&gt;
&lt;li&gt;Reference check details&lt;/li&gt;
&lt;li&gt;Are they interested in us? Or generally, following up?&lt;/li&gt;
&lt;li&gt;Short note to self about the fund and plans we have with the fund.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the second Sheet, “Notes”, let’s add all the notes/conversations related to these investors; we’ll use an identifier named &lt;code&gt;id&lt;/code&gt; to filter our discussions based on the Investors. Additionally, we will also save the links to media/pitch decks that need to be shared with the Investors. Following are the columns we would need in the second Sheet. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Date of conversation&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;li&gt;Pitch deck shared (link/upload)&lt;/li&gt;
&lt;li&gt;Other files shared (summary + links)&lt;/li&gt;
&lt;li&gt;Next steps (Text field)&lt;/li&gt;
&lt;li&gt;Next steps date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make this more precise, we’ve made a sample Google Sheet with some mock data &lt;a href="https://docs.google.com/spreadsheets/d/19ewbxuiNwfD5etHpb__jMzFYjVdYaeLSviC951htlsI/edit#gid=333192" rel="noopener noreferrer"&gt;here&lt;/a&gt;. We’ll be using the same Sheet throughout this tutorial, and you can either follow with this or create your own based on our requirements. &lt;/p&gt;

&lt;p&gt;In the next section, let’s fetch all the investor information and display it on a beautiful table.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fetch Data from Excel Sheet to Appsmith
&lt;/h3&gt;

&lt;p&gt;Now that we are connected to our Google Sheets data source, let’s connect to our Google Sheet and query all the data onto a table widget in Appsmith. To do this, navigate to the created data source under the APIs section and click on the &lt;code&gt;New API&lt;/code&gt; button on the top right. Next, follow the below steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After clicking the &lt;code&gt;New API&lt;/code&gt; button, you’ll be redirected to a new query tab, name your API to &lt;code&gt;getInvestorDetails&lt;/code&gt; by double-clicking on the existing one.&lt;/li&gt;
&lt;li&gt;Now set the method to &lt;code&gt;Fetch Sheets Row&lt;/code&gt;, this method will query the data that’s present in the given Google Sheet.&lt;/li&gt;
&lt;li&gt;In the SpreadSheet URL property, paste the URL of your Google Sheet, in this tutorial we’ll be following with the following URL: &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;https://docs.google.com/spreadsheets/d/19ewbxuiNwfD5etHpb__jMzFYjVdYaeLSviC951htlsI/edit#gid=333192&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next, in the Sheet name, add the name of our first sheet which is &lt;code&gt;Investor Details&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The Table Heading Row Index property takes in the row number that basically has our column heading,  we’ll set this to &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Next, we’ll set the &lt;code&gt;Row Offset&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;Row limit&lt;/code&gt; to &lt;code&gt;100&lt;/code&gt;, this will query only the first 100 rows of our Google Sheet.&lt;/li&gt;
&lt;li&gt;Lastly, click on the &lt;code&gt;Run&lt;/code&gt; button on the top right, we should see the sheet information in JSON format in the response pane at the bottom. Below is the GIF showing the same:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620721373008%2FhF3nHIzau.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620721373008%2FhF3nHIzau.gif" alt="Query Table Gif Two.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome, now that we have our data from the Google Sheet, let’s put this in a table; follow the below steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure the API is saved as &lt;code&gt;getInvestorDetails&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Next, click on the &lt;code&gt;+&lt;/code&gt; icon next to the widgets and drag and drop a table widget onto the canvas.&lt;/li&gt;
&lt;li&gt;Open the Table property pane by clicking on the cog icon on the top right of the table. &lt;/li&gt;
&lt;li&gt;Now under the Table Data property, paste the following code snippet:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{ getInvestorDetails.data }}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Here, we’re using the moustache syntax to bind the data from the API to the table widget. &lt;/li&gt;
&lt;li&gt;With this, we should see the Table data with the investor details from the Google Sheet. Below is a GIF showing the same:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620722275284%2FOCkHum7jn.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620722275284%2FOCkHum7jn.gif" alt="Show Table Gif Three.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect! We now binded our Investor Data into a table widget; you could play with it by opening the table’s property pane and displaying only required values or adding custom columns. Next, let’s add a feature to add new Investor Details to the Google Sheet from Appsmith. &lt;/p&gt;

&lt;h3&gt;
  
  
  Insert new data/rows to Google Sheet from Appsmith
&lt;/h3&gt;

&lt;p&gt;In this section, let’s learn to add a new row from Appsmith UI to Google Sheet. With this, we should be able to add new investor details for our Investor CRM. Let’s start by adding a button and showing a modal that has a form to add all the details of the new investors. Follow the below steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Drag and drop a button widget on to the canvas and next open the property pane of the button by clicking on the cog icon on the top right of the button when selected. &lt;/li&gt;
&lt;li&gt;Open the &lt;code&gt;onClick&lt;/code&gt; property and select the &lt;code&gt;Open  Modal&lt;/code&gt; option and click on &lt;code&gt;New Modal&lt;/code&gt;, this should open a new modal.&lt;/li&gt;
&lt;li&gt;Now add the necessary form fields by dragging the Input widgets onto the Modal. In our case of Investor CRM, we will add the following fields:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Investors
- Company
- Location
- Amount
- Link
- Website
- Round
- Interest Levels
- Notes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Name the input widgets to follow to easily use them for other operations for our CRM. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Investors : &lt;code&gt;addNewInvestors&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Company: &lt;code&gt;addCompany&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Location: &lt;code&gt;addLocation&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Amount: &lt;code&gt;addAmount&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Link: &lt;code&gt;addLink&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Website: &lt;code&gt;addWebsite&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Round: &lt;code&gt;addRound&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Notes: &lt;code&gt;addNotes&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Interest Levels: &lt;code&gt;addInterest&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is a screenshot of how our form should look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620722412238%2FMB6x62p8Y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620722412238%2FMB6x62p8Y.png" alt="Modal Form Add Investor.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have our form ready, let's write the logic to push the values from the form to the Google Sheet whenever submitted. Follow the below steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new API from the existing Google Sheets data source and set the query method to &lt;code&gt;Insert Sheet Row&lt;/code&gt;. This query method helps us insert new data to the Google Sheet from Appsmith.&lt;/li&gt;
&lt;li&gt;Name the query as &lt;code&gt;addNewInvestor&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Next, in the SpreadSheet URL property, add the link to our Google Sheet.&lt;/li&gt;
&lt;li&gt;The Sheet Name will be &lt;code&gt;Investor Details&lt;/code&gt; as named in our Google Sheet.&lt;/li&gt;
&lt;li&gt;The Table Heading Row Index will be the row where the names of the columns are listed; in our case, this will be &lt;code&gt;1&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;Lastly, the Row Object takes a JSON object with keys set to the column names associated with the desired values. In our case, below is how the Row Object should look like:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Company&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{addCompany.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Amount&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{addAmount.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Location&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{addLocation.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Investors&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{addNewInvestors.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{addLink.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Website&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{addWebsite.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Round&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{addRound.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Notes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;{{addNotes.text}}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the key's are the column names in the Google Sheet, and the values associated with them are the names of the input widgets. The &lt;code&gt;.text&lt;/code&gt; method is used to pick the text that's written in the input widgets. &lt;/p&gt;

&lt;p&gt;Lastly, in the form below for the submit button, set the on click property to &lt;code&gt;Call an API&lt;/code&gt; and call the addNewInvestor API from the options. &lt;/p&gt;

&lt;p&gt;Our query is now complete, go ahead and try adding a new Investor Detail from the created UI. We should be able to see the updates on the Google Sheet automatically. Magical, isn't it? In this way, we could add new data using the &lt;code&gt;Insert Sheet Row&lt;/code&gt; query. In the next section, let's see how we can edit existing row data from Appsmith.&lt;/p&gt;

&lt;h3&gt;
  
  
  Displaying and Updating Investor Details
&lt;/h3&gt;

&lt;p&gt;Displaying on the table is cumbersome, hence let’s shrink our table and show all the details in a different container. Additionally, let’s give the functionality to edit the details when displaying them. With Appsmith, all these are pretty straightforward. Now, first, let’s reduce the width of the table and only show the Investor Name and Company, we can do this by opening the property pane and clicking on the eye icon to make the other fields invisible. Next, follow the below steps:&lt;/p&gt;

&lt;p&gt;Drag and drop a container and add necessary input widgets to display the Investor Details. In this case, we’ll be adding the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Investor : &lt;code&gt;investorInput&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Company: &lt;code&gt;companyInput&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Amount: &lt;code&gt;amountInput&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Reference Names: &lt;code&gt;refInput&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Website: &lt;code&gt;websiteInput&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Location: &lt;code&gt;locationInput&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Round Type: &lt;code&gt;roundInput&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Link: &lt;code&gt;linkInput&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Interest Levels: &lt;code&gt;intrestInput&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Short note to self about the fund and plans we have with the fund: &lt;code&gt;notesInput&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is a screenshot of how our app should look like: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620725820052%2FQdxNOckFM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620725820052%2FQdxNOckFM.png" alt="App Screen #2.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we see in the image we have the Investor Table on the left, and the details on the right. Notice an &lt;code&gt;Update Details&lt;/code&gt; button at the end? This button should help us the investor details wherever updated. Now in each of these inputs widgets, let’s use the &lt;code&gt;selectedRow&lt;/code&gt; property from the table and display data.&lt;/p&gt;

&lt;p&gt;Set the following to the Default text of input widgets in the investor details container:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Investor Input Widget: &lt;code&gt;{{ Table1.selectedRow.Investors }}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Company Input Widget: &lt;code&gt;{{ Table1.selectedRow.Company }}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Location Input Widget: &lt;code&gt;{{Table1.selectedRow.Location}}&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similarly, add the default text to the other widgets. Now, when a row is selected in the table you should have all the details of the selected investor in the investor detail container. Below is a screenshot of how it should look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620725721798%2FXQhdRkwUB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620725721798%2FXQhdRkwUB.png" alt="App Screen .png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome! Our CRM is almost ready, but we missed one more thing in here; whenever we made changes in the input widgets and hit update details, the associated investor details should be updated in the Google Sheet. For this, let’s write a new update API that’ll help us update the values in the selected row of the Google Sheet. Follow the below steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new API from the existing Google Sheets data source and set the query method to &lt;code&gt;Update Sheet Row&lt;/code&gt;. This query method helps us update row data in the Google Sheet from Appsmith.&lt;/li&gt;
&lt;li&gt;Name the API to &lt;code&gt;editInvestorDetail&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Next, in the SpreadSheet URL property, add the link to our Google Sheet.&lt;/li&gt;
&lt;li&gt;The Sheet Name will be &lt;code&gt;Investor Details&lt;/code&gt; as named in our Google Sheet.&lt;/li&gt;
&lt;li&gt;The Table Heading Row Index will be the row where the names of the columns are listed; in our case, this will be &lt;code&gt;1&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;Lastly, the Row Object takes a JSON object with keys set to the column names associated with the desired values. In our case, below is how the Row Object should look like:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"rowIndex"&lt;/span&gt;&lt;span class="p"&gt;:{{&lt;/span&gt;&lt;span class="err"&gt;Table&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;.selectedRow.rowIndex&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Company"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"{{companyInput.text}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"{{amountInput.text}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Location"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"{{locationInput.text}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Investors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"{{investorInput.text}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Link"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"{{linkInput.text}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Website"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"{{websiteInput.text}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Round"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"{{roundInput.text}}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Notes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"{{notesInput.text}}"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lastly, for the Update Details button, set the onclick property to Call an API and call the &lt;code&gt;editInvestorDetail&lt;/code&gt; API. We should now be able to update the investor details by editing the necessary input widgets and clicking on the update button. &lt;/p&gt;

&lt;p&gt;Awesome, now we have a fully functional app that allows us to manage all our investor contacts. Now let’s extend this application by adding a new page to save all the conversations, media files related to each investor. &lt;/p&gt;

&lt;h3&gt;
  
  
  Creating new conversations page to save notes and files
&lt;/h3&gt;

&lt;p&gt;A fully functioning CRM should also have all the details of conversations, files with the associated investor. For this, let’s create a new page where we display all the notes and conversations from the Investors. Follow the below steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new page and name it “Investor Conversations”&lt;/li&gt;
&lt;li&gt;On this page, add a query to the URL to show only details of the selected investor. Now to the Appsmith URL, you see on the top add &lt;code&gt;?id=1&lt;/code&gt;. With this, we will filter all the investor details related to row one. &lt;/li&gt;
&lt;li&gt;Now your data source will also be copied to these pages as well, click on the create &lt;code&gt;New API&lt;/code&gt; from the existing data source to fetch the data from the second sheet which is &lt;code&gt;Notes&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Name the API as &lt;code&gt;fetchInvestorDetails&lt;/code&gt;, next add the SpreadSheet URL and  set the sheet name as &lt;code&gt;Investor Details&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set the row offset to &lt;code&gt;{{appsmith.URL.queryParams.id}}&lt;/code&gt;, this will query the row index given from the id param. &lt;/li&gt;
&lt;li&gt;Lastly, set the row limit to &lt;code&gt;1&lt;/code&gt;, if you run the query you should see the details of investor details in the first row of the Google Sheet (as id is hard-coded to 1).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Below is the screenshot showing the same. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620726035475%2FNmMP1K7FX.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1620726035475%2FNmMP1K7FX.png" alt="CRM Fetch Investor Details.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Awesome, let’s add some details regarding the investor to the conversation page before we list down the conversations. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now, on the conversation page, let’s add some Text Widgets to display the details of the Investors. Set the default text property to &lt;code&gt;{{fetchInvestorDetails.data[0].Company}}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;This will display the investor name based on the filtered id from the URL; later, we’ll have to pass this id dynamically from the investor table on the first page. &lt;/li&gt;
&lt;li&gt;Now create one more API that fetches all the conversations from Sheet 2, which is notes.&lt;/li&gt;
&lt;li&gt;Name the API to &lt;code&gt;getConversationDetails&lt;/code&gt;, and set the query method to &lt;code&gt;Fetch Sheets Row&lt;/code&gt; and add the link to Google Sheets URL under the Spreadsheet URL property. &lt;/li&gt;
&lt;li&gt;Next, set the sheet name to &lt;code&gt;Notes&lt;/code&gt;, and this will fetch all the information that’s listed in the Notes Sheet. &lt;/li&gt;
&lt;li&gt;The Table Row Heading Index, Row Offset will be &lt;code&gt;1&lt;/code&gt;, and the Row limit will be 100; you can increase this based on the data on your Google Sheets.&lt;/li&gt;
&lt;li&gt;Run the query. You should see all the notes listed down in the response pane in JSON format.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, drag and drop a table on the Canvas and in the table property pane under the Table Data, paste the following JS code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{getConversationDetails.data.filter((note)=&amp;gt;note.id === appsmith.URL.queryParams.id)}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we’re filtering the notes only based on the query parameter that’s passed in the URL. Remember, we set the id to 1. Hence, we should see the conversations only from the first investor. &lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamically Passing the Query Params and Adding Notes
&lt;/h3&gt;

&lt;p&gt;Now on our conversation page, we’ve hardcoded the id parameter; that’s why we were able to see only notes from the first investor. Now let’s add a new column in the table that’ll redirect to the conversation page of the selected investor. We should pass the ID dynamically based on the rowIndex. Follow the below steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;First, open the table property pane in the Investor Details Page and click on &lt;code&gt;Add A New Column.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Set the Column Type to &lt;code&gt;Button&lt;/code&gt; and Label to &lt;code&gt;View Conversations&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Now when the button is clicked, it should navigate to the conversation page with the particular investor row id as a query parameter&lt;/li&gt;
&lt;li&gt;Now set the onClick property to &lt;code&gt;Navigate to Page&lt;/code&gt;, enter the Page name as &lt;code&gt;Investor Conversations&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Under the page name, you’ll find the Query Parameters property; add the following JS code snippet to pass the id as a query parameter:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;Table1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selectedRow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rowIndex&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome, this will send the &lt;code&gt;id&lt;/code&gt; variable as the query parameter when navigated to the Conversation page, thereby filtering the notes based on the investor. &lt;/p&gt;

&lt;p&gt;Now let’s add a new API that will add new conversations to the investor's details.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firstly, add a new Rich Text Editor to the Investor Conversation page and a button to add these notes to the list. Set the RTE input name to &lt;code&gt;addConversation&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Now create one more API that adds new conversations to Sheet 2, which is notes.&lt;/li&gt;
&lt;li&gt;Name the API to &lt;code&gt;addNote&lt;/code&gt;, and set the query method to &lt;code&gt;Insert Sheets Row&lt;/code&gt; and add the link to Google Sheets URL under the Spreadsheet URL property. &lt;/li&gt;
&lt;li&gt;Next, set the sheet name to &lt;code&gt;Notes&lt;/code&gt;, and Table Heading Row Index to &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;In the Row Object paste the following JS code:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "id":"{{appsmith.URL.queryParams.id}}",
    "Notes": "{{addConversation.text}}",
    "Author": "{{appsmith.user.name}}",
    "rowIndex":"0"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome, this will add new notes to the Notes sheet in the Google Sheet. Also, make sure you call the &lt;code&gt;addNote&lt;/code&gt; API when the “Add Notes” button is clicked. &lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Deploy your application on the cloud and share it with others, and that's it. We're done!&lt;/p&gt;

&lt;p&gt;You've seen how easy it is to build an application on &lt;a href="https://www.appsmith.com/?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=google_sheets_crm&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=google_sheets_crm" rel="noopener noreferrer"&gt;Appsmith&lt;/a&gt;, specifically a CRM with Google Sheets as a backend. This guide covered how to create an Investor CRM and connect it to a Google Sheets, as well as how to create, read, update and delete data. You learned how to build interactive pages, work with widgets, and customize them for your purposes.&lt;/p&gt;

&lt;p&gt;We have made a slightly more robust application public here; try it out and let us know what you think. You can also check the live demo of our app &lt;a href="https://app.appsmith.com/applications/6098bdc65864501cc39c3d2f/pages/6098bdc65864501cc39c3d31?utm_source=blog&amp;amp;utm_medium=direct&amp;amp;utm_content=google_sheets_crm&amp;amp;utm_campaign=weeklyblog&amp;amp;utm_term=google_sheets_crm" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Cover Image Credits: Photo by &lt;a href="https://unsplash.com/@epicantus?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Daria Nepriakhina&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/startups?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>opensource</category>
      <category>codenewbie</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
