Merge branch 'develop' into feat/formula-field

This commit is contained in:
Shams
2022-12-26 21:36:52 +01:00
committed by GitHub
10 changed files with 133 additions and 82 deletions

View File

@@ -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

View File

@@ -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 rows 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.
[![Run on Google Cloud](https://deploy.cloud.run/button.svg)](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

View File

@@ -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>
);
}

View File

@@ -232,7 +232,7 @@ export function emptyExtensionObject(
): IExtension {
return {
name: `${type} extension`,
active: false,
active: true,
triggers: [],
type,
extensionBody: extensionBodyTemplate[type] ?? extensionBodyTemplate["task"],

View File

@@ -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),

View File

@@ -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
{

View File

@@ -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 =

View File

@@ -81,8 +81,10 @@ export default function TablePage({
// Set permissions here so we can pass them to the `Table` component, which
// shouldnt 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 =

View File

@@ -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 }
);

View File

@@ -75,6 +75,7 @@ export type TableSettings = {
description?: string;
details?: string;
thumbnailURL?: string;
modifiableBy?: string[];
_createdBy?: {
displayName?: string;