mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
Merge branch 'feat/airtable-migration' of https://github.com/htuerker/rowy into feat/airtable-migration
This commit is contained in:
22
README.md
22
README.md
@@ -3,13 +3,13 @@
|
||||
</p>
|
||||
|
||||
<h1 align="center">
|
||||
✨ Data x Code ✨ <br/>
|
||||
✨ Low-code for Firebase and GCP ✨ <br/>
|
||||
</h1>
|
||||
<h3 align="center">
|
||||
Modern Backend Stack
|
||||
Airtable-like UI for Firestore meets IDE in browser for cloud functions
|
||||
</h3>
|
||||
<p align="center">
|
||||
Forget CLIs, configs, and DevOps. Focus on building your apps with a platform designed for developer productivity. Your production database (Firestore) in an Airtable-like UI with full coding extensibility via Cloud Functions visually in the browser.
|
||||
Connect to your database, manage data in table-UI with role based access controls. Build cloud function workflows in JS/TS using any NPM or APIs. Forget CLIs, configs, and DevOps. Focus on building your apps with a platform designed for developer productivity.
|
||||
</p>
|
||||
|
||||
<div align="center">
|
||||
@@ -23,7 +23,6 @@ Forget CLIs, configs, and DevOps. Focus on building your apps with a platform de
|
||||
<a href="https://twitter.com/rowyio"><b>Twitter</b></a>
|
||||
</p>
|
||||
|
||||
[](https://github.com/rowyio/rowy/blob/main/LICENSE)
|
||||
[](https://github.com/rowyio/rowy/commits/rc)
|
||||
[](https://github.com/rowyio/rowy/stargazers/)
|
||||
|
||||
@@ -54,17 +53,18 @@ https://user-images.githubusercontent.com/307298/157185793-f67511cd-7b7b-4229-95
|
||||
-->
|
||||
### Powerful spreadsheet interface for Firestore
|
||||
|
||||
- CMS for Firestore
|
||||
- CRUD operations
|
||||
- Bulk import or export data - csv, json, tsv
|
||||
- Sort and filter by row values
|
||||
- Lock, Freeze, Resize, Hide and Rename columns
|
||||
- Multiple views for the same collection
|
||||
- Bulk import or export data - csv, json
|
||||
|
||||
### Automate with cloud functions and ready made extensions
|
||||
|
||||
- Effortlessly build cloud functions on field level triggers right in the browser
|
||||
- Build cloud functions workflows on field level data changes
|
||||
- Use any NPM modules or APIs
|
||||
- Connect to your favourite tool with pre-built extensions or create your own
|
||||
- Connect to your favourite tool with pre-built code blocks or create your own
|
||||
- SendGrid, Algolia, Twilio, Bigquery and more
|
||||
|
||||
### Rich and flexible data fields
|
||||
@@ -73,17 +73,17 @@ https://user-images.githubusercontent.com/307298/157185793-f67511cd-7b7b-4229-95
|
||||
- Basic types: Short Text, Long Text, Email, Phone, URL…
|
||||
- Custom UI pickers: Date, Checkbox, Single Select, Multi Select…
|
||||
- Uploaders: Image, File
|
||||
- Rich Editors: JSON, Code, Rich Text (HTML)
|
||||
- Data validation, default values, required fields
|
||||
- Rich Editors: JSON, Code, Rich Text (HTML), Markdown
|
||||
- Data validation, default values, required fields
|
||||
- Action field: Clickable trigger for any Cloud Function
|
||||
- Aggregate field: Populate cell with value aggregated from the row’s sub-table
|
||||
- Connect Table: Get snapshot of data from another data table using Algolia
|
||||
- Connector field: Connect data from multiple table collections
|
||||
- Connect Service: Get data from any HTTP endpoint
|
||||
|
||||
### Collaborate with your team
|
||||
|
||||
- Granular table-level and field-level permission control
|
||||
with custom user roles
|
||||
with role based access controls
|
||||
- Built in user management
|
||||
- Customizable views for different user roles
|
||||
|
||||
|
||||
@@ -346,16 +346,6 @@ export const updateFieldAtom = atom(
|
||||
update[tableSettings.auditFieldUpdatedBy || "_updatedBy"] = auditValue;
|
||||
}
|
||||
|
||||
// Check for required fields
|
||||
const requiredFields = ignoreRequiredFields
|
||||
? []
|
||||
: tableColumnsOrdered
|
||||
.filter((column) => column.config?.required)
|
||||
.map((column) => column.key);
|
||||
const missingRequiredFields = ignoreRequiredFields
|
||||
? []
|
||||
: requiredFields.filter((field) => row[field] === undefined);
|
||||
|
||||
// Apply field update
|
||||
if (!deleteField) {
|
||||
// Check for equality. If updated value is same as current, skip update
|
||||
@@ -367,6 +357,17 @@ export const updateFieldAtom = atom(
|
||||
_set(update, fieldName, value);
|
||||
}
|
||||
|
||||
// Check for required fields
|
||||
const newRowValues = updateRowData(cloneDeep(row), update);
|
||||
const requiredFields = ignoreRequiredFields
|
||||
? []
|
||||
: tableColumnsOrdered
|
||||
.filter((column) => column.config?.required)
|
||||
.map((column) => column.key);
|
||||
const missingRequiredFields = ignoreRequiredFields
|
||||
? []
|
||||
: requiredFields.filter((field) => newRowValues[field] === undefined);
|
||||
|
||||
// If it’s a local row, update the row in rowsLocal
|
||||
if (isLocalRow) {
|
||||
set(tableRowsLocalAtom, {
|
||||
@@ -379,12 +380,11 @@ export const updateFieldAtom = atom(
|
||||
// If it has no missingRequiredFields, also write to db
|
||||
// And write entire row to handle the case where it doesn’t exist in db yet
|
||||
if (missingRequiredFields.length === 0) {
|
||||
const rowValues = updateRowData(cloneDeep(row), update);
|
||||
if (deleteField) unset(rowValues, fieldName);
|
||||
if (deleteField) unset(newRowValues, fieldName);
|
||||
|
||||
await updateRowDb(
|
||||
row._rowy_ref.path,
|
||||
omitRowyFields(rowValues),
|
||||
omitRowyFields(newRowValues),
|
||||
deleteField ? [fieldName] : []
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user