mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
Merge branch 'develop' into feat/formula-field
This commit is contained in:
@@ -22,26 +22,11 @@ to start.
|
||||
|
||||
## Working on existing issues
|
||||
|
||||
If you are working on an [issue](https://github.com/rowyio/rowy/issues), share
|
||||
that you are working on it by commenting on the issue and posting a message on
|
||||
#contributions channel in Rowy's
|
||||
[Discord](https://discord.com/invite/fjBugmvzZP). This allows others in the
|
||||
community and the maintainers a chance to provide feedback and guidance before
|
||||
you spend time working on it. Before you get started working on an
|
||||
[issue](https://github.com/rowyio/rowy/issues), please make sure to share that
|
||||
you are working on it by commenting on the issue and posting a message on
|
||||
#contributions channel in Rowy's
|
||||
[Discord](https://discord.com/invite/fjBugmvzZP). The maintainers will then
|
||||
assign the issue to you after making sure any relevant information or context in
|
||||
addition is provided before you can start on the task.
|
||||
|
||||
Once you are assigned a task, please provide periodic updates or share any
|
||||
questions or roadblocks on either discord or the Github issue, so that the
|
||||
commmunity or the project maintainers can provide you any feedback or guidance
|
||||
as needed. If you are inactive for more than 1-2 week on a issue that was
|
||||
assigned to you, then we will assume you have stopped working on it and we will
|
||||
unassign it from you - so that we can give a chance to others in the community
|
||||
to work on it.
|
||||
|
||||
Before you get started working on an [issue](https://github.com/rowyio/rowy/issues), please make sure to share that you are working on it by commenting on the issue and posting a message on #contributions channel in Rowy's [Discord](https://discord.com/invite/fjBugmvzZP). The maintainers will then assign the issue to you after making sure any relevant information or context in addition is provided before you can start on the task.
|
||||
|
||||
Once you are assigned a task, please provide periodic updates or share any questions or roadblocks on either discord or the Github issue, so that the commmunity or the project maintainers can provide you any feedback or guidance as needed. If you are inactive for more than 1-2 week on a issue that was assigned to you, then we will assume you have stopped working on it and we will unassign it from you - so that we can give a chance to others in the community to work on it.
|
||||
|
||||
## File a feature request
|
||||
|
||||
|
||||
43
README.md
43
README.md
@@ -30,7 +30,8 @@ Connect to your database, manage data in table-UI with role based access control
|
||||
<img width="100%" src="https://user-images.githubusercontent.com/307298/157184506-f94f3f5b-e6d3-49df-9a2c-f665511883f2.png" />
|
||||
|
||||
## Live Demo
|
||||
💥 Check out the [live demo](https://demo.rowy.io/) of Rowy 💥
|
||||
|
||||
💥 Check out the [live demo](https://demo.rowy.io/) of Rowy 💥
|
||||
|
||||
## Quick Deploy
|
||||
|
||||
@@ -42,7 +43,7 @@ https://rowy.app
|
||||
|
||||
## Documentation
|
||||
|
||||
You can find the full documentation with how-to guides and templates
|
||||
You can find the full documentation with how-to guides and templates
|
||||
[here](http://docs.rowy.io/).
|
||||
|
||||
## Features
|
||||
@@ -51,6 +52,7 @@ https://user-images.githubusercontent.com/307298/157185793-f67511cd-7b7b-4229-95
|
||||
|
||||
<!-- <img width="85%" src="https://firebasestorage.googleapis.com/v0/b/rowyio.appspot.com/o/publicDemo%2FRowy%20Website%20Video%20GIF%20Small.gif?alt=media&token=3f699a8f-c1f2-4046-8ed5-e4ff66947cd8" />
|
||||
-->
|
||||
|
||||
### Powerful spreadsheet interface for Firestore
|
||||
|
||||
- CMS for Firestore
|
||||
@@ -62,22 +64,22 @@ https://user-images.githubusercontent.com/307298/157185793-f67511cd-7b7b-4229-95
|
||||
|
||||
### Automate with cloud functions and ready made extensions
|
||||
|
||||
- Build cloud functions workflows on field level data changes
|
||||
- Use any NPM modules or APIs
|
||||
- Build cloud functions workflows on field level data changes
|
||||
- Use any NPM modules or APIs
|
||||
- Connect to your favourite tool with pre-built code blocks or create your own
|
||||
- SendGrid, Algolia, Twilio, Bigquery and more
|
||||
- SendGrid, Algolia, Twilio, Bigquery and more
|
||||
|
||||
### Rich and flexible data fields
|
||||
|
||||
- [30+ fields supported](https://docs.rowy.io/field-types/supported-fields)
|
||||
- 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), Markdown
|
||||
- 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), 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
|
||||
- Connector field: Connect data from multiple table collections
|
||||
- Connector field: Connect data from multiple table collections
|
||||
- Connect Service: Get data from any HTTP endpoint
|
||||
|
||||
### Collaborate with your team
|
||||
@@ -89,7 +91,8 @@ https://user-images.githubusercontent.com/307298/157185793-f67511cd-7b7b-4229-95
|
||||
|
||||
## Install
|
||||
|
||||
Set up Rowy on your Google Cloud project with this one-click deploy button. Your data and cloud functions stay on your own Firestore/GCP.
|
||||
Set up Rowy on your Google Cloud project with this one-click deploy button. Your
|
||||
data and cloud functions stay on your own Firestore/GCP.
|
||||
|
||||
[](https://rowy.app/)
|
||||
|
||||
@@ -105,16 +108,24 @@ Alternatively, you can manually install by
|
||||
|
||||
## Roadmap
|
||||
|
||||
[View our roadmap](https://demo.rowy.io/table/roadmap) on Rowy - Upvote, downvote, share your thoughts!
|
||||
[View our roadmap](https://demo.rowy.io/table/roadmap) on Rowy - Upvote,
|
||||
downvote, share your thoughts!
|
||||
|
||||
If you'd like to propose a feature, submit an issue [here](https://github.com/rowyio/rowy/issues/new?assignees=&labels=&template=feature_request.md&title=).
|
||||
If you'd like to propose a feature, submit an issue
|
||||
[here](https://github.com/rowyio/rowy/issues/new?assignees=&labels=&template=feature_request.md&title=).
|
||||
|
||||
## Support the project
|
||||
|
||||
- Join a community of developers on [Discord](https://discord.gg/fjBugmvzZP) and share your ideas/feedback 💬
|
||||
- Follow us on [Twitter](https://twitter.com/rowyio) and help [spread the word](https://twitter.com/intent/tweet?text=Check%20out%20@rowyio%20-%20It%27s%20like%20an%20open-source%20Airtable%20for%20your%20database,%20but%20with%20a%20built-in%20code%20editor%20for%20cloud%20functions%20to%20run%20on%20data%20CRUD!%0a%0aEsp%20if%20building%20on%20@googlecloud%20and%20@Firebase%20stack,%20it%20is%20the%20fastest%20way%20to%20build%20your%20product.%20Live%20demo:%20https://demo.rowy.io) 🙏
|
||||
- Join a community of developers on [Discord](https://discord.gg/fjBugmvzZP) and
|
||||
share your ideas/feedback 💬
|
||||
- Follow us on [Twitter](https://twitter.com/rowyio) and help
|
||||
[spread the word](https://twitter.com/intent/tweet?text=Check%20out%20@rowyio%20-%20It%27s%20like%20an%20open-source%20Airtable%20for%20your%20database,%20but%20with%20a%20built-in%20code%20editor%20for%20cloud%20functions%20to%20run%20on%20data%20CRUD!%0a%0aEsp%20if%20building%20on%20@googlecloud%20and%20@Firebase%20stack,%20it%20is%20the%20fastest%20way%20to%20build%20your%20product.%20Live%20demo:%20https://demo.rowy.io)
|
||||
🙏
|
||||
- Give us a star to this Github repo ⭐️
|
||||
- Submit a PR. Take a look at our [contribution guide](https://github.com/rowyio/rowy/blob/main/CONTRIBUTING.md) and get started with [good first issues](https://github.com/rowyio/rowy/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
|
||||
- Submit a PR. Take a look at our
|
||||
[contribution guide](https://github.com/rowyio/rowy/blob/main/CONTRIBUTING.md)
|
||||
and get started with
|
||||
[good first issues](https://github.com/rowyio/rowy/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
|
||||
|
||||
## Help
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { useAtom, useSetAtom } from "jotai";
|
||||
import { useSetAtom } from "jotai";
|
||||
|
||||
import { Box, BoxProps, Button } from "@mui/material";
|
||||
import { AddColumn as AddColumnIcon } from "@src/assets/icons";
|
||||
|
||||
import { projectScope, userRolesAtom } from "@src/atoms/projectScope";
|
||||
import { tableScope, columnModalAtom } from "@src/atoms/tableScope";
|
||||
import { spreadSx } from "@src/utils/ui";
|
||||
|
||||
@@ -17,10 +16,43 @@ export default function FinalColumnHeader({
|
||||
canAddColumns,
|
||||
...props
|
||||
}: IFinalColumnHeaderProps) {
|
||||
const [userRoles] = useAtom(userRolesAtom, projectScope);
|
||||
const openColumnModal = useSetAtom(columnModalAtom, tableScope);
|
||||
|
||||
if (!userRoles.includes("ADMIN"))
|
||||
if (canAddColumns)
|
||||
return (
|
||||
<Box
|
||||
role="columnheader"
|
||||
{...props}
|
||||
sx={[
|
||||
{
|
||||
backgroundColor: "background.default",
|
||||
border: (theme) => `1px solid ${theme.palette.divider}`,
|
||||
borderLeft: "none",
|
||||
borderTopRightRadius: (theme) => theme.shape.borderRadius,
|
||||
borderBottomRightRadius: (theme) => theme.shape.borderRadius,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
width: 32 * 3 + 4 * 2 + 10 * 2,
|
||||
overflow: "visible",
|
||||
px: 0.75,
|
||||
},
|
||||
...spreadSx(props.sx),
|
||||
]}
|
||||
className="column-header"
|
||||
>
|
||||
<Button
|
||||
onClick={() => openColumnModal({ type: "new" })}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<AddColumnIcon />}
|
||||
style={{ zIndex: 1, flexShrink: 0 }}
|
||||
tabIndex={focusInsideCell ? 0 : -1}
|
||||
>
|
||||
Add column
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
else
|
||||
return (
|
||||
<Box
|
||||
role="columnheader"
|
||||
@@ -47,40 +79,4 @@ export default function FinalColumnHeader({
|
||||
Actions
|
||||
</Box>
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
role="columnheader"
|
||||
{...props}
|
||||
sx={[
|
||||
{
|
||||
backgroundColor: "background.default",
|
||||
border: (theme) => `1px solid ${theme.palette.divider}`,
|
||||
borderLeft: "none",
|
||||
borderTopRightRadius: (theme) => theme.shape.borderRadius,
|
||||
borderBottomRightRadius: (theme) => theme.shape.borderRadius,
|
||||
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
|
||||
width: 32 * 3 + 4 * 2 + 10 * 2,
|
||||
overflow: "visible",
|
||||
px: 0.75,
|
||||
},
|
||||
...spreadSx(props.sx),
|
||||
]}
|
||||
className="column-header"
|
||||
>
|
||||
<Button
|
||||
onClick={() => openColumnModal({ type: "new" })}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<AddColumnIcon />}
|
||||
style={{ zIndex: 1, flexShrink: 0 }}
|
||||
tabIndex={focusInsideCell ? 0 : -1}
|
||||
>
|
||||
Add column
|
||||
</Button>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ export function emptyExtensionObject(
|
||||
): IExtension {
|
||||
return {
|
||||
name: `${type} extension`,
|
||||
active: false,
|
||||
active: true,
|
||||
triggers: [],
|
||||
type,
|
||||
extensionBody: extensionBodyTemplate[type] ?? extensionBodyTemplate["task"],
|
||||
|
||||
@@ -99,7 +99,7 @@ export function emptyWebhookObject(
|
||||
): IWebhook {
|
||||
return {
|
||||
name: `${type} webhook`,
|
||||
active: false,
|
||||
active: true,
|
||||
endpoint: generateId(),
|
||||
type,
|
||||
parser: webhookSchemas[type].parser?.template(table),
|
||||
|
||||
@@ -311,6 +311,17 @@ export const tableSettings = (
|
||||
label: "Suggested Firestore Rules",
|
||||
watchedField: "collection",
|
||||
},
|
||||
{
|
||||
step: "accessControls",
|
||||
type: FieldType.multiSelect,
|
||||
name: "modifiableBy",
|
||||
label: "Modifiable by",
|
||||
labelPlural: "Modifier Roles",
|
||||
options: roles ?? [],
|
||||
defaultValue: ["ADMIN"],
|
||||
required: true,
|
||||
freeText: true,
|
||||
},
|
||||
|
||||
// Step 4: Auditing
|
||||
{
|
||||
|
||||
@@ -2,13 +2,17 @@ import { useAtom } from "jotai";
|
||||
import { find, get } from "lodash-es";
|
||||
import { useSnackbar } from "notistack";
|
||||
|
||||
import { Button } from "@mui/material";
|
||||
import ReEvalIcon from "@mui/icons-material/ReplayOutlined";
|
||||
import EvalIcon from "@mui/icons-material/PlayCircleOutline";
|
||||
import InlineOpenInNewIcon from "@src/components/InlineOpenInNewIcon";
|
||||
|
||||
import {
|
||||
projectScope,
|
||||
compatibleRowyRunVersionAtom,
|
||||
rowyRunAtom,
|
||||
projectIdAtom,
|
||||
projectSettingsAtom,
|
||||
} from "@src/atoms/projectScope";
|
||||
import {
|
||||
tableScope,
|
||||
@@ -34,6 +38,8 @@ export const ContextMenuActions: IFieldConfig["contextMenuActions"] = (
|
||||
const [tableSettings] = useAtom(tableSettingsAtom, tableScope);
|
||||
const [tableSchema] = useAtom(tableSchemaAtom, tableScope);
|
||||
const [tableRows] = useAtom(tableRowsAtom, tableScope);
|
||||
const [projectId] = useAtom(projectIdAtom, projectScope);
|
||||
const [projectSettings] = useAtom(projectSettingsAtom, projectScope);
|
||||
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
|
||||
const [compatibleRowyRunVersion] = useAtom(
|
||||
compatibleRowyRunVersionAtom,
|
||||
@@ -76,8 +82,32 @@ export const ContextMenuActions: IFieldConfig["contextMenuActions"] = (
|
||||
} else {
|
||||
enqueueSnackbar("Cell evaluated", { variant: "success" });
|
||||
}
|
||||
} catch (error) {
|
||||
enqueueSnackbar(`Failed: ${error}`, { variant: "error" });
|
||||
} catch (error: any) {
|
||||
if (error.message === "Failed to fetch") {
|
||||
enqueueSnackbar(
|
||||
"Evaluation failed. Rowy Run is likely out of memory. Please allocate more in GCP console.",
|
||||
{
|
||||
variant: "warning",
|
||||
persist: true,
|
||||
action: (snackbarId) => (
|
||||
<Button
|
||||
href={`https://console.cloud.google.com/run/deploy/${
|
||||
projectSettings.rowyRunRegion ?? "us-central1"
|
||||
}/rowy-backend?project=${projectId}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
onClick={() => closeSnackbar(snackbarId)}
|
||||
variant="contained"
|
||||
color="secondary"
|
||||
>
|
||||
Open GCP Console <InlineOpenInNewIcon />
|
||||
</Button>
|
||||
),
|
||||
}
|
||||
);
|
||||
} else {
|
||||
enqueueSnackbar(`Failed: ${error}`, { variant: "error" });
|
||||
}
|
||||
}
|
||||
};
|
||||
const isEmpty =
|
||||
|
||||
@@ -81,8 +81,10 @@ export default function TablePage({
|
||||
|
||||
// Set permissions here so we can pass them to the `Table` component, which
|
||||
// shouldn’t access `projectScope` at all, to separate concerns.
|
||||
const canAddColumns =
|
||||
userRoles.includes("ADMIN") || userRoles.includes("OPS");
|
||||
const canAddColumns = Boolean(
|
||||
userRoles.includes("ADMIN") ||
|
||||
tableSettings.modifiableBy?.some((r) => userRoles.includes(r))
|
||||
);
|
||||
const canEditColumns = canAddColumns;
|
||||
const canDeleteColumns = canAddColumns;
|
||||
const canEditCells =
|
||||
|
||||
@@ -145,10 +145,25 @@ export function useTableFunctions() {
|
||||
// Shallow merge new settings with old
|
||||
tables[tableIndex] = { ...tables[tableIndex], ...settings };
|
||||
|
||||
// Create tablesSettings object from tables array
|
||||
const tablesSettings = tables.reduce(
|
||||
(acc, table) => {
|
||||
if (table.tableType === "primaryCollection") {
|
||||
acc.pc[table.id] = table;
|
||||
} else {
|
||||
acc.cg[table.id] = table;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{
|
||||
pc: {},
|
||||
cg: {},
|
||||
} as Record<string, Record<string, TableSettings>>
|
||||
);
|
||||
// Updates settings doc with new tables array
|
||||
const promiseUpdateSettings = setDoc(
|
||||
doc(firebaseDb, SETTINGS),
|
||||
{ tables },
|
||||
{ tables, tablesSettings },
|
||||
{ merge: true }
|
||||
);
|
||||
|
||||
|
||||
1
src/types/table.d.ts
vendored
1
src/types/table.d.ts
vendored
@@ -75,6 +75,7 @@ export type TableSettings = {
|
||||
description?: string;
|
||||
details?: string;
|
||||
thumbnailURL?: string;
|
||||
modifiableBy?: string[];
|
||||
|
||||
_createdBy?: {
|
||||
displayName?: string;
|
||||
|
||||
Reference in New Issue
Block a user