Merge branch 'develop' into feature/multi-tenants
This commit is contained in:
commit
ec26f6ab5e
|
@ -152,6 +152,35 @@
|
||||||
"contributions": [
|
"contributions": [
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "seoulaja",
|
||||||
|
"name": "seoulaja",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/15101654?v=4",
|
||||||
|
"profile": "https://github.com/seoulaja",
|
||||||
|
"contributions": [
|
||||||
|
"translation"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"login": "mslourens",
|
||||||
|
"name": "Maurits Lourens",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/1907152?v=4",
|
||||||
|
"profile": "https://github.com/mslourens",
|
||||||
|
"contributions": [
|
||||||
|
"test",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Rory-Powell",
|
||||||
|
"name": "Rory Powell",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/8755148?v=4",
|
||||||
|
"profile": "https://github.com/Rory-Powell",
|
||||||
|
"contributions": [
|
||||||
|
"infra",
|
||||||
|
"test",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
|
|
@ -221,6 +221,11 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
||||||
<td align="center"><a href="https://github.com/victoriasloan"><img src="https://avatars.githubusercontent.com/u/9913651?v=4?s=100" width="100px;" alt=""/><br /><sub><b>victoriasloan</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=victoriasloan" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/victoriasloan"><img src="https://avatars.githubusercontent.com/u/9913651?v=4?s=100" width="100px;" alt=""/><br /><sub><b>victoriasloan</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=victoriasloan" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/yashank09"><img src="https://avatars.githubusercontent.com/u/37672190?v=4?s=100" width="100px;" alt=""/><br /><sub><b>yashank09</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=yashank09" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/yashank09"><img src="https://avatars.githubusercontent.com/u/37672190?v=4?s=100" width="100px;" alt=""/><br /><sub><b>yashank09</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=yashank09" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://github.com/SOVLOOKUP"><img src="https://avatars.githubusercontent.com/u/53158137?v=4?s=100" width="100px;" alt=""/><br /><sub><b>SOVLOOKUP</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=SOVLOOKUP" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/SOVLOOKUP"><img src="https://avatars.githubusercontent.com/u/53158137?v=4?s=100" width="100px;" alt=""/><br /><sub><b>SOVLOOKUP</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=SOVLOOKUP" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/seoulaja"><img src="https://avatars.githubusercontent.com/u/15101654?v=4?s=100" width="100px;" alt=""/><br /><sub><b>seoulaja</b></sub></a><br /><a href="#translation-seoulaja" title="Translation">🌍</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/mslourens"><img src="https://avatars.githubusercontent.com/u/1907152?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Maurits Lourens</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=mslourens" title="Tests">⚠️</a> <a href="https://github.com/Budibase/budibase/commits?author=mslourens" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/Rory-Powell"><img src="https://avatars.githubusercontent.com/u/8755148?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rory Powell</b></sub></a><br /><a href="#infra-Rory-Powell" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/Budibase/budibase/commits?author=Rory-Powell" title="Tests">⚠️</a> <a href="https://github.com/Budibase/budibase/commits?author=Rory-Powell" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,230 @@
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://www.budibase.com">
|
||||||
|
<img alt="Budibase" src="https://d33wubrfki0l68.cloudfront.net/aac32159d7207b5085e74a7ef67afbb7027786c5/2b1fd/img/logo/bb-emblem.svg" width="60" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<h1 align="center">
|
||||||
|
Budibase
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<h3 align="center">
|
||||||
|
Membangun, mengotomatisasi dan <i>hosting</i> sendiri aplikasi internal dalam hitungan menit
|
||||||
|
</h3>
|
||||||
|
<p align="center">
|
||||||
|
Budibase adalah sebuah platform <i>low-code</i> dengan sumber terbuka, bertujuan untuk membantu para <i>developer</i> dan professional IT, untuk membangun, mengotomatisasi, dan mengirimkan aplikasi internal di infrastruktur sendiri dalam waktu hitungan menit.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 align="center">
|
||||||
|
🤖 🎨 🚀
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img alt="Budibase design ui" src="https://i.imgur.com/5BnXPsN.png">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/Budibase/budibase/releases">
|
||||||
|
<img alt="GitHub all releases" src="https://img.shields.io/github/downloads/Budibase/budibase/total">
|
||||||
|
</a>
|
||||||
|
<a href="https://github.com/Budibase/budibase/releases">
|
||||||
|
<img alt="GitHub release (latest by date)" src="https://img.shields.io/github/v/release/Budibase/budibase">
|
||||||
|
</a>
|
||||||
|
<a href="https://twitter.com/intent/follow?screen_name=budibase">
|
||||||
|
<img src="https://img.shields.io/twitter/follow/budibase?style=social" alt="Follow @budibase" />
|
||||||
|
</a>
|
||||||
|
<img src="https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg" alt="Code of conduct" />
|
||||||
|
<a href="https://codecov.io/gh/Budibase/budibase">
|
||||||
|
<img src="https://codecov.io/gh/Budibase/budibase/graph/badge.svg?token=E8W2ZFXQOH"/>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 align="center">
|
||||||
|
<a href="https://docs.budibase.com/getting-started">Memulai</a>
|
||||||
|
<span> · </span>
|
||||||
|
<a href="https://docs.budibase.com">Dokumentasi</a>
|
||||||
|
<span> · </span>
|
||||||
|
<a href="https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas">Permintaan Fitur</a>
|
||||||
|
<span> · </span>
|
||||||
|
<a href="https://github.com/Budibase/budibase/issues">Laporkan bug</a>
|
||||||
|
<span> · </span>
|
||||||
|
Bantuan: <a href="https://github.com/Budibase/budibase/discussions">Diskusi</a>
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
## ✨ Fitur-fitur
|
||||||
|
|
||||||
|
- **Membangun dan mengirimkan perangkat lunak sebenarnya .** Tidak seperti platform lain, dengan Budibase Anda membuat dan mengirimkan aplikasi-aplikasi satu halaman. Aplikasi-aplikasi Budibase memiliki kinerja yang matang dan dapat dirancang secara responsif, memberikan pengalaman yang menyenangkan bagi pengguna.
|
||||||
|
|
||||||
|
- **Sumber terbuka dan dapat dikembangkan.** Budibase adalah platform dengan sumber terbuka - dilisensikan sebagai GPL v3. Ini akan membuat Anda yakin bahwa Budibase akan selalu ada. Anda juga dapat berkontribusi terhadap kode Budibase atau melakukan <i>fork</i> dan membuat perubahan sesuka Anda, memberikan pengalaman yang ramah developer.
|
||||||
|
|
||||||
|
- **Memuat data atau mulai dari awal.** Budibase menarik data dari berbagai sumber, termasuk MongoDB, CouchDB, PostgreSQL, mySQL, Airtable, S3, DyanmoDB, atau REST API. Dan tidak seperti platform lain, dengan Budibase Anda dapat memulai dari awal dan membuat aplikasi bisnis tanpa sumber data sekalipun. [Permintaan untuk sumber data baru](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas).
|
||||||
|
|
||||||
|
- **Rancang dan bangun aplikasi dengan komponen siap pakai yang kuat.** Budibase tersedia dengan siap pakai dan dirancang dengan indah, komponen-komponen kuat yang dapat anda gunakan layaknya blok penyusun untuk merancang antar muka Anda. Kami juga menyediakan banyak sekali pilihan-pilihan CSS favorit yang dapat digunakan sesuai dengan kreatifitas yang Anda inginkan. [Permintaan komponen baru [Permintaan untuk komponen baru](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas).
|
||||||
|
|
||||||
|
- **Otomatiskan proses, integrasikan dengan aplikasi lain, dan sambungkan ke webhook.** Menghemat waktu dengan mengotomatisasikan proses dan alur kerja yang masih dikerjakan secara manual. Dari menghubungkan ke webhooks, hingga mengotomatiasi surel, cukup beritahu Budibase apa yang harus dilakukan dan biarkan dia berkerja untuk Anda. Anda bisa dengan mudah [membuat otomatisasi baru untuk Budibase disini ](https://github.com/Budibase/automations) atau [minta otomatisasi baru](https://github.com/Budibase/budibase/discussions?discussions_q=category%3AIdeas).
|
||||||
|
|
||||||
|
- **Surga bagi Admin.** Budibase dibuat untuk berkembang. Dengan Budibase, Anda dapat meng<i>hosting</i> sendiri di infrastruktrur Anda punya dan secara global mengelola para pengguna, orientasi, SMTP, aplikasi-aplikasi, grup-grup, tema, dan masih masih banyak lagi. Anda juga dapat menyediakan para pengguna/grup dengan sebuah aplikasi portal dan menyebarkan pengelolaan pengguna kepada manaajer grup.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## 🏁 Memulai
|
||||||
|
Saat ini ada 2 cara untuk memulai Budibase, yaitu: Digital Ocean dan Docker.
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
### Memulai Dengan Digital Ocean
|
||||||
|
Cara paling mudah dan cepat untuk memulai adalah dengan menggunakan Digital Ocean:
|
||||||
|
<a href="https://marketplace.digitalocean.com/apps/budibase">1-klik Digital Ocean <i>deploy</i></a>
|
||||||
|
|
||||||
|
<a href="https://marketplace.digitalocean.com/apps/budibase">
|
||||||
|
<img src="https://user-images.githubusercontent.com/552074/87779219-5c3b7600-c824-11ea-9898-981a8ba94f6c.png" alt="digital ocean badge">
|
||||||
|
</a>
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
### Memulai dengan Docker
|
||||||
|
Untuk memulai, Anda harus memiliki docker dan docker compose ter<i>install</i> di mesin anda.
|
||||||
|
Setelah Anda docker ter<i>install</i>, prosesnya akan memakan waktu 5 menit, dengan empat langkah ini:
|
||||||
|
|
||||||
|
1. <i>Install</i> CLI Budibase.
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npm i -g @budibase/cli
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
2. Mempersiapkan Budibase (pilih tempat menyimpan Budibase dan <i>port</i> untuk menjalankannya)
|
||||||
|
|
||||||
|
```
|
||||||
|
budi hosting --init
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
3. Jalankan Budibase
|
||||||
|
|
||||||
|
```
|
||||||
|
budi hosting --start
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
4. Buat pengguna admin Anda
|
||||||
|
|
||||||
|
Masukkan surel dan sandi untuk admin baru.
|
||||||
|
|
||||||
|
Selesai! Anda sekarang siap untuk membangun aplikasi internal yang mumpuni dalam hitungan menit. Untuk informasi tambahan tentang cara memulai dan mempelajari Budibase, kunjungi [dokumentasi](https://docs.budibase.com/getting-started) kami.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## 🎓 Belajar Budibase
|
||||||
|
|
||||||
|
Dokumentasi Budibase [dapat dilihat disini](https://docs.budibase.com).
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
## 💬 Komunitas
|
||||||
|
|
||||||
|
Jika Anda memiliki pertanyaan atau ingin berbicara dengan pengguna Budibase lainnya dan bergabung dengan komunitas kami, silakan kunjungi [Diskusi Github](https://github.com/Budibase/budibase/discussions)
|
||||||
|
|
||||||
|
<img src="https://d33wubrfki0l68.cloudfront.net/e9241201fd89f9abbbdaac4fe44bb16312752abe/84013/img/hero-images/community.webp" />
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## ❗ Kode etik
|
||||||
|
|
||||||
|
Budibase berdedikasi untuk memberikan pengalaman yang ramah, beragam, dan bebas pelecehan bagi semua orang. Kami mengharapkan semua orang di komunitas Budibase untuk mematuhi [**Kode etik**](https://github.com/Budibase/budibase/blob/HEAD/.github/CODE_OF_CONDUCT.md). Mohon dibaca.
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## 🙌 Berkontribusi untuk Budibase
|
||||||
|
|
||||||
|
Dari membuka laporan bug hingga membuat <i>pull request</i>: setiap kontribusi dihargai dan disambut. Jika Anda berencana untuk menerapkan fitur baru atau mengubah API, harap buat <i>issue</i> terlebih dahulu. Dengan cara ini kami dapat memastikan pekerjaan Anda tidak sia-sia.
|
||||||
|
|
||||||
|
### Tidak yakin memulai dari mana?
|
||||||
|
Sebuat tempat yang baik untuk mulai berkontribusi, adalah [masalah pertama di proyek](https://github.com/Budibase/budibase/projects/22).
|
||||||
|
|
||||||
|
### Bagaimana repositori diatur
|
||||||
|
Budibase adalah <i>monorepo</i> yang dikelola oleh lerna. Lerna mengelola pembangunan dan penerbitan paket Budibase. Pada level tinggi, inilah paket-paket yang membentuk Budibase.
|
||||||
|
|
||||||
|
- [packages/builder](https://github.com/Budibase/budibase/tree/HEAD/packages/builder) - berisi kode untuk aplikasi svelte sisi klien pembangun Budibase.
|
||||||
|
|
||||||
|
- [packages/client](https://github.com/Budibase/budibase/tree/HEAD/packages/client) - Modul yang berjalan di <i>browser</i> yang bertanggung jawab untuk membaca definisi JSON dan membuat aplikasi web yang hidup dan bernafas darinya.
|
||||||
|
|
||||||
|
- [packages/server](https://github.com/Budibase/budibase/tree/HEAD/packages/server) - <i>Server</i> Budibase. Aplikasi Koa ini bertanggung jawab untuk melayani JS untuk aplikasi builder dan budibase, serta menyediakan API untuk interaksi dengan database dan sistem file.
|
||||||
|
|
||||||
|
Untuk informasi lebih lanjut, lihat [CONTRIBUTING.md](https://github.com/Budibase/budibase/blob/HEAD/.github/CONTRIBUTING.md)
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
## 📝 Lisensi
|
||||||
|
|
||||||
|
Budibase adalah sumber terbuka, dilisensikan sebagai [GPL v3](https://www.gnu.org/licenses/gpl-3.0.en.html). Pustaka klien dan komponen dilisensikan sebagai [MPL](https://directory.fsf.org/wiki/License:MPL-2.0) - sehingga aplikasi yang Anda buat dapat dilisensikan sesuka Anda.
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
## ⭐ Stargazers over time
|
||||||
|
|
||||||
|
[![Stargazers over time](https://starchart.cc/Budibase/budibase.svg)](https://starchart.cc/Budibase/budibase)
|
||||||
|
|
||||||
|
Jika Anda mengalami masalah di antara pembaruan, silakan gunakan panduan [disini](https://github.com/Budibase/budibase/blob/HEAD/.github/CONTRIBUTING.md#troubleshooting) untuk membersihkan <i>environment</i> Anda.
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
|
||||||
|
## Kontributor ✨
|
||||||
|
|
||||||
|
Terima kasih untuk orang-orang hebat ini ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
||||||
|
<!-- prettier-ignore-start -->
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="http://martinmck.com"><img src="https://avatars1.githubusercontent.com/u/11256663?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Martin McKeaveney</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=shogunpurple" title="Code">💻</a> <a href="https://github.com/Budibase/budibase/commits?author=shogunpurple" title="Documentation">📖</a> <a href="https://github.com/Budibase/budibase/commits?author=shogunpurple" title="Tests">⚠️</a> <a href="#infra-shogunpurple" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||||
|
<td align="center"><a href="http://www.michaeldrury.co.uk/"><img src="https://avatars2.githubusercontent.com/u/4407001?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Drury</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=mike12345567" title="Documentation">📖</a> <a href="https://github.com/Budibase/budibase/commits?author=mike12345567" title="Code">💻</a> <a href="https://github.com/Budibase/budibase/commits?author=mike12345567" title="Tests">⚠️</a> <a href="#infra-mike12345567" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/aptkingston"><img src="https://avatars3.githubusercontent.com/u/9075550?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Kingston</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=aptkingston" title="Documentation">📖</a> <a href="https://github.com/Budibase/budibase/commits?author=aptkingston" title="Code">💻</a> <a href="https://github.com/Budibase/budibase/commits?author=aptkingston" title="Tests">⚠️</a> <a href="#design-aptkingston" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://budibase.com/"><img src="https://avatars3.githubusercontent.com/u/3524181?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Shanks</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=mjashanks" title="Documentation">📖</a> <a href="https://github.com/Budibase/budibase/commits?author=mjashanks" title="Code">💻</a> <a href="https://github.com/Budibase/budibase/commits?author=mjashanks" title="Tests">⚠️</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/kevmodrome"><img src="https://avatars3.githubusercontent.com/u/534488?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kevin Åberg Kultalahti</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=kevmodrome" title="Documentation">📖</a> <a href="https://github.com/Budibase/budibase/commits?author=kevmodrome" title="Code">💻</a> <a href="https://github.com/Budibase/budibase/commits?author=kevmodrome" title="Tests">⚠️</a></td>
|
||||||
|
<td align="center"><a href="https://www.budibase.com/"><img src="https://avatars2.githubusercontent.com/u/49767913?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Joe</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=joebudi" title="Documentation">📖</a> <a href="https://github.com/Budibase/budibase/commits?author=joebudi" title="Code">💻</a> <a href="#content-joebudi" title="Content">🖋</a> <a href="#design-joebudi" title="Design">🎨</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Conor-Mack"><img src="https://avatars1.githubusercontent.com/u/36074859?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Conor_Mack</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=Conor-Mack" title="Code">💻</a> <a href="https://github.com/Budibase/budibase/commits?author=Conor-Mack" title="Tests">⚠️</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://github.com/pngwn"><img src="https://avatars1.githubusercontent.com/u/12937446?v=4?s=100" width="100px;" alt=""/><br /><sub><b>pngwn</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=pngwn" title="Code">💻</a> <a href="https://github.com/Budibase/budibase/commits?author=pngwn" title="Tests">⚠️</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/HugoLd"><img src="https://avatars0.githubusercontent.com/u/26521848?v=4?s=100" width="100px;" alt=""/><br /><sub><b>HugoLd</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=HugoLd" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/victoriasloan"><img src="https://avatars.githubusercontent.com/u/9913651?v=4?s=100" width="100px;" alt=""/><br /><sub><b>victoriasloan</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=victoriasloan" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/yashank09"><img src="https://avatars.githubusercontent.com/u/37672190?v=4?s=100" width="100px;" alt=""/><br /><sub><b>yashank09</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=yashank09" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/SOVLOOKUP"><img src="https://avatars.githubusercontent.com/u/53158137?v=4?s=100" width="100px;" alt=""/><br /><sub><b>SOVLOOKUP</b></sub></a><br /><a href="https://github.com/Budibase/budibase/commits?author=SOVLOOKUP" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||||
|
|
||||||
|
Proyek ini mengikuti spesifikasi [all-contributors](https://github.com/all-contributors/all-contributors). Kontribusi dalam bentuk apa pun dipersilakan!
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"packages": [
|
"packages": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/auth",
|
"name": "@budibase/auth",
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"description": "Authentication middlewares for budibase builder and apps",
|
"description": "Authentication middlewares for budibase builder and apps",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
|
|
|
@ -6,6 +6,7 @@ const { newid } = require("../../hashing")
|
||||||
const { createASession } = require("../../security/sessions")
|
const { createASession } = require("../../security/sessions")
|
||||||
const { getGlobalUserByEmail } = require("../../utils")
|
const { getGlobalUserByEmail } = require("../../utils")
|
||||||
const { getGlobalDB, getTenantId } = require("../../tenancy")
|
const { getGlobalDB, getTenantId } = require("../../tenancy")
|
||||||
|
const fetch = require("node-fetch")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common authentication logic for third parties. e.g. OAuth, OIDC.
|
* Common authentication logic for third parties. e.g. OAuth, OIDC.
|
||||||
|
@ -67,7 +68,7 @@ exports.authenticateThirdParty = async function (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbUser = syncUser(dbUser, thirdPartyUser)
|
dbUser = await syncUser(dbUser, thirdPartyUser)
|
||||||
|
|
||||||
// create or sync the user
|
// create or sync the user
|
||||||
const response = await db.post(dbUser)
|
const response = await db.post(dbUser)
|
||||||
|
@ -89,10 +90,26 @@ exports.authenticateThirdParty = async function (
|
||||||
return done(null, dbUser)
|
return done(null, dbUser)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function syncProfilePicture(user, thirdPartyUser) {
|
||||||
|
const pictureUrl = thirdPartyUser.profile._json.picture
|
||||||
|
if (pictureUrl) {
|
||||||
|
const response = await fetch(pictureUrl)
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
const type = response.headers.get("content-type")
|
||||||
|
if (type.startsWith("image/")) {
|
||||||
|
user.pictureUrl = pictureUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @returns a user that has been sync'd with third party information
|
* @returns a user that has been sync'd with third party information
|
||||||
*/
|
*/
|
||||||
function syncUser(user, thirdPartyUser) {
|
async function syncUser(user, thirdPartyUser) {
|
||||||
// provider
|
// provider
|
||||||
user.provider = thirdPartyUser.provider
|
user.provider = thirdPartyUser.provider
|
||||||
user.providerType = thirdPartyUser.providerType
|
user.providerType = thirdPartyUser.providerType
|
||||||
|
@ -115,6 +132,8 @@ function syncUser(user, thirdPartyUser) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user = await syncProfilePicture(user, thirdPartyUser)
|
||||||
|
|
||||||
// profile
|
// profile
|
||||||
user.thirdPartyProfile = {
|
user.thirdPartyProfile = {
|
||||||
...profile._json,
|
...profile._json,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/bbui",
|
"name": "@budibase/bbui",
|
||||||
"description": "A UI solution used in the different Budibase projects.",
|
"description": "A UI solution used in the different Budibase projects.",
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"svelte": "src/index.js",
|
"svelte": "src/index.js",
|
||||||
"module": "dist/bbui.es.js",
|
"module": "dist/bbui.es.js",
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
export let id = null
|
export let id = null
|
||||||
export let text = null
|
export let text = null
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
|
export let dataCy = null
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const onChange = event => {
|
const onChange = event => {
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
|
|
||||||
<div class="spectrum-Switch spectrum-Switch--emphasized">
|
<div class="spectrum-Switch spectrum-Switch--emphasized">
|
||||||
<input
|
<input
|
||||||
|
data-cy={dataCy}
|
||||||
checked={value}
|
checked={value}
|
||||||
{disabled}
|
{disabled}
|
||||||
on:change={onChange}
|
on:change={onChange}
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
export let text = null
|
export let text = null
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
export let error = null
|
export let error = null
|
||||||
|
export let dataCy = null
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
const onChange = e => {
|
const onChange = e => {
|
||||||
|
@ -18,5 +19,5 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Field {label} {labelPosition} {error}>
|
<Field {label} {labelPosition} {error}>
|
||||||
<Switch {error} {disabled} {text} {value} on:change={onChange} />
|
<Switch {dataCy} {error} {disabled} {text} {value} on:change={onChange} />
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -29,10 +29,10 @@ context("Create a automation", () => {
|
||||||
cy.get(".setup").within(() => {
|
cy.get(".setup").within(() => {
|
||||||
cy.get(".spectrum-Picker-label").click()
|
cy.get(".spectrum-Picker-label").click()
|
||||||
cy.contains("dog").click()
|
cy.contains("dog").click()
|
||||||
cy.get("input")
|
cy.get(".spectrum-Textfield-input")
|
||||||
.first()
|
.first()
|
||||||
.type("goodboy")
|
.type("goodboy")
|
||||||
cy.get("input")
|
cy.get(".spectrum-Textfield-input")
|
||||||
.eq(1)
|
.eq(1)
|
||||||
.type("11")
|
.type("11")
|
||||||
})
|
})
|
||||||
|
@ -41,7 +41,7 @@ context("Create a automation", () => {
|
||||||
cy.contains("Save Automation").click()
|
cy.contains("Save Automation").click()
|
||||||
|
|
||||||
// Activate Automation
|
// Activate Automation
|
||||||
cy.get("[aria-label=PlayCircle]").click()
|
cy.get("[data-cy=activate-automation]").click()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should add row when a new row is added", () => {
|
it("should add row when a new row is added", () => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/builder",
|
"name": "@budibase/builder",
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -65,10 +65,10 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^0.9.80-alpha.9",
|
"@budibase/bbui": "^0.9.87-alpha.7",
|
||||||
"@budibase/client": "^0.9.80-alpha.9",
|
"@budibase/client": "^0.9.87-alpha.7",
|
||||||
"@budibase/colorpicker": "1.1.2",
|
"@budibase/colorpicker": "1.1.2",
|
||||||
"@budibase/string-templates": "^0.9.80-alpha.9",
|
"@budibase/string-templates": "^0.9.87-alpha.7",
|
||||||
"@sentry/browser": "5.19.1",
|
"@sentry/browser": "5.19.1",
|
||||||
"@spectrum-css/page": "^3.0.1",
|
"@spectrum-css/page": "^3.0.1",
|
||||||
"@spectrum-css/vars": "^3.0.1",
|
"@spectrum-css/vars": "^3.0.1",
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { automationStore } from "builderStore"
|
import { automationStore } from "builderStore"
|
||||||
import { database } from "stores/backend"
|
import { database } from "stores/backend"
|
||||||
import { notifications, Icon, Button, Modal, Heading } from "@budibase/bbui"
|
import { notifications, Button, Modal, Heading, Toggle } from "@budibase/bbui"
|
||||||
import AutomationBlockSetup from "./AutomationBlockSetup.svelte"
|
import AutomationBlockSetup from "./AutomationBlockSetup.svelte"
|
||||||
import CreateWebookModal from "../Shared/CreateWebhookModal.svelte"
|
import CreateWebookModal from "../Shared/CreateWebhookModal.svelte"
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
$: automationLive = automation?.live
|
$: automationLive = automation?.live
|
||||||
|
|
||||||
function setAutomationLive(live) {
|
function setAutomationLive(live) {
|
||||||
if (automation.live === live) {
|
if (automationLive === live) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
automation.live = live
|
automation.live = live
|
||||||
|
@ -48,20 +48,11 @@
|
||||||
|
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<Heading size="S">Setup</Heading>
|
<Heading size="S">Setup</Heading>
|
||||||
<Icon
|
<Toggle
|
||||||
l
|
value={automationLive}
|
||||||
disabled={!automationLive}
|
on:change={() => setAutomationLive(!automationLive)}
|
||||||
hoverable={automationLive}
|
dataCy="activate-automation"
|
||||||
name="PauseCircle"
|
text="Live"
|
||||||
on:click={() => setAutomationLive(false)}
|
|
||||||
/>
|
|
||||||
<Icon
|
|
||||||
l
|
|
||||||
name="PlayCircle"
|
|
||||||
disabled={automationLive}
|
|
||||||
hoverable={!automationLive}
|
|
||||||
data-cy="activate-automation"
|
|
||||||
on:click={() => setAutomationLive(true)}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{#if $automationStore.selectedBlock}
|
{#if $automationStore.selectedBlock}
|
||||||
|
@ -69,7 +60,7 @@
|
||||||
bind:block={$automationStore.selectedBlock}
|
bind:block={$automationStore.selectedBlock}
|
||||||
{webhookModal}
|
{webhookModal}
|
||||||
/>
|
/>
|
||||||
{:else if $automationStore.selectedAutomation}
|
{:else if automation}
|
||||||
<div class="block-label">{automation.name}</div>
|
<div class="block-label">{automation.name}</div>
|
||||||
<Button secondary on:click={testAutomation}>Test Automation</Button>
|
<Button secondary on:click={testAutomation}>Test Automation</Button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -172,6 +172,11 @@
|
||||||
alt: `Many ${table.name} rows → many ${linkTable.name} rows`,
|
alt: `Many ${table.name} rows → many ${linkTable.name} rows`,
|
||||||
value: RelationshipTypes.MANY_TO_MANY,
|
value: RelationshipTypes.MANY_TO_MANY,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: `One ${linkName} row → many ${thisName} rows`,
|
||||||
|
alt: `One ${linkTable.name} rows → many ${table.name} rows`,
|
||||||
|
value: RelationshipTypes.ONE_TO_MANY,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: `One ${thisName} row → many ${linkName} rows`,
|
name: `One ${thisName} row → many ${linkName} rows`,
|
||||||
alt: `One ${table.name} rows → many ${linkTable.name} rows`,
|
alt: `One ${table.name} rows → many ${linkTable.name} rows`,
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
"children": [
|
"children": [
|
||||||
"heading",
|
"heading",
|
||||||
"text",
|
"text",
|
||||||
|
"divider",
|
||||||
"image",
|
"image",
|
||||||
"backgroundimage",
|
"backgroundimage",
|
||||||
"link",
|
"link",
|
||||||
|
|
|
@ -101,6 +101,12 @@
|
||||||
conditions = conditions.filter(link => link.id !== id)
|
conditions = conditions.filter(link => link.id !== id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const duplicateCondition = id => {
|
||||||
|
const condition = conditions.find(link => link.id === id)
|
||||||
|
const duplicate = { ...condition, id: generate() }
|
||||||
|
conditions = [...conditions, duplicate]
|
||||||
|
}
|
||||||
|
|
||||||
const handleFinalize = e => {
|
const handleFinalize = e => {
|
||||||
updateConditions(e)
|
updateConditions(e)
|
||||||
dragDisabled = true
|
dragDisabled = true
|
||||||
|
@ -235,6 +241,12 @@
|
||||||
bind:value={condition.referenceValue}
|
bind:value={condition.referenceValue}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
<Icon
|
||||||
|
name="Duplicate"
|
||||||
|
hoverable
|
||||||
|
size="S"
|
||||||
|
on:click={() => duplicateCondition(condition.id)}
|
||||||
|
/>
|
||||||
<Icon
|
<Icon
|
||||||
name="Close"
|
name="Close"
|
||||||
hoverable
|
hoverable
|
||||||
|
@ -273,7 +285,7 @@
|
||||||
gap: var(--spacing-l);
|
gap: var(--spacing-l);
|
||||||
display: grid;
|
display: grid;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
grid-template-columns: auto 1fr auto 1fr 1fr 1fr 1fr auto;
|
grid-template-columns: auto 1fr auto 1fr 1fr 1fr 1fr auto auto;
|
||||||
border-radius: var(--border-radius-s);
|
border-radius: var(--border-radius-s);
|
||||||
transition: background-color ease-in-out 130ms;
|
transition: background-color ease-in-out 130ms;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<script>
|
||||||
|
import { Select, Label } from "@budibase/bbui"
|
||||||
|
import { currentAsset, store } from "builderStore"
|
||||||
|
import { getActionProviderComponents } from "builderStore/dataBinding"
|
||||||
|
|
||||||
|
export let parameters
|
||||||
|
|
||||||
|
$: actionProviders = getActionProviderComponents(
|
||||||
|
$currentAsset,
|
||||||
|
$store.selectedComponentId,
|
||||||
|
"ClearForm"
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="root">
|
||||||
|
<Label small>Form</Label>
|
||||||
|
<Select
|
||||||
|
bind:value={parameters.componentId}
|
||||||
|
options={actionProviders}
|
||||||
|
getOptionLabel={x => x._instanceName}
|
||||||
|
getOptionValue={x => x._id}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.root {
|
||||||
|
display: grid;
|
||||||
|
column-gap: var(--spacing-l);
|
||||||
|
row-gap: var(--spacing-s);
|
||||||
|
grid-template-columns: 60px 1fr;
|
||||||
|
align-items: center;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -5,6 +5,7 @@ import ExecuteQuery from "./ExecuteQuery.svelte"
|
||||||
import TriggerAutomation from "./TriggerAutomation.svelte"
|
import TriggerAutomation from "./TriggerAutomation.svelte"
|
||||||
import ValidateForm from "./ValidateForm.svelte"
|
import ValidateForm from "./ValidateForm.svelte"
|
||||||
import LogOut from "./LogOut.svelte"
|
import LogOut from "./LogOut.svelte"
|
||||||
|
import ClearForm from "./ClearForm.svelte"
|
||||||
|
|
||||||
// Defines which actions are available to configure in the front end.
|
// Defines which actions are available to configure in the front end.
|
||||||
// Unfortunately the "name" property is used as the identifier so please don't
|
// Unfortunately the "name" property is used as the identifier so please don't
|
||||||
|
@ -42,4 +43,8 @@ export default [
|
||||||
name: "Log Out",
|
name: "Log Out",
|
||||||
component: LogOut,
|
component: LogOut,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Clear Form",
|
||||||
|
component: ClearForm,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<script>
|
||||||
|
import { Select, Label, Input } from "@budibase/bbui"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component takes the query object and populates the 'extra' property
|
||||||
|
* when a datasource has specified a configuration for these fields in SCHEMA.extra
|
||||||
|
*/
|
||||||
|
export let populateExtraQuery
|
||||||
|
export let config
|
||||||
|
export let query
|
||||||
|
|
||||||
|
$: extraFields = Object.keys(config).map(key => ({
|
||||||
|
...config[key],
|
||||||
|
key,
|
||||||
|
}))
|
||||||
|
|
||||||
|
$: extraQueryFields = query.fields.extra || {}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each extraFields as { key, displayName, type }}
|
||||||
|
<div class="config-field">
|
||||||
|
<Label>{displayName}</Label>
|
||||||
|
{#if type === "string"}
|
||||||
|
<Input
|
||||||
|
on:change={() => populateExtraQuery(extraQueryFields)}
|
||||||
|
bind:value={extraQueryFields[key]}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if type === "list"}
|
||||||
|
<Select
|
||||||
|
on:change={() => populateExtraQuery(extraQueryFields)}
|
||||||
|
bind:value={extraQueryFields[key]}
|
||||||
|
options={config[key].data[query.queryVerb]}
|
||||||
|
getOptionLabel={current => current}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.config-field {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 20% 1fr;
|
||||||
|
grid-gap: var(--spacing-l);
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -15,6 +15,7 @@
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { notifications, Divider } from "@budibase/bbui"
|
import { notifications, Divider } from "@budibase/bbui"
|
||||||
import api from "builderStore/api"
|
import api from "builderStore/api"
|
||||||
|
import ExtraQueryConfig from "./ExtraQueryConfig.svelte"
|
||||||
import IntegrationQueryEditor from "components/integration/index.svelte"
|
import IntegrationQueryEditor from "components/integration/index.svelte"
|
||||||
import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte"
|
import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte"
|
||||||
import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte"
|
import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte"
|
||||||
|
@ -60,6 +61,14 @@
|
||||||
fields = fields
|
fields = fields
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetDependentFields() {
|
||||||
|
if (query.fields.extra) query.fields.extra = {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateExtraQuery(extraQueryFields) {
|
||||||
|
query.fields.extra = extraQueryFields
|
||||||
|
}
|
||||||
|
|
||||||
async function previewQuery() {
|
async function previewQuery() {
|
||||||
try {
|
try {
|
||||||
const response = await api.post(`/api/queries/preview`, {
|
const response = await api.post(`/api/queries/preview`, {
|
||||||
|
@ -127,11 +136,19 @@
|
||||||
<Label>Function</Label>
|
<Label>Function</Label>
|
||||||
<Select
|
<Select
|
||||||
bind:value={query.queryVerb}
|
bind:value={query.queryVerb}
|
||||||
|
on:change={resetDependentFields}
|
||||||
options={Object.keys(queryConfig)}
|
options={Object.keys(queryConfig)}
|
||||||
getOptionLabel={verb =>
|
getOptionLabel={verb =>
|
||||||
queryConfig[verb]?.displayName || capitalise(verb)}
|
queryConfig[verb]?.displayName || capitalise(verb)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
{#if integrationInfo?.extra && query.queryVerb}
|
||||||
|
<ExtraQueryConfig
|
||||||
|
{query}
|
||||||
|
{populateExtraQuery}
|
||||||
|
config={integrationInfo.extra}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
<ParameterBuilder bind:parameters={query.parameters} bindable={false} />
|
<ParameterBuilder bind:parameters={query.parameters} bindable={false} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
export let exportApp
|
export let exportApp
|
||||||
export let viewApp
|
export let viewApp
|
||||||
export let editApp
|
export let editApp
|
||||||
|
export let updateApp
|
||||||
export let deleteApp
|
export let deleteApp
|
||||||
export let unpublishApp
|
export let unpublishApp
|
||||||
export let releaseLock
|
export let releaseLock
|
||||||
|
@ -53,6 +54,9 @@
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !app.deployed}
|
{#if !app.deployed}
|
||||||
|
<MenuItem on:click={() => updateApp(app)} icon="Edit">
|
||||||
|
Update
|
||||||
|
</MenuItem>
|
||||||
<MenuItem on:click={() => deleteApp(app)} icon="Delete">
|
<MenuItem on:click={() => deleteApp(app)} icon="Delete">
|
||||||
Delete
|
Delete
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
export let exportApp
|
export let exportApp
|
||||||
export let viewApp
|
export let viewApp
|
||||||
export let editApp
|
export let editApp
|
||||||
|
export let updateApp
|
||||||
export let deleteApp
|
export let deleteApp
|
||||||
export let unpublishApp
|
export let unpublishApp
|
||||||
export let releaseLock
|
export let releaseLock
|
||||||
|
@ -82,6 +83,7 @@
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
{/if}
|
{/if}
|
||||||
{#if !app.deployed}
|
{#if !app.deployed}
|
||||||
|
<MenuItem on:click={() => updateApp(app)} icon="Edit">Update</MenuItem>
|
||||||
<MenuItem on:click={() => deleteApp(app)} icon="Delete">Delete</MenuItem>
|
<MenuItem on:click={() => deleteApp(app)} icon="Delete">Delete</MenuItem>
|
||||||
{/if}
|
{/if}
|
||||||
</ActionMenu>
|
</ActionMenu>
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
<script>
|
||||||
|
import { writable, get as svelteGet } from "svelte/store"
|
||||||
|
import {
|
||||||
|
notifications,
|
||||||
|
Input,
|
||||||
|
Modal,
|
||||||
|
ModalContent,
|
||||||
|
Body,
|
||||||
|
} from "@budibase/bbui"
|
||||||
|
import { hostingStore } from "builderStore"
|
||||||
|
import { apps } from "stores/portal"
|
||||||
|
import { string, object } from "yup"
|
||||||
|
import { onMount } from "svelte"
|
||||||
|
import { capitalise } from "helpers"
|
||||||
|
|
||||||
|
const values = writable({ name: null })
|
||||||
|
const errors = writable({})
|
||||||
|
const touched = writable({})
|
||||||
|
const validator = {
|
||||||
|
name: string().required("Your application must have a name"),
|
||||||
|
}
|
||||||
|
|
||||||
|
export let app
|
||||||
|
|
||||||
|
let modal
|
||||||
|
let valid = false
|
||||||
|
let dirty = false
|
||||||
|
$: checkValidity($values, validator)
|
||||||
|
$: {
|
||||||
|
// prevent validation by setting name to undefined without an app
|
||||||
|
if (app) {
|
||||||
|
$values.name = app?.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(async () => {
|
||||||
|
await hostingStore.actions.fetchDeployedApps()
|
||||||
|
const existingAppNames = svelteGet(hostingStore).deployedAppNames
|
||||||
|
validator.name = string()
|
||||||
|
.required("Your application must have a name")
|
||||||
|
.test(
|
||||||
|
"non-existing-app-name",
|
||||||
|
"Another app with the same name already exists",
|
||||||
|
value => {
|
||||||
|
return !existingAppNames.some(
|
||||||
|
appName => dirty && appName.toLowerCase() === value.toLowerCase()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const checkValidity = async (values, validator) => {
|
||||||
|
const obj = object().shape(validator)
|
||||||
|
Object.keys(validator).forEach(key => ($errors[key] = null))
|
||||||
|
try {
|
||||||
|
await obj.validate(values, { abortEarly: false })
|
||||||
|
} catch (validationErrors) {
|
||||||
|
validationErrors.inner.forEach(error => {
|
||||||
|
$errors[error.path] = capitalise(error.message)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
valid = await obj.isValid(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function updateApp() {
|
||||||
|
try {
|
||||||
|
// Update App
|
||||||
|
await apps.update(app.instance._id, $values.name)
|
||||||
|
hide()
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
notifications.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const show = () => {
|
||||||
|
modal.show()
|
||||||
|
}
|
||||||
|
export const hide = () => {
|
||||||
|
modal.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onShow = () => {
|
||||||
|
dirty = false
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Modal bind:this={modal} on:hide={onCancel} on:show={onShow}>
|
||||||
|
<ModalContent
|
||||||
|
title={"Update app"}
|
||||||
|
confirmText={"Update app"}
|
||||||
|
onConfirm={updateApp}
|
||||||
|
disabled={!(valid && dirty)}
|
||||||
|
>
|
||||||
|
<Body size="S">
|
||||||
|
Give your new app a name, and choose which groups have access (paid plans
|
||||||
|
only).
|
||||||
|
</Body>
|
||||||
|
<Input
|
||||||
|
bind:value={$values.name}
|
||||||
|
error={$touched.name && $errors.name}
|
||||||
|
on:blur={() => ($touched.name = true)}
|
||||||
|
on:change={() => (dirty = true)}
|
||||||
|
label="Name"
|
||||||
|
/>
|
||||||
|
</ModalContent>
|
||||||
|
</Modal>
|
|
@ -54,7 +54,11 @@
|
||||||
</Layout>
|
</Layout>
|
||||||
<ActionMenu align="right">
|
<ActionMenu align="right">
|
||||||
<div slot="control" class="avatar">
|
<div slot="control" class="avatar">
|
||||||
<Avatar size="M" initials={$auth.initials} />
|
<Avatar
|
||||||
|
size="M"
|
||||||
|
initials={$auth.initials}
|
||||||
|
url={$auth.user.pictureUrl}
|
||||||
|
/>
|
||||||
<Icon size="XL" name="ChevronDown" />
|
<Icon size="XL" name="ChevronDown" />
|
||||||
</div>
|
</div>
|
||||||
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}>
|
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}>
|
||||||
|
|
|
@ -100,7 +100,11 @@
|
||||||
<div />
|
<div />
|
||||||
<ActionMenu align="right">
|
<ActionMenu align="right">
|
||||||
<div slot="control" class="avatar">
|
<div slot="control" class="avatar">
|
||||||
<Avatar size="M" initials={$auth.initials} />
|
<Avatar
|
||||||
|
size="M"
|
||||||
|
initials={$auth.initials}
|
||||||
|
url={$auth.user.pictureUrl}
|
||||||
|
/>
|
||||||
<Icon size="XL" name="ChevronDown" />
|
<Icon size="XL" name="ChevronDown" />
|
||||||
</div>
|
</div>
|
||||||
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}>
|
<MenuItem icon="UserEdit" on:click={() => userInfoModal.show()}>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
Body,
|
Body,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import CreateAppModal from "components/start/CreateAppModal.svelte"
|
import CreateAppModal from "components/start/CreateAppModal.svelte"
|
||||||
|
import UpdateAppModal from "components/start/UpdateAppModal.svelte"
|
||||||
import api, { del } from "builderStore/api"
|
import api, { del } from "builderStore/api"
|
||||||
import analytics from "analytics"
|
import analytics from "analytics"
|
||||||
import { onMount } from "svelte"
|
import { onMount } from "svelte"
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
let template
|
let template
|
||||||
let selectedApp
|
let selectedApp
|
||||||
let creationModal
|
let creationModal
|
||||||
|
let updatingModal
|
||||||
let deletionModal
|
let deletionModal
|
||||||
let unpublishModal
|
let unpublishModal
|
||||||
let creatingApp = false
|
let creatingApp = false
|
||||||
|
@ -164,6 +166,11 @@
|
||||||
selectedApp = null
|
selectedApp = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateApp = async app => {
|
||||||
|
selectedApp = app
|
||||||
|
updatingModal.show()
|
||||||
|
}
|
||||||
|
|
||||||
const releaseLock = async app => {
|
const releaseLock = async app => {
|
||||||
try {
|
try {
|
||||||
const response = await del(`/api/dev/${app.devId}/lock`)
|
const response = await del(`/api/dev/${app.devId}/lock`)
|
||||||
|
@ -236,6 +243,7 @@
|
||||||
{editApp}
|
{editApp}
|
||||||
{exportApp}
|
{exportApp}
|
||||||
{deleteApp}
|
{deleteApp}
|
||||||
|
{updateApp}
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
@ -289,6 +297,8 @@
|
||||||
Are you sure you want to unpublish the app <b>{selectedApp?.name}</b>?
|
Are you sure you want to unpublish the app <b>{selectedApp?.name}</b>?
|
||||||
</ConfirmDialog>
|
</ConfirmDialog>
|
||||||
|
|
||||||
|
<UpdateAppModal app={selectedApp} bind:this={updatingModal} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.title,
|
.title,
|
||||||
.filter {
|
.filter {
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
on:change
|
on:change
|
||||||
{options}
|
{options}
|
||||||
label="Role"
|
label="Role"
|
||||||
getOptionLabel={role => role.name}
|
getOptionLabel={role => role.label}
|
||||||
getOptionValue={role => role._id}
|
getOptionValue={role => role.value}
|
||||||
/>
|
/>
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { writable } from "svelte/store"
|
import { writable } from "svelte/store"
|
||||||
import { get } from "builderStore/api"
|
import { get } from "builderStore/api"
|
||||||
import { AppStatus } from "../../constants"
|
import { AppStatus } from "../../constants"
|
||||||
|
import api from "../../builderStore/api"
|
||||||
|
|
||||||
export function createAppStore() {
|
export function createAppStore() {
|
||||||
const store = writable([])
|
const store = writable([])
|
||||||
|
@ -53,9 +54,29 @@ export function createAppStore() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function update(appId, name) {
|
||||||
|
const response = await api.put(`/api/applications/${appId}`, { name })
|
||||||
|
if (response.status === 200) {
|
||||||
|
store.update(state => {
|
||||||
|
const updatedAppIndex = state.findIndex(
|
||||||
|
app => app.instance._id === appId
|
||||||
|
)
|
||||||
|
if (updatedAppIndex !== -1) {
|
||||||
|
const updatedApp = state[updatedAppIndex]
|
||||||
|
updatedApp.name = name
|
||||||
|
state.apps = state.splice(updatedAppIndex, 1, updatedApp)
|
||||||
|
}
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
throw new Error("Error updating name")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
subscribe: store.subscribe,
|
subscribe: store.subscribe,
|
||||||
load,
|
load,
|
||||||
|
update,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/cli",
|
"name": "@budibase/cli",
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
"description": "Budibase CLI, for developers, self hosting and migrations.",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/client",
|
"name": "@budibase/client",
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"license": "MPL-2.0",
|
"license": "MPL-2.0",
|
||||||
"module": "dist/budibase-client.js",
|
"module": "dist/budibase-client.js",
|
||||||
"main": "dist/budibase-client.js",
|
"main": "dist/budibase-client.js",
|
||||||
|
@ -18,9 +18,9 @@
|
||||||
"dev:builder": "rollup -cw"
|
"dev:builder": "rollup -cw"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^0.9.80-alpha.9",
|
"@budibase/bbui": "^0.9.87-alpha.7",
|
||||||
"@budibase/standard-components": "^0.9.80-alpha.9",
|
"@budibase/standard-components": "^0.9.87-alpha.7",
|
||||||
"@budibase/string-templates": "^0.9.80-alpha.9",
|
"@budibase/string-templates": "^0.9.87-alpha.7",
|
||||||
"regexparam": "^1.3.0",
|
"regexparam": "^1.3.0",
|
||||||
"shortid": "^2.2.15",
|
"shortid": "^2.2.15",
|
||||||
"svelte-spa-router": "^3.0.5"
|
"svelte-spa-router": "^3.0.5"
|
||||||
|
|
|
@ -130,7 +130,6 @@
|
||||||
}
|
}
|
||||||
#app-root {
|
#app-root {
|
||||||
position: relative;
|
position: relative;
|
||||||
border: 1px solid var(--spectrum-global-color-gray-300);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom scrollbars */
|
/* Custom scrollbars */
|
||||||
|
|
|
@ -6,6 +6,7 @@ export const ActionTypes = {
|
||||||
ValidateForm: "ValidateForm",
|
ValidateForm: "ValidateForm",
|
||||||
RefreshDatasource: "RefreshDatasource",
|
RefreshDatasource: "RefreshDatasource",
|
||||||
SetDataProviderQuery: "SetDataProviderQuery",
|
SetDataProviderQuery: "SetDataProviderQuery",
|
||||||
|
ClearForm: "ClearForm",
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ApiVersion = "1"
|
export const ApiVersion = "1"
|
||||||
|
|
|
@ -86,6 +86,14 @@ const logoutHandler = async () => {
|
||||||
await authStore.actions.logOut()
|
await authStore.actions.logOut()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const clearFormHandler = async (action, context) => {
|
||||||
|
return await executeActionHandler(
|
||||||
|
context,
|
||||||
|
action.parameters.componentId,
|
||||||
|
ActionTypes.ClearForm
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const handlerMap = {
|
const handlerMap = {
|
||||||
["Save Row"]: saveRowHandler,
|
["Save Row"]: saveRowHandler,
|
||||||
["Delete Row"]: deleteRowHandler,
|
["Delete Row"]: deleteRowHandler,
|
||||||
|
@ -95,6 +103,7 @@ const handlerMap = {
|
||||||
["Validate Form"]: validateFormHandler,
|
["Validate Form"]: validateFormHandler,
|
||||||
["Refresh Datasource"]: refreshDatasourceHandler,
|
["Refresh Datasource"]: refreshDatasourceHandler,
|
||||||
["Log Out"]: logoutHandler,
|
["Log Out"]: logoutHandler,
|
||||||
|
["Clear Form"]: clearFormHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirmTextMap = {
|
const confirmTextMap = {
|
||||||
|
|
|
@ -7,3 +7,4 @@ public/
|
||||||
db/dev.db/
|
db/dev.db/
|
||||||
dist
|
dist
|
||||||
coverage/
|
coverage/
|
||||||
|
watchtower-hook.json
|
|
@ -1,5 +1,10 @@
|
||||||
FROM node:12-alpine
|
FROM node:12-alpine
|
||||||
|
|
||||||
|
LABEL com.centurylinklabs.watchtower.lifecycle.pre-check="scripts/watchtower-hooks/pre-check.sh"
|
||||||
|
LABEL com.centurylinklabs.watchtower.lifecycle.pre-update="scripts/watchtower-hooks/pre-update.sh"
|
||||||
|
LABEL com.centurylinklabs.watchtower.lifecycle.post-update="scripts/watchtower-hooks/post-update.sh"
|
||||||
|
LABEL com.centurylinklabs.watchtower.lifecycle.post-check="scripts/watchtower-hooks/post-check.sh"
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
ENV PORT=4001
|
ENV PORT=4001
|
||||||
|
|
|
@ -5,11 +5,26 @@ module MongoMock {
|
||||||
this.connect = jest.fn()
|
this.connect = jest.fn()
|
||||||
this.close = jest.fn()
|
this.close = jest.fn()
|
||||||
this.insertOne = jest.fn()
|
this.insertOne = jest.fn()
|
||||||
|
this.insertMany = jest.fn(() => ({toArray: () => []}))
|
||||||
this.find = jest.fn(() => ({toArray: () => []}))
|
this.find = jest.fn(() => ({toArray: () => []}))
|
||||||
|
this.findOne = jest.fn()
|
||||||
|
this.count = jest.fn()
|
||||||
|
this.deleteOne = jest.fn()
|
||||||
|
this.deleteMany = jest.fn(() => ({toArray: () => []}))
|
||||||
|
this.updateOne = jest.fn()
|
||||||
|
this.updateMany = jest.fn(() => ({toArray: () => []}))
|
||||||
|
|
||||||
|
|
||||||
this.collection = jest.fn(() => ({
|
this.collection = jest.fn(() => ({
|
||||||
insertOne: this.insertOne,
|
insertOne: this.insertOne,
|
||||||
find: this.find,
|
find: this.find,
|
||||||
|
insertMany: this.insertMany,
|
||||||
|
findOne: this.findOne,
|
||||||
|
count: this.count,
|
||||||
|
deleteOne: this.deleteOne,
|
||||||
|
deleteMany: this.deleteMany,
|
||||||
|
updateOne: this.updateOne,
|
||||||
|
updateMany: this.updateMany,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
this.db = () => ({
|
this.db = () => ({
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/server",
|
"name": "@budibase/server",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"description": "Budibase Web Server",
|
"description": "Budibase Web Server",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -62,9 +62,9 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/auth": "^0.9.80-alpha.9",
|
"@budibase/auth": "^0.9.87-alpha.7",
|
||||||
"@budibase/client": "^0.9.80-alpha.9",
|
"@budibase/client": "^0.9.87-alpha.7",
|
||||||
"@budibase/string-templates": "^0.9.80-alpha.9",
|
"@budibase/string-templates": "^0.9.87-alpha.7",
|
||||||
"@elastic/elasticsearch": "7.10.0",
|
"@elastic/elasticsearch": "7.10.0",
|
||||||
"@koa/router": "8.0.0",
|
"@koa/router": "8.0.0",
|
||||||
"@sendgrid/mail": "7.1.1",
|
"@sendgrid/mail": "7.1.1",
|
||||||
|
@ -117,7 +117,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.14.3",
|
"@babel/core": "^7.14.3",
|
||||||
"@babel/preset-env": "^7.14.4",
|
"@babel/preset-env": "^7.14.4",
|
||||||
"@budibase/standard-components": "^0.9.80-alpha.9",
|
"@budibase/standard-components": "^0.9.87-alpha.7",
|
||||||
"@jest/test-sequencer": "^24.8.0",
|
"@jest/test-sequencer": "^24.8.0",
|
||||||
"@types/bull": "^3.15.1",
|
"@types/bull": "^3.15.1",
|
||||||
"@types/jest": "^26.0.23",
|
"@types/jest": "^26.0.23",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
echo '{ "current-hook" : "post-check" }' > 'watchtower-hook.json'
|
|
@ -0,0 +1 @@
|
||||||
|
echo '{ "current-hook" : "post-update" }' > 'watchtower-hook.json'
|
|
@ -0,0 +1 @@
|
||||||
|
echo '{ "current-hook" : "pre-check" }' > 'watchtower-hook.json'
|
|
@ -0,0 +1 @@
|
||||||
|
echo '{ "current-hook" : "pre-update" }' > 'watchtower-hook.json'
|
|
@ -30,6 +30,7 @@ function generateQueryValidation() {
|
||||||
default: Joi.string().allow(""),
|
default: Joi.string().allow(""),
|
||||||
})),
|
})),
|
||||||
queryVerb: Joi.string().allow().required(),
|
queryVerb: Joi.string().allow().required(),
|
||||||
|
extra: Joi.object().optional(),
|
||||||
schema: Joi.object({}).required().unknown(true)
|
schema: Joi.object({}).required().unknown(true)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -39,6 +40,7 @@ function generateQueryPreviewValidation() {
|
||||||
return joiValidator.body(Joi.object({
|
return joiValidator.body(Joi.object({
|
||||||
fields: Joi.object().required(),
|
fields: Joi.object().required(),
|
||||||
queryVerb: Joi.string().allow().required(),
|
queryVerb: Joi.string().allow().required(),
|
||||||
|
extra: Joi.object().optional(),
|
||||||
datasourceId: Joi.string().required(),
|
datasourceId: Joi.string().required(),
|
||||||
parameters: Joi.object({}).required().unknown(true)
|
parameters: Joi.object({}).required().unknown(true)
|
||||||
}))
|
}))
|
||||||
|
|
|
@ -49,6 +49,15 @@ export interface QueryDefinition {
|
||||||
urlDisplay?: boolean
|
urlDisplay?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ExtraQueryConfig {
|
||||||
|
[key: string]: {
|
||||||
|
displayName: string
|
||||||
|
type: string
|
||||||
|
required: boolean
|
||||||
|
data?: object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export interface Integration {
|
export interface Integration {
|
||||||
docs: string
|
docs: string
|
||||||
plus?: boolean
|
plus?: boolean
|
||||||
|
@ -58,6 +67,7 @@ export interface Integration {
|
||||||
query: {
|
query: {
|
||||||
[key: string]: QueryDefinition
|
[key: string]: QueryDefinition
|
||||||
}
|
}
|
||||||
|
extra?: ExtraQueryConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SearchFilters {
|
export interface SearchFilters {
|
||||||
|
|
|
@ -10,7 +10,6 @@ module MongoDBModule {
|
||||||
interface MongoDBConfig {
|
interface MongoDBConfig {
|
||||||
connectionString: string
|
connectionString: string
|
||||||
db: string
|
db: string
|
||||||
collection: string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SCHEMA: Integration = {
|
const SCHEMA: Integration = {
|
||||||
|
@ -28,10 +27,6 @@ module MongoDBModule {
|
||||||
type: DatasourceFieldTypes.STRING,
|
type: DatasourceFieldTypes.STRING,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
collection: {
|
|
||||||
type: DatasourceFieldTypes.STRING,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
create: {
|
create: {
|
||||||
|
@ -40,6 +35,30 @@ module MongoDBModule {
|
||||||
read: {
|
read: {
|
||||||
type: QueryTypes.JSON,
|
type: QueryTypes.JSON,
|
||||||
},
|
},
|
||||||
|
update: {
|
||||||
|
type: QueryTypes.JSON,
|
||||||
|
},
|
||||||
|
delete: {
|
||||||
|
type: QueryTypes.JSON,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extra: {
|
||||||
|
collection: {
|
||||||
|
displayName: "Collection",
|
||||||
|
type: DatasourceFieldTypes.STRING,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
actionTypes: {
|
||||||
|
displayName: "Action Types",
|
||||||
|
type: DatasourceFieldTypes.LIST,
|
||||||
|
required: true,
|
||||||
|
data: {
|
||||||
|
read: ["find", "findOne", "findOneAndUpdate", "count", "distinct"],
|
||||||
|
create: ["insertOne", "insertMany"],
|
||||||
|
update: ["updateOne", "updateMany"],
|
||||||
|
delete: ["deleteOne", "deleteMany"],
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,12 +75,27 @@ module MongoDBModule {
|
||||||
return this.client.connect()
|
return this.client.connect()
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(query: { json: object }) {
|
async create(query: { json: object; extra: { [key: string]: string } }) {
|
||||||
try {
|
try {
|
||||||
await this.connect()
|
await this.connect()
|
||||||
const db = this.client.db(this.config.db)
|
const db = this.client.db(this.config.db)
|
||||||
const collection = db.collection(this.config.collection)
|
const collection = db.collection(query.extra.collection)
|
||||||
|
|
||||||
|
// For mongodb we add an extra actionType to specify
|
||||||
|
// which method we want to call on the collection
|
||||||
|
switch (query.extra.actionTypes) {
|
||||||
|
case "insertOne": {
|
||||||
return collection.insertOne(query.json)
|
return collection.insertOne(query.json)
|
||||||
|
}
|
||||||
|
case "insertMany": {
|
||||||
|
return collection.insertOne(query.json).toArray()
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new Error(
|
||||||
|
`actionType ${query.extra.actionTypes} does not exist on DB for create`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error writing to mongodb", err)
|
console.error("Error writing to mongodb", err)
|
||||||
throw err
|
throw err
|
||||||
|
@ -70,12 +104,34 @@ module MongoDBModule {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async read(query: { json: object }) {
|
async read(query: { json: object; extra: { [key: string]: string } }) {
|
||||||
try {
|
try {
|
||||||
await this.connect()
|
await this.connect()
|
||||||
const db = this.client.db(this.config.db)
|
const db = this.client.db(this.config.db)
|
||||||
const collection = db.collection(this.config.collection)
|
const collection = db.collection(query.extra.collection)
|
||||||
|
|
||||||
|
switch (query.extra.actionTypes) {
|
||||||
|
case "find": {
|
||||||
return collection.find(query.json).toArray()
|
return collection.find(query.json).toArray()
|
||||||
|
}
|
||||||
|
case "findOne": {
|
||||||
|
return collection.findOne(query.json)
|
||||||
|
}
|
||||||
|
case "findOneAndUpdate": {
|
||||||
|
return collection.findOneAndUpdate(query.json)
|
||||||
|
}
|
||||||
|
case "count": {
|
||||||
|
return collection.countDocuments(query.json)
|
||||||
|
}
|
||||||
|
case "distinct": {
|
||||||
|
return collection.distinct(query.json)
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new Error(
|
||||||
|
`actionType ${query.extra.actionTypes} does not exist on DB for read`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Error querying mongodb", err)
|
console.error("Error querying mongodb", err)
|
||||||
throw err
|
throw err
|
||||||
|
@ -83,6 +139,60 @@ module MongoDBModule {
|
||||||
await this.client.close()
|
await this.client.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async update(query: { json: object; extra: { [key: string]: string } }) {
|
||||||
|
try {
|
||||||
|
await this.connect()
|
||||||
|
const db = this.client.db(this.config.db)
|
||||||
|
const collection = db.collection(query.extra.collection)
|
||||||
|
|
||||||
|
switch (query.extra.actionTypes) {
|
||||||
|
case "updateOne": {
|
||||||
|
return collection.updateOne(query.json)
|
||||||
|
}
|
||||||
|
case "updateMany": {
|
||||||
|
return collection.updateMany(query.json).toArray()
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new Error(
|
||||||
|
`actionType ${query.extra.actionTypes} does not exist on DB for update`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error writing to mongodb", err)
|
||||||
|
throw err
|
||||||
|
} finally {
|
||||||
|
await this.client.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(query: { json: object; extra: { [key: string]: string } }) {
|
||||||
|
try {
|
||||||
|
await this.connect()
|
||||||
|
const db = this.client.db(this.config.db)
|
||||||
|
const collection = db.collection(query.extra.collection)
|
||||||
|
|
||||||
|
switch (query.extra.actionTypes) {
|
||||||
|
case "deleteOne": {
|
||||||
|
return collection.deleteOne(query.json)
|
||||||
|
}
|
||||||
|
case "deleteMany": {
|
||||||
|
return collection.deleteMany(query.json).toArray()
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new Error(
|
||||||
|
`actionType ${query.extra.actionTypes} does not exist on DB for delete`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error writing to mongodb", err)
|
||||||
|
throw err
|
||||||
|
} finally {
|
||||||
|
await this.client.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -8,6 +8,13 @@ class TestConfiguration {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function disableConsole() {
|
||||||
|
jest.spyOn(console, 'error');
|
||||||
|
console.error.mockImplementation(() => {});
|
||||||
|
|
||||||
|
return console.error.mockRestore;
|
||||||
|
}
|
||||||
|
|
||||||
describe("MongoDB Integration", () => {
|
describe("MongoDB Integration", () => {
|
||||||
let config
|
let config
|
||||||
let indexName = "Users"
|
let indexName = "Users"
|
||||||
|
@ -22,7 +29,8 @@ describe("MongoDB Integration", () => {
|
||||||
}
|
}
|
||||||
const response = await config.integration.create({
|
const response = await config.integration.create({
|
||||||
index: indexName,
|
index: indexName,
|
||||||
json: body
|
json: body,
|
||||||
|
extra: { collection: 'testCollection', actionTypes: 'insertOne'}
|
||||||
})
|
})
|
||||||
expect(config.integration.client.insertOne).toHaveBeenCalledWith(body)
|
expect(config.integration.client.insertOne).toHaveBeenCalledWith(body)
|
||||||
})
|
})
|
||||||
|
@ -31,10 +39,46 @@ describe("MongoDB Integration", () => {
|
||||||
const query = {
|
const query = {
|
||||||
json: {
|
json: {
|
||||||
address: "test"
|
address: "test"
|
||||||
}
|
},
|
||||||
|
extra: { collection: 'testCollection', actionTypes: 'find'}
|
||||||
}
|
}
|
||||||
const response = await config.integration.read(query)
|
const response = await config.integration.read(query)
|
||||||
expect(config.integration.client.find).toHaveBeenCalledWith(query.json)
|
expect(config.integration.client.find).toHaveBeenCalledWith(query.json)
|
||||||
expect(response).toEqual(expect.any(Array))
|
expect(response).toEqual(expect.any(Array))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("calls the delete method with the correct params", async () => {
|
||||||
|
const query = {
|
||||||
|
json: {
|
||||||
|
id: "test"
|
||||||
|
},
|
||||||
|
extra: { collection: 'testCollection', actionTypes: 'deleteOne'}
|
||||||
|
}
|
||||||
|
const response = await config.integration.delete(query)
|
||||||
|
expect(config.integration.client.deleteOne).toHaveBeenCalledWith(query.json)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("calls the update method with the correct params", async () => {
|
||||||
|
const query = {
|
||||||
|
json: {
|
||||||
|
id: "test"
|
||||||
|
},
|
||||||
|
extra: { collection: 'testCollection', actionTypes: 'updateOne'}
|
||||||
|
}
|
||||||
|
const response = await config.integration.update(query)
|
||||||
|
expect(config.integration.client.updateOne).toHaveBeenCalledWith(query.json)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("throws an error when an invalid query.extra.actionType is passed for each method", async () => {
|
||||||
|
const restore = disableConsole()
|
||||||
|
|
||||||
|
const query = {
|
||||||
|
extra: { collection: 'testCollection', actionTypes: 'deleteOne'}
|
||||||
|
}
|
||||||
|
// Weird, need to do an IIFE for jest to recognize that it throws
|
||||||
|
expect(() => config.integration.read(query)()).toThrow(expect.any(Object))
|
||||||
|
|
||||||
|
restore()
|
||||||
|
})
|
||||||
|
|
||||||
})
|
})
|
|
@ -312,6 +312,39 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"divider": {
|
||||||
|
"name": "Divider",
|
||||||
|
"description": "A basic divider",
|
||||||
|
"icon": "Separator",
|
||||||
|
"illegalChildren": ["section"],
|
||||||
|
"settings": [
|
||||||
|
{
|
||||||
|
"type": "select",
|
||||||
|
"label": "Size",
|
||||||
|
"key": "size",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"label": "Small",
|
||||||
|
"value": "S"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Medium",
|
||||||
|
"value": "M"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Large",
|
||||||
|
"value": "L"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"defaultValue": "M"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"label": "Vertical",
|
||||||
|
"key": "vertical"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"repeater": {
|
"repeater": {
|
||||||
"name": "Repeater",
|
"name": "Repeater",
|
||||||
"description": "A configurable data list that attaches to your backend tables.",
|
"description": "A configurable data list that attaches to your backend tables.",
|
||||||
|
@ -331,11 +364,6 @@
|
||||||
"key": "noRowsMessage",
|
"key": "noRowsMessage",
|
||||||
"defaultValue": "No rows found"
|
"defaultValue": "No rows found"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "filter",
|
|
||||||
"label": "Filtering",
|
|
||||||
"key": "filter"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "select",
|
"type": "select",
|
||||||
"label": "Direction",
|
"label": "Direction",
|
||||||
|
@ -1647,7 +1675,8 @@
|
||||||
"hasChildren": true,
|
"hasChildren": true,
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"actions": [
|
"actions": [
|
||||||
"ValidateForm"
|
"ValidateForm",
|
||||||
|
"ClearForm"
|
||||||
],
|
],
|
||||||
"styles": ["size"],
|
"styles": ["size"],
|
||||||
"settings": [
|
"settings": [
|
||||||
|
@ -1678,6 +1707,7 @@
|
||||||
"name": "Field Group",
|
"name": "Field Group",
|
||||||
"icon": "Group",
|
"icon": "Group",
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
|
"styles": ["size"],
|
||||||
"hasChildren": true,
|
"hasChildren": true,
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -1706,6 +1736,7 @@
|
||||||
"name": "Text Field",
|
"name": "Text Field",
|
||||||
"icon": "Text",
|
"icon": "Text",
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
|
"styles": ["size"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
"type": "field/string",
|
"type": "field/string",
|
||||||
|
@ -1733,6 +1764,7 @@
|
||||||
"numberfield": {
|
"numberfield": {
|
||||||
"name": "Number Field",
|
"name": "Number Field",
|
||||||
"icon": "123",
|
"icon": "123",
|
||||||
|
"styles": ["size"],
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -1761,6 +1793,7 @@
|
||||||
"passwordfield": {
|
"passwordfield": {
|
||||||
"name": "Password Field",
|
"name": "Password Field",
|
||||||
"icon": "LockClosed",
|
"icon": "LockClosed",
|
||||||
|
"styles": ["size"],
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -1789,6 +1822,7 @@
|
||||||
"optionsfield": {
|
"optionsfield": {
|
||||||
"name": "Options Picker",
|
"name": "Options Picker",
|
||||||
"icon": "ViewList",
|
"icon": "ViewList",
|
||||||
|
"styles": ["size"],
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -1807,6 +1841,22 @@
|
||||||
"key": "placeholder",
|
"key": "placeholder",
|
||||||
"placeholder": "Choose an option"
|
"placeholder": "Choose an option"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"type": "select",
|
||||||
|
"label": "Type",
|
||||||
|
"key": "optionsType",
|
||||||
|
"placeholder": "Pick an options type",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"label": "Select",
|
||||||
|
"value": "select"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Radio buttons",
|
||||||
|
"value": "radio"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"label": "Disabled",
|
"label": "Disabled",
|
||||||
|
@ -1818,6 +1868,7 @@
|
||||||
"booleanfield": {
|
"booleanfield": {
|
||||||
"name": "Checkbox",
|
"name": "Checkbox",
|
||||||
"icon": "Checkmark",
|
"icon": "Checkmark",
|
||||||
|
"styles": ["size"],
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -1846,6 +1897,7 @@
|
||||||
"longformfield": {
|
"longformfield": {
|
||||||
"name": "Rich Text",
|
"name": "Rich Text",
|
||||||
"icon": "TextParagraph",
|
"icon": "TextParagraph",
|
||||||
|
"styles": ["size"],
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -1875,6 +1927,7 @@
|
||||||
"datetimefield": {
|
"datetimefield": {
|
||||||
"name": "Date Picker",
|
"name": "Date Picker",
|
||||||
"icon": "DateInput",
|
"icon": "DateInput",
|
||||||
|
"styles": ["size"],
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -1909,6 +1962,7 @@
|
||||||
"attachmentfield": {
|
"attachmentfield": {
|
||||||
"name": "Attachment",
|
"name": "Attachment",
|
||||||
"icon": "Attach",
|
"icon": "Attach",
|
||||||
|
"styles": ["size"],
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -1932,6 +1986,7 @@
|
||||||
"relationshipfield": {
|
"relationshipfield": {
|
||||||
"name": "Relationship Picker",
|
"name": "Relationship Picker",
|
||||||
"icon": "TaskList",
|
"icon": "TaskList",
|
||||||
|
"styles": ["size"],
|
||||||
"illegalChildren": ["section"],
|
"illegalChildren": ["section"],
|
||||||
"settings": [
|
"settings": [
|
||||||
{
|
{
|
||||||
|
@ -2065,6 +2120,7 @@
|
||||||
"daterangepicker": {
|
"daterangepicker": {
|
||||||
"name": "Date Range",
|
"name": "Date Range",
|
||||||
"icon": "Date",
|
"icon": "Date",
|
||||||
|
"styles": ["size"],
|
||||||
"hasChildren": false,
|
"hasChildren": false,
|
||||||
"info": "Your data provider will be automatically filtered to the given date range.",
|
"info": "Your data provider will be automatically filtered to the given date range.",
|
||||||
"settings": [
|
"settings": [
|
||||||
|
|
|
@ -29,12 +29,13 @@
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"svelte"
|
"svelte"
|
||||||
],
|
],
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc",
|
"gitHead": "d1836a898cab3f8ab80ee6d8f42be1a9eed7dcdc",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/bbui": "^0.9.80-alpha.9",
|
"@budibase/bbui": "^0.9.87-alpha.7",
|
||||||
"@spectrum-css/card": "^3.0.3",
|
"@spectrum-css/card": "^3.0.3",
|
||||||
|
"@spectrum-css/divider": "^1.0.3",
|
||||||
"@spectrum-css/link": "^3.1.3",
|
"@spectrum-css/link": "^3.1.3",
|
||||||
"@spectrum-css/page": "^3.0.1",
|
"@spectrum-css/page": "^3.0.1",
|
||||||
"@spectrum-css/typography": "^3.0.2",
|
"@spectrum-css/typography": "^3.0.2",
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
<script>
|
||||||
|
import { getContext } from "svelte"
|
||||||
|
import "@spectrum-css/divider/dist/index-vars.css"
|
||||||
|
|
||||||
|
const { styleable } = getContext("sdk")
|
||||||
|
const component = getContext("component")
|
||||||
|
|
||||||
|
export let size = "M"
|
||||||
|
|
||||||
|
export let vertical = false
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<hr
|
||||||
|
use:styleable={$component.styles}
|
||||||
|
class="spectrum-Divider spectrum-Divider--{vertical
|
||||||
|
? 'vertical'
|
||||||
|
: 'horizontal'} spectrum-Dialog-divider spectrum-Divider--size{size}"
|
||||||
|
/>
|
|
@ -64,6 +64,13 @@
|
||||||
})
|
})
|
||||||
return get(formState).valid
|
return get(formState).valid
|
||||||
},
|
},
|
||||||
|
clear: () => {
|
||||||
|
const fields = Object.keys(fieldMap)
|
||||||
|
fields.forEach(field => {
|
||||||
|
const { fieldApi } = fieldMap[field]
|
||||||
|
fieldApi.clearValue()
|
||||||
|
})
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Provide both form API and state to children
|
// Provide both form API and state to children
|
||||||
|
@ -72,6 +79,7 @@
|
||||||
// Action context to pass to children
|
// Action context to pass to children
|
||||||
const actions = [
|
const actions = [
|
||||||
{ type: ActionTypes.ValidateForm, callback: formApi.validate },
|
{ type: ActionTypes.ValidateForm, callback: formApi.validate },
|
||||||
|
{ type: ActionTypes.ClearForm, callback: formApi.clear },
|
||||||
]
|
]
|
||||||
|
|
||||||
// Creates an API for a specific field
|
// Creates an API for a specific field
|
||||||
|
@ -108,8 +116,27 @@
|
||||||
|
|
||||||
return !newError
|
return !newError
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const clearValue = () => {
|
||||||
|
const { fieldState } = fieldMap[field]
|
||||||
|
const newValue = initialValues[field] ?? defaultValue
|
||||||
|
fieldState.update(state => {
|
||||||
|
state.value = newValue
|
||||||
|
state.error = null
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
|
||||||
|
formState.update(state => {
|
||||||
|
state.values = { ...state.values, [field]: newValue }
|
||||||
|
delete state.errors[field]
|
||||||
|
state.valid = Object.keys(state.errors).length === 0
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setValue,
|
setValue,
|
||||||
|
clearValue,
|
||||||
validate: () => {
|
validate: () => {
|
||||||
const { fieldState } = fieldMap[field]
|
const { fieldState } = fieldMap[field]
|
||||||
setValue(get(fieldState).value, true)
|
setValue(get(fieldState).value, true)
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { CoreSelect } from "@budibase/bbui"
|
import { CoreSelect, RadioGroup } from "@budibase/bbui"
|
||||||
import Field from "./Field.svelte"
|
import Field from "./Field.svelte"
|
||||||
|
|
||||||
export let field
|
export let field
|
||||||
export let label
|
export let label
|
||||||
export let placeholder
|
export let placeholder
|
||||||
export let disabled = false
|
export let disabled = false
|
||||||
|
export let optionsType = "select"
|
||||||
|
|
||||||
let fieldState
|
let fieldState
|
||||||
let fieldApi
|
let fieldApi
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
bind:fieldSchema
|
bind:fieldSchema
|
||||||
>
|
>
|
||||||
{#if fieldState}
|
{#if fieldState}
|
||||||
|
{#if optionsType === "select"}
|
||||||
<CoreSelect
|
<CoreSelect
|
||||||
value={$fieldState.value}
|
value={$fieldState.value}
|
||||||
id={$fieldState.fieldId}
|
id={$fieldState.fieldId}
|
||||||
|
@ -31,5 +33,15 @@
|
||||||
{placeholder}
|
{placeholder}
|
||||||
on:change={e => fieldApi.setValue(e.detail)}
|
on:change={e => fieldApi.setValue(e.detail)}
|
||||||
/>
|
/>
|
||||||
|
{:else if optionsType === "radio"}
|
||||||
|
<RadioGroup
|
||||||
|
value={$fieldState.value}
|
||||||
|
id={$fieldState.fieldId}
|
||||||
|
disabled={$fieldState.disabled}
|
||||||
|
error={$fieldState.error}
|
||||||
|
options={fieldSchema?.constraints?.inclusion ?? []}
|
||||||
|
on:change={e => fieldApi.setValue(e.detail)}
|
||||||
|
/>
|
||||||
|
{/if}
|
||||||
{/if}
|
{/if}
|
||||||
</Field>
|
</Field>
|
||||||
|
|
|
@ -17,6 +17,7 @@ export { default as Placeholder } from "./Placeholder.svelte"
|
||||||
export { default as container } from "./Container.svelte"
|
export { default as container } from "./Container.svelte"
|
||||||
export { default as section } from "./Section.svelte"
|
export { default as section } from "./Section.svelte"
|
||||||
export { default as dataprovider } from "./DataProvider.svelte"
|
export { default as dataprovider } from "./DataProvider.svelte"
|
||||||
|
export { default as divider } from "./Divider.svelte"
|
||||||
export { default as screenslot } from "./ScreenSlot.svelte"
|
export { default as screenslot } from "./ScreenSlot.svelte"
|
||||||
export { default as button } from "./Button.svelte"
|
export { default as button } from "./Button.svelte"
|
||||||
export { default as repeater } from "./Repeater.svelte"
|
export { default as repeater } from "./Repeater.svelte"
|
||||||
|
|
|
@ -2,6 +2,59 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@adobe/spectrum-css-workflow-icons@^1.2.1":
|
||||||
|
version "1.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@adobe/spectrum-css-workflow-icons/-/spectrum-css-workflow-icons-1.2.1.tgz#7e2cb3fcfb5c8b12d7275afafbb6ec44913551b4"
|
||||||
|
integrity sha512-uVgekyBXnOVkxp+CUssjN/gefARtudZC8duEn1vm0lBQFwGRZFlDEzU1QC+aIRWCrD1Z8OgRpmBYlSZ7QS003w==
|
||||||
|
|
||||||
|
"@budibase/bbui@^0.9.87-alpha.3":
|
||||||
|
version "0.9.88"
|
||||||
|
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-0.9.88.tgz#4adf11405af063997deb933fabd20c528b74976b"
|
||||||
|
integrity sha512-kc/4OTJmLjAojODpXpfLpvgDZs4KaquNEFTDLsDwwuvsFtH/PRQd7K577pHk7qsnl97oSUnqN7OC0gL5S4B1Zw==
|
||||||
|
dependencies:
|
||||||
|
"@adobe/spectrum-css-workflow-icons" "^1.2.1"
|
||||||
|
"@spectrum-css/actionbutton" "^1.0.1"
|
||||||
|
"@spectrum-css/actiongroup" "^1.0.1"
|
||||||
|
"@spectrum-css/avatar" "^3.0.2"
|
||||||
|
"@spectrum-css/button" "^3.0.1"
|
||||||
|
"@spectrum-css/buttongroup" "^3.0.2"
|
||||||
|
"@spectrum-css/checkbox" "^3.0.2"
|
||||||
|
"@spectrum-css/dialog" "^3.0.1"
|
||||||
|
"@spectrum-css/divider" "^1.0.1"
|
||||||
|
"@spectrum-css/dropzone" "^3.0.2"
|
||||||
|
"@spectrum-css/fieldgroup" "^3.0.2"
|
||||||
|
"@spectrum-css/fieldlabel" "^3.0.1"
|
||||||
|
"@spectrum-css/icon" "^3.0.1"
|
||||||
|
"@spectrum-css/illustratedmessage" "^3.0.2"
|
||||||
|
"@spectrum-css/inputgroup" "^3.0.2"
|
||||||
|
"@spectrum-css/label" "^2.0.10"
|
||||||
|
"@spectrum-css/link" "^3.1.1"
|
||||||
|
"@spectrum-css/menu" "^3.0.1"
|
||||||
|
"@spectrum-css/modal" "^3.0.1"
|
||||||
|
"@spectrum-css/pagination" "^3.0.3"
|
||||||
|
"@spectrum-css/picker" "^1.0.1"
|
||||||
|
"@spectrum-css/popover" "^3.0.1"
|
||||||
|
"@spectrum-css/progressbar" "^1.0.2"
|
||||||
|
"@spectrum-css/progresscircle" "^1.0.2"
|
||||||
|
"@spectrum-css/radio" "^3.0.2"
|
||||||
|
"@spectrum-css/search" "^3.0.2"
|
||||||
|
"@spectrum-css/sidenav" "^3.0.2"
|
||||||
|
"@spectrum-css/statuslight" "^3.0.2"
|
||||||
|
"@spectrum-css/switch" "^1.0.2"
|
||||||
|
"@spectrum-css/table" "^3.0.1"
|
||||||
|
"@spectrum-css/tabs" "^3.0.1"
|
||||||
|
"@spectrum-css/tags" "^3.0.2"
|
||||||
|
"@spectrum-css/textfield" "^3.0.1"
|
||||||
|
"@spectrum-css/toast" "^3.0.1"
|
||||||
|
"@spectrum-css/tooltip" "^3.0.3"
|
||||||
|
"@spectrum-css/treeview" "^3.0.2"
|
||||||
|
"@spectrum-css/typography" "^3.0.1"
|
||||||
|
"@spectrum-css/underlay" "^2.0.9"
|
||||||
|
"@spectrum-css/vars" "^3.0.1"
|
||||||
|
dayjs "^1.10.4"
|
||||||
|
svelte-flatpickr "^3.1.0"
|
||||||
|
svelte-portal "^1.0.0"
|
||||||
|
|
||||||
"@rollup/pluginutils@^4.1.0":
|
"@rollup/pluginutils@^4.1.0":
|
||||||
version "4.1.0"
|
version "4.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.0.tgz#0dcc61c780e39257554feb7f77207dceca13c838"
|
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.1.0.tgz#0dcc61c780e39257554feb7f77207dceca13c838"
|
||||||
|
@ -10,16 +63,103 @@
|
||||||
estree-walker "^2.0.1"
|
estree-walker "^2.0.1"
|
||||||
picomatch "^2.2.2"
|
picomatch "^2.2.2"
|
||||||
|
|
||||||
|
"@spectrum-css/actionbutton@^1.0.1":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/actionbutton/-/actionbutton-1.0.3.tgz#8f7342a69b303c5acdcfa0a59f5e9267b9f3cb30"
|
||||||
|
integrity sha512-P9qoCPSiZ1SB6ZYqK5hub0vGty00YYqonQE0KTjtb1i+T1nYR/87vWqVPERx9j63uhgZncjwFYaThTvRqye7eQ==
|
||||||
|
|
||||||
|
"@spectrum-css/actiongroup@^1.0.1":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/actiongroup/-/actiongroup-1.0.3.tgz#4713ce65e6f5c72c404a7b638fbc3b4fd7e3874f"
|
||||||
|
integrity sha512-NlB9Q4ZlWixXxymoPIYG6g2hkwAGKFodHWPFfxHD8ddkjXWRB9G2akUP7cfsJ4DcYn4VisUORCOYQwqDiSmboQ==
|
||||||
|
|
||||||
|
"@spectrum-css/avatar@^3.0.2":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/avatar/-/avatar-3.0.2.tgz#4f1826223eae330e64b6d3cc899e9bc2e98dac95"
|
||||||
|
integrity sha512-wEczvSqxttTWSiL3cOvXV/RmGRwSkw2w6+slcHhnf0kb7ovymMM+9oz8vvEpEsSeo5u598bc+7ktrKFpAd6soQ==
|
||||||
|
|
||||||
|
"@spectrum-css/button@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/button/-/button-3.0.3.tgz#2df1efaab6c7e0b3b06cb4b59e1eae59c7f1fc84"
|
||||||
|
integrity sha512-6CnLPqqtaU/PcSSIGeGRi0iFIIxIUByYLKFO6zn5NEUc12KQ28dJ4PLwB6WBa0L8vRoAGlnWWH2ZZweTijbXgg==
|
||||||
|
|
||||||
|
"@spectrum-css/buttongroup@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/buttongroup/-/buttongroup-3.0.3.tgz#719d868845ac9d2c4f939c1b9f6044507902d5aa"
|
||||||
|
integrity sha512-eXl8U4QWMWXqyTu654FdQdEGnmczgOYlpIFSHyCMVjhtPqZp2xwnLFiGh6LKw+bLio6eeOZ0L+vpk1GcoYqgkw==
|
||||||
|
|
||||||
"@spectrum-css/card@^3.0.3":
|
"@spectrum-css/card@^3.0.3":
|
||||||
version "3.0.3"
|
version "3.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@spectrum-css/card/-/card-3.0.3.tgz#56b2e2da6b80c1583228baa279de7407383bfb6b"
|
resolved "https://registry.yarnpkg.com/@spectrum-css/card/-/card-3.0.3.tgz#56b2e2da6b80c1583228baa279de7407383bfb6b"
|
||||||
integrity sha512-+oKLUI2a0QmQP9EzySeq/G4FpUkkdaDNbuEbqCj2IkPMc/2v/nwzsPhh1fj2UIghGAiiUwXfPpzax1e8fyhQUg==
|
integrity sha512-+oKLUI2a0QmQP9EzySeq/G4FpUkkdaDNbuEbqCj2IkPMc/2v/nwzsPhh1fj2UIghGAiiUwXfPpzax1e8fyhQUg==
|
||||||
|
|
||||||
"@spectrum-css/link@^3.1.3":
|
"@spectrum-css/checkbox@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/checkbox/-/checkbox-3.0.3.tgz#8577067fc8b97e4609f92bd242364937a533a7bb"
|
||||||
|
integrity sha512-QVG9uMHq+lh70Dh6mDNnY+vEvNz2p7VC6xgLfDYfijp2qeiqYPq72fQK6p/SiyqPk96ZACzNRwgeROU6Xf6Wgg==
|
||||||
|
|
||||||
|
"@spectrum-css/dialog@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/dialog/-/dialog-3.0.3.tgz#7715a4ea435e753afb623d99ca5917ed1bcd6f34"
|
||||||
|
integrity sha512-AhmKgfRIVyTe3ABiJ8lLUQL34VB/H6fN16na2LlbDRJvyRMzkdN1Xf2i6U3f4OMd3qQ8Gm5xat4BvMxIQPBAUQ==
|
||||||
|
|
||||||
|
"@spectrum-css/divider@^1.0.1", "@spectrum-css/divider@^1.0.3":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/divider/-/divider-1.0.3.tgz#639e2ebaa0834efa40f42397668bbd5c153ea385"
|
||||||
|
integrity sha512-Zy4Rn40w8UtzMh3wx/U9+CepSCpm1aOCGftHgWDub0XZuVTzh0c1WwyzTuLCx2Hf21z5VRGNiDh8bGEEzSbtNA==
|
||||||
|
dependencies:
|
||||||
|
"@spectrum-css/vars" "^3.0.2"
|
||||||
|
|
||||||
|
"@spectrum-css/dropzone@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/dropzone/-/dropzone-3.0.3.tgz#aee71697a2c195947599d7541b858c3c198741dc"
|
||||||
|
integrity sha512-ujrswdtB6bHigklyHsm6zomFd6rUnKJ3xVVRjroVF4+ouK4DxK5tX0iVd0EW6AOfOjx4Cc28uyFot3fpxp+MQw==
|
||||||
|
|
||||||
|
"@spectrum-css/fieldgroup@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/fieldgroup/-/fieldgroup-3.0.3.tgz#85d85da048d08200f25ceab378026dd2b11e0bb2"
|
||||||
|
integrity sha512-wXUXTXN1CPnR7M4Ltd+3uh7BfcNGUV1+Xe0/h0tCpq/j+S2Sd4xo7/pUMdU19sIDrAAtpEFp1tt+nouHcU5HGQ==
|
||||||
|
|
||||||
|
"@spectrum-css/fieldlabel@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/fieldlabel/-/fieldlabel-3.0.3.tgz#f73c04d20734d4718ffb620dc46458904685b449"
|
||||||
|
integrity sha512-nEvIkEXCD5n4fW67Unq6Iu7VXoauEd/JGpfTY02VsC5p4FJLnwKfPDbJUuUsqClAxqw7nAsmXVKtn4zQFf5yPQ==
|
||||||
|
|
||||||
|
"@spectrum-css/icon@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/icon/-/icon-3.0.3.tgz#5c612822380927087aebd526855d82ed2c3e2cba"
|
||||||
|
integrity sha512-hyloKOejPCXhP3MBNsm3SjR9j8xT1R1S19p32KW/0Qhj+VMUtfyEPmevyFptpn7wcovQccdl/vZVIVDuML/imw==
|
||||||
|
|
||||||
|
"@spectrum-css/illustratedmessage@^3.0.2":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/illustratedmessage/-/illustratedmessage-3.0.2.tgz#6a480be98b027e050b086e7899e40d87adb0a8c0"
|
||||||
|
integrity sha512-dqnE8X27bGcO0HN8+dYx8O4o0dNNIAqeivOzDHhe2El+V4dTzMrNIerF6G0NLm3GjVf6XliwmitsZK+K6FmbtA==
|
||||||
|
|
||||||
|
"@spectrum-css/inputgroup@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/inputgroup/-/inputgroup-3.0.3.tgz#00c9a370ddc2c55cf0f37dd6069faa9501fd7eb5"
|
||||||
|
integrity sha512-FqRJTiLL7jiGfzDVXWUGVLqHryJjCcqQIrqAi+Tq0oenapzsBe2qc/zIrKgh2wtMI+NTIBLXTECvij3L1HlqAg==
|
||||||
|
|
||||||
|
"@spectrum-css/label@^2.0.10":
|
||||||
|
version "2.0.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/label/-/label-2.0.10.tgz#2368651d7636a19385b5d300cdf6272db1916001"
|
||||||
|
integrity sha512-xCbtEiQkZIlLdWFikuw7ifDCC21DOC/KMgVrrVJHXFc4KRQe9LTZSqmGF3tovm+CSq1adE59mYoTbojVQ9YuEQ==
|
||||||
|
|
||||||
|
"@spectrum-css/link@^3.1.1", "@spectrum-css/link@^3.1.3":
|
||||||
version "3.1.3"
|
version "3.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/@spectrum-css/link/-/link-3.1.3.tgz#b0e560a7e0acdb4a2b329b6669696aa3438f5993"
|
resolved "https://registry.yarnpkg.com/@spectrum-css/link/-/link-3.1.3.tgz#b0e560a7e0acdb4a2b329b6669696aa3438f5993"
|
||||||
integrity sha512-8Pmy5d73MwKcATTPaj+fSrZYnIw7GmfX40AvpC1xx5LauOxsbUb4AVNp1kn2H8rrOBmxF7czyhoBBhEiv66QUg==
|
integrity sha512-8Pmy5d73MwKcATTPaj+fSrZYnIw7GmfX40AvpC1xx5LauOxsbUb4AVNp1kn2H8rrOBmxF7czyhoBBhEiv66QUg==
|
||||||
|
|
||||||
|
"@spectrum-css/menu@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/menu/-/menu-3.0.3.tgz#46a9b221bb5f470a2f8a934bdfd512d84d2fdc4d"
|
||||||
|
integrity sha512-qKA9J/MrikNKIpCEHsAazG2vY3im5tjGCmo6p9Pdnu8/aQMsiuZDHZayukeCttJUZkrb9guDVL9OIHlK5RZvcQ==
|
||||||
|
|
||||||
|
"@spectrum-css/modal@^3.0.1":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/modal/-/modal-3.0.2.tgz#58b6621cab65f90788d310374f40df1f7090473f"
|
||||||
|
integrity sha512-YnIivJhoaao7Otu+HV7sgebPyFbO6sd/oMvTN/Rb2wwgnaMnIIuIRdGandSrcgotN2uNgs+P0knG6mv/xA1/dg==
|
||||||
|
|
||||||
"@spectrum-css/page@^3.0.1":
|
"@spectrum-css/page@^3.0.1":
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@spectrum-css/page/-/page-3.0.2.tgz#8f0c03d25f5565fb13115541a8fcaf0e1d3a8ee0"
|
resolved "https://registry.yarnpkg.com/@spectrum-css/page/-/page-3.0.2.tgz#8f0c03d25f5565fb13115541a8fcaf0e1d3a8ee0"
|
||||||
|
@ -27,11 +167,101 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@spectrum-css/vars" "^3.0.2"
|
"@spectrum-css/vars" "^3.0.2"
|
||||||
|
|
||||||
"@spectrum-css/typography@^3.0.2":
|
"@spectrum-css/pagination@^3.0.3":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/pagination/-/pagination-3.0.3.tgz#b204c3ada384c4af751a354bc428346d82eeea65"
|
||||||
|
integrity sha512-OJ/v9GeNXJOZ9Yr9LDBYPrR2NCiLOWP9wANT/a5sqFuugRnQbn/HYMnRp9TBxwpDY6ihaPo0T/wi7kLiAJFdDw==
|
||||||
|
|
||||||
|
"@spectrum-css/picker@^1.0.1":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/picker/-/picker-1.0.3.tgz#21379bcf8ae94277deeb6ad65dcd9e2bbfacb487"
|
||||||
|
integrity sha512-oHLGxBx5BwVCSGo7/T1C9PTHX1+/5AmVjyLiTJ4UoIdSJmOERw9YcRZbcGZgBJNWbxcjr4TyGtwj1EcSjEy97w==
|
||||||
|
|
||||||
|
"@spectrum-css/popover@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/popover/-/popover-3.0.3.tgz#6fb69873474fb968afb738eacb9e121f93e83a09"
|
||||||
|
integrity sha512-KvmXv4TV19FBx39KfmgVlDYtvtBqv/8RRK7RRLDDHGViTxZtShjVsVpwIgfkfgn4iJztCnXpWzFqRXWUu2XCpQ==
|
||||||
|
|
||||||
|
"@spectrum-css/progressbar@^1.0.2":
|
||||||
|
version "1.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/progressbar/-/progressbar-1.0.3.tgz#f70bcc38a2a21cff2f422ec825724ebbb9455e67"
|
||||||
|
integrity sha512-vJHplefUuy8+NjCw1X7fLbqHVGNVBpvGFXNAeaIj4SFf4ygxiUq/5c9iRhhsCQixEsJlfD/b7BnGXU7BUDkr6Q==
|
||||||
|
|
||||||
|
"@spectrum-css/progresscircle@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/progresscircle/-/progresscircle-1.0.2.tgz#258ea9170fb70f795edda03e38a61d93bef4487c"
|
||||||
|
integrity sha512-JLULpyzjIY95lzlWR1yE1gv4l1K6p+scQ+edmuZZUHBzwM3pUtkvHJmUlA9TYdResUYW6Uka60VRdY6lZ8gnFQ==
|
||||||
|
|
||||||
|
"@spectrum-css/radio@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/radio/-/radio-3.0.3.tgz#25c3bc5e9c30a8a8ae728717b7c7fb736cdae640"
|
||||||
|
integrity sha512-LaLGfz/eGNR2iyqouXYILIA+pKRqF769iPdwM0REm5RpWvMQDD7rPZ/kWlg18owjaFsyllEp25gEjmhRJIIVOw==
|
||||||
|
|
||||||
|
"@spectrum-css/search@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/search/-/search-3.0.3.tgz#3415dc106aca0d5dd996e87084a1b47c2b95a882"
|
||||||
|
integrity sha512-kdLpKTt0obljuhS1q1tukujRlvSs8sBwij76D4Qp8KpMzwePfZyvv1kYzuWPNZfTeISxWsmyZ6Wxd1uvzjn+UA==
|
||||||
|
|
||||||
|
"@spectrum-css/sidenav@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/sidenav/-/sidenav-3.0.3.tgz#132141fbd2500a927c312fa4e1d712c438b3d597"
|
||||||
|
integrity sha512-cQ+CgwjxGftrcc79i1XnGd66QTl7H7zopSU0UTV4Qq7hvqfrjjWxfZ6b+3tezrrhNlDope1ff9o8sm67PsPXtg==
|
||||||
|
|
||||||
|
"@spectrum-css/statuslight@^3.0.2":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/statuslight/-/statuslight-3.0.2.tgz#dc54b6cd113413dcdb909c486b5d7bae60db65c5"
|
||||||
|
integrity sha512-xodB8g8vGJH20XmUj9ZsPlM1jHrGeRbvmVXkz0q7YvQrYAhim8pP3W+XKKZAletPFAuu8cmUOc6SWn6i4X4z6w==
|
||||||
|
|
||||||
|
"@spectrum-css/switch@^1.0.2":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/switch/-/switch-1.0.2.tgz#f0b4c69271964573e02b08e90998096e49e1de44"
|
||||||
|
integrity sha512-zqmHpgWPNg1gEwdUNFYV3CBX5JaeALfIqcJIxE0FLZqr9d1C4+oLE0ItIFzt1bwr4bFAOmkEpvtiY+amluzGxQ==
|
||||||
|
|
||||||
|
"@spectrum-css/table@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/table/-/table-3.0.3.tgz#7f7f19905ef3275cbf907ce3a5818e63c30b2caf"
|
||||||
|
integrity sha512-nxwzVjLPsXoY/v4sdxOVYLcC+cEbGgJyLcLclT5LT9MGSbngFeUMJzzVR4EvehzuN4dH7hrATG7Mbuq29Mf0Hg==
|
||||||
|
|
||||||
|
"@spectrum-css/tabs@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/tabs/-/tabs-3.0.3.tgz#51dd6f168c897b0fdc3a7e9f901df7bd2288b4fc"
|
||||||
|
integrity sha512-iLP1I72bJWz9APdQB1jiw+pOv5a7N+hYOCJvRoc56Us/hJKVzowkyGRe3uH+8v36nCG9bHxiAQNLoU8eXisVrg==
|
||||||
|
|
||||||
|
"@spectrum-css/tags@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/tags/-/tags-3.0.3.tgz#fc76d2735cdc442de91b7eb3bee49a928c0767ac"
|
||||||
|
integrity sha512-SL8vPxVDfWcY5VdIuyl0TImEXcOU1I7yCyXkk7MudMwfnYs81FaIyY32hFV9OHj0Tz/36UzRzc7AVMSuRQ53pw==
|
||||||
|
|
||||||
|
"@spectrum-css/textfield@^3.0.1":
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/textfield/-/textfield-3.0.2.tgz#907f62d2dc82852dd6236a820be99e252b531631"
|
||||||
|
integrity sha512-nkFgAb0cP4jUodkUBErMNfyF78jJLtgL1Mrr9/rvGpGobo10IAbb8zZY4CkZ64o8XmMy/85+wZTKcx+KHatqpg==
|
||||||
|
|
||||||
|
"@spectrum-css/toast@^3.0.1":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/toast/-/toast-3.0.3.tgz#97c1527384707600832ecda35643ed304615250f"
|
||||||
|
integrity sha512-CjLeaMs+cjUXojCCRtbj0YkD2BoZW16kjj2o5omkEpUTjA34IJ8xJ1a+CCtDILWekhXvN0MBN4sbumcnwcnx8w==
|
||||||
|
|
||||||
|
"@spectrum-css/tooltip@^3.0.3":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/tooltip/-/tooltip-3.0.3.tgz#26b8ca3b3d30e29630244d85eb4fc11d0c841281"
|
||||||
|
integrity sha512-ztRF7WW1FzyNavXBRc+80z67UoOrY9wl3cMYsVD3MpDnyxdzP8cjza1pCcolKBaFqRTcQKkxKw3GWtGICRKR5A==
|
||||||
|
|
||||||
|
"@spectrum-css/treeview@^3.0.2":
|
||||||
|
version "3.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/treeview/-/treeview-3.0.3.tgz#aeda5175158b9f8d7529cb2b394428eb2a428046"
|
||||||
|
integrity sha512-D5gGzZC/KtRArdx86Mesc9+99W9nTbUOeyYGqoJoAfJSOttoT6Tk5CrDvlCmAqjKf5rajemAkGri1ChqvUIwkw==
|
||||||
|
|
||||||
|
"@spectrum-css/typography@^3.0.1", "@spectrum-css/typography@^3.0.2":
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@spectrum-css/typography/-/typography-3.0.2.tgz#ea3ca0a60e18064527819d48c8c4364cab4fcd38"
|
resolved "https://registry.yarnpkg.com/@spectrum-css/typography/-/typography-3.0.2.tgz#ea3ca0a60e18064527819d48c8c4364cab4fcd38"
|
||||||
integrity sha512-5ZOLmQe0edzsDMyhghUd4hBb5uxGsFrxzf+WasfcUw9klSfTsRZ09n1BsaaWbgrLjlMQ+EEHS46v5VNo0Ms2CA==
|
integrity sha512-5ZOLmQe0edzsDMyhghUd4hBb5uxGsFrxzf+WasfcUw9klSfTsRZ09n1BsaaWbgrLjlMQ+EEHS46v5VNo0Ms2CA==
|
||||||
|
|
||||||
|
"@spectrum-css/underlay@^2.0.9":
|
||||||
|
version "2.0.10"
|
||||||
|
resolved "https://registry.yarnpkg.com/@spectrum-css/underlay/-/underlay-2.0.10.tgz#8b75b646605a311850f6620caa18d4996cd64ed7"
|
||||||
|
integrity sha512-PmsmkzeGD/rY4pp3ILXHt9w8BW7uaEqXe08hQRS7rGki7wqCpG4mE0/8N3yEcA3QxWQclmG9gdkg5uz6wMmYzA==
|
||||||
|
|
||||||
"@spectrum-css/vars@^3.0.1", "@spectrum-css/vars@^3.0.2":
|
"@spectrum-css/vars@^3.0.1", "@spectrum-css/vars@^3.0.2":
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.2.tgz#ea9062c3c98dfc6ba59e5df14a03025ad8969999"
|
resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-3.0.2.tgz#ea9062c3c98dfc6ba59e5df14a03025ad8969999"
|
||||||
|
@ -95,6 +325,11 @@ colorette@^1.2.2:
|
||||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
|
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
|
||||||
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
|
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
|
||||||
|
|
||||||
|
dayjs@^1.10.4:
|
||||||
|
version "1.10.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.6.tgz#288b2aa82f2d8418a6c9d4df5898c0737ad02a63"
|
||||||
|
integrity sha512-AztC/IOW4L1Q41A86phW5Thhcrco3xuAA+YX/BLpLWWjRcTj5TOt/QImBLmCKlrF7u7k47arTnOyL6GnbG8Hvw==
|
||||||
|
|
||||||
dayjs@^1.10.5:
|
dayjs@^1.10.5:
|
||||||
version "1.10.5"
|
version "1.10.5"
|
||||||
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986"
|
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986"
|
||||||
|
@ -246,6 +481,11 @@ svelte-hmr@^0.14.2:
|
||||||
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.4.tgz#b7ef2bfeef23916e0e912828c50645ca572ac355"
|
resolved "https://registry.yarnpkg.com/svelte-hmr/-/svelte-hmr-0.14.4.tgz#b7ef2bfeef23916e0e912828c50645ca572ac355"
|
||||||
integrity sha512-kItFF7vqzStckSigoFmMnxJpTOdB9TWnQAW6Js+yAB4277tLbJIIE5KBlGHNmJNpA7MguqidsPB27Uw5UzQPCA==
|
integrity sha512-kItFF7vqzStckSigoFmMnxJpTOdB9TWnQAW6Js+yAB4277tLbJIIE5KBlGHNmJNpA7MguqidsPB27Uw5UzQPCA==
|
||||||
|
|
||||||
|
svelte-portal@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/svelte-portal/-/svelte-portal-1.0.0.tgz#36a47c5578b1a4d9b4dc60fa32a904640ec4cdd3"
|
||||||
|
integrity sha512-nHf+DS/jZ6jjnZSleBMSaZua9JlG5rZv9lOGKgJuaZStfevtjIlUJrkLc3vbV8QdBvPPVmvcjTlazAzfKu0v3Q==
|
||||||
|
|
||||||
svelte@^3.38.2:
|
svelte@^3.38.2:
|
||||||
version "3.38.2"
|
version "3.38.2"
|
||||||
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.38.2.tgz#55e5c681f793ae349b5cc2fe58e5782af4275ef5"
|
resolved "https://registry.yarnpkg.com/svelte/-/svelte-3.38.2.tgz#55e5c681f793ae349b5cc2fe58e5782af4275ef5"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/string-templates",
|
"name": "@budibase/string-templates",
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"description": "Handlebars wrapper for Budibase templating.",
|
"description": "Handlebars wrapper for Budibase templating.",
|
||||||
"main": "src/index.cjs",
|
"main": "src/index.cjs",
|
||||||
"module": "dist/bundle.mjs",
|
"module": "dist/bundle.mjs",
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
node_modules/
|
node_modules/
|
||||||
.env
|
.env
|
||||||
|
watchtower-hook.json
|
|
@ -1,5 +1,10 @@
|
||||||
FROM node:12-alpine
|
FROM node:12-alpine
|
||||||
|
|
||||||
|
LABEL com.centurylinklabs.watchtower.lifecycle.pre-check="scripts/watchtower-hooks/pre-check.sh"
|
||||||
|
LABEL com.centurylinklabs.watchtower.lifecycle.pre-update="scripts/watchtower-hooks/pre-update.sh"
|
||||||
|
LABEL com.centurylinklabs.watchtower.lifecycle.post-update="scripts/watchtower-hooks/post-update.sh"
|
||||||
|
LABEL com.centurylinklabs.watchtower.lifecycle.post-check="scripts/watchtower-hooks/post-check.sh"
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# copy files and install dependencies
|
# copy files and install dependencies
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@budibase/worker",
|
"name": "@budibase/worker",
|
||||||
"email": "hi@budibase.com",
|
"email": "hi@budibase.com",
|
||||||
"version": "0.9.80-alpha.9",
|
"version": "0.9.87-alpha.7",
|
||||||
"description": "Budibase background service",
|
"description": "Budibase background service",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -23,8 +23,8 @@
|
||||||
"author": "Budibase",
|
"author": "Budibase",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@budibase/auth": "^0.9.80-alpha.9",
|
"@budibase/auth": "^0.9.87-alpha.7",
|
||||||
"@budibase/string-templates": "^0.9.80-alpha.9",
|
"@budibase/string-templates": "^0.9.87-alpha.7",
|
||||||
"@koa/router": "^8.0.0",
|
"@koa/router": "^8.0.0",
|
||||||
"@techpass/passport-openidconnect": "^0.3.0",
|
"@techpass/passport-openidconnect": "^0.3.0",
|
||||||
"aws-sdk": "^2.811.0",
|
"aws-sdk": "^2.811.0",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
echo '{ "current-hook" : "post-check" }' > 'watchtower-hook.json'
|
|
@ -0,0 +1 @@
|
||||||
|
echo '{ "current-hook" : "post-update" }' > 'watchtower-hook.json'
|
|
@ -0,0 +1 @@
|
||||||
|
echo '{ "current-hook" : "pre-check" }' > 'watchtower-hook.json'
|
|
@ -0,0 +1 @@
|
||||||
|
echo '{ "current-hook" : "pre-update" }' > 'watchtower-hook.json'
|
Loading…
Reference in New Issue