Building a Google Cloud Storage (GCS) file explorer app in 30 minutes
Tags: showdev, webdev, programming, opensource
Published: 2022-08-22 12:44:37

> In this tutorial, we will build an internal tool for reading, downloading and uploading files to the buckets in Google Cloud Storage.

#### What is Google Cloud Storage?
Google Cloud Storage (GCS) is the global, secure, and scalable object storage for immutable data such as images, texts, videos, or any other file format. Objects are stored in buckets that are associated with a project, which are grouped under an organization.

#### What you'll need to build the GCS file explorer?
- **ToolJet** (https://github.com/ToolJet/ToolJet): A free and open-source low-code platform that allows you to quickly build applications. You can create a free account on [ToolJet Cloud](https://www.tooljet.com/) or run it on your [local machine](https://docs.tooljet.com/docs/setup/).
- **Google Cloud Storage (GCS)**: JSON private key for the service account required for connecting ToolJet to GCS

**Bonus**: [Download](https://blog.tooljet.com/content/files/2022/08/file_explorer_gcs-export.json) the exported application from here and import it to your ToolJet account to use it straight away.

Here's a glimpse of the application:

![app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jzrp7xey1583l0itgaue.png)

Without further ado, let's start building the application.

---

## Building the UI of GCS file explorer

Let's start with building the UI for Explorer. Login to the ToolJet and then on the **Dashboard**, click on the **Create new application** button to create a new app. Once the app is created, you will be redirected to the visual app editor. You can change the name of the app by editing the default name i.e **Untitled app** from the top left of the app builder.

![new_app](https://blog.tooljet.com/content/images/2021/12/login-1.gif)

**Visual app editor has 4 sections:**

- **Canvas** at the center, where you'll drag and drop widgets to build UI.
- [Query editor](https://docs.tooljet.com/docs/tutorial/building-queries) at the bottom, where you can create queries.
- On the right sidebar, you'll find [Widget Manager](https://docs.tooljet.com/docs/tutorial/adding-widget/) that has a list of built-in widgets and components. You can drag and drop to start building out user interface.
- On the left sidebar, you'll see the Inspector, debugger, comments, settings, and [Datasource manager](https://docs.tooljet.com/docs/tutorial/adding-a-datasource). Datasource manager is used to add a new datasource or manage the connected datasource.

### Let's build the UI

For building the user interface, you’ll need to drag and drop the following components from the Widget Manager(right sidebar) and place them accordingly.

Here is the configuration of widgets that I used for building the UI:

- A **Container** as header and **Text** widget inside the container to give a title to the app i.e **GCS File Explorer**

![header](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-1.41.51-AM.png)

- Another **container** below the header that will contain all the sections of the application. Give this container a background color of your choice from the Styles.

![container](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-1.44.45-AM.png)

- Let's add a **text** widget in the center and set the text to **Please select a bucket** - we will display this text by conditionally disabling the visibility of the container that we will add on top of this text widget.

![select](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-1.50.29-AM.png)

- Let's drag a **container** on top of the text widget, and put list view widget inside the container. You can also use **text** widgets to set columns names- **Name, Updated on, Size, and Actions.**

![drag](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-1.52.35-AM.png)

- In the **List view** widget, use text widget for name, updated on, and size. Use Image widget for the Action. User will click on the **download** image to download the object from the GCS.

![list](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-1.57.29-AM.png)

- Set the following field value for the three text widgets **Name, Updated on, and Size** as `{{listItem.name}}`, `{{moment(listItem).format("DD/MM/YYYY h:mm:ss a")}}`, and `{{(listItem.size/1024).toFixed(2)}}` kb respectively. In the image widget set the loading state value to `{{listItem.id === variables.currentlyLoadingId}}` , and add the event handler to open the webpage `{{queries.urlfordownload.data.url}}`


![event](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.43.05-AM.png)

- Drag a **button** on the right side of the container that will be used to trigger the dialog for **choosing the bucket**.

![button](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-2.00.44-AM.png)

- Drag a **modal** somewhere below the container, go to the button properties and set the **event handler** to **show the modal** that you have added.

![modal](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-2.03.18-AM.png)

- Click on the button to show the modal, and then you can drag and drop **dropdown** and **button** widget inside the modal to build the modal UI. The dropdown will include the list of buckets that we will retrieve from the query, and the button will have an event handler to fire the query for listing the files from the selected bucket.

![dropdown](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-2.05.58-AM.png)

- Let's add **text** widget next to button for showing up the currently selected bucket. Set the text value as `{{components.dropdown1.value}}`

![text](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-2.17.02-AM.png)

- Now, the last section of the UI - the **upload** section. We will build this section inside a container. We will be using **text, divider, text input, file picker and button** widget to build the section. The button widget will include an event handler for firing up the **upload** query that we will create later.

![upload](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-2.20.11-AM.png)

> 💡 Check the [documentation](https://docs.tooljet.com/docs/widgets/text) to learn more about customising the widgets and beautifying the UI. ✨

Now, we are done building the UI - let's move forward with connecting the Google Cloud Storage and build the queries.

---

## Connecting the GCS datasource and creating queries

Before creating the queries let's connect the GCS datasource first:

- Go to the datasource manager on the left sidebar and click on **+** button to **add a new datasource**.
- Search and click on **Google Cloud Storage**.
- Enter and save the **JSON private key for the service account**
- You can click on **Test connection** button to check the connection and then click on **Save** button to save the datasource.
- Now, we are good to go for creating queries.

![save](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-2.26.47-AM.png)

### For this application, we will need to build the queries for:

- JavaScript code for triggering show modal action
- Listing the buckets from GCS
- Listing the object/files from the selected bucket
- Uploading the file to the selected bucket
- Creating signed URL for downloading the file from the bucket

#### JavaScript code for triggering show modal action
- Go to the Query Panel, and click on the **+** button
Create a new **JavaScript code** query and enter the following code for triggering the show modal action:
```js
actions.showModal('modal1')
```

![js](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-2.32.52-AM.png)

- Go to the **Advanced** tab, toggle on the Run query on page load? option, and save the query as **showModalOnPageLoad**. Enabling Run query on page load option will display the modal every time the app is loaded - giving users the flexibility to choose the bucket before moving to other app functions.

#### Listing the buckets from GCS

- Go to the Query Panel, and click on the **+** button to create a new query
- Select **Google Cloud Storage** as the datasource
- In the **operations** dropdown, select the **List buckets** option

![listbuckets](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-2.56.08-AM.png)

- Go to the **Advanced** tab, toggle on the **Run query on page load?** option, and click **Save and Run** button.
- Let's open up the **modal** by clicking on the **change** button, and then edit the properties of the **dropdown** inside the **modal**. Set the Option Values and Option Label as `{{queries.listBuckets.data.buckets}}` , Default value to `{{queries.listBuckets.data.buckets[0]}}`, and Options loading state to `{{queries.listBuckets.isLoading}}`

![option](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.09.32-AM.png)

#### Listing the object/files from the selected bucket

- Go to the Query Panel, and click on the **+** button to create a new query
- Select Google Cloud Storage as the datasource
- In the **operations** dropdown, select the **List files in a bucket** option
- In **Bucket** field, use JS to dynamically get the value from the selected option in the dropdown widget - `{{components.dropdown1.value}}`

![listfiles](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.12.45-AM.png)

- Now, go to **Advanced** tab and add an event handler to **close the modal** once the query is successful.
- Save and run the query as **listFiles**

![save](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.14.42-AM.png)

- Let's open up the **modal** by clicking on the **change** button, and then edit the properties of the button that is inside the modal. Add an **event handler** for running the **listFiles** query for **On Click** event.

![onclick](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.18.04-AM.png)

- Go to the **list view** widget and connect the data returned by the query. Set list data field value to `{{queries.listFiles.data.files}}`

#### Uploading the file to the selected bucket

- Go to the **Query Panel**, and click on the **+** button to create a new query
- Select **Google Cloud Storage** as the datasource
- In the **operations** dropdown, select the **Upload file** option
- In the **Bucket** field enter `{{components.dropdown1.value}}` , **File name** field enter `{{components.textinput1.value}}` , **Content** type field enter `{{components.filepicker1.file[0].type}}` , **Upload data** field enter `{{components.filepicker1.file[0].content}}` , and set **Encoding** to **utf8**

![encoding](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.21.13-AM.png)

- Go to **Advanced** tab and add the **two event handlers**, one to run the **listFiles** query for **On Success** event. This will reload the list of files in the listview widget.

![query1](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.21.51-AM.png)

- And the other **event handler** to **set component specific action** for **file picker** that will **clear the file** from the widget once the query is successful.

![claer](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.22.00-AM.png)

- **Save and run** the query as **upload**.

#### Creating signed URL for downloading the file from the bucket

- Go to the **Query Panel**, and click on the **+** button to create a new query
- Select **Google Cloud Storage** as the datasource
- In the **operations** dropdown, select the **Signed URL for download** option
- In the **Bucket** field enter `{{components.dropdown1.value}}`, and in **File name** field enter `{{queries.listFiles.data.files[components.listview2.selectedRowId].name}}`

![file](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.46.26-AM.png)

- Go to the **Advanced** tab and set an event handler to **unset a variable** - **currentlyLoadingId**

![set](https://blog.tooljet.com/content/images/size/w1600/2022/08/Screenshot-2022-08-22-at-3.46.51-AM.png)

- Save the query as **urlfordownload**
- Go to the **list view** widget and click on its handle to edit its properties.
- Add the two event handlers- one to **set a variable** **currentlyLoadingId** for On row click event and set its value to `{{queries.listFiles.data.files[components.listview2.selectedRowId].id}}`
- And the other handler to run the **urlfordownload** query.
- Now you can click one on row on the list view widget and it will fire up the **urlfordownload** query.

**Awesome! We have successfully built all the queries and connected with the UI.**

---

And now FINALLY just **Release** your application from the top right corner of the app editor.

You have successfully created a **File explorer app for your Google Cloud Storage**. 🎉

---

If you have any queries related to building applications with ToolJet or just want to hangout in the community of low-code application developers the just drop us a Hi in our [Slack Community](https://join.slack.com/t/tooljet/shared_invite/zt-r2neyfcw-KD1COL6t2kgVTlTtAV5rtg). 🚀