# What is Qore?

Qore is a low code platform and you can build system and application easily!

We want to help developers by **creating system and app builders**, so they can work more efficiently and are easier to maintain.

This doc will boost you to understand about Qore building blocks so that you can start create your own app and system.&#x20;

## With Qore you can:

✨ **Manage table data as easily** as using a spreadsheet

✨ **Customize your application** without having to deploy every time there is a change&#x20;

✨ **Create workflows** and connect to Qore system as needed


# Start Exploring

Qore is a low code platform and you can build system/application for a specific purpose.

## Login and start exploring QORE

Start your adventure in Qore :

1. [**Sign in**](https://console.qore.dev/) to Qore and **start creating a** *project*&#x20;

{% hint style="info" %}
**Tips** : If you're new to Qore, you will first be prompted to create a *project in* workspace  to start your journey
{% endhint %}

{% content-ref url="/pages/9ALIYf5gDN6F88YcYwtt" %}
[Broken mention](broken://pages/9ALIYf5gDN6F88YcYwtt)
{% endcontent-ref %}


# Qorebase

Pada segmen kali ini akan dideskripsikan penggunaan Qorebase sebagai fondasi dalam membangun aplikasi pada platform Qore.

Untuk membuat aplikasi pada platform Qore, kita harus membuat database yang akan kita gunakan untuk menampung data-data dalam penggunaan aplikasi nanti. Untuk membuat database pada platform Qore ini terdapat beberapa langkah yang dapat Anda lakukan sebagai berikut.

Pertama, Anda harus membuat tabel yang berisi data yang akan digunakan dalam aplikasi. Tabel yang dibuat pada langkah ini merupakan sebuah tabel entity relational pada database yang digunakan pada umumnya. Anda dapat menambahkan berbagai macam jenis tabel sesuai kebutuhan dalam penggunaan aplikasi.&#x20;

<img src="https://lh4.googleusercontent.com/pp8WnxJ_ENr--mOj15OzKDwqwClZJ-_ntV83mxTwUNeUD0ylFfFT9CM-lrDiTG7VvgVuAR-O2wlEB5jDV2uO1dh6BYdRwgcS4iCzu_0vKxgh8kKT4k6ZVPpHDuUNDmOuR6dYU1fNrgcPHpC0cGW_b-M" alt="" data-size="original">

Selain itu, Anda juga dapat menambahkan data-data yang akan dimasukkan pada aplikasi dengan mengklik tombol Add Row sesuai yang Anda inginkan.

![](/files/pY7DRUjeWM7XklA4qXd3)

Lalu, Anda dapat mengisi data berdasarkan parameter atribut yang telah dibuat. Pastikan data yang anda masukkan sesuai dengan data type yang Anda telah atur di awal.

![](https://lh3.googleusercontent.com/uNowkzYVptjVoP86yQlhKCP8bgV1h5FCCrlNZIDYVe05xSlcODbqM0_OH4RJxljHO-1p7zmpcYFIQyVCBEIEgVk23HILdMgnLU5rZxqW0Ib3-sEEc8Nv5OxeOdnKsAumUEMh-eiI5LwJMaKjo2MuBTw)

Anda juga dapat memfilter data Anda dengan mengklik tombol Add Filter dan mengatur untuk mengkonfigurasi tampilan filter berdasarkan parameter data yang diinginkan

![](https://lh3.googleusercontent.com/7lEe5jWZU_KBKNr26z8vaswI7xpNLKm6ilA_9csgkWYmenZRRLvxpwOdBrHJnycQtxvNge4MyPAcTajJJcfIowzG5xI37lvte2nESYbl_UwTt_FUvYjfczbPS445l-uHT9CTDmZbpCjhv1EryMvnU3E)

Anda dapat mengurutkan tampilan data Anda berdasarkan urutan yang Anda inginkan. Anda dapat mengurutkan tampilan dengan single maupun multiple fields.

![](https://lh5.googleusercontent.com/p1shNCOC2brYhPBT2aTPQ2cp-wl5N1lkOGJtNONeB9pD64NypeJnCbrVOkFKx7TRlzKY1Cr03gWCixdND0WVkmfubP7yHrn5aM2YNStYe9UyqPCThzBAdJGyryr0-vLLifutpE0yn3Puf5TFP0zgpvU)

Pada bagian dashboard atas, Anda dapat melihat beberapa fitur yang dapat Anda manfaatkan dalam pembuatan database ini. Pada menu tersebut terdapat fitur seperti ERD (untuk melihat diagram hubungan antar entitas pada database), dokumentasi API yang digunakan, import data CSV dari eksternal, dan export data dari database tersebut dengan forma file tertentu.

![](https://lh6.googleusercontent.com/JQXGpjvNiDFw6qNRcl4hShxzu6NOLgbfCMI_1Pqq9VsoiF-wUiXuxHJiaX0Mo49qlmOu8lpyT8afo5_A2V3JJzHviiPeSYqibOB5PtBZUY9vLGfMqnY4vAsgCDPQWnx7X4mcoayJWd1XKnWxe5DAR2s)

Pada dashborad tersebut, Anda dapat membuat Entity Relationship Diagram (ERD) secara otomatis berdasarkan tabel data yang telah Anda buat sebelumnya dengan mengklik tombol ERD. Anda dapat melihat secara langsung hubungan antar relasi tabel yang telah Anda buat beserta detail dari atribut dan tipe datanya.

![](https://lh6.googleusercontent.com/Gz0y9VCNvyZ5PUdPQHOnkyfUgCP6PfasyHw60fUwnNgw423sjaWJv8m1rvqzzjX7tocZ7SD70zmdGBZcZXFTj0rspUWyNgXVr_WnsTfEo432taMqxia4EA5L6rxWJAAw0FEaVs_AK9e0ftPEdr05Dz4)

Selain itu, Anda dapat melihat dokumentasi Qore Engine pada menu API Docs. Pada API Docs ini Anda dapat melihat dokumentasi penggunaan API untuk keperluan integrasi maupun kebutuhan lain sesuai yang Anda inginkan.

![](https://lh5.googleusercontent.com/ew0b2CAXoQPoTQgHLz9jgCfqimhP213vGxiNS6LC70vijO9y6dOz05H8XNaNOVJ86pCP9zxeBYM2c8x-NxZyA2u9U_TSNWt3a_JzzweIN9lJNGbTOgoUQUjSvQrXTxufBbuCNGaFK5VF0q72TSGnX9w)

Anda juga dapat mengimpor file data CSV kustom Anda dari repositori lokal Anda berdasarkan tabel tujuan yang telah Anda buat sebelumnya. Untuk melakukan hal ini, Anda harus memastikan bahwa data dalam format CSV yang Anda unggah sudah sesuai dengan atribut dan tipe data yang telah sesuai Anda atur di awal.

![](https://lh6.googleusercontent.com/SLset_ixDVF-fXvJ6uJyTIbFNGZKyP_UnC0aY2kPFVlIRb6EIl_Jvq2MvlQvLvMk2qipNir21_VM_nfEE8s-pgMZ-GYTutxDBgp53k5NFQksKQ8ZmC7aMShjyl_CfqRhZ8D92upOC95SPVknzURe444)

Anda juga dapat mengekspor data tabel secara rinci sebagai format CSV maupun format Excel.

![](https://lh5.googleusercontent.com/CnoYDXG8KV1B9MGXpfQGoLq_vgdC0aydmZjonN7jQnC4RoFJE1d16JhN1DJwSw4mzcfD5mNvdGFklsNo1C1ZCj0Zi0-V6R7AhRGkfJl3PqHQysyP4Me00xtMQ2aFOJSmLho33pQ-UrbVZyZDlYlgguM)


# Table & View

Pada segmen ini akan dijelaskan mengenai penggunaan Table & View dalam Qorebase

Hal pertama yang harus Anda buat dalam membuat aplikasi pada platform Qore adalah dengan membuat tabel database. Untuk melakukan pembuatan database pada Qore ini, terdapat beberapa langkah yang dapat dilakukan sebagai berikut.

Pertama, Anda harus membuat tabel yang berisi data yang akan digunakan dalam aplikasi. Tabel yang dibuat pada langkah ini merupakan sebuah tabel entity relational pada database yang digunakan pada umumnya. Anda dapat menambahkan berbagai macam jenis tabel sesuai kebutuhan dalam penggunaan aplikasi.&#x20;

<img src="https://lh4.googleusercontent.com/pp8WnxJ_ENr--mOj15OzKDwqwClZJ-_ntV83mxTwUNeUD0ylFfFT9CM-lrDiTG7VvgVuAR-O2wlEB5jDV2uO1dh6BYdRwgcS4iCzu_0vKxgh8kKT4k6ZVPpHDuUNDmOuR6dYU1fNrgcPHpC0cGW_b-M" alt="" data-size="original">

Selain itu, Anda juga dapat menambahkan data-data yang akan dimasukkan pada aplikasi dengan mengklik tombol Add Row sesuai yang Anda inginkan.

![](/files/pY7DRUjeWM7XklA4qXd3)


# View Insight

Pada segmen ini akan dijelaskan mengenai view insight dalam Qorebase.

View Insight merupakan fitur yang digunakan untuk melakukan agregasi view yang ada.

Untuk melakukan hal tersebut, dapat dilakukan dengan menekan tombol "+" pada relasi data yang telah dibuat. Lalu akan muncul beberapa opsi seperti Grid View, Insight View, dan Event Trigger.

![](/files/8RuLX5owjNz4jKcDt3ZV)

Tampilan Insight view seperti berikut dengan tiga kolom seperti View Name, Data Type, Aggregates.&#x20;

![](/files/Fm1QO4nf4qTmFDzCyvSJ)

Anda dapat memberika nama View pada kolom view\_name dan mengisi sesuai dengan nama yang diinginkan.

![](/files/V3A6G17YnaollAqwPAVx)

Setelah itu, Anda dapat melakukan penentuan Data Type baik dengan Group By berdasarkan dengan parameter tertentu, maupun dengan Timeseries berdasarkan waktu timeline tertentu.

![](/files/uhIsXy3MhcveqkMJlhaL)

Jika memilih Group By, maka Anda dapat memilih fields yang sesuai Anda inginkan

![](/files/k5OD7yZrm7ZlAjxWV7j7)

Jika Anda memilih Timeserries, maka Anda dapat memilih Filed beserta Interval waktu yang diinginkan.

![](/files/Xtwb6hptfAp2oqi1zUYo)

Lalu, Anda dapat mengisi Aggregates dengan mengisi logic agregasi yang Anda inginkan, seperti Absolute, Average, Ceiling, Count, Day, Duration, dll.

![](/files/daQAoxmDpTJ7ct6Dtqeo)

Jika Anda ingin menambahkan agregasi lain, Anda dapat mengklik tombol Add another aggregate

![](/files/jgV8L1AQ7oL3bXNmZUWF)

Jika sudah, Anda dapat membuatnya dengan menekan tombol Create.

![](/files/CvonHdkyrjhggK8j9vOu)


# Field Types

Pada segmen ini akan dijelaskan tipe data field yang digunakan pada database di Qorebase.

Untuk melakukan konfigurasi mengenai tipe data filed pada database di Qorebase, kita dapat menekan tombol "+" pada bagian kanan atribut yang akan ditambah. Setelah itu, akan muncul beragam tipe data yang dapat Anda pilih sesuai dengan kebutuhan.

![](/files/4eEunTuZp2KWyUX7RbfF)

Tipe data yang tersedia seperti text, integer, float, date, datetime, select, boolean, relation, lookup, rollup, action, file, richtext, SQL, auto, formula, point, polygon, linestring

![](/files/xRYn07Vq1H44Qn1x6E6i)

1. Text

Tipe data pertama adalah text. Dengan tipe data seperti ini, Anda dapat menggunakannya pada data-data yang mengandung teks tanpa adanya unsur lain selain teks.

![](/files/HMDdoPHn7DbcibTl7qnp)

2\. Integer

Tipe data selanjutnya adalah integer. Pada tipe data ini, Anda dapat menambahkan integer atau angka bilangan bulat (seperti 1, 2, 3, dst) pada data yang menggunakan tipe tersebut.

![](/files/iKV05OBNCnl7ElcKQK6w)

3\. Float

Tipe data float dapat Anda gunakan untuk jenis tipe data bilangan tidak bulat atau bilangan real (seperti 1,2 ; 2,7, 3,9)

![](/files/82o5Ce5fp482KdfEnogw)

4\.  Date

Tipe date digunakan untuk jenis tipe data date atau tanggal.

![](/files/cArqVJhHwR4aXczb7JCA)

5\. Datetime

Tipe data datetime digunakan untuk jenis data yang memerlukan date dan time (tanggal dan waktu)

![](/files/wxfPU2iRIQKi7VEcG6C2)

6\. Select

Tipe data select digunakan untuk menyeleksi jenis data tertentu sesuai yang diinginkan

![](/files/Erd6ZpMg2y1L9d9hOcmO)

7\. Boolean

Tipe data boolean digunakanuntuk jenis tipe data logic (True or False)

![](/files/8oPj5lb1nUAN9dncM9UL)

8\. Relation

Tipe data relation digunakan untuk tipe relasi tertentu

![](/files/vRcf4mIiEWbk3n1483Af)

9\. Lookup

Tipe data ini digunkan untuk mencari atau menyeleksi data berdasarkan range dari referensi

![](/files/cEp20kr0YUdYjMCamaqS)

10\. File

Tipe data ini digunakan untuk data berupa file atau berkas tunggal.

![](/files/8KSPocPMMYkKCGwVIypj)

11\. Json

Tipe data ini digunakan untuk data dengan tipe script json

![](/files/rf6ms637fE0HVPZ4sx5x)

12\. Multiple Files

Tipe data ini digunakan untuk data berupa file majemuk atau lebih dari satu berkas

![](/files/BdjRTz638IzAWa0l4ImK)

13\. Rich Text

Tipe data ini digunakan untuk data berupa rich text atau teks dengan format tertentu

![](/files/gfItZftSCarj6vE3F1K3)

14\. SQL

Tipe data ini digunakan untuk data SQL dengan query tertentu

![](/files/hqyJ3gA1RK3alPB3irFE)


# Manage Data (Import & Export)

Pada segmen ini akan dijelaskan mengenai penggunaan pengelolaan data baik melalui mekanisme Import maupun Export pada Qorebase.

Untuk melakukan manage data, Anda dapat memilih Import untuk memasukkan data eksternal dari lokal komputer Anda untuk dimasukkan ke dalam database yang telah Anda buat. Selain itu, Anda juga dapat melakukan Export untuk melakukan ekspor data yang telah ada dalam database untuk dijadikan dalam format tertentu, baik CSV maupun Excel.

Anda dapat mengimpor file data CSV kustom Anda dari repositori lokal Anda berdasarkan tabel tujuan yang telah Anda buat sebelumnya. Untuk melakukan hal ini, Anda harus memastikan bahwa data dalam format CSV yang Anda unggah sudah sesuai dengan atribut dan tipe data yang telah sesuai Anda atur di awal.

![](https://lh6.googleusercontent.com/SLset_ixDVF-fXvJ6uJyTIbFNGZKyP_UnC0aY2kPFVlIRb6EIl_Jvq2MvlQvLvMk2qipNir21_VM_nfEE8s-pgMZ-GYTutxDBgp53k5NFQksKQ8ZmC7aMShjyl_CfqRhZ8D92upOC95SPVknzURe444)

Anda juga dapat mengekspor data tabel secara rinci sebagai format CSV maupun format Excel. Untuk format CSV, Anda hanya dapat mengekspor data dengan format file text dengan tanpa format maupun formula tertentu. Sementara, untuk format excel Anda dapat melihat file dengan pemformatan tertentu.

![](https://lh5.googleusercontent.com/CnoYDXG8KV1B9MGXpfQGoLq_vgdC0aydmZjonN7jQnC4RoFJE1d16JhN1DJwSw4mzcfD5mNvdGFklsNo1C1ZCj0Zi0-V6R7AhRGkfJl3PqHQysyP4Me00xtMQ2aFOJSmLho33pQ-UrbVZyZDlYlgguM)


# Role & Permission

Pada segmen ini akan dijelaskan mengenai Role & Permission pada Qorebase

Role & Permission merupakan fitur pada Qorebase untuk melakukan setting konfigrasi mengenai role tertentu dan permission yang dapat dilakukan dalam mengakses basis data pada Qorebase.

Pada bagian awal, kita dapat mengklik Settings untuk mengatur Role & Permission pada database.

![](/files/IKcAnXgz7UzB77Pp27QR)

Lalu, akan tampil page seperti berikut dengan tampilan user roles seperti Admin, Public, maupun User.

![](/files/J4bdoFoPZwAcUviZvgkY)

Untuk melihat detail roles dan permission yang dapat dilakukan, kita dapat mengklik salah satu roles yang ingin kita lihat detailnya tersebut.

Dapat kita lihat bahwa pada tampilan terlihat Role ID beserta Role Name dari masing-masing role.&#x20;

![](/files/kQ4XzaYw9ngiLvK677V6)

Lalu, kita dapat melakukan konfigurasi mengenai permission yang dpat dilakukan roles tersebut dengan melakukan checklist terhadap aksi permission tertentu (seperti Insight, Select, Update, Delete, dan Insert)

* Select digunakan untuk melihat data yang tersedia
* Update digunakan untuk melakukan update atau pembaharuan terkait data yang tersedia
* Delete digunakan untuk menghapus data yang tersedia
* Insert digunakan untuk menambahkan data pada database yang tersedia

![](/files/fRHc4Xe7LhQT7XSQrGk4)


# Filter & Sort

Pada segmen ini akan dijelaskan mengenai penggunaan Filter & Sort pada penggunaan pembuatan database di Qorebas

1. Filter

Filter merupakan sebuah fitur yang dapat Anda gunakan untuk melakukan filtering data atau penyaringan data berdasarkan parameter tertentu. Anda juga dapat memfilter data Anda dengan mengklik tombol Add Filter dan mengatur untuk mengkonfigurasi tampilan filter berdasarkan parameter data yang diinginkan.

![](https://lh3.googleusercontent.com/7lEe5jWZU_KBKNr26z8vaswI7xpNLKm6ilA_9csgkWYmenZRRLvxpwOdBrHJnycQtxvNge4MyPAcTajJJcfIowzG5xI37lvte2nESYbl_UwTt_FUvYjfczbPS445l-uHT9CTDmZbpCjhv1EryMvnU3E)

Pada bagian awal, Anda dapat memilih logic yang diinginkan, baik Any atau All. Any merupakan logic untuk memastikan bahwa jika salah satu saja dari parameter filtering terpenuhi, maka kondisi tersebut akan dilakukan pemrosesan. Sementara, All merupakan sebuah logic untuk memastikan bahwa harus semua parameter yang ditetapkan untuk proses filtering yang akan ditampilkan.

![](/files/xz34h9TDgrHg3KzWUQjA)

Anda dapat mengatur parameter berdasarkan komponen tertentu. Dalam hal ini, kita dapat mengatur komponen filtering berdasarkan createdat (tanggal pembuatan), update\_at (tanggal modifikasi), role (siapa yang membuat), id (berdasarkan id tertentu), dan Transform to formula (untuk melakukan filtering berdasarkan custom formula tertentu yang akan digunakan).&#x20;

![](/files/PXTE9bhecTfQFf1XGXAn)

![](/files/SgbZybzOAXgqwdLhoJh3)

Selain itu, Anda dapat melakukan conditioning parameter untuk melakukan logic filtering yang akan ditampilkan datanya.&#x20;

1. Equal to (untuk logic yang harus benar-benar sesuai atau equal)
2. Equal either (untuk logic equal yang memenuhi salah satu parameter dari beberapa parameter yang dimasukkan)
3. Contains (untuk logic parameter yang contains atau mengandung parameter yang ditetapkan)
4. Starts with (untuk logic parameter yang diawali dengan parameter yang dimasukkan)
5. Ends with (untuk logic parameter yang diakhiri dengan parameter yang dimasukkan)
6. Is not equal to (untuk logic parameter yang tidak sesuai dengan parameter yang ditetapkan)
7. Is not contains (untuk logic parameter yang tidak mengandung parameter yang ditetapkan)
8. Is not starts with (untuk logic parameter yang tidak diawali dengan parameter yang ditetapkan)
9. Is not ends with (untuk logic parameter yang tidak diakhiri dengan parameter yang ditetapkan)
10. Is empty (untuk logic parameter untuk parameter yang empty atau kosong)
11. Is not empty (untuk logic parameter untuk parameter yang tidak empty atau kosong)

![](/files/AeiP5Dy9GieO0L5ooaNp)

![](/files/3A6rI44ZtCiUYANEW9Sa)

![](/files/yUHTWa9wavmyrBIr2iEi)

Lalu, Anda dapat menambahkan filter tersebut dengan menekan tombol "Add filter"

![](/files/pyJAkMa82V0IQ2G0fUvU)

Anda juga dapat menambahkan kelompok filter berdasarkan kategori tertentu yang Anda inginkan.

![](/files/VxKzRBWV7Vn1RUIUJ6Qp)

Untuk mengaplikasikan filter tersebut, Anda dapat menekan tombol Apply filter

![](/files/C69MrOgBpVdeCT2hBo9b)

2\. Sort

Anda dapat mengurutkan tampilan data Anda berdasarkan urutan yang Anda inginkan. Anda dapat mengurutkan tampilan dengan single maupun multiple fields.

![](https://lh5.googleusercontent.com/p1shNCOC2brYhPBT2aTPQ2cp-wl5N1lkOGJtNONeB9pD64NypeJnCbrVOkFKx7TRlzKY1Cr03gWCixdND0WVkmfubP7yHrn5aM2YNStYe9UyqPCThzBAdJGyryr0-vLLifutpE0yn3Puf5TFP0zgpvU)

Untuk menambahkan parameter sorting, Anda dapat memilih tombol Add sort dan memilih beberapa jenis sorting yang tersedia. Sorting ini terdiri dari External\_id, Created\_at, Updated\_at, Role, Id.

1. External\_id (sorting berdasarkan external id tertentu)

2\. Created\_at (sorting berdasarkan tanggal pembuatan)

3\. Updated\_at (sorting berdasarkan tanggal update atau pembaharuan)

4\. Role (sorting berdasarkan jenis role tertentu)

5\. Id (sorting berdasarkan ID tertentu)

![](/files/vY5zLuy6Ys5RWYdf4RUW)


# Qore App


# Pages

Pada segmen ini akan dijelaskan mengenai Pages dari Qore App

Untuk membuat tampilan dari aplikasi yang akan dikembangkan, Anda dapat melakukan beberapa konfigurasi secara custome pada Pages di Qore App.

Anda dapat membuat aplikasi dengan mengklik tombol "Apps".

![](https://lh5.googleusercontent.com/0RtZfh04qWK0UCj2c7Sf6xMBBJimsnS2ptm35GU5tJ6Obi3wDoqRZJI2FN-vfb2-ITJ3P30ZUTTR9txzjverFG12vI-VjWIgLt45zo_KfzmXrjuLeKI-rk1tA7wnQwZYnXmbpDp6DDccBaS-yr04BUQ)

Anda dapat membuat halaman baru dengan mengklik tombol “Add pages”

![](https://lh4.googleusercontent.com/gFr7FaGJn79Fxxkpe_IQWqE-ykA-dsaPrL40WsS4u04VvAAwhkuKXgoP4-V5_Wb7B96AT3crDE7i8VNxye7SmNqanqctWRYCH9DtbJXMGP71DamQE0MkFXjsizEZ_ICxAo72T9tWWjwqo85d6YnI3ro)

Pada menu Pages, Anda dapat memilih beberapa bentuk seperti Display atau Form.

![](/files/d6j243dZisfh9DgpNZQh)

Tampilan awal dari Display Pages seperti berikut. Pada layout tersebut, Anda dapat menambahkan berbagai macam komponen yang telah tersedia pada Component Library.

![](/files/gqTwEj1ATbalFLblVlRj)


# Settings

Pada segmen ini akan dijelaskan mengenai Settings dari Qore App

Pada bagian Settings, Anda dapat melakukan pengaturan terkait penggunaan Display Page maupun Component Library yang akan digunakan. Dalam settings ini kita dapat melakukan custom setup sesuai yang kita inginkan.

Kita dapat mengatur dari Name untuk mengatur nama, Title untuk mengatur judul page, Data Source untuk mengatur sumber data yang akan digunakan, Row Type, Row ID, dan parameter-parameter lainnya.

![](/files/HsMVIzfn1Iw6dqIPfZhr)


# Component

Pada segmen ini akan dijelaskan mengenai Component dari Qore App

Anda dapat menambahkan jenis komponen apa pun yang Anda sesuaikan dengan memilih di bagian "Library".

![](https://lh5.googleusercontent.com/2-YzGCCFocDMm-CWWbg5ed9uXqpmdRuxvFHROa5orMa62k7ytxuXZA0cAG72xbE5gZ29hP7vNQbwa_jz1-39f_hTzbX-QFPRk3hR3dT26D8m4PI4TpxZzH5x9yjjkaaAKXrLYC-gfzisBeSJyBY0g1c)

Anda dapat menambahkan Teks dan Deskripsi Teks baru di layar

![](https://lh6.googleusercontent.com/gqbwGh6r3sdkQetml5KVjntKpXli1MIgx1Px4Xisc7u_kzuFgJNBrU3l4gvZGwPjRFo_njXQIshGM_X1mi8AS0lZSIAsfbCIhIHgi3R-uLoV7uYIslo_DWPQHksVPQkbJP5Xqtg3AN8dLhR7fIa3hcw)

Anda dapat membuat pemberitahuan petunjuk di halaman dengan mengklik "Hint Text"

![](https://lh4.googleusercontent.com/zAFIuskHBFemNr7OQptGMPWamkj63mBR24ABA1KEY1Gn22kMvzCU2rSMCL_Ha1m_ohFauagFJ8QQamo3cDSkM6V_4xkZbXT2tt1EyE41bk8T7jS_GxRhdvkQHwCCgqYP8wJvvtsyn0EXyUZced01sf0) ![](https://lh3.googleusercontent.com/lTWKlxRw7D2juf5tzJ9oBtMN_yr1sVWV2YM4kOLJsOBzqmSYwJlTALBwXtuw0gKyn16LEL-qEQhAvLuR-9hnParFPTcHlJOrvQIMF3OomBQCyU-zk2ofRIZz6GkLt6cPNnl3gL478Cp-Kn0vR6rtB1c)

Anda dapat menambahkan "Action Text" dan deskripsi dengan mengklik tombol Action Text

![](https://lh6.googleusercontent.com/0ztMamBoFw_lK5Oeo1wHm03-V5Cc3waVQjFK9NfQI5SAi27Drs4KUIxEUPxCWOY_tn1Pte_76YYb6Jb_yHPuSFsCk7oQk68alcDHtn_lSGtWnC_IQ8FRT46x-A1yKD763qD41RwQgQ-b2oV0KoujBtY) ![](https://lh6.googleusercontent.com/hDh0o4Uzhk6PQZBT8QO1_C8wCCXK-jzCnbyFNBZHcI4CxdifYNP4FmOuQHjlcojxTgRyDJBs109EKSINcqcX-tvqbz96uiplVCE2XYUSF0bklQT46nWzEgjB3yD2FsL2vRxq9DxM2T91wC-WXh-zUHE)

Anda dapat menambahkan tampilan peta dengan mengklik tombol Location

![](https://lh5.googleusercontent.com/P1eTx62RGEkV6jwoYYYJrIpgsjp3gZBgk0zJyqFPArDG_C3LmD6VB318hSjZmU0PrS8MVcP9u_zWuGH1l4HxHZguaRS06Di9Q6wzid95T5LzgwjhPgfsl6SYMg6z8yHbIGJwiG9WVMIFe0nuQ0FDhhk) ![](https://lh6.googleusercontent.com/GFVuCkq6bUAUvqbrqYDV7k-M4cuhc4hN7Q-VMf9RMy8fTRHKdMGnXyj5Zr2NBU35yWa42uRsWYcV9mMpV4Wgo8T3b8IvX7tN19kqu6MEE3Hex9Kayoz1p0Cxr8ZgL4qBwNZFDCS5a6hpQWeQXqhNKdM)

Anda dapat menambahkan beberapa gambar pada halaman dengan mengklik tombol “Image”![](https://lh4.googleusercontent.com/F8GcgYMJoXctxoBl48-pieMH0d5rVfGchTAbUWHHXVhI6VgNAhl4UD7b5o8aW8tGPMfAe5Zm6vyM6x-L7fi7782MlCve_rgVYiJQe34lagNncPxVNcDJYuzQna0vZ_ff9B-aH-5Y3P3zZqghgEtI3ic) ![](https://lh4.googleusercontent.com/7hCoOPlb48SEWdsh-Rw6rDkON83wlzk1wba2rB9zPU1AlVIQc26hMQA3oJaLSJ-YJ8m-orikWieFhRCbvXJtX7MtuBjfu_slznRNJXJy7cXVsEapvPStEjeiwy0nDnvfzKvqvwy8KklFWJWKIH1NHZI)

Anda dapat menyematkan tautan video di halaman dengan mengklik tombol "Embed"

![](https://lh4.googleusercontent.com/BR4xvstQ9XEflmWDSWAfbIBP2csElyy87AVKijyInmlT2THbOhwETRyvP98JHJ2MWdhOC7nGzR7Oujx4dKKc-2nPr2QJWvwOFlIAVdZVtGEC5FLAlhqVJXTK2dIHWhsJhz-ZQeku139jUO5Xc5wbjDo) ![](https://lh5.googleusercontent.com/QNMDnlpymWSu-HXkE32k37SaJCXmYq3k_q6sjj7-JFCN43B-HJmYh5GRSHSx_DhhWyfudeYe1JVo2f1EIQeOR-9u0zItsymAQEy3V4AaEErG1ZB30xCvvbNmFCUu6JnLInmZBSxo5FcCEH0TFJVd5Wg)

Anda dapat menambahkan Generator Barcode khusus dan deskripsi dengan mengklik tombol Barcode Generator

![](https://lh3.googleusercontent.com/hy-T8qXTN7i3hwVOOoW-XdlAjgg2nmc3X3VxNC4zGhq_OqxOnD-IW6buKpe7IViCWbTG8-K_2LhghG6YK1OFBbdN9F2nH8dLWV_FD1UdIJuIuRL2XtZBd-sNquARl5AsrQUuygEZ02Ma02I1Yq2Ew5g) ![](https://lh6.googleusercontent.com/twl3vBcYT9z58iINVWeKXstuuBFOKoWI5fBVciWWdPDzDlxEAcjbjeXBFyeou3u3P3TTuyAk5Q4B76odTUwT0MACI4Oky-rXF760H2TKXqqgmZgnBRFGtnLNPAf9v5Ku6pCttmMnq29aUqRKHe2QnuQ)

Anda dapat menambahkan beberapa gambar yang dapat di-swipe dengan mengklik tombol Carousel

![](https://lh3.googleusercontent.com/_y3C-kBenoc_YJyVfdWRjGaPVNdS8CZq5WmIptVhzPHyeJ3fLGKr6Nni1IMYRkSQzJRf8n4r4LC9a9NU9cwYpqAVgTuxXA_Opu0yBGzOHBjvDcxHXtWNZmBwGR6vntwMcrBWb6DlpNARDbFFTKsvfV4)

![](https://lh3.googleusercontent.com/6DKE93kymNNskdpPq87MVb_6n2LhvaeI-ucsYwfKfrW3h8ZyW1lzKXdJf2OrYvCYptC6vorl7dew8CpP4XYadZUAT5ODHh1H1yID80JQgodonvPeCA9zv38lKWD1bRCdf9ESX_fxilJ3qBOH4A5ZYqw)

Anda dapat menambahkan beberapa list secara custom (List, List Card, Horizontal Tile, and Vertical Tile) dengan mengklik pada List button.

![](https://lh6.googleusercontent.com/6mq0IKEpqZzbUKSJkmcf0A0RwT8lRA8Opf3GflkKIsSofQrI4StlgUYijstlzxz1mo9Kb1AZ29d_OBnNURO0BKM5MN5UuMs3Q7vCT_jNhVCO8jg57U6uhwLHAWyALoJMid-iToSTtzrOa61sR4U7mtE) ![](https://lh3.googleusercontent.com/sJIzDfjyAD3dCcdAseZ2x73U0C8Xvx5EaQjrdtN__MbuQxG740UUZCIYcDQOcktHFTqNNwV5LgNIok5FA0mHuJoflFPBUKr35JcMrbLh6NFmsVaheWHN2ATuMGEwQDK9GEcx2eVq7lTezwIC_RcECDo)

Anda dapat menambahkan tombol yang dipersonalisasi (Button, Button Bar, Menu Grid, and Icon Button) dengan mengeklik pada Button section.

![](https://lh3.googleusercontent.com/7OgC-BZp1tQO2hhcxaR-7U9q52QyLKUys44dlJmxYsy80PyCjegddMp6QhN8Ipz8LosWVqCovFYfA1y3s2Gnitt6D1Hnv7-3B5qshegxvsE7hofOBMfpPnXs8Y6Juv_G9SPCGzUfVsZdjlkbI9GoOI4) ![](https://lh3.googleusercontent.com/IyTon2-4AwioO23-1ngFTyHTJzYVEtuTXe1J6_ihRyQuiekKgsldoUxRgugxpPvuGji-ukNIIN9iHAe5IqMZSquvXyKgC6zAjboUUhzW215g7w8-SYrK138BUxWGOQYHzlgw1mT5cpM3LPDNLKkFJsQ)


# Create Workflow

Pipeline is a wonderful tools to automate any of your business needs, from tinkering your csv or excel file, to building your Qore data always in sync with other tools.

After you created the application display, you can configure it’s workflow by clicking on Pipeline button. Hare, you can adjust trigger event and condition on the application.

![](https://lh5.googleusercontent.com/JTixVYzYzm7WC4S31l4gi5sxS7zbWXqK6bIc0Oevvz2QjoR-aBFjCsD9Jr0-G6NOdX7AABeZt1YEIk0hHEJIZZE7qYx8UI5eM8mgao1_1eHGFieVB0_bpEClMrn7m0w2f453Lm9mkUCFNlIFIy4PR9o)

You can simply connect one block to another blocks and insert some parameters on each blocks.

![](https://lh3.googleusercontent.com/P2KVl87RS88Pg2NOSBu-r8OVWUEPT4nLqAfEDhEEEVQkRCTEA7ruutmQizdJc5VlUOPK4Z5k3tMw4_0ladF-vkn7aujy6E227_lzF2vnij1Re5r-IBt8e6t7QQURK0BZUj6DDwpTQD0T_XyDPShDqSM)


# Account Setting

### Rename Account

Follow this step by step to rename your account

1. Go to workspace&#x20;
2. Click profile button on the top-right corner and select edit profile\
   \
   ![](/files/7sWyrrEWzFUhcde9Nwe2)
3. Then on account setting page, click icon pencil \
   ![](/files/GShew7ey00HIjK0kHQJi)
4. After rename we can click button save&#x20;

### Change Password

Step by step to change password

1. Go to workspace&#x20;
2. Click profile button on the top-right corner and select edit profile\
   \
   ![](/files/7sWyrrEWzFUhcde9Nwe2)
3. Then on account setting page, click button change password \
   ![](/files/Ie7ERVjnbzPYe4nPiG4h)
4. And complete this last step, fill your previous password and setup new password\
   ![](/files/hYTyAgKmEVNO3cHe6yX1)


# Manage Project

In Qore you can find the projects you are using in the workspace area.\
Projects will be displayed by team, and each team is possible to have more than one project or depending on the limitations set.

{% hint style="info" %}
**Tips** : Before creating a project, it would be better if you have determined the purpose of your system/application that will help you to design the database and determine the features in the apps.
{% endhint %}

In the workspace page we can sort list of project or search by project name.


# Create New Project

Let's start create system and application by create new project!

Step by step to create new project :\
1\. In the workspace page \
2\. Select a team \
![](/files/IiXtIVQtn8HgN007pitX)\
3\. Then click button create project \
![](/files/M7ob7fvSRlxZpDsAtyOO)\
4\. After success create project it will add new project with default name is Unamed Project 1\
![](/files/p1xng4adAT1ERwbhe4M1)


# Customize Project

Customize the appearance of the project based on the category or theme of your project

### Rename the project&#x20;

Unamed Project is default name after we create new project, but we can rename it by follow this step :

1. Go to workspace page
2. Select the project you want to rename, then hover on the top-left. Until display this icon and click it\
   ![](/files/AsXGVghyICo4Fh3X1s4w)
3. It will display pop up to rename the project\
   ![](/files/sAHWXsPBLQ4Fm5VjT5qv)
4. Save with press enter on keyboard, and the project name will be changed\
   ![](/files/aurs7DQVehaoY1Lc6FBx)

### &#x20;Change color and icon project

We can customize the icons and colors that have been provided based on the mood board or the theme of the project

1. Go to workspace page
2. Select the project you want to customize, then hover on the top-left. Until display this icon and click it\
   ![](/files/AsXGVghyICo4Fh3X1s4w)
3. It will display pop up action for project
4. Then choose the color that you want\
   ![](/files/XZOKmmg7aWLD4f8dWv6X)
5. And click tab icons to change the icon\
   ![](/files/EEjFyPE4boC9XTvHC0TX)


# Delete Project

Be careful before deleting the project because it will delete the application and system that is in it too. Likewise for apps that have been released :(

### Detail project information&#x20;

We can see detail information about the project, before we want to delete it. You can follow this step to see more information&#x20;

1. Go to workspace page
2. Select the project then hover on the top-left. Until display this icon and click it\
   ![](/files/AsXGVghyICo4Fh3X1s4w)
3. Then select menu project detail\
   ![](/files/ubiViokkr5bwzbCJYL0e)
4. And we can see detail information about the project\
   ![](/files/SOMqiJrB5Qifb3ibLum8)

### Delete project

You can delete the project by follow this step by step&#x20;

1. Go to workspace page
2. Select the project then hover on the top-left. Until display this icon and click it\
   ![](/files/AsXGVghyICo4Fh3X1s4w)
3. Then select menu delete, and to confirm our action we need to type project name\
   ![](/files/dYZsYmHkbd4wFJUI9Bf3)![](/files/9Egg0t2Wt8tWha2gGQGr)
4. If successful, the project will be removed from the project team list


# Manage Table

Qore Data Table is where you manage your tables, views, fields, data, and data schema for your database model. Qore Data Table allows you to arrange your information or data, typically in rows and columns, or possibly in a more complex structure.

{% hint style="info" %}
**Hint:** You can manage your table after you [create a new project](/project/manage-project/create-new-project). When you open your project for the first time, there would be a [default table named "User"](/table/manage-table/users-table) which can be use to manage user in your project.
{% endhint %}


# Users Table

Users table is a default table that show right after you create your project

After you successfully [create a new project](/project/manage-project/create-new-project), now it's time to start use your project. When you open the project, by default there would be one table which is "User" table.

![](/files/A7SCDm5iYaaWfIXQiXov)

In this table, you can find 5 default field, which are:

1. external\_id
2. role
3. password
4. created\_at
5. updated\_at

The function of this table is to manage users and its role based on the permission type you want to share.

![](/files/pokjQKke63zMquYg56Ng)

{% hint style="warning" %}
You can't delete Users table otherwise your project will be crashed. You also can't delete external\_id, role, and password field.
{% endhint %}


# Create Table

### How to create new Table:

1. Click on (+) icon\
   ![](/files/XfkufoKk36sqeZARIOwt)
2. Click "Add new table"\
   ![](/files/RqkigW7lgaCIPEtSIrRh)
3. Input your table name, click enter\
   ![](/files/DdBH9xCpMz10yLQbgq3u)
4. Your new table will be created with default field name and description in text field type\
   ![](/files/XBi5lCF4rK1LBpvnWjdb)


# Rename Table

### How to rename your Table:

1. Choose the table you want to rename
2. Click on the triple dot icon\
   ![](/files/szSQnxXXNQHkV0GDqvM1)
3. Click "Rename"\
   ![](/files/a1uSPWgsYnRToSvugsUK)
4. Type your new table name, click enter


# Delete Table

### How to delete your Table:

1. Choose the table you want to delete
2. Click on the triple dot icon\
   ![](/files/szSQnxXXNQHkV0GDqvM1)
3. Click "delete"\
   ![](/files/9j5auzwKhdN6we2MWAtM)
4. Confirm your deletion action\
   ![](/files/Ayvaaol8HgMLC5wNjsba)

{% hint style="warning" %}
**Warning:** You can't undo deleted table or retrieve your deleted data. So before you delete your table, make sure you didn't use the table and you don't have any important data on the table
{% endhint %}


# Manage Row

### Add Row

There are two ways to add row in your table:

1. Click "Add Row" button on top of your table\
   ![](/files/5WBF9VvptlC3ghtV28GY)
2. Click (+) button on bottom of your table\
   ![](/files/oXNrSgSqUR6EPreFfvIX)

### Add Row with Constrain and Validation

If you had field with constrain or validation on your table, then you want to add row on that table, your new row would not save directly. Instead, there would be a highlight and a sign on the row that says your data should meet the validation before it saved to the database.

**Example:**

![](/files/l71511l8kquPAMFWmE4x)

### Delete Row

Steps to delete row on your table:

1. Hover on row you desire to delete, click on triple dot icon\
   ![](/files/MQmWn6kqcokSZ1xBFsFe)
2. Click "Delete this row" option\
   ![](/files/yLrkUwRz0VZbkfzQPX99)

{% hint style="warning" %}
**Warning:** You can't undo deleted row or retrieve your deleted data. So before you delete your row, make sure you didn't use the data.
{% endhint %}

### Delete Multiple Row


# Manage Views

Qore Data Views is a mirror of your data that can be tailored to your unique needs, all while staying connected to the source. Any data you add or remove from a view will take place in the table it was sourced from without disturbing with the source table’s formatting.

Views allow you to view your data how you want it, when you want it, all while keeping your data up-to-date. Qore Data Views allows you to arrange or visualize your information or data in a table in a different way with [modify data table](/table/modify-table) (hide/show field, filter, sort). You can create multiple views of the same table that can look slightly different or substantially different depending on your needs.

{% hint style="info" %}
**Hint:** You can manage your views after you [create new table](/table/manage-table/create-table)
{% endhint %}


# Create Views

There are two ways to create a View

### Create new views from Table:

1. 'Save Click on (+) icon on your table\
   ![](/files/Lz5xg416BcEpdr2srfhK)
2. Choose "Grid" option\
   ![](/files/ADosTJMgzQtp6zZR3YEN)
3. Type your view name, click enter\
   ![](/files/whsDGX1xtsfCJhWWbZgz)
4. Your new view will be created

### Save modified Table as new View:

1. [Modify your table](/table/modify-table) based on what you need. You can use [sort](/table/modify-table/sort), [filter](/table/modify-table/filter), or [hide/show field](/table/modify-table/hide-and-show-field) feature
2. Click "Save to new view" button\ <mark style="background-color:red;">\[screenshot]</mark>
3. Type your view name, click enter\ <mark style="background-color:red;">\[screenshot]</mark>
4. Your new view will be created


# Rename Views

### How to rename your View:

1. Click on the triple dot icon on your View\
   ![](/files/tItay6aLKCXvhIqkbxmD)
2. Click "Rename"\
   ![](/files/DFoHlK0FqgQyCUnESzz3)
3. Type your new table name, click enter


# Delete View

### How to delete your View:

1. Click on the triple dot icon on your View\
   ![](/files/tItay6aLKCXvhIqkbxmD)
2. Click "delete"\
   ![](/files/QXfr5eqddZVHyimyJzFq)
3. Confirm your deletion action\
   ![](/files/ZPqB3VdxpTm6QkzuJ4SN)

{% hint style="warning" %}
**Info:** Your data won't be deleted even if you delete your view as long **as you didn't delete your source Table**
{% endhint %}


# Manage Field

Qore Data Field is where you manage your data, data type, and data schema for your database model. Qore Data Field allows you to store your information or data based on data type you have.

{% hint style="info" %}
**Hint:** You can manage your field after you [create a table](/table/manage-table/create-table).
{% endhint %}


# Create Field

### How to create new Field:

1. Click on (+) icon on field row\
   ![](/files/iADjzyd0XPQr192LoUjO)
2. Fill field name\
   ![](/files/Go2tjvzsBi58iiV20CG4)
3. Choose field type you want to use\
   ![](/files/4XEs67UhoctIN65lbpdh)
4. Fill the mandatory details on that field and other settings you want to use
5. Click "create"\
   ![](/files/gkzB8WJvzQr7T6pkS55s)

{% hint style="info" %}
**Notes:** Every [field type](/table/field-type) has different mandatory and optional settings based on which field type you use
{% endhint %}


# Update Field

### How to update Field:

1. Click on field you want to update
2. Click "Update"
3. Edit settings you want to change
4. Click "Update"


# Delete Field

### How to delete your Field:

1. Click arrow icon on your field
2. Click "delete"

{% hint style="warning" %}
**Warning:** You can't undo deleted field or retrieve your deleted data. So before you delete your field, make sure you didn't use the field and you don't have any important data on that field
{% endhint %}


# Field Type

## Text

The TEXT field type stores any kind of text data. The length string (can contain letters, numbers, and special characters).

Settings you can set on Text field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. Unique setting
4. Value for new rows

## Integer

The INTEGER field type store a whole number, positive or negative.

Settings you can set on Integer field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. Value for new rows

## Float

The FLOAT field type store floating point number, is a positive or negative whole number with a decimal point.

Settings you can set on Float field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. Precision <mark style="color:red;">(mandatory must be between 1 and 1000)</mark>
4. Scale
5. Value for new rows

## Date

The DATE field type store date and time combination data. A point in time that consist of a date and a time component.

Settings you can set on Date field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. Date format

## Boolean

True or False

Settings you can set on Boolean field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. Value for new rows

## Select

The SELECT field type allows you to create a list of selectable text values. Select lists allow you and your collaborators to adhere to specific naming or labeling so everything stays organized in your tables. You can add as many options as you want and see them clearly in a dropdown list.

Settings you can set on Select field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. Select settings <mark style="color:red;">(mandatory)</mark>
4. Value for new rows

## Relation

The RELATION field type allows you to set a relationship from table A to table B. However, a proper relationship column would be one that automatically creates a column in the referenced table that holds all references to a row in that table. Relation field allows you to create fields where you select relation to an item in other table

A relationship field is a custom field on an object record that contains a link to another record. When we place a relationship custom field on an object, we are effectively creating a many-to-one relationship between the object on which the relationship field is placed.

Settings you can set on Relation field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. Relations <mark style="color:red;">(mandatory)</mark>

## Lookup

A LOOKUP field is a field in a table whose value is retrieved from another table. You must add a relation column first to be able to retrieve data from the destination table according to the settings in the relation column.

Settings you can set on Lookup field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. Lookup settings

## Rollup

A ROLLUP field contains an aggregate value computed over the records related to a specified recor&#x64;**.** Aggregate operations that we provide in this field type ar&#x65;**:**

1. SUM
2. MIN
3. MAX
4. AVERAGE
5. COUNT

Settings you can set on Rollup field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. Rollup settings
4. Condition

## File

FILE fields utilize the built-in file browser to store uploaded files and images. The file’s extensions that we provide for this field are:

1. JPG
2. PNG
3. SVG

Settings you can set on File field:

1. Field name <mark style="color:red;">(mandatory)</mark>
2. Description
3. File extensions

## Json

## Password

PASSWORD field type only available in users table by default right after you create a project. This field is a default field so you can't update or delete this field.


# Modify Table

Modify data table in Qore is used to re-arrange your data table based on what you need. There are three feature for modify data table in Qore

1. [Sort](/table/modify-table/sort)
2. [Filter](/table/modify-table/filter)
3. [Hide and Show Field](/table/modify-table/hide-and-show-field)

{% hint style="info" %}
**Tip:** You can [save your modified Table as a view](/table/manage-views/create-views#save-modified-table-as-new-view)
{% endhint %}


# Sort

Sort is used to **describe the process of organizing data in a particular order allowing for information to be found easier**. For example, names and contact information may be sorted in alphabetical order to allow the person looking for a name to see if it's available.

How to use Sort feature:

1. Open table you want to sort
2. Click on "Sort" button\
   ![](/files/6GBUlPG3F1zbYF7fd5yW)
3. Click "Add Sort"\
   ![](/files/yDk251kaOOGLrAQa7hb0)
4. Input attribute you want to use to sort your data
5. Make sure to activate the toggle\
   ![](/files/C3OHQwUqq2BaJq4XewPi)
6. If you set up more than one attribute, you can re-arrange prioritization of your attribute by drag and drop the attribute\
   ![](/files/He4rIx6MKzVNTE0H32XU)


# Filter

The Qore FILTER function **filters a range of data based on supplied criteria, and extracts matching records**. In plain language, the FILTER function will extract matching records from a set of data by applying one or more attribute.

### There are two types of logic in Qore FILTER:

1. **Any**\
   The data only displayed at least one of the filter attribute. That means, if you set filter for more than one attribute, your data will displayed at least one that contains one of the attribute.
2. **All**\
   The data displayed all the data that meets all the filter attribute. That means, if you set filter for more that one attribute, your data will filtered based on all the attributes.

![](/files/ivc6On3zpoa3cQvI8i3v)

### How to use Filter feature:

1. Open table you want to filter
2. Click on "Filter" button
3. Click "Add Filter"\
   ![](/files/0NGwj7fvzl45To4aTYKJ)
4. Input attribute you want to use to filter your data\
   ![](/files/NpvQiVkZJTC6I38SWBHL)
5. You can use group filter for grouping your filter logic

{% hint style="info" %}
**Filter group** helps you with multiple filter logic on multiple attribute. There are 2 logic you can use on filter group, **AND** and **OR**
{% endhint %}

### Delete Filter

To delete your filter, you can just simply click on the trashcan icon.

![](/files/uLYWFLEA5faIQdh9TziM)


# Dynamic Filter

**What is dynamic filter?**

Dynamic filter is a type of filter that allows you to quickly narrow down the data displayed to only those data you looking for.

In Qore Base, you can filter your data without create new view everytime you change your filter by using dynamic filtering or **parameter**

### How to use Dynamic Filter feature:

1. Create new view\ <img src="https://lh4.googleusercontent.com/9ZABfb8rE0KxlsvDGLlnKUdLN6K_GfD_i3C9ajX_i-aeJd5TPLssLkKG-Ely2fJ2gaDtRInDuVarwIxtIfSxX1bLiIHVZuISacIxHoCXAnmGwZ8vTJI9SJ3FKBUkNb6MzhIkDbMGSxIC" alt="" data-size="original">
2. Add parameter & syntax parameter\
   ![](/files/S0zcXmlDS6Yzg7D46guE)\
   \
   ![](https://lh4.googleusercontent.com/xmA0KCLV06-PBujCSVyASQEPXaA4ky-DoJyhaArn1qVgqgfXrlqHQHxXA-1Xcuf0snpMWHeNmlcTA1hg3UD5GkMjd51CUcCdFa_HgpOWgRz6t2myvbefCR0cRvIid34mHPnGMmsdO1ra)
3. Create filter to connect with parameter\
   ![](/files/D1x2UJYfhCHknIOy3fX4)

   a. Click Add Filter

   b. Choose field you want to filter

   c. Choose operation “contains” or "equal to"

   d. Input syntax parameter with {{}}
4. Save your changes\
   ![](/files/WEyeZzPtWtiSF7vvRBXb)
5. Result: input your values\
   ![](/files/uRtqXtPdH8MdT60en6M2)\
   \
   ![](/files/pYtXigsczwhAxncftWeq)


# Hide and Show Field

Hide and show field is one of the feature for modify table where you can manage which field you want to show as a view and which table you want to hide as a view.

There is an exception in Users table. In Users table, you can't hide external\_id, role, and password field.

How to use Hide/Show Field feature:

1. Click on "Shown Field" button\ <img src="/files/UVOHMFWkfU09XP6TERdO" alt="" data-size="original">
2. Click on the fields you want to hide or show\
   ![](/files/np2sBixRUwBminfHPUJ6)
3. Field with checked mark on it means the field will be shown, meanwhile field that has no checked mark on it means the field will be hidden


# Text

Komponen yang termasuk ke dalam kategori ini berfokus untuk menampilkan data text yang bervariasi. Kamu dapat menggunakan component ini untuk menampilkan title, header, label, atau paragraf.

Terdapat 6 kategori text yang dapat dipilih yakni&#x20;

1. [Component Text ](/component/text/text)
2. Component Description Text
3. Component Rich Text
4. Component Hint
5. Component Action Text
6. Component Paragraph


# Text

Komponen ini bertujuan untuk menampilkan simple text, namun dapat divariasikan sebagai header ataupun judul dari sebuah konten.

### Cara menambahkan *text component*

Berikut langkah-langkah untuk menambahkan *text component*

1. Buka Qore App Editor&#x20;
2. Pada tab library, di section text pilih *text component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

   * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
   * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

   <figure><img src="/files/a9M1nGJFemBYTCQNNOxv" alt=""><figcaption></figcaption></figure>
3. Jika berhasil maka *text component* akan muncul di *emulator editor screen* seperti berikut <br>

   <figure><img src="/files/tDVKzpblgyQNViAsL4nS" alt=""><figcaption><p>Tampilan component text di emulator screen </p></figcaption></figure>

Properties *text component*

* **Label** : *properties* ini menentukan text yang akan muncul di aplikasi
* **Font Size** : *properties* ini menyediakan pilihan ukuran text&#x20;
* **Font Weight** : *properties* ini menyediakan pilihan ketebalan text
* **Font Style** : *properties* ini dapat memberikan formatting text seperti huruf miring, garis bawah, dan text tercoret
* **Alignment** : *properties* ini mengatur perataan text di aplikasi apakah rata kiri, rata tengah, rata kanan
* **Letter Case** : *properties* ini memungkinkan editor untuk mengubah huruf kecil atau huruf besar dengan cepat&#x20;
* **Font Color** : *properties* ini mengatur pewarnaan huruf

Berikut adalah contoh modifikasi *properties* untuk text *component*

<figure><img src="/files/w07agZrgRVmDF9jNqCH1" alt=""><figcaption></figcaption></figure>


# Description Text

Komponen ini bertujuan untuk menampilkan text dengan deskripsi singkat.

### Cara menambahkan *description text component*&#x20;

Berikut langkah-langkah untuk menambahkan *description* *text component*

* Buka Qore App Editor&#x20;
* Pada tab library, di section text pilih *description text component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;
  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan<br>

    <figure><img src="/files/daCPmOX8k1y6Iu9hotk6" alt=""><figcaption></figcaption></figure>
* Jika berhasil maka description *text component* akan muncul di *emulator editor screen* seperti berikut <br>

  <figure><img src="/files/emwhfagbJqZMbzfALr2v" alt=""><figcaption></figcaption></figure>

### Properties *description text component*

Description text component memiliki 2 bagian yakni title dan description. Setiap bagian memiliki properties sendiri - sendiri.

#### Title

* **Title** : *properties* ini menentukan text untuk title yang akan muncul di aplikasi
* **Weight :** *properties* ini menyediakan pilihan ketebalan text
* **Color :**  *properties* ini mengatur pewarnaan huruf

#### Description

* **Style :** *properties* ini untuk mengatur style description text, terdapat 2 pilihan yakni text dan label. Jika editor mmeilih style label maka akan terdapat setting tambahan yakni editor dapat menambahkan warna background description text&#x20;
* **Label :** *properties* ini menentukan text yang akan muncul di aplikasi
* **Weight :** *properties* ini menyediakan pilihan ketebalan text
* **Font Color :**  *properties* ini mengatur pewarnaan huruf
* **Label Color :**  *properties* ini mengatur pewarnaan label background

Berikut adalah contoh modifikasi *properties* untuk description text *component*

<figure><img src="/files/CxvPjcfFW9A7oo5vFXYy" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/9StjfyohHDEXpbNRBW5c" alt=""><figcaption></figcaption></figure>


# Rich Text

Komponen ini bertujuan untuk menampilkan text dengan multiline text ataupun deskripsi tanpa format text.

### Cara menambahkan *rich text component*&#x20;

Berikut langkah-langkah untuk menambahkan *rich* *text component*

* Buka Qore App Editor&#x20;
* Pada tab library, di section text pilih *rich text component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;
  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan<br>

    <figure><img src="/files/0UuV1dRIZOwGMvFpV5jV" alt=""><figcaption></figcaption></figure>

    &#x20;Jika berhasil maka description *text component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/NCUY8XlQ5FWwBIn5ybeL" alt=""><figcaption></figcaption></figure>

### Properties *rich text component*

Rich text component memiliki 3 properties yang dapat diatur yakni&#x20;

* **Text** : *properties* ini menentukan text yang akan muncul di aplikasi
* **Alignment  :***properties* ini mengatur perataan text di aplikasi apakah rata kiri, rata tengah, rata kanan
* **Limit text :**  *properties* ini mengatur apakah text tersebut dapat ditampilkan sebagian atau langsung ditampilkan secara keseluruhan. \
  \
  Jika setting limit text diaktifkan maka text akan ditampilkan sebagian dan terdapat button untuk mengakses keseluruhan text <br>

  <figure><img src="/files/Z3wwFrJTrva1eXj0KvQP" alt=""><figcaption><p>Component Rich Text dengan setting limit text yang diaktifkan</p></figcaption></figure>


# Hint Text

Komponen ini bertujuan untuk menampilkan informasi berupa teks petunjuk.

### Cara menambahkan *hint text component*&#x20;

Berikut langkah-langkah untuk menambahkan *hint* *text component*

* Buka Qore App Editor&#x20;
* Pada tab library, di section text pilih *hint text component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;
  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan<br>

    <figure><img src="/files/ZZ2aLreIfUEqsRD8RO3u" alt=""><figcaption></figcaption></figure>
* Jika berhasil maka hint *text component* akan muncul di *emulator editor screen* seperti berikut <br>

  <figure><img src="/files/IQlfO1NuJr93RX5REwwl" alt=""><figcaption></figcaption></figure>

### Properties *hint text component*

Hint text component memiliki properties yang dapat diatur oleh editor yakni&#x20;

* **Status** : *properties* ini menentukan status dari petunjuk apakah sebagai info, error , sukses atau warning. Status yang dipilih nantinya akan mempengaruhi layout dari hint component
* **Title  :** *properties* ini mengatur text yang akan dijadikan sebagai judul dari petunjuk tersebut
* **Description** : *properties* ini mengatur penjelasan tambahan dari petunjuk yang akan disampaikan ke user
* **Letter case :**  *properties* ini memungkinkan editor untuk mengubah huruf kecil atau huruf besar dengan cepat&#x20;
* **Close action :** jika properties ini diaktifkan maka petunjuk tersebut bersifat sementara, dan user tidak diharuskan untuk memenuhi suatu hal dari petunjuk tersebut\ <br>

  <figure><img src="/files/kPDbat9BViWagk4PsGkC" alt=""><figcaption><p>Tampilan hint text component dengan properties close action yang aktif</p></figcaption></figure>


# Paragraph Text


# Media

Komponen yang masuk ke kategori media berfokus untuk menampilkan gambar, video, hingga code dalam bentuk bar maupun QR.

Terdapat 6 kategori media yang dapat dipilih, yakni :

1. Headline
2. Image
3. Embed
4. QR Code Generator
5. Barcode Generator
6. Carousel


# Headline

Cara menambahkan Headline component

Berikut langkah-langkah untuk menambahkan headline *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section media pilih headline *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/awCfVzNQCCfjhRBfJQIl" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka headline *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/nkne4mDol7i2uQ6X9s2i" alt=""><figcaption></figcaption></figure>

Properties dari headline component adalah&#x20;

Design :

* Source : sumber gambar dari headline, dapat berupa link gambar ataupun baris dalam qore data
* Style : mengubah gaya headline, apakah gambar ditampilkan secara penuh atau dalam bentuk profile
* Title : sebagai judul headline
* Description : menunjukkan keterangan atau deskripsi singkat dari headline

Berikut contoh headline yang telah dimodifikasi

<figure><img src="/files/ZHhCTGJaFS3iLZsdzSut" alt=""><figcaption></figcaption></figure>


# Image

Cara menambahkan Image component

Berikut langkah-langkah untuk menambahkan image *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section media pilih image *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/Yqm0JitAUk9mpg7Gj6df" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka image *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/lHUiUSfPLItNRnNySmXu" alt=""><figcaption></figcaption></figure>

Properties dari image component adalah&#x20;

Source :

* All Device : jika gambar ingin ditampilkan di semua tipe device dengan sumber gambar yang sama, maka aktifkan toggle
* Source : sumber gambar, dapat berupa link gambar ataupun baris dalam qore data

Design

* Preview : jika toggle diaktifkan, maka pengguna dapat mengetuk gambar untuk melihat gambar dalam layar penuh

Phone :

* Source : sumber gambar yang ditampilkan jika device adalah phone, dapat berupa link gambar ataupun baris dalam qore data
* Ratio : ratio ukuran gambar yang ditampilkan jika device adalah phone, dapat berupa 1:1, 16:9, 4:3, ataupun 3:1
* Fit image : mengatur tampilan image pada device phone, apakah fill ataupun fit&#x20;

Tablet :

* Source : sumber gambar yang ditampilkan jika device adalah tablet, dapat berupa link gambar ataupun baris dalam qore data
* Ratio : ratio ukuran gambar yang ditampilkan jika device adalah tablet, dapat berupa 1:1, 16:9, 4:3, ataupun 3:1
* Fit image : mengatur tampilan image pada device tablet, apakah fill ataupun fit

Dekstop :

* Source : sumber gambar yang ditampilkan jika device adalah dekstop, dapat berupa link gambar ataupun baris dalam qore data
* Ratio : ratio ukuran gambar yang ditampilkan jika device adalah dekstop, dapat berupa 1:1, 16:9, 4:3, ataupun 3:1
* Fit image : mengatur tampilan image pada device dekstop, apakah fill ataupun fit

Berikut contoh image yang telah dimodifikasi

<figure><img src="/files/29xdh2yTmKaB8IAtGrd0" alt=""><figcaption></figcaption></figure>


# Embed

Cara menambahkan Embed component

Berikut langkah-langkah untuk menambahkan embed *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section media pilih embed *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/d9khDUs3iLqmZ2wNqsJu" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka embed *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/Kv9wseG31ydhOxaIkHkA" alt=""><figcaption></figcaption></figure>

Properties dari embed component adalah&#x20;

Design :&#x20;

* Embed : link dari video yang akan di-embed
* Ratio : ratio dari tampilan video, apakah square, 16:9, 4:3, 2:1

Berikut contoh embed yang telah dimodifikasi

<figure><img src="/files/bmQPfF08TFtA7gH1yr48" alt=""><figcaption></figcaption></figure>


# QR Code Generator

Cara menambahkan QR Code Generator component

Berikut langkah-langkah untuk menambahkan qr code generator *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section media pilih qr code generator *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/keYMX4HLwBRAK9HeazfE" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka qr code generator *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/TVv8WPYxszfcfXvxaxvZ" alt=""><figcaption></figcaption></figure>

Properties dari qr code generator component adalah&#x20;

Data :

* Source : tabel pada qore data yang digunakan sebagai sumber data
* Default row : baris data yang akan diretrieve dari tabel, apakah defaultnya adalah baris pertama, atau juga dapat menggunakan id baris

Design :&#x20;

* Title : judul dari QR code&#x20;
* Description : keterangan atau deskripsi singkat dari qr code
* Code : code yang akan digunakan untuk menggenerate qr code
* Display code : Jika toggle diaktifkan maka di bawah qr code akan ditampilkan code dari qr code
* Style : mengatur style tampilan qr code, apakah ghost (tanpa background) ataupun solid (menggunakan background)

Berikut contoh qr code generator yang telah dimodifikasi

<figure><img src="/files/2nxNwxtofeHTO4clqzAi" alt=""><figcaption></figcaption></figure>


# Barcode Generator

Cara menambahkan Barcode Generator component

Berikut langkah-langkah untuk menambahkan barcode generator *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section media pilih barcode generator *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/hrpYJuvDHFu8INhgPWum" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka barcode generator *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/HaaIcF3s975Gzk4MNl3Y" alt=""><figcaption></figcaption></figure>

Properties dari barcode generator component adalah&#x20;

Data :

* Source : tabel pada qore data yang digunakan sebagai sumber data
* Default row : baris data yang akan diretrieve dari tabel, apakah defaultnya adalah baris pertama, atau juga dapat menggunakan id baris

Design :&#x20;

* Title : judul dari QR code&#x20;
* Description : keterangan atau deskripsi singkat dari qr code
* Code : code yang akan digunakan untuk menggenerate qr code
* Display code : Jika toggle diaktifkan maka di bawah qr code akan ditampilkan code dari qr code
* Style : mengatur style tampilan qr code, apakah ghost (tanpa background) ataupun solid (menggunakan background)
* Format : format tampilan dari barcode, apakah code 39 atau code 128

Berikut contoh barcode generator yang telah dimodifikasi

<figure><img src="/files/zJQ5TjZSheayyzrkDNGV" alt=""><figcaption></figcaption></figure>


# Carousel

Cara menambahkan Carousel component

Berikut langkah-langkah untuk menambahkan carousel *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section media pilih carousel *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/BNUJmd0XPIJpsop25Udq" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka carousel *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/ZIPzjvFfugRlOWxAYibz" alt=""><figcaption></figcaption></figure>

Properties dari carousel component adalah&#x20;

Data :

* Source : tabel pada qore data yang digunakan sebagai sumber data

Design :&#x20;

* Style : mengatur tampilan carousel, apakah full atau menggunakan frame
* Round corner : mengatur tampilan carousel, apakah sudut-sudutnya rounded
* Autoplay : mengatur animasi carousel, apakah sliding gambar dimainkan secara otomatis

All Device :

* All Device : jika gambar ingin ditampilkan di semua tipe device dengan sumber gambar yang sama, maka aktifkan toggle
* Images : sumber gambar, berupa baris data pada tabel qore data

Phone :

* Images : sumber gambar yang ditampilkan jika device adalah phone, berupa baris dalam tabel qore data
* Ratio : ratio ukuran gambar yang ditampilkan jika device adalah phone, dapat berupa 1:1, 16:9, 4:3, ataupun 3:1
* Fit image : mengatur tampilan image pada device phone, apakah fill ataupun fit&#x20;

Tablet :

* Images : sumber gambar yang ditampilkan jika device adalah tablet, berupa baris dalam tabel qore data
* Ratio : ratio ukuran gambar yang ditampilkan jika device adalah tablet, dapat berupa 1:1, 16:9, 4:3, ataupun 3:1
* Fit image : mengatur tampilan image pada device tablet, apakah fill ataupun fit&#x20;

Dekstop :

* Images : sumber gambar yang ditampilkan jika device adalah dekstop, berupa baris dalam tabel qore data
* Ratio : ratio ukuran gambar yang ditampilkan jika device adalah dekstop, dapat berupa 1:1, 16:9, 4:3, ataupun 3:1
* Fit image : mengatur tampilan image pada device dekstop, apakah fill ataupun fit&#x20;

Berikut contoh carousel yang telah dimodifikasi

<figure><img src="/files/erzYMjVSPxGAQDWdYKdZ" alt=""><figcaption></figcaption></figure>


# List

Apakah kamu ingin menampilkan daftar produkmu? Jangan khawatir, kami memiliki beragam varian list yang akan membantumu menampilkan sekumpulan item.

Terdapat 4 kategori list yang dapat dipilih, yakni :

1. List
2. List Card
3. Horizontal Tile
4. Vertical Tile


# List

Cara menambahkan List component

Berikut langkah-langkah untuk menambahkan list *component*

* Buka Qore App Editor&#x20;
* Pada tab library, di section list pilih list *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;
  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

<figure><img src="/files/EeO5xmF2WHh7qwxlyTNB" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka list *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/5Y1c5yNP066U0tY3xZE6" alt=""><figcaption></figcaption></figure>

Properties dari list component adalah&#x20;

Data :

* Source : tabel yang akan digunakan sebagai sumber data
* Limit : batas data yang akan diretrieve, defaultnya adalah 50. Pengguna juga dapat menentukan sendiri batas dengan custom limit.

Design :

* Header : sebagai judul atau keterangan list
* Title : sebagai judul item list
* Subtitle : keterangan lebih detail dari title item list
* Caption : isi dari item list
* Icon : menambahkan icon pada list, dapat dengan memilih icon yang telah tersedia ataupun mengunggah gambar
* Style : memilih gaya untuk item list, apakah dengan gaya card atau tidak
* Display : mengatur jumlah item list yang ditampilkan, apakah semua, infinite scroll, atau menggunakan pagination. Jika menggunakan pagination, atur jumlah limit untuk setiap page

Thumbnail :

* Source : sumber gambar untuk thumbnail, bisa berupa link gambar
* Position : mengatur peletakan thumbnail, apakah rata kanan atau kiri
* Shape : mengatur bentuk thumbnail, apakah square, rounded, ataupun circle

Empty state :

* Title : judul dari list ketika dalam kondisi kosong
* Subtitle : keterangan lebih detail mengenai kondisi list yang kosong, misalnya "Anda tidak memiliki data apapun"
* Image : Gambar ketika list dalam kondisi kosong

Berikut contoh list yang telah dimodifikasi

<figure><img src="/files/eqkX57H9vSdv93YLqvfA" alt=""><figcaption></figcaption></figure>


# List Card

Cara menambahkan List Card component

Berikut langkah-langkah untuk menambahkan list *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section list pilih list card *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/YJpFVzxK7sOkcTkm42Uy" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka list *card component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/dGiJ4ktdfSom87OtgipL" alt=""><figcaption></figcaption></figure>

Properties dari list card component adalah&#x20;

Data :

* Source : tabel yang akan digunakan sebagai sumber data
* Limit : batas data yang akan diretrieve, defaultnya adalah 50. Pengguna juga dapat menentukan sendiri batas dengan custom limit.

Design :

* List title : sebagai judul atau keterangan list
* Title : sebagai judul item list
* Label : seperti tag, label digunakan untuk mengelompokkan list card berdasar kategori tertentu
* Description : menunjukkan keterangan atau deskripsi singkat mengenai list card
* Caption : isi dari item list
* Image : sumber gambar pada list card, dapat berupa baris pada qore data ataupun link gambar
* Display : mengatur jumlah item list yang ditampilkan, apakah semua, infinite scroll, atau menggunakan pagination. Jika menggunakan pagination, atur jumlah limit untuk setiap page

Thumbnail :

* Avatar : sumber gambar untuk thumbnail yang akan muncul sebagai gambar kecil, bisa berupa link gambar atau baris dalam qore data
* Icon : menambahkan icon pada list, dapat dengan memilih icon yang telah tersedia ataupun mengunggah gambar
* Icon style : mengatur gaya tampilan dari icon
* Size : mengatur ukuran list card, apakah half size atau full size jika ingin lebih lebar
* Style : mengatur style tampilan dari list card, apakah default, card, atau overlay
* Round : mengatur bentuk card, apakah menggunakan round atau tidak

Empty state :

* Title : judul dari list ketika dalam kondisi kosong
* Subtitle : keterangan lebih detail mengenai kondisi list yang kosong, misalnya "Anda tidak memiliki data apapun"
* Image : Gambar ketika list dalam kondisi kosong

Berikut contoh list card yang telah dimodifikasi

<figure><img src="/files/XpFlXjL0VCPaGJdONRbo" alt=""><figcaption></figcaption></figure>


# Horizontal Tile

Cara menambahkan Horizontal Tile component

Berikut langkah-langkah untuk menambahkan horizontal tile *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section list pilih horizontal tile *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/xQN6Fid8MbDhZxgUNv79" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka horizontal tile *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/yJfZ6kTntaodY4ZVjZfU" alt=""><figcaption></figcaption></figure>

Properties dari horizontal tile component adalah&#x20;

Data :

* Source : tabel yang akan digunakan sebagai sumber data

Design :

* Header : sebagai judul atau keterangan list
* Title : sebagai judul item list
* Label : seperti tag, label digunakan untuk mengelompokkan list card berdasar kategori tertentu
* Description : menunjukkan keterangan atau deskripsi singkat mengenai list card
* Caption : isi dari item list
* Image : sumber gambar pada list card, dapat berupa baris pada qore data ataupun link gambar

Empty state :

* Title : judul dari list ketika dalam kondisi kosong
* Subtitle : keterangan lebih detail mengenai kondisi list yang kosong, misalnya "Anda tidak memiliki data apapun"
* Image : Gambar ketika list dalam kondisi kosong

Berikut contoh horizontal tile yang telah dimodifikasi

<figure><img src="/files/7SFL8IXywymXkLapQux3" alt=""><figcaption></figcaption></figure>


# Vertical Tile

Cara menambahkan Vertical Tile component

Berikut langkah-langkah untuk menambahkan vertical tile *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section list pilih vertical tile *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/Lqs3wX18TwSUABeBTKmN" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka vertical tile *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/pCdbwj8yGEsuVxRM9jU4" alt=""><figcaption></figcaption></figure>

Properties dari vertical tile component adalah&#x20;

Data :

* Source : tabel yang akan digunakan sebagai sumber data

Design :

* Header : sebagai judul atau keterangan list
* Title : sebagai judul item list
* Description : menunjukkan keterangan atau deskripsi singkat mengenai list card
* Image : sumber gambar pada list card, dapat berupa baris pada qore data ataupun link gambar

Empty state :

* Title : judul dari list ketika dalam kondisi kosong
* Subtitle : keterangan lebih detail mengenai kondisi list yang kosong, misalnya "Anda tidak memiliki data apapun"
* Image : Gambar ketika list dalam kondisi kosong

Berikut contoh vertical tile yang telah dimodifikasi

<figure><img src="/files/92uch63wfRovgQ3HHMeg" alt=""><figcaption></figcaption></figure>


# Button

Komponen button berfungsi untuk menampilkan berbagai jenis tombol.

Terdapat 5 kategori button yang dapat dipilih, yakni :

1. Button
2. Button Bar
3. Menu Grid
4. Icon Button
5. Floating Button


# Button

Cara menambahkan button component

Berikut langkah-langkah untuk menambahkan button *component*

* Buka Qore App Editor&#x20;
* Pada tab library, di section button pilih button *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;
  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

<figure><img src="/files/th2526YQh5cXclyM03vF" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka button *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/SnmjFr0vhgHnc32L6Wm2" alt=""><figcaption></figcaption></figure>

Properties dari button component adalah&#x20;

Design :

* Label : mengatur text pada button yang menggambarkan fungsi dari button, seperti save, cancel, delete, dan lainnya
* Size : mengatur ukuran button, apakah small, medium, atau large
* Style : mengatur tampilan button yaitu warna font dan background

Action :

* Logout : mengeluarkan akun user dari sistem aplikasi
* View Detail : User akan dialihkan ke halaman detail yang otomatis digenerate oleh aplikasi
* Open Link : ketika button ditekan, user akan diarahkan ke halaman tertentu. Link halaman tersebut disimpan di properties direct link
* Trigger Action : ketika button ditekan akan mentrigger aksi tertentu. Properties yang dimiliki trigger antara lain : event name atau nama dari event, on success dan on fail yang akan menjalankan aksi tertentu ketika aksi user sukses atau gagal, dan response message display yang akan menampilkan pesan ketika user berhasil ataupun gagal.
* Jump To Page : Ketika button ditekan, user akan diarahkan ke halaman tertentu dari aplikasi. Properties yang dimiliki antara lain : event name atau nama event, select page untuk memilih halaman yang dituju, dan rowId sebagai baris data yang akan diretrieve
* Trigger Pipeline : Ketika button ditekan maka aplikasi akan otomatis menjalankan serangkaian aksi yang telah disetting
* Scan QR Code : Ketika button ditekan maka aplikasi dalam model scan qr code. Properties yang dimiliki antara lain : variabel output yaitu output dari qr code yang berhasil discan, message yaitu pesan untuk user saat menscan qr code, dan on success untuk pesan notifikasi ketika user berhasil
* Open As Modal : Ketika button ditekan akan menampilkan pop up. Pop up yang ditampilkan berasal dari properties page. Tinggi pop up juga dapat diatur melalui properties height
* Close Page Modal : Action ini adalah kebalikan dari open as modal, yang bertujuan menutup modal yang sedang aktif. Pada properties on close terdapat pilihan aksi ketika modal ditutup.
* Show Toast : Digunakan untuk menampilkan notifikasi berupa informasi, sukses, warning, hingga error. Proerties yang dimiliki yaitu title sebagai judul notifikasi dan subtitle sebagai deskripsi singkat notifikasi

Visibility :

* Disabled : mengatur kondisi apa yang membuat button disabled atau tidak berfungsi
* Hidden : mengatur kondisi apa yang membuat button tidak terlihat

Berikut contoh button yang telah dimodifikasi

<figure><img src="/files/shuo3NGoZU2CUgp6zqHo" alt=""><figcaption></figcaption></figure>


# Button Bar

Cara menambahkan Button Bar component

Berikut langkah-langkah untuk menambahkan Button Bar *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section button pilih Button Bar *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/scR2GDGuHhP8FB0ewVal" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka Button Bar *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/OdgRIIY7vUa3KAQREjG7" alt=""><figcaption></figcaption></figure>

Properties dari Button Bar component adalah&#x20;

Design :

* Size : mengatur ukuran dari button, apakah small, medium, atau large

Left Button :

* Left Label : mengatur text pada button pertama (kiri) yang menggambarkan fungsi dari button, seperti save, cancel, delete, dan lainnya
* Left Action :
  * Logout : mengeluarkan akun user dari sistem aplikasi
  * View Detail : User akan dialihkan ke halaman detail yang otomatis digenerate oleh aplikasi
  * Open Link : ketika button ditekan, user akan diarahkan ke halaman tertentu. Link halaman tersebut disimpan di properties direct link
  * Trigger Action : ketika button ditekan akan mentrigger aksi tertentu. Properties yang dimiliki trigger antara lain : event name atau nama dari event, on success dan on fail yang akan menjalankan aksi tertentu ketika aksi user sukses atau gagal, dan response message display yang akan menampilkan pesan ketika user berhasil ataupun gagal.
  * Jump To Page : Ketika button ditekan, user akan diarahkan ke halaman tertentu dari aplikasi. Properties yang dimiliki antara lain : event name atau nama event, select page untuk memilih halaman yang dituju, dan rowId sebagai baris data yang akan diretrieve
  * Trigger Pipeline : Ketika button ditekan maka aplikasi akan otomatis menjalankan serangkaian aksi yang telah disetting
  * Scan QR Code : Ketika button ditekan maka aplikasi dalam model scan qr code. Properties yang dimiliki antara lain : variabel output yaitu output dari qr code yang berhasil discan, message yaitu pesan untuk user saat menscan qr code, dan on success untuk pesan notifikasi ketika user berhasil
  * Open As Modal : Ketika button ditekan akan menampilkan pop up. Pop up yang ditampilkan berasal dari properties page. Tinggi pop up juga dapat diatur melalui properties height
  * Close Page Modal : Action ini adalah kebalikan dari open as modal, yang bertujuan menutup modal yang sedang aktif. Pada properties on close terdapat pilihan aksi ketika modal ditutup.
  * Show Toast : Digunakan untuk menampilkan notifikasi berupa informasi, sukses, warning, hingga error. Proerties yang dimiliki yaitu title sebagai judul notifikasi dan subtitle sebagai deskripsi singkat notifikasi

Right Button :

* Right Label : mengatur text pada button kedua (kanan) yang menggambarkan fungsi dari button, seperti save, cancel, delete, dan lainnya
* Right Action :
  * Logout : mengeluarkan akun user dari sistem aplikasi
  * View Detail : User akan dialihkan ke halaman detail yang otomatis digenerate oleh aplikasi
  * Open Link : ketika button ditekan, user akan diarahkan ke halaman tertentu. Link halaman tersebut disimpan di properties direct link
  * Trigger Action : ketika button ditekan akan mentrigger aksi tertentu. Properties yang dimiliki trigger antara lain : event name atau nama dari event, on success dan on fail yang akan menjalankan aksi tertentu ketika aksi user sukses atau gagal, dan response message display yang akan menampilkan pesan ketika user berhasil ataupun gagal.
  * Jump To Page : Ketika button ditekan, user akan diarahkan ke halaman tertentu dari aplikasi. Properties yang dimiliki antara lain : event name atau nama event, select page untuk memilih halaman yang dituju, dan rowId sebagai baris data yang akan diretrieve
  * Trigger Pipeline : Ketika button ditekan maka aplikasi akan otomatis menjalankan serangkaian aksi yang telah disetting
  * Scan QR Code : Ketika button ditekan maka aplikasi dalam model scan qr code. Properties yang dimiliki antara lain : variabel output yaitu output dari qr code yang berhasil discan, message yaitu pesan untuk user saat menscan qr code, dan on success untuk pesan notifikasi ketika user berhasil
  * Open As Modal : Ketika button ditekan akan menampilkan pop up. Pop up yang ditampilkan berasal dari properties page. Tinggi pop up juga dapat diatur melalui properties height
  * Close Page Modal : Action ini adalah kebalikan dari open as modal, yang bertujuan menutup modal yang sedang aktif. Pada properties on close terdapat pilihan aksi ketika modal ditutup.
  * Show Toast : Digunakan untuk menampilkan notifikasi berupa informasi, sukses, warning, hingga error. Proerties yang dimiliki yaitu title sebagai judul notifikasi dan subtitle sebagai deskripsi singkat notifikasi

Berikut contoh Button Bar yang telah dimodifikasi

<figure><img src="/files/ZQ2xTWTT2nnCmCCDZSLA" alt=""><figcaption></figcaption></figure>


# Menu Grid

Cara menambahkan Menu Grid component

Berikut langkah-langkah untuk menambahkan Menu Grid *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section button pilih Menu Grid *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/TOYYC7lzepcTYjPWgmWN" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka Menu Grid *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/G3KdZ905iQyBO8ucdqJT" alt=""><figcaption></figcaption></figure>

Setiap button dari menu grid akan memiliki properties sebagai berikut :

* Menu enabled : Jika toggle diaktifkan, maka button akan tampil, jika dinonaktifkan, maka button tidak akan tampil (hidden)
* Menu label : mengatur text pada button yang menggambarkan fungsi dari button
* Menu icon : mengatur icon yang terletak di tepi kiri button
* Menu action :
  * Logout : mengeluarkan akun user dari sistem aplikasi
  * View Detail : User akan dialihkan ke halaman detail yang otomatis digenerate oleh aplikasi
  * Open Link : ketika button ditekan, user akan diarahkan ke halaman tertentu. Link halaman tersebut disimpan di properties direct link
  * Trigger Action : ketika button ditekan akan mentrigger aksi tertentu. Properties yang dimiliki trigger antara lain : event name atau nama dari event, on success dan on fail yang akan menjalankan aksi tertentu ketika aksi user sukses atau gagal, dan response message display yang akan menampilkan pesan ketika user berhasil ataupun gagal.
  * Jump To Page : Ketika button ditekan, user akan diarahkan ke halaman tertentu dari aplikasi. Properties yang dimiliki antara lain : event name atau nama event, select page untuk memilih halaman yang dituju, dan rowId sebagai baris data yang akan diretrieve
  * Trigger Pipeline : Ketika button ditekan maka aplikasi akan otomatis menjalankan serangkaian aksi yang telah disetting
  * Scan QR Code : Ketika button ditekan maka aplikasi dalam model scan qr code. Properties yang dimiliki antara lain : variabel output yaitu output dari qr code yang berhasil discan, message yaitu pesan untuk user saat menscan qr code, dan on success untuk pesan notifikasi ketika user berhasil
  * Open As Modal : Ketika button ditekan akan menampilkan pop up. Pop up yang ditampilkan berasal dari properties page. Tinggi pop up juga dapat diatur melalui properties height
  * Close Page Modal : Action ini adalah kebalikan dari open as modal, yang bertujuan menutup modal yang sedang aktif. Pada properties on close terdapat pilihan aksi ketika modal ditutup.
  * Show Toast : Digunakan untuk menampilkan notifikasi berupa informasi, sukses, warning, hingga error. Proerties yang dimiliki yaitu title sebagai judul notifikasi dan subtitle sebagai deskripsi singkat notifikasi

Berikut contoh Menu Grid yang telah dimodifikasi

<figure><img src="/files/F27IYaqH8dyMxy4K3RNg" alt=""><figcaption></figcaption></figure>


# Icon Button

Cara menambahkan Icon Button component

Berikut langkah-langkah untuk menambahkan Icon Button *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section button pilih Icon Button *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/z9QjHPMX4KfjDwwdB96e" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka Icon Button *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/c0xDJhfEhDYVxexzrvro" alt=""><figcaption></figcaption></figure>

Properties dari Icon Button component adalah&#x20;

Design :

* Icon : mengatur icon yang ditampilkan pada button
* Variant : mengatur style atau tampilan button
* Size : mengatur ukuran button, apakah large, medium, small, atau extra small

Berikut contoh Icon Button yang telah dimodifikasi

<figure><img src="/files/tiYzEJeaSPJna96ZI8Yt" alt=""><figcaption></figcaption></figure>


# Floating Button

Cara menambahkan Floating Button component

Berikut langkah-langkah untuk menambahkan Floating Button *component*

* Buka Qore App Editor&#x20;

* Pada tab library, di section button pilih Floating Button *component*. Terdapat 2 cara untuk menambahkan *component* ke dalam emulator&#x20;

  * Jika ingin menambahkan *component* langsung ke suatu page, kamu dapat *double-click card* tersebut
  * Jika ingin menambahkan *component* ke dalam salah satu kontainer di page tersebut, kamu dapat *drag and drop* ke dalam kontainer yang diinginkan

  <figure><img src="/files/LsrR1HUjQFFmk8U3o1Wj" alt=""><figcaption></figcaption></figure>

* Jika berhasil maka Floating Button *component* akan muncul di *emulator editor screen* seperti berikut&#x20;

<figure><img src="/files/Y2SRwQJDBcFanv5B3Qcm" alt=""><figcaption></figcaption></figure>

Properties dari Floating Button component adalah&#x20;

Design :

* Icon Button : mengatur icon yang ditampilkan pada button
* Size : mengatur ukuran button, apakah small, medium, atau large
* Show on : mengatur floating button akan tampil pada tipe device apa saja, apakah mobile, tablet, dekstop, atau semua tipe device
* Type : mengatur tipe dari button, terdapat pilihan action dan expand. Jika action&#x20;

Berikut contoh Floating Button yang telah dimodifikasi

<figure><img src="/files/hqQ2olLawUlHTgwD4uWQ" alt=""><figcaption></figcaption></figure>


# Custom Component

Custom component can be used by editors to create components with the appearance and functionality according to their needs, if the official Qore component has not been able to meet these needs.

With this custom component, it allows editors to add script code with output components that can be used in the app editor. You can follow these steps to create a custom component.

This provides a starter template for building custom qore app compoent using Rollup and TypeScript.

### Setup a new project

To use this package, run the following command in your terminal:

```
npm init qore-app-component [component name]
```

This will create a new directory with the specified package name and install all necessary dependencies.

### Development

Start edit your component in `src/[componentName].tsx`, all qore apps api are available via props with more api added viw import from `@qorebase/app-component` package. If you're using third party package, make sure the package supports schema script module, if not, that package will be bundled by rollup.

### Usage

To build the package, run the following command:

```
npm run build
```

This will compile the TypeScript code and bundle the source and commonjs packages with Rollup.

### Publish

To publish the package, run the following command to bump the version:

```
npm version [major|minor|patch|prerelease]
```

This will bump the version in `package.json` and `package-lock.json` and create a new commit and tag.

Then, run the following command to publish the package:

```
npm publish
```

###


# Props

#### registerComponent Props

| Name           | Value                                                                | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| -------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type           | `'none'`, `'record'`, `'list'`, `'nested-list'`, `'standalone-list'` | <p>Define the component type and how the component get its data.<br></p><ul><li><code>record</code> - <em>component with the data source is reference to the table selected in page context</em></li><li><code>list</code> - <em>component with a different data source from the page context, but the state property defined in its component would still reference from the table selected in page context</em></li><li><code>nested-list</code> - <em>like a <code>list</code> component, but used to get many to many or one to many data relation</em></li><li><code>standalone-list</code> - <em>like a <code>list</code> component, but the defined state property in this component is going to be reference from the table selected in this component source.</em></li></ul> |
| propDefinition | `Object`                                                             | Define the *`schema`* of properties in the component                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| defaultProps   | `Object`                                                             | Define the *`default value`* for registered properties in propDefinition                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| Component      | `React Component`                                                    | Render a custom component that will be shown on apps                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |

#### Component props

| Name       | Description                                                                                                                               |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| hooks      | [component hooks list](https://github.com/feedloop/qore-apps/pull/594/files?short_path=07185a1\&unchanged=expanded#component-props-hooks) |
| source     | Get detail of selected source table if you are using `list`, `nested-list` type component, `standalone-list`.                             |
| pageSource | Get detail of selected source table if you are using `record` type component.                                                             |
| properties | Value of the defined properties in propDefinition                                                                                         |
| instance   | Schema of the component                                                                                                                   |

#### Component props hooks

| Name             | Description                                                                                                                       |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| useTemplate      | make a template of the `string` value if the it's uses the suggested `@` tag. if it's not, it would be trait as a normal `string` |
| useActionTrigger | create an action trigger, usually used with a property defined as `action` type                                                   |
| sourceHooks      | an axios client wrapper used to make request to selected source.                                                                  |

<br>


# Example

![Example of custom component](/files/MzxIK840a7uQTRXMPZTw)

```
import { Button } from "@chakra-ui/button";
import { useDisclosure, useOutsideClick } from "@chakra-ui/hooks";
import Icon from "@chakra-ui/icon";
import {
  Box,
  Center,
  Flex,
  Spacer,
  Text,
  Image,
  VStack,
  FormControl,
  FormLabel,
  Input,
  Spinner,
  Link,
} from "@chakra-ui/react";
import {
  Modal,
  ModalHeader,
  ModalBody,
  ModalFooter,
  ModalContent,
  ModalOverlay,
} from "@chakra-ui/modal";
import { Popover, PopoverContent, PopoverTrigger } from "@chakra-ui/popover";
import { Portal } from "@chakra-ui/portal";
import { css } from "@emotion/react";
import { EmotionJSX } from "@emotion/react/types/jsx-namespace";
import {
  IconChevronRight,
  IconClick,
  IconFreetext,
  IconListUl,
  IconMultimedia,
  IconPlus,
  IconSelect,
  IconTemplate,
  IconDesktop,
  IconCheck,
  IconX,
  CodeAlt,
} from "@feedloop/icon";
import produce from "immer";
import React from "react";
import { DropResult } from "react-beautiful-dnd";
import Scrollbars from "react-custom-scrollbars";
import iconsList from "../runtime/iconsList";
import {
  buildComponent,
  ComponentGroupType,
  ComponentInstance,
  ComponentProps,
  getComponentList,
  registerComponent,
} from "../runtime/interfaces";
import { RuntimeContext } from "../runtime/RuntimeContext";
import EditorContext from "./EditorContext";
import PageMenu from "./PageMenuItem";
import { useForm } from "react-hook-form";
import importCustomComponent from "../runtime/importCustomComponent";

const ModalLayout = (props: { isOpen: boolean; onClose: () => void }) => (
  <Modal isOpen={props.isOpen} onClose={props.onClose} isCentered>
    <ModalOverlay />
    <ModalContent w="408px" h="448px" p="40px">
      <ModalBody>
        <Center>
          <Image src="/assets/ilustration/dekstop.svg" alt="Desktop" />
        </Center>
        <Center>
          <Text
            css={css`
              font-weight: 600;
              font-size: 24px;
              color: #001e4d;
            `}
          >
            Only For Dekstop
          </Text>
        </Center>
        <Center pt={2}>
          <Text
            css={css`
              font-weight: normal;
              font-size: 12px;
              color: #6f809a;
              text-align: center;
            `}
          >
            This component only for dekstop, change to dekstop mode to use this
            component
          </Text>
        </Center>
        <Center pt={4}>
          <Button
            w="328px"
            css={css`
              background: #0065ff;
              color: #fff;
            `}
          >
            Go to Desktop Mode
          </Button>
        </Center>
        <Center pt={2}>
          <Button variant="ghost" w="328px" onClick={props.onClose}>
            Cancel
          </Button>
        </Center>
      </ModalBody>
    </ModalContent>
  </Modal>
);

export const bannedComponents = new Set([
  "ColumnLayout2",
  "ColumnLayout3",
  "Gallery",
  "Menu Grid",
]);

interface IAddComponentsMenu {
  isOpen: boolean;
  isOpenByComponent: boolean;
  layoutID: string;
  layoutIdx: number;
}
interface ComponentsManagerState {
  componentBeingEdit: string;
  addComponentMenu: IAddComponentsMenu;
}

type CustomComponentModal = "register" | "loading" | "success" | "error";

export default React.memo(function ComponentsManager() {
  const pageID = RuntimeContext.useSelectState(({ control }) => control.page);
  const maps = RuntimeContext.useSelectState(({ app }) => app.maps);
  const runtimeActions = RuntimeContext.useActions();
  const editorActions = EditorContext.useActions();
  const form = useForm({
    defaultValues: {
      name: "",
      url: "",
    },
  });
  const [modalCustomComponent, setModalCustomComponent] =
    React.useState<CustomComponentModal | null>(null);
  const activeComponent = EditorContext.useSelectState(
    ({ activeComponent }) => activeComponent
  );

  const [state, setState] = React.useState<ComponentsManagerState>({
    componentBeingEdit: undefined,
    addComponentMenu: {
      isOpen: false,
      isOpenByComponent: false,
      layoutID: null,
      layoutIdx: null,
    },
  });

  const page = React.useMemo(() => maps.page[pageID], [maps.page, pageID]);
  const componentPresets = React.useMemo(() => getComponentList(), []);

  const iconMaps = React.useMemo(
    () =>
      componentPresets.reduce(
        (result, item) => ({
          ...result,
          [item.id]: item.icon,
        }),
        {} as Record<string, string>
      ),
    [componentPresets]
  );

  const components = React.useMemo(
    () =>
      Iterator.from(page?.components || [])
        .map((ref) => maps.component[ref.component])
        .filter((x) => !!x)
        .toArray(),
    [page?.components, maps.component]
  );

  const groupingComponents = React.useMemo(() => {
    const groupedComponents: {
      layer0: Array<ComponentInstance<ComponentProps>>;
      layer1: Record<string, Array<ComponentInstance<ComponentProps>>>;
    } = {
      layer0: [],
      layer1: {},
    };
    components.forEach((component) => {
      if (
        !!component.metadata &&
        !!component.metadata.layout &&
        !!component.metadata.layout.id
      ) {
        groupedComponents.layer1[component.metadata.layout.id] = [
          ...(groupedComponents.layer1[component.metadata.layout.id] || []),
          component,
        ];
      } else {
        groupedComponents.layer0.push(component);
      }
    });
    return groupedComponents;
  }, [components]);

  React.useEffect(() => {
    if (
      page?.components?.find((ref) => ref.component === activeComponent) ===
      undefined
    ) {
      editorActions.setActiveComponent(page?.components?.[0]?.component);
      editorActions.setEditMode("play");
    }
  }, [page?.components, activeComponent]);

  const getNewDestination = React.useCallback(
    (destinationIndex: number, draggableId: string) => {
      const newDestinationFilter = groupingComponents.layer0.filter(
        (comp, idx) => idx < destinationIndex
      );
      let newDestination = 0;
      newDestinationFilter?.forEach((current) => {
        if (
          (current.componentID === "ColumnLayout2" ||
            current.componentID === "ColumnLayout3") &&
          !!groupingComponents.layer1[current.id] &&
          draggableId !== current.id
        ) {
          newDestination += groupingComponents.layer1[current.id].length + 1;
        } else {
          newDestination += 1;
        }
      });
      return newDestination;
    },
    [groupingComponents]
  );

  const handleAddComponent = React.useCallback(
    (presetID: string, name?: string, componentURL?: string) => {
      if (presetID === "Custom Component") {
        setModalCustomComponent("register");
        return;
      }
      const compInstance = buildComponent(presetID, {
        metadata: {
          name,
          layout:
            state.addComponentMenu.isOpenByComponent &&
            !!state.addComponentMenu.layoutID
              ? { id: state.addComponentMenu.layoutID, column: 1 }
              : undefined,
          componentURL,
        },
      });
      if (!!state.addComponentMenu.isOpenByComponent) {
        const layoutIdx = getNewDestination(
          state.addComponentMenu.layoutIdx,
          state.addComponentMenu.layoutID
        );
        const idx =
          layoutIdx +
          1 +
          (groupingComponents.layer1[state.addComponentMenu.layoutID]?.length ||
            0);

        runtimeActions.addComponent(
          compInstance,
          { page: pageID },
          { idx: idx }
        );
      } else {
        runtimeActions.addComponent(compInstance, { page: pageID });
      }
    },
    [pageID, state.addComponentMenu, getNewDestination, groupingComponents]
  );

  const handleDragEnd = React.useCallback(
    (result: DropResult) => {
      if (!result.destination || !page) return;
      const newDestination = getNewDestination(
        result.destination.index,
        result.draggableId
      );
      const newSourceIndex: number = components.findIndex(
        (comp) => comp.id === result.draggableId
      );
      const deletionLength =
        (groupingComponents.layer1[result.draggableId]?.length || 0) + 1;
      runtimeActions.swapComponent(
        { page: page.id },
        newSourceIndex,
        newDestination,
        deletionLength
      );
    },
    [runtimeActions, page, groupingComponents, getNewDestination, components]
  );

  const handleLayer1DragEnd = React.useCallback(
    (result: DropResult, offset: number = 0, parentId: string) => {
      if (!result.destination || !page) return;
      const parentPageIndex = getNewDestination(offset, parentId);
      const newDestinationIndex =
        parentPageIndex + result.destination.index + 1;
      const newSourceIndex = parentPageIndex + result.source.index + 1;
      runtimeActions.swapComponent(
        { page: page.id },
        newSourceIndex,
        newDestinationIndex
      );
    },
    [runtimeActions, page, getNewDestination]
  );

  const handleMoveToLayout = React.useCallback(
    (sourceId: string, destinationLayoutId: string) => {
      const destinationLayer0Idx = groupingComponents.layer0.findIndex(
        (comp) => comp.id === destinationLayoutId
      );
      const layoutIndex = getNewDestination(destinationLayer0Idx, sourceId);
      const sourceIndex = components.findIndex((comp) => comp.id === sourceId);
      const destinationIndex =
        layoutIndex +
        (groupingComponents.layer1[destinationLayoutId]?.length || 0) +
        (layoutIndex < sourceIndex ? 1 : 0);
      runtimeActions.setComponentMetadata({ component: sourceId }, "layout", {
        id: destinationLayoutId,
        column: 1,
      });
      runtimeActions.swapComponent(
        { page: page.id },
        sourceIndex,
        destinationIndex
      );
    },
    [groupingComponents, components, getNewDestination, page]
  );

  const handleRemoveFromLayout = React.useCallback(
    (compId: string) => {
      const sourceIndex = components.findIndex((comp) => comp.id === compId);
      const destinationIndex = components.length;
      runtimeActions.removeComponentLayoutMetadata({ component: compId });
      runtimeActions.swapComponent(
        { page: page.id },
        sourceIndex,
        destinationIndex
      );
    },
    [components, page]
  );

  const handleRenameOnBlur = React.useCallback(
    (e: React.FocusEvent<HTMLInputElement>, compId: string) => {
      runtimeActions.setComponentMetadata(
        { component: compId },
        "name",
        e.currentTarget.value
      );
      setState((state) =>
        produce(state, (draft) => {
          draft.componentBeingEdit = undefined;
        })
      );
    },
    []
  );

  const { isOpen, onClose } = useDisclosure();
  const ModalItem = ModalLayout;

  const renderLayoutComponentsMenu = React.useMemo(() => {
    let layer1: Record<string, EmotionJSX.Element[]> = {};
    Object.keys(groupingComponents.layer1).forEach((layoutID) => {
      layer1[layoutID] = [
        ...(layer1[layoutID] || []),
        <PageMenu
          onDragEnd={(result) =>
            handleLayer1DragEnd(
              result,
              groupingComponents.layer0.findIndex(
                (comp) => comp.id === layoutID
              ),
              layoutID
            )
          }
          iconMaps={iconMaps}
          componentToEditID={state.componentBeingEdit}
          components={groupingComponents.layer1[layoutID]}
          onBlurRenameItem={handleRenameOnBlur}
          onStateChange={setState}
          onRemoveComponent={runtimeActions.removeComponent}
          onSetActiveComponent={editorActions.setActiveComponent}
          activeComponent={activeComponent}
          onRemoveFromLayout={handleRemoveFromLayout}
        />,
      ];
    });
    return layer1;
  }, [
    groupingComponents,
    iconMaps,
    state.componentBeingEdit,
    activeComponent,
    handleDragEnd,
    handleRenameOnBlur,
    runtimeActions.removeComponent,
    editorActions.setActiveComponent,
  ]);

  const AddComponentsCallback = React.useCallback(() => {
    return (
      <AddComponents
        isOpen={state.addComponentMenu.isOpen}
        isOpenByComponent={state.addComponentMenu.isOpenByComponent}
        onAddComponent={handleAddComponent}
        onEventChange={(value, eventName) => {
          switch (eventName) {
            case "open":
              setState((state) =>
                produce(state, (draft) => {
                  draft.addComponentMenu.isOpen = value.isOpen;
                  draft.addComponentMenu.isOpenByComponent =
                    value.isOpenByComponent;
                  draft.addComponentMenu.layoutID = value.layoutID;
                  draft.addComponentMenu.layoutIdx = value.layoutIdx;
                })
              );
              break;
            case "close":
              setState((state) =>
                produce(state, (draft) => {
                  draft.addComponentMenu.isOpen = false;
                })
              );
              break;
            default:
              return;
          }
        }}
      />
    );
  }, [
    state.addComponentMenu.isOpenByComponent,
    state.addComponentMenu.isOpen,
    handleAddComponent,
  ]);

  if (!page) return null;

  return (
    <Box position="relative" height="100%">
      <Flex
        css={css`
          padding: 12px 16px;
        `}
      >
        <Box flex={1}>
          <Text fontSize="sm" fontWeight="semibold" color="#001E4D">
            Components
          </Text>
        </Box>
        <AddComponentsCallback />
      </Flex>
      <ModalItem isOpen={isOpen} onClose={onClose} />
      <Box
        position="absolute"
        top="48px"
        left="0"
        right="0"
        bottom="0"
        overflowY="auto"
      >
        <Scrollbars>
          <PageMenu
            onDragEnd={handleDragEnd}
            iconMaps={iconMaps}
            componentToEditID={state.componentBeingEdit}
            components={groupingComponents.layer0}
            onBlurRenameItem={handleRenameOnBlur}
            onStateChange={setState}
            onRemoveComponent={runtimeActions.removeComponent}
            onSetActiveComponent={editorActions.setActiveComponent}
            activeComponent={activeComponent}
            renderLayoutComponentsMenu={renderLayoutComponentsMenu}
            layer1={groupingComponents.layer1}
            onMoveToLayout={handleMoveToLayout}
          />
        </Scrollbars>
      </Box>

      <Modal
        isOpen={!!modalCustomComponent}
        onClose={() => {
          modalCustomComponent !== "loading" && setModalCustomComponent(null);
        }}
      >
        <ModalOverlay />
        {modalCustomComponent &&
          (modalCustomComponent === "register" ? (
            <ModalContent>
              <ModalHeader>
                <Text fontSize="2xl">Add custom component</Text>
              </ModalHeader>
              <ModalBody>
                <VStack spacing={4}>
                  <Box
                    padding="16px"
                    borderRadius="4px"
                    backgroundColor="gray.100"
                  >
                    <Text fontSize="sm" color="gray.600">
                      Custom component can be used by editors to create
                      components with the appearance and functionality according
                      to their needs, if the official Qore component has not
                      been able to meet these needs.{" "}
                      <Link
                        href="https://docs.qore.dev/component/custom-component"
                        color="blue.500"
                        isExternal
                      >
                        Learn more
                      </Link>
                    </Text>
                  </Box>
                  <FormControl id="name">
                    <FormLabel>Name</FormLabel>
                    <Input
                      name="name"
                      ref={form.register({ required: true })}
                      placeholder="Component Name"
                    />
                  </FormControl>
                  <FormControl id="subdomain">
                    <FormLabel>Component URL</FormLabel>
                    <Input
                      name="url"
                      ref={form.register({ required: true })}
                      placeholder="Component URL"
                    />
                  </FormControl>
                </VStack>
              </ModalBody>

              <ModalFooter flex={1}>
                <Button
                  width="100%"
                  mr={3}
                  onClick={() => setModalCustomComponent(null)}
                >
                  Cancel
                </Button>
                <Button
                  width="100%"
                  colorScheme="brand"
                  onClick={form.handleSubmit(({ name, url }) => {
                    setModalCustomComponent("loading");
                    importCustomComponent(url)
                      .then(({ id, component }) => {
                        handleAddComponent(id, name, url);
                        setModalCustomComponent("success");
                      })
                      .catch((err) => {
                        console.error(err);
                        setModalCustomComponent("error");
                      });
                  })}
                >
                  Add component
                </Button>
              </ModalFooter>
            </ModalContent>
          ) : (
            <ModalContent>
              <ModalHeader>
                <Text fontSize="2xl">Validation Component</Text>
              </ModalHeader>
              <ModalBody>
                <Box
                  borderWidth="1px"
                  borderStyle="solid"
                  borderColor="gray.200"
                  borderRadius="md"
                  p={3}
                >
                  {modalCustomComponent === "loading" ? (
                    <Flex alignItems="flex-start">
                      <Spinner
                        thickness="4px"
                        speed="0.65s"
                        emptyColor="gray.200"
                        color="blue.500"
                        size="xl"
                      />
                      <Box flex={1} marginLeft="3">
                        <Text fontWeight="bold">Creating Component</Text>
                        <Text color="gray.500" fontSize="sm">
                          Fetching and validating component from URL
                        </Text>
                      </Box>
                    </Flex>
                  ) : modalCustomComponent === "success" ? (
                    <Flex alignItems="flex-start">
                      <Box
                        w={10}
                        h={10}
                        borderRadius="full"
                        backgroundColor="green.100"
                        alignItems="center"
                        justifyContent="center"
                        boxSizing="border-box"
                        display="flex"
                      >
                        <Icon as={IconCheck} color="green" />
                      </Box>
                      <Box flex={1} marginLeft="3">
                        <Text fontWeight="bold">Component created</Text>
                        <Text color="gray.500" fontSize="sm">
                          Your component has been created
                        </Text>
                      </Box>
                    </Flex>
                  ) : (
                    <Flex alignItems="flex-start">
                      <Box
                        w={10}
                        h={10}
                        borderRadius="full"
                        backgroundColor="red.100"
                        alignItems="center"
                        justifyContent="center"
                        boxSizing="border-box"
                        display="flex"
                      >
                        <Icon as={IconX} color="red" />
                      </Box>
                      <Box flex={1} marginLeft="3">
                        <Text fontWeight="bold">Failed create component</Text>
                        <Text color="gray.500" fontSize="sm">
                          Your component URL is invalid
                        </Text>
                      </Box>
                    </Flex>
                  )}
                </Box>
              </ModalBody>

              <ModalFooter flex={1}>
                <Button
                  width="100%"
                  mr={3}
                  disabled={modalCustomComponent === "loading"}
                  onClick={() => setModalCustomComponent("register")}
                >
                  Create again
                </Button>
                <Button
                  width="100%"
                  colorScheme="brand"
                  disabled={modalCustomComponent === "loading"}
                  onClick={() => setModalCustomComponent(null)}
                >
                  Done
                </Button>
              </ModalFooter>
            </ModalContent>
          ))}
      </Modal>
    </Box>
  );
});

interface IAddComponents {
  isOpen: boolean;
  onEventChange: (e: Partial<IAddComponentsMenu>, eventName: string) => void;
  isOpenByComponent: boolean;
  onAddComponent: (componentId: string) => void;
}

interface category {
  icon: (props: React.SVGProps<SVGSVGElement>) => JSX.Element;
  text: ComponentGroupType;
}

const categories: Array<category> = [
  {
    icon: IconFreetext,
    text: "text",
  },
  {
    icon: IconMultimedia,
    text: "media",
  },
  {
    icon: IconListUl,
    text: "list",
  },
  {
    icon: IconClick,
    text: "button",
  },
  {
    icon: IconSelect,
    text: "input",
  },
  {
    icon: IconTemplate,
    text: "layout",
  },
  {
    icon: IconDesktop,
    text: "data",
  },
  {
    icon: CodeAlt,
    text: "advanced",
  },
];

const AddComponents = React.memo(function ({
  isOpen,
  isOpenByComponent,
  onEventChange,
  onAddComponent,
}: IAddComponents) {
  const initRef = React.useRef();
  const ref = React.useRef();
  const componentPresets = React.useMemo(
    () =>
      getComponentList().concat({
        legacy: true,
        id: "Custom Component",
        type: "record",
        icon: "Atom",
        group: "advanced",
        defaultProps: {},
        propDefinition: () => ({}),
        Component: () => null,
      }),
    []
  );

  const [activeCategory, setActiveCategory] =
    React.useState<ComponentGroupType | null>(null);

  useOutsideClick({
    ref: ref,
    handler: () => {
      setActiveCategory(null);
    },
  });

  const handlePopoverClose = React.useCallback(() => {
    onEventChange(
      {
        isOpen: false,
      },
      "close"
    );
  }, []);
  const handlePopoverOpen = React.useCallback(() => {
    onEventChange(
      {
        isOpen: true,
        isOpenByComponent: false,
        layoutID: null,
        layoutIdx: null,
      },
      "open"
    );
  }, []);

  return (
    <Box>
      <Popover
        placement="auto-end"
        isLazy
        closeOnBlur={true}
        initialFocusRef={initRef}
        isOpen={isOpen}
        onClose={handlePopoverClose}
      >
        {({ onClose }) => (
          <>
            <PopoverTrigger>
              <Box onClick={handlePopoverOpen}>
                <Icon cursor="pointer" as={IconPlus} />
              </Box>
            </PopoverTrigger>
            <Portal>
              <PopoverContent
                ml={2}
                css={css`
                  border-radius: 0px;
                `}
              >
                <Box h="93.1vh" overflow="auto" py={4}>
                  <Box mb={4} pl={4}>
                    <Text fontWeight="semibold" color="#001E4D">
                      All Category
                    </Text>
                  </Box>
                  <div ref={ref}>
                    {categories.map((category, index) => {
                      return (
                        <Popover
                          key={`${category.text}-${index}`}
                          isOpen={activeCategory === category.text}
                          placement="auto-end"
                          isLazy
                        >
                          <PopoverTrigger>
                            <Flex
                              my={1}
                              mx={2}
                              p={2}
                              cursor="pointer"
                              onClick={() => {
                                setActiveCategory(category.text);
                              }}
                              bg={
                                activeCategory === category.text
                                  ? "#E6F0FF"
                                  : undefined
                              }
                              css={css`
                                border-radius: 8px;
                                &:hover {
                                  background-color: #e6f0ff;
                                  border-radius: 4px;
                                }
                              `}
                            >
                              <Center
                                p="6px"
                                bg={
                                  activeCategory === category.text
                                    ? "white"
                                    : "#E6F0FF"
                                }
                                css={css`
                                  border-radius: 4px;
                                `}
                              >
                                <Icon
                                  fontSize="24px"
                                  as={category.icon}
                                  color="#0065ff"
                                />
                              </Center>
                              <Center pl={2}>
                                <Text>{category.text}</Text>
                              </Center>
                              <Spacer />
                              <Center>
                                <Icon
                                  color="#A6B0C1"
                                  fontSize="24px"
                                  as={IconChevronRight}
                                />
                              </Center>
                            </Flex>
                          </PopoverTrigger>
                          <PopoverContent
                            ml={-2}
                            css={css`
                              border-left: 1px solid white;
                              border-radius: 0px;
                            `}
                          >
                            <Box h="93.1vh" w="350" overflow="auto" py={4}>
                              <Scrollbars>
                                <Box mt={10} mx={4} bg="#F9F9FA">
                                  {componentPresets
                                    .filter((selected) =>
                                      selected.group === category.text &&
                                      selected.group &&
                                      isOpenByComponent
                                        ? !bannedComponents.has(selected.id)
                                        : true
                                    )
                                    .sort((a, b) => {
                                      if (a.id < b.id) return -1;
                                      else if (a.id > b.id) return 1;
                                      else return 0;
                                    })
                                    .map((preset) =>
                                      preset.group === category.text ? (
                                        <Flex
                                          p={2}
                                          mb={2}
                                          onClick={() => {
                                            onAddComponent(preset.id);
                                            onClose();
                                          }}
                                          key={preset.id}
                                          css={css`
                                            border: 1px solid transparent;
                                            cursor: pointer;
                                            background-color: white;
                                            border-color: #e6f0ff;
                                            border-radius: 8px;
                                            &:hover {
                                              border-color: #0065ff;
                                            }
                                          `}
                                        >
                                          <Center
                                            p="6px"
                                            bg="#E6F0FF"
                                            css={css`
                                              border-radius: 4px;
                                            `}
                                          >
                                            <Icon
                                              fontSize="24px"
                                              color="#0065FF"
                                              as={iconsList[preset.icon]}
                                            />
                                          </Center>
                                          <Center pl={2} pt="0">
                                            <Text>{preset.id}</Text>
                                          </Center>
                                        </Flex>
                                      ) : undefined
                                    )}
                                </Box>
                              </Scrollbars>
                            </Box>
                          </PopoverContent>
                        </Popover>
                      );
                    })}
                  </div>
                </Box>
              </PopoverContent>
            </Portal>
          </>
        )}
      </Popover>
    </Box>
  );
});
```


# How to display Image in Qore App

Sebagai editor kita dapat menampilkan gambar di aplikasi melalui editor, gambar yang ditampilkan nantinya dapat berasal dari table qore ataupun melalui link url.\
\
Ikuti beberapa guide untuk masing-masing component yang dapat digunakan menampilkan gambar :sparkles:\ <br>


# Gallery Component

Dengan component gallery ini kita dapat menampilkan kumpulan gambar yang otomatis berubah-ubah sesuai dengan source data yang kita setup. Biasanya component ini berguna untuk menampilkan promo, event , ataupun highlight informasi lainnya agar ketika user membuka apps dapat langsung melihat informasi tersebut.\
\
Ikuti step step cara menampilkan gambar menggunakan gallery component&#x20;

1\. Setup kumpulan gambar di table Qore.\
Pada step pertama ini kita akan membuat tabel baru yang berisi informasi nama (type: text) dan file (type:file).

![](/files/a1rVSMAztwv7BXl1IbFi)

2\. Setelah berhasil di step 1, selanjutnya kita akan mulai menambahkan component gallery di editor aplikasi. Kita awali dengan mengakses app editor terlebih dahulu, kemudian ikuti simple step berikut

* Go to app builder, dari menu table klik menu apps kemudian pilih salah satu apps yang ingin kita edit.\
  ![](/files/rxc7CdFyq3oBYd9YfXQI)
* Pilih atau tambahkan halaman yang ingin kita tambahkan gambar \
  ![](/files/MNfxAixXtHvFVR4CrdCd)
* Tambahkan component gallery pada category media\
  ![](/files/AcvmqkLC6zx6cM1SXhEC)
* Aktifkan component gallery untuk mulai mengatur data \
  ![](/files/AVfCz0FHlUy728Nt2SnI)

3\. Kemudian kita dapat sesuaikan source table yang berisi data gambar yang ingin kita tampilkan di aplikasi. Source akan berisi list table yang ada.

![](/files/AfnbvuTQegxHHWu6aKL1)

4\. Lalu pilih kolom dari table/view source yang menyimpan informasi gambar dengan mengetikkan @namakolom.

![](/files/pSqPTq9K1Kv0Geno3fZX)

5\. Jika berhasil maka akan muncul gambar di emulator screen sesuai dengan data di table promo yang sebelumnya telah ditambahkan.

![](/files/CKt0i5hsPKCGgOLRnLN0)


# Headline Component

Headline component ini selain digunakan untuk menampilkan gambar kita juga dapat menambahkan informasi lainnya yang berbentuk text. \
\
Ikuti step step cara menampilkan gambar dari link url menggunakan headline component.

\
1\. Pilih atau tambahkan halaman yang ingin kita tambahkan gambar.\
Sebagai contoh kita ingin menampilkan gambar di halaman profile, maka kita perlu memilih halaman profile sehingga akan muncul highlight biru seperti berikut ini.

![](/files/iJ6EFr6VgTLqo2TReMZj)

2\. Kemudian tambahkan component headline yang berada pada category media.

![](/files/2milPUimAKaKM2noWIyx)

3\. Setelah berhasil menambahkan component headline, aktifkan component headline untuk mulai mengatur component tersebut.

![](/files/c4JX3bmSvhori1mko7bI)

4\. Copy link url gambar pada setting source di component headline.\
Setelah berhasil mengcopy link url maka di emulator akan muncul gambar dari url tersebut.

![](/files/yGf3jM86bvVuTyjt3Zaq)

5\. Kita juga dapat menyesuaikan style dari component headline sesuai dengan kebutuhan dan bentuk gambar yang ingin ditampilkan di aplikasi.

![Jika ditampilkan dengan style full](/files/nWTVHoX0dfULaDnt0Brk)

![Jika ditampilkan dengan style profile](/files/e7FByRKcOrgz04HLjaqG)


# Image Component

Kita dapat menampilkan gambar yang berasal dari link url menggunakan image component. Terdapat beberapa ukuran ratio yang dapat disetup di image component ini.\
\
Ikuti step step cara menampilkan gambar dari link url menggunakan image component.

1\. Pilih atau tambahkan halaman yang ingin kita tambahkan gambar.\
Sebagai contoh kita ingin menampilkan gambar di halaman profile, maka kita perlu memilih halaman profile sehingga akan muncul highlight biru seperti berikut ini.

![](/files/iJ6EFr6VgTLqo2TReMZj)

2\. Kemudian tambahkan component image yang berada pada category media.

![](/files/Djs7kBXD0mxzcJAbLw2W)

3\. Setelah berhasil menambahkan component image, aktifkan component image untuk mulai mengatur component tersebut.

![](/files/E40jJs9xdadE6KOzJaHy)

4\. Copy link url gambar pada setting source di component image.\
Setelah berhasil mengcopy link url maka di emulator akan muncul gambar dari url tersebut.

![](/files/IGAGj9GVPUp4ZeUTE5hI)


# Horizontal Tile Component

Horizontal tile merupakan category dari list component dimana data akan ditampilkan secara horizontal sehingga user dapat scrolling data dari kanan ke kiri di aplikasi.\
\
Di component ini kita juga dapat menampilkan gambar dari kumpulan data yang ada di table.&#x20;

\
Ikuti step step cara menampilkan gambar menggunakan horizontal tile component.

1\. Setup kumpulan gambar di table Qore.\
Pada step pertama ini kita akan membuat tabel baru yang berisi informasi nama (type: text) dan file (type:file).

![](/files/a1rVSMAztwv7BXl1IbFi)

2\. Setelah berhasil di step 1, selanjutnya kita akan mulai menambahkan component horizontal tile di editor aplikasi. Kita awali dengan mengakses app editor terlebih dahulu, kemudian ikuti simple step berikut

* Go to app builder, dari menu table klik menu apps kemudian pilih salah satu apps yang ingin kita edit.\
  ![](/files/rxc7CdFyq3oBYd9YfXQI)
* Pilih atau tambahkan halaman yang ingin kita tambahkan gambar \
  ![](/files/MNfxAixXtHvFVR4CrdCd)
* Tambahkan component horizontal tile pada category list\
  ![](/files/8BOv7cqAObuqVHN5wPrG)
* Aktifkan component horizontal untuk mulai mengatur data \
  ![](/files/KAG1nG3gNUoHKEm6qgVz)

3\. Kemudian kita dapat sesuaikan source table yang berisi data gambar yang ingin kita tampilkan di aplikasi. Source akan berisi list table yang ada.<br>

![](/files/aSLLYdVYROV9oAJ1WTZj)

4\. Lalu pilih kolom dari table/view source yang menyimpan informasi gambar dengan mengetikkan @namakolom pada image setting\
![](/files/eyyMpgWByaOQHn05HcK8)

5\. Jika berhasil maka akan muncul gambar di emulator screen sesuai dengan data di table promo yang sebelumnya telah ditambahkan.

![](/files/KIUFFkuDo2WxAKn9RIL9)


# List Component

List merupakan salah satu component untuk display kumpulan data yang ada di table Qore. Pada component list kita juga dapat menampilkan gambar, apabila pada kumpulan data tersebut memiliki entity gambar.

\
Ikuti step step cara menampilkan gambar dari kumpulan data menggunakan list component.

1\. Setup kumpulan gambar di table Qore.\
Pada step pertama ini kita akan membuat tabel baru yang berisi informasi nama (type: text) dan file (type:file).

![](/files/a1rVSMAztwv7BXl1IbFi)

2\. Setelah berhasil di step 1, selanjutnya kita akan mulai menambahkan component list di editor aplikasi. Kita awali dengan mengakses app editor terlebih dahulu, kemudian ikuti simple step berikut

* Go to app builder, dari menu table klik menu apps kemudian pilih salah satu apps yang ingin kita edit.\
  ![](/files/rxc7CdFyq3oBYd9YfXQI)
* Pilih atau tambahkan halaman yang ingin kita tambahkan gambar \
  ![](/files/MNfxAixXtHvFVR4CrdCd)
* Tambahkan component list pada category list\
  ![](/files/bgXlfM2Hf6pkX8swBAi8)
* Aktifkan component list untuk mulai mengatur data \
  ![](/files/zxPi6mEYu7H8HWLwQO9A)

3\. Kemudian kita dapat sesuaikan source table yang berisi data gambar yang ingin kita tampilkan di aplikasi. Source akan berisi list table yang ada.

![](/files/sNuq2KtNQYMiBGTlxZCx)

4\. Lalu pilih kolom dari table/view source yang menyimpan informasi gambar dengan mengetikkan @namakolom pada properties thumbnail.

![](/files/w3tJhlMrcjkIpbYWL5Yd)

5\. Jika berhasil maka akan muncul gambar di emulator screen sesuai dengan data di table promo yang sebelumnya telah ditambahkan.

![](/files/QTCxscZkWDRV8QvHGxPS)


# List Card Component

List card ini merupakan bentuk style lain dari list component, namun memiliki fungsi yang sama yakni menampilkan kumpulan data. Apabila kumpulan data tersebut memiliki data image maka kita dapat menampilkannya menggunakan component ini.

\
Ikuti step step cara menampilkan gambar dari kumpulan data menggunakan list card component.

1\. Setup kumpulan gambar di table Qore.\
Pada step pertama ini kita akan membuat tabel baru yang berisi informasi nama (type: text) dan file (type:file).

![](/files/a1rVSMAztwv7BXl1IbFi)

2\. Setelah berhasil di step 1, selanjutnya kita akan mulai menambahkan component list card di editor aplikasi. Kita awali dengan mengakses app editor terlebih dahulu, kemudian ikuti simple step berikut

* Go to app builder, dari menu table klik menu apps kemudian pilih salah satu apps yang ingin kita edit.\
  ![](/files/rxc7CdFyq3oBYd9YfXQI)
* Pilih atau tambahkan halaman yang ingin kita tambahkan gambar \
  ![](/files/MNfxAixXtHvFVR4CrdCd)
* Tambahkan component list card pada category list\
  ![](/files/J1ecjXvstxCOaQi0ULDq)
* Aktifkan component list card untuk mulai mengatur data ![](/files/QT2ejQ4UrQiT52YTNEYd)

3\. Kemudian kita dapat sesuaikan source table yang berisi data gambar yang ingin kita tampilkan di aplikasi. Source akan berisi list table yang ada.

![](/files/Mb20a1p0LjDJRoCa2NlK)

4\. Lalu pilih kolom dari table/view source yang menyimpan informasi gambar dengan mengetikkan @namakolom pada properties images.

![](/files/GqEQX52njlQqlL66uUFH)

5\. Jika berhasil maka akan muncul gambar di emulator screen sesuai dengan data di table promo yang sebelumnya telah ditambahkan.

![](/files/73IpzTnxGspnyqIQR28V)


# Vertical Tile Component

Vertical Tile Component ini merupakan bentuk style lain dari list component, namun memiliki fungsi yang sama yakni menampilkan kumpulan data. Apabila kumpulan data tersebut memiliki data image maka kita dapat menampilkannya menggunakan component ini.

Vertical Tile Component ini memiliki result gambar yang lebih besar dibandingkan dengan component category list lainnya. Kamu dapat melihat hasilnya di akhir step step cara menampilkan gambar.

\
Ikuti step step cara menampilkan gambar dari kumpulan data menggunakan vertical tile component.

1\. Setup kumpulan gambar di table Qore.\
Pada step pertama ini kita akan membuat tabel baru yang berisi informasi nama (type: text) dan file (type:file).

![](/files/a1rVSMAztwv7BXl1IbFi)

2\. Setelah berhasil di step 1, selanjutnya kita akan mulai menambahkan component vertical tile di editor aplikasi. Kita awali dengan mengakses app editor terlebih dahulu, kemudian ikuti simple step berikut

* Go to app builder, dari menu table klik menu apps kemudian pilih salah satu apps yang ingin kita edit.\
  ![](/files/rxc7CdFyq3oBYd9YfXQI)
* Pilih atau tambahkan halaman yang ingin kita tambahkan gambar \
  ![](/files/MNfxAixXtHvFVR4CrdCd)
* Tambahkan component vertical tile pada category list\
  ![](/files/0997kQOrdsQLJRuNL2QW)
* Aktifkan component vertical tile untuk mulai mengatur data \
  ![](/files/AwNamlH6oVKHY5UOZKXY)

3\. Kemudian kita dapat sesuaikan source table yang berisi data gambar yang ingin kita tampilkan di aplikasi. Source akan berisi list table yang ada.

![](/files/527XZNuEpW9xELpYM1Tl)

4\. Lalu pilih kolom dari table/view source yang menyimpan informasi gambar dengan mengetikkan @namakolom pada properties image.

![](/files/G0sJwewTZllInsWLzExq)

5\. Jika berhasil maka akan muncul gambar di emulator screen sesuai dengan data di table promo yang sebelumnya telah ditambahkan.

![](/files/QeKGSveSS9CTSLVfpwzt)


# How to display filtered data from table

Apabila kamu ingin menampilkan kumpulan data di aplikasi, dimana data yang akan ditampilkan itu merupakan data hasil proses filter. Kamu dapat mengikuti step by step yang akan disampaikan di tutorial ini.

Sebelum kita mengatur component ataupun gambar yang ingin ditampilkan di editor, ada beberapa hal yang perlu dipersiapkan yakni membuat table data.

**Step 1** , Siapkan table dan view yang akan menjadi source data.&#x20;

Misalkan kita memiliki data menu makanan dengan 3 category yakni seafood, vegetarian, meaty.

![](/files/wQuOYioxFslltmCYZDUX)

**Step 2**, Pisahkan data berdasarkan categorynya menggunakan grid view. \
Untuk mengetahui cara memisahkan data dan membuat view baru dari table kamu dapat membaca di tutorial berikut [Broken mention](broken://pages/RQ7VBT2YYAFKuwVhgk3e). \
\
Setelah dipisahkan maka tampilan table akan menjadi seperti ini

![](/files/vq8UNb8zONgsKPKmH9Hc)

**Step 3,** Go to app editor aplikasi kemudian pilih atau tambahkan halaman yang ingin kita tambahkan gambar.<br>

![](/files/MNfxAixXtHvFVR4CrdCd)

**Step 4,** Menampilkan list menu berdasarkan category di aplikasi.\
Untuk menampilkan daftar menu ini kita dapat menggunakan component horizontal tile ataupun component category list lainnya.&#x20;

1. Tambahkan component horizontal tile di category list \
   ![](/files/8BOv7cqAObuqVHN5wPrG)
2. Aktifkan component horizontal untuk mulai mengatur data \
   ![](/files/KAG1nG3gNUoHKEm6qgVz)
3. Kemudian kita dapat sesuaikan source table yang berisi data gambar yang ingin kita tampilkan di aplikasi. Source akan berisi list table yang ada. \ <img src="/files/aSLLYdVYROV9oAJ1WTZj" alt="" data-size="original">
4. Dikarenakan kita ingin menampilkan list dari ketiga category makanan, maka kita dapat memilih view dari salah satu category.
5. Lalu sesuaikan data yang ingin ditampilkan pada component setting.\
   Setting ini dapat disesuaikan dengan kebutuhan kamu, atau kamu juga dapat mengikuti contoh berikut ini

   -Header : Menu seafood\
   -Title : Data dari kolom name \
   -Image : Data dari kolom gambar\
   -Caption : Data dari kolom category\
   \
   ![](/files/CK3er1nsEXb7JucJ7FVz)
6. Tambahkan juga untuk category menu lainnya dengan mengulangi step 4 (point 4-5).<br>

**Step 5,** apabila semua list telah ditambahkan maka di halaman tersebut akan nampak seperti ini.

![](/files/0YLTWWwScewFhVdOV0RJ)


# How to filter data on table/view

Di table Qore kita dapat memfilter data yang kita butuhkan berdasarkan dengan kolom yang ada di table tersebut. Setelah berhasil apply filter maka data yang ada di table akan tersortir berdasarkan setting yang dipilih.

Pada setting filter terdapat 2 logic apabila kita memiliki lebih dari satu rule untuk memfilter data yaitu Any dan All. Logic **Any = OR** digunakan apabila kita ingin memfilter data yang memiliki salah satu diantara rule yang disetup. Sedangkan Logic **All = AND** digunakan apabila kita ingin memfilter data yang memiliki kedua rule yang disetup. <br>

Untuk lebih mengetahui kegunaan masing-masing rule tersebut ikuti mini demo dibawah ini.

### Mini Demo

\
**Step 1**, Siapkan data table dan sebagai contoh kita memiliki data permintaan pinjaman uang seperti berikut&#x20;

![](/files/mjuFatvxXzqmviXzeHXT)

**Step 2 ,** Tambahkan filter pada table tersebut.\
Sebagai contoh kita ingin memfilter data permintaan pinjaman yang memiliki **jumlah pinjaman lebih dari 5.000.000** <mark style="color:blue;">**DAN**</mark> **tenor kurang dari 6 bulan**.

1. Klik button filter maka akan muncul pop up setting filter\
   ![](/files/NTy6chCV1xpSosluNvxB)
2. Di pop up setting filter klik **button add filter**\
   ![](/files/1y0f84FvVJ6HhvAhWZVu)
3. Tambahkan kolom jumlah pinjaman pada filter setting, pilih operator ">" , inputkan value "5000000"\
   ![](/files/Q7XAFKHBEdoxRjIOl46w)
4. Lalu tambahkan kolom tenor sebagai rule kedua di filter setting, dan pilih operator "<" inputkan value "6"\
   ![](/files/q1f5GObGliIdnRLQQOF4)
5. Karena terdapat dua rule di filter setting, kita perlu menentukan logic filternya apakah menggunakan All atau Any. Jika kita ingin kedua rule tersebut terpenuhi dan kata kuncinya adalah <mark style="color:blue;">**DAN**</mark> maka kita akan memilih logic **All.**\
   \
   ![](/files/2JtpJhATKVugZ2nPw7gg)
6. Kemudian step yang terakhir untuk menyimpan filter setting yakni klik button apply filter.\
   ![](/files/DNLBIhOjZaOmcxI0txBW)
7. Kemudian akan menampilkan berapa jumlah rule yang ada di filter tersebut dan data table akan otomatis menyesuaikan filter yang telah di apply.\
   ![](/files/9aDClHVu7B55QwWllstp)<br>


# Save configuration filter on table/view

Pada step sebelumnya kita telah mengetahui bagaimana cara memfilter data table [Broken mention](broken://pages/a9SlfTY3gAMLEliT42qD), kemudian pada tutorial kali ini kita akan membahas bagaimana menyimpan setting filter tersebut. Ketika setting filter disimpan maka akan digenerate sebagai grid view atau bentuk lain dari table tersebut.\
\
Ikuti step step berikut ini untuk menyimpan setting filter

1\. Setelah melakukan step dan step di tutorial sebelumnya [Broken mention](broken://pages/a9SlfTY3gAMLEliT42qD), kita dapat menyimpan filter setting tersebut dengan klik button Save to new view.<br>

![](/files/S14cocsmAfTAd5LgBWBF)

2\. Kemudian akan muncul pesan konfirmasi untuk membuat view baru, klik button Save modification as a new view.

![](/files/hr7GEXyfrdyjMvnzV6et)

3\. Tentukan nama view baru yang akan berisi setting filter. Lalu klik button create.<br>

![](/files/fK7iLyyTvv4IVRh7bS7A)

4\. Jika berhasil maka akan muncul view baru yang menjadi table child dari table request pinjaman.

![](/files/VI14pKS0gzI1YknSLd2b)

5\. Apabila nantinya terdapat perubahan filter setting, kita dapat mengupdate perubahannya dengan klik button save view config.

![](/files/AcJxdBvIFwZTzpKnSDOy)

Data di grid view tersebut juga akan terupdate sesuai dengan setting filter yang baru.

![](/files/zyc5UssNa7UM03DILKdp)


# Create list of restaurant menu

Dengan menggunakan Qore, kita dapat menampilkan data dalam bentuk list serta menambahkan detail data dari list tersebut.\
\
Sebagai contoh usecase kita akan coba untuk membuat daftar menu restoran dan detail menunya. Simak langkah-langkahnya dibawah ini&#x20;

1. Kita perlu untuk membuat collection datanya terlebih dahulu di table Qore.\
   dengan menambahkan column name, category dan image. Sehingga tampilan table akan menjadi seperti ini.\
   ![](/files/nVZ89wAFRQ6bghtePryG)
2. Setelah menyiapkan collection data kita dapat menuju ke app editor dari aplikasi menu restoran ini.
3. Di halaman editor aplikasi buat halaman navigasi untuk menampilkan daftar menunya. Misalkan kita ingin menampilkannya di halaman menu, maka aktifkan halaman menu terlebih dahulu\
   .![](/files/1dLS39sOC6ojwz6rd2Zd)
4. Setelah itu mulai menambahkan component list, dan di app editor telah menyediakan beberapa macam type list yakni list, list card, horizontal tile dan vertical. Untuk menu restaurant ini kita dapat memilih component list dengan type list card.\
   ![](/files/xxj6UERkL07p3fT73iHD)
5. Selanjutnya kita dapat menyesuaikan setting component list card, agar data yang ditampilkan di aplikasi sesuai dengan keinginan. Maka yang perlu kita lakukan yakni

   * Menentukan source data yang akan ditampilkan di list, ketika kita klik source data maka akan terdapat pilihan table dan view. Kita dapat memilih table/view menu yang sebelumnya telah dibuat di step 1.\
     ![](/files/KKkuDLRpBIGUWbIJewio)
   * Setelah menentukan source maka tampilan component di emulator akan menyesuaikan jumlah card list berdasarkan jumlah data dari view/table yang dipilih.\
     ![](/files/m3xX9A03CET9sFQ00r9o)
   * Kemudian sesuaikan data dengan kolom yang ada di table dan view\
     ![](/files/xXl7C7y5qahys8Gr5BTC)\
     \
     Kamu juga bisa menyesuaikan lagi design setting, ataupun menambahkan thumbnail di component tersebut.

   6\. Setelah berhasil mengatur data dan style component list card, selanjutnya kita akan mulai menambahkan action pada component tersebut.
6. Action component ini akan dijalankan apabila user klik salah satu data yang ada di list. Terdapat beberapa pilihan action, dan kita dapat memilih action view detail untuk menampilkan detail menu yang dipilih oleh user.\
   ![](/files/BwJ513yKq9W3PXzySJqH)
7. Jika sudah coba untuk mengakses halaman detail yang baru terbentuk setelah kita setup action menjadi view detail.\
   ![](/files/zyNzARaPKUIvAt848Zqg) ![](/files/wNZRqhshww4mvOgfF0vB)<br>
8. Di halaman detail page kita dapat sesuaikan lagi component dan data yang ingin ditampilkan, untuk itu kita dapat menambahkan component&#x20;

   * Image -> menampilkan gambar menu \
     ![](/files/WeFXTNj36Ud8wtPg9Nlv) ![](/files/zBf7eLqyGIMXaq5U8PoC)
   * Text -> menampilkan judul menu\
     ![](/files/AazF9EaFTqhPjoZdvMNF)![](/files/S3RrdBrq2iTtFJJ9jOye)
   * Description text -> menampilkan category menu\
     ![](/files/JQMDqVu7aJbqeNhlOCbG)<br>

   9\. Setelah berhasil menyelesaikan step-step di point 8, maka kita dapat mencoba hasilnya dengan klik data menu lainnya maka halaman detail akan menampilkan data yang sesuai.\
   &#x20;![](/files/9rkiV1UagLLmsqG4msXc)  ![](/files/jPADSU1J0671s9tsNO5J)<br>


