Git Product home page Git Product logo

whitebrick-client's Introduction

whitebrick logo

whitebrick-client No Code DB

⚠️ This project is no longer maintained


gatsby-theme-whitebrick-client (See whitebrick-cloud for back end)

No Code Database built on Hasura, GraphQL, Gatsby and Serverless
Screenshot Screenshot Screenshot Screenshot
Adding a record Creating a column Creating a DB Managing access

Points of difference:

  1. Gatsby static Jamstack client allows for easy customization with theme shadowing and simple, zero downtime deployment to static web servers.
  2. Hasura is leveraged for battle-tested table tracking, query processing and authentication and RBAC.
  3. The Serverless framework with Apollo GraphQL allows for rapid development of light-weight Lambda support functions.

Roadmap:

  • DDL Table & Column CRUD
  • Live editing with subscription
  • Table-level RBAC
  • Joins
  • Background process queue
  • Background process UI
  • UI styling and themes
  • psql reader/writer access
  • Validations
  • Bucket file download columns
  • Column-level RBAC

Licensing

Whitebrick is licensed under the MIT License however dependency licenses vary.


Overview

system diagram

The Whitebrick No Code DB (Data Repository) comprises a front end Gatsby Jamstack client (whitebrick-client) and back end Serverless application (whitebrick-cloud) that adds multi-tenant DDL and access control functions to a Database via the Hasura GraphQL Server. The Jamstack client uses AG Grid as a spreadsheet-like UI that reads/writes table data directly from/to Hasura over GraphQL. Additional functions including DDL are provided by whitebrick-cloud Serverless functions that are exposed through the Hasura endpoint via schema stitching.


Getting Started

UPDATE June 2022: We were unable to find the community interest or commercial support to continue providing the Whitebrick Cloud back end as a service. You will need to run your own back end and authentication service following the instructions here.

Getting Started with Shadowing

The Whitebrick front end is packaged as a Gatsby Theme that can be installed from npm. Gatsby Themes are customized using a system called Shadowing that allows individual pages, components and assets to be overridden by conforming to a specific directory structure. The advantage of this is that the Whitebrick client Theme can be maintained and updated independently of your customizations.

The easiest way to get started is to use our Gastby Starter that installs our Gatsby Theme and also includes a simple example of overriding the header and branding.

  1. Clone the Whitebrick Starter Repository

    git clone [email protected]:whitebrick/gatsby-starter-whitebrick.git
    
  2. Install Packages

    cd gatsby-starter-whitebrick
    npm install
    
  3. Start Gatsby

    npm run develop
    

    Gatsby will start a hot-reloading development environment accessible by default at http://localhost:8000.

  4. Customize

    Copy or add files to the gatsby-starter-whitebrick/src directory to make changes by overriding the corresponding Whitebrick Theme files.

Client Development

To run the Whitebrick client independently (rather than as a Theme) simple clone the Whitebrick repository, configure the .env and run Gatsby directly.

  1. Clone or Fork the Whitebrick Client Repository

    git clone [email protected]:whitebrick/whitebrick-client.git
    
  2. Install Packages

    cd whitebrick-client
    npm install
    
  3. Configure the Client

    The .env.development is provided with default values - see .env.example for additional options.

  4. Start Gatsby

    npm run develop
    

    Gatsby will start a hot-reloading development environment accessible by default at http://localhost:8000.

Contributing

  • Questions, comments, suggestions and contributions welcome - contact: hello at whitebrick dot com

whitebrick-client's People

Contributors

harshithpabbati avatar s1monj avatar vsevagen avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

whitebrick-client's Issues

Organization CRUD functions

  • One user can be part of many organizations, an organization can have many users
  • Each user has a role in the organization (admin, user, external user)
  • Any user can create an organization
  • The user that creates the organization is automatically an admin of that organization
  • Only admins can add/remove and set roles for users for the organization
  • We want the UI to support adding/removing users or changing the roles of multiple users at once (so checkboxes to select all etc)

Breaking change: defaultColumnTypes have been moved out of Schema.context field and put in new method:

query MyQuery {
  wbCloudContext
}
  • this also now has the user role names for organzations
  1. Create a new organization:
mutation MyMutation {
  wbCreateOrganization(
    label: "My Test Org",
    name: "my_test_org",
    currentUserEmail: "[email protected]"
  ) {
    name
  }
}

The currentUserEmail is only there until we have the access control working with the userID in the header

  1. Because Donna is the creator she is automatically granted organization_administrator
query MyQuery {
  wbOrganizationUsers(name: "my_test_org") {
    email
    role
  }
}
  1. Add 2 more users
mutation MyMutation {
  wbSetOrganizationUsersRole(
    organizationName: "my_test_org",
    role: "organization_user",
    userEmails: [
      "[email protected]",
      "[email protected]"
    ]
  )
}
  1. Check again:
query MyQuery {
  wbOrganizationUsers(name: "my_test_org") {
    email
    role
  }
}
  1. Modify a user role:
mutation MyMutation {
  wbSetOrganizationUsersRole(
    organizationName: "my_test_org",
    role: "organization_external_user",
    userEmails: [
      "[email protected]"
    ]
  )
}
  1. Check again:
query MyQuery {
  wbOrganizationUsers(name: "my_test_org") {
    email
    role
  }
}
  1. Try to delete an organization:
mutation MyMutation {
  wbDeleteOrganization(name: "my_test_org")
}
// "Error: Remove all non-administrative users from Organization before deleting."
  1. Remove non-admin users:
mutation MyMutation {
  wbRemoveUsersFromOrganization(
    organizationName: "my_test_org",
    userEmails: [
      "[email protected]",
      "[email protected]"
    ]
  )
}
  1. Now try to deleting again:
mutation MyMutation {
  wbDeleteOrganization(name: "my_test_org")
}
  1. Check again:
query MyQuery {
  wbOrganizationUsers(name: "my_test_org") {
    email
    role
  }
}
// "Error: Organization with name 'my_test_org' could not be found"

Improve current loading screen

The loading screen is currently just displaying a text, "Loading..." I believe we can improve it by adding an actual loading animation.

Staging & Dev environments for Gatsby and Auth0

rm ~/git/whitebrick/deploy_staging.sh
rm ~/git/whitebrick-web/deploy_staging.sh

instead use:

git pull
bash scripts/deploy.bash dev|staging [skipBuild]

so we have the following domains:

dev.whitebrick.com (root redirects to dev-hello.whitebrick.com)
dev-hello.whitebrick.com
staging.whitebrick.com (root redirects to staging-hello.whitebrick.com)
staging-hello.whitebrick.com

We need to have .env.development .env.staging .env.production for both whitebrick and whitebrick-web gatsby apps. See this link: https://www.gatsbyjs.com/docs/how-to/local-development/environment-variables/#additional-environments-staging-test-etc

When you run bash scripts/deploy.bash it will do a gatsby build with the STAGING=true or DEVELOPMENT=true flags set (view the source)

For now, lets set up auth0 with staging only (because we only have graph-staging.whitebrick.com) so don't worry about dev

I have set up a staging-whitebrick tenant in auth0, so switch to that and try get the log in flow working with staging.whitebrick.com including callbacks.

Fix warnings

There are a bunch of warnings when checking out the consoles.
They don't seem to break anything so I'l; put them as low priority.

Get new JWT without signing-out and in again

When a user signs-in with Auth0, a "Rule" is run that calls wbCloud graph-staging.whitebrick.com and gets a random role.

Screen Shot 2021-06-10 at 1 03 42 PM

So for example, when you click "Save And try" and then "Try" you will see the roles as https://hasura.io/jwt/claims custom claims are returned and added into the JWT

Screen Shot 2021-06-10 at 1 07 48 PM

  • The RANDOM_ROLE_XXXX is there for testing so we can be sure a new role is being issued by wbCloud each time

This works well. This means each time a user signs-in we can assign the correct roles

The problem is when we change a user role while they are signed-in. For example, if Donna gives Daisy write access to a table, Daisy should be able to click a button to reload her new permissions without having to sign-in to Auth0 all over again.

We need a way to get a new JWT without forcing the user to sign out and sign in again from the Auth0 prompt.

So there are two tasks:

1. Get a new access token from a refresh token using react client

  • Don't worry about the custom claims and roles, just first try set up refresh tokens so the user can get a new token into React without having to sign-in from Auth0 prompt again

See: https://auth0.com/blog/refresh-tokens-what-are-they-and-when-to-use-them/

2. Set the custom claims/roles in the new token

  • The script to get the custom claims/roles only runs at sign-in because it is a "Rule"
  • We need to make the same script run when a new token is requested from a refresh token
  • I think we need to use either Auth0 "Hooks" or "Actions" for this - will need to experiment. We might need to post to Auth0 help or stack over flow

Show table permissions in table settings screen

  • Change "update 'authors' table" to "Authors Table Settings" (ie use label instead of name)

Screen Shot 2021-06-29 at 11 11 22 PM

- Below the Label text input add a small header "Permissions" and a grid like below
User Reader Editor Manager Administrator
[email protected]
etc...
  • use this query to get all table permissions

Screen Shot 2021-06-29 at 11 10 26 PM

Delete an organisation or database from the interface

While testing out a few changes, I created several orgs, databases and tables. In the end, it felt bulky and I wanted to remove a few organisations mainly. This is assuming that when deleting an org, the databases and tables associated with it will be removed as well.

There doesn't seem to be a UI way of doing it for now. I think that would be a good addition.

Sending role with requests

  • "x-hasura-allowed-roles" is the list of roles inside the JWT
  • each role can be a table read+write or a table read only
    • rw12345 = read and write for tableId 12345
    • ro12345 = read only for tableId 12345
  • permissions below are automatically set on the tables by wbCloud

Screen Shot 2021-06-22 at 6 00 57 PM

Screen Shot 2021-06-22 at 6 01 45 PM

Screen Shot 2021-06-22 at 6 02 57 PM

When the client makes a request to a Hasura endpoint, eg: test_donnasdvd_actor the client needs to include the role for that table in the header as x-hasura-role: rw4051

  • x-hasura-role can only ever have one single role
  • each user has at most one role per table
  • this is only required for Hasura endpoints, not the wbXxx endpoints

To implement:

  1. when JWT is fetched/refreshed: read all the roles in the x-hasura-roles array from the JWT
  2. store each role (split the ID from the role string) against the tableName or tableId or in the schema/table object structure (whatever makes most sense)
    eg:
//`tableId`: `roleName`
{
  4051: "rw4051"
...

or:

//`tableName`: `roleName`
{
  "actor": "rw4051"
...

Or in another table object/structure - whatever makes sense

Then when any query/mutation requests are made to test_donnasdvd_actor the header x-hasura-role: rw4051 must be included

Hasura will check that "rw4051" exists in the JWT and if it does, will allow the request access to the table

Editing an organisation opens an empty panel.

Right now, if I want to edit my orgs details, I'll click on the pen icon and it opens up and empty panel.

empty-panel

The type editOrganization is set when clicking on the pen icon. However, editOrganisation doesn't seem to be there in the source code.

DB Selection and URL slug ideas

One DB At-a-time

  • We want the users to feel like they are only ever using one database at-a-time
  • For this reason we should not display other databases on the main screen, only the tables for the current database
  • When a user wants to change database, they go to the menu and select "Switch Database"
  • This will open a screen showing them all the databases they have access to (and who owns them) - something similar to this below:
-- Please select a database --

[Filter Databases]  <-- Text box to search/filter DBs displayed below

-- Databases owned by me --
------------    --------------    --------------
| + Create |    | My Recipes |    | Finances   |   (db label)
|   New    |    | ddrecipe   |    | ddfinances |   (db name)
------------    --------------    --------------

-- Databases shared with me --
-----------------------    -----------------------
| Marys Movie Reviews |    | Bob's Bowling Stats |   (db label)
| mary_reviews        |    | bowling_stats       |   (db name)
| public              |    | [email protected] |   (db owner)
-----------------------    -----------------------

-- Databases owned by my organizations --

== Donna's Media ==
------------    ------------------    --------------------
| + Create |    | Donnas DVD DB  |    | Chinook Music DB |
|   New    |    | test_donnasdvd |    | test_chinook     |
------------    ------------------    --------------------

== Spotify Music ==
------------    -------------------
| + Create |    | Spotify Catalog |
|   New    |    | spotify_cat     |
------------    -------------------

A database should take the following URL pattern:

  • If it is owned by an organization:
    http://localhost:8000/:organization_name/:schema_name
  • If it is owned by a user:
    http://localhost:8000/db/:schema_name

(schem_names are globally unique regardless of owner)

Implementation ideas/discussion:

  • Use globals for $$currentSchemaName and $$currentOrganizationName
  • onLoad if(!$$currentSchemaName) display Switch DB screen above
  • when DB is selected, load corresponding URL
  • onLoad set $$currentSchemaName and $$currentOrganizationName from URL slug
  • every request that requires schemaName passes $$currentSchemaName value

Fix Breadcrumb

Screen Shot 2021-07-25 at 4 40 21 PM

  • Make breadcrump clickable so we can return back to the database to see all tables, or Databases to see all DBs

Screen Shot 2021-07-25 at 4 42 20 PM

  • Breadcrumb should be displaying the label of the schema with matching case (ie Donna's DVD DB rather than donna's dvd db)

Add Edit Delete Column

Please just mock up the backend to develop with until Simon has caught up

Add New Column

When a user is viewing a table:

  1. They click on the context menu at the top of a column (see https://www.ag-grid.com/javascript-grid/context-menu/)
  2. They select "Add new Column"
  3. A dialog pops up and prompts for:
  • Column Name
  • Column Type - select box - for now just hard code values:
    numeric
    text
    date
    timestamp
    
  1. User clicks "Add" (there is also a cancel button)
  2. New column is added to the right of column in (1)

Edit Existing Column

When a user is viewing a table:
6. They click on the context menu at the top of a column
7. They select "Edit Column"
8. A dialog pops up the same as (3) above
9. User clicks "Save" (there is also a cancel button)
10. Column is modified

Delete Existing Column

When a user is viewing a table:
11. They click on the context menu at the top of a column
12. They select "Delete Column"
13. A dialog pops up asking them to confirm the column and all data will be deleted
14. User clicks "Delete" (there is also a cancel button)
15. Column is deleted

Have a tooltip for hidden field

When a user views any table, the fields should be readable. In the cases where it not due to sheer number of columns and size, we can have a tooltip to help the user understand what the field is about.

Screenshot_2021-08-10_10-26-11

Add/Invite/Set Roles for users organizations, schemas and tables

In the edit panel for organizations/schemas/tables we need a feature to assign roles, similar to GitHub below
We should re-use the same screen for organizations, schemas and tables so users are familiar with the flow

  1. Click "Invite User" button from organizations/schemas/tables members screen

  2. "Search by User E-mail or name" as placeholder text similar to below

Screen Shot 2021-07-05 at 10 04 30 PM

  1. Autocomplete (see gql below)
  • Research best autocomplete component library

Screen Shot 2021-07-05 at 8 35 57 PM

  • Use search pattern <user_input>*

Screen Shot 2021-07-05 at 9 53 44 PM

  1. If no user first/last name matches:

Screen Shot 2021-07-05 at 10 06 51 PM

  1. If no user email matches: (the invite mutation is TBD so just use mock placeholder)

Screen Shot 2021-07-05 at 10 07 00 PM

  1. Display roles and set using wbSetOrganizationUsersRole / wbSetSchemaUsersRole / wbSetTableUsersRole

Screen Shot 2021-07-05 at 10 01 08 PM

Dropdowns in breadcrumb

This is just a nice-to-have and low priority

Now we have removed the sidebar, it would be nice to have dropdowns for DB and Table in the breadcrumb to allow the user to switch quickly between different databases and tables

Screen Shot 2021-08-09 at 11 31 52 AM

  • If they change the DB dropdown it should load the first table (alphabetically ordered by label) of that database
  • If they change the Table dropdown it should load that table

Testing Schema-Level permissions

  • Eventually users will be able to assign Schema-Level and Table-Level roles

  • To start with, we are only allowing users to assign Schema-Level roles and all Table-Level roles are automatically inherited

  • When a Schema-Level permission is set, all tables in the Schema inherit the corresponding permissions (eg if a user has a schema_manager role for the schema, they will automatically be give a table_manager role for all the tables in that schema

  • When a table role is set, two things happen:

    1. They are added to table_users with a specific role (there can only be one single role per user per table)
      Screen Shot 2021-06-29 at 2 44 01 PM
    2. They are given a set of permissions in the table_permissions table
      Screen Shot 2021-06-29 at 2 54 44 PM
  • Depending on the role in table_users the permissions are set as follows, eg for table with table.id=1234

    • table_reader roles only have the permission key: s1234 ie SELECT from table 1234
    • all other roles also have the permission keys: i1234 INSERT u1234 UPDATE d1234 DELETE
  • wbCloud automatically configures Hasura permissions to check the user with the permission from table_permissions
    Screen Shot 2021-06-29 at 3 00 33 PM

  • When a request is made to the Hasura-managed GraphQL endpoints, Haura checks the X-Hasura-User-Id against the table_permissions to determine if the user can perform the action

Task

  • Test granting/revoking different schema roles to different users and then sign-in as that user from another incognito tab and check that they have the correct corresponding permissions as described above (dont forget to switch off sending the admin secret from #14)
  • Set the role with wbSetSchemaUsersRole
  • Remove the role with wbRemoveSchemaUsers
  • use the Hasura admin console to debug

Live updates (subscriptions)

The table needs to support live updates of data, so if multiple people are working on the same table and one person makes an edit, the other person sees the updated data (the same as Google Docs works)

We should try this firstly using a subscription to the hasura endpoint with redux - so the subscription event triggers a redux change to update the table data

If that's not feasible we'll have to try use something like pusher (https://pusher.com/channels)

Screen Shot 2021-05-12 at 10 56 19 PM

Foreign key values and joins

We need to think about how we're going to implement FK values and joins

For example, when the user enters the value of a foreign key such as author_id in Posts they should select it from a popup as below. And likewise the parent table Authors should display the many links in the column "Posts"

See the demo here:
https://baserow.io/signup
u: [email protected]
p: rowrowrowboat

adding_fk_vals2.mp4

Many links in Posts column:
Screen Shot 2021-07-30 at 8 56 15 PM

But we also need to consider views with joins (I dont think baserow does it yet?)

For example, when we view a Post, we should also be able to view the author's Name (this is far more useful) not just the author's ID. And then when we click to edit or add a new value for Author Name we can select it from the same popup.

Have a play around and let's come up with a plan and let me know if you need additional logic on the back-end

I remember when we were doing the introspection queries we were able to determine which was a local column vs a joined column - so we may need to revisit that. For now, lets just try get "1st degree" joins working - ie only one level deep of joins - so showing the authors name on the posts table is a great start

AG-Grid sidebar configuration

Screen Shot 2021-07-25 at 4 24 52 PM

  • For now sidebar should only be used to select which columns are displayed (because the other functions are client-side and will confuse the user)
  • Remove all the other buttons (https://www.ag-grid.com/javascript-grid/side-bar/)
  • Sidebar should be hidden by default unless user clicks "Select Columns" toggle at the top of the table next to the "Save Default View" button (see setSideBarVisible(visible))
  • Then the user clicks toggles back to hide sidebar

Table loading animation and faulty "Add database" button

In the case tables are yet to be created, the loading animation should not be there, or at least it should activate for a few seconds only. At the moment, it keeps on loading forever.

company_field

Also, I'm not sure whether it is a side effect of this issue but the "Add table" button doesn't seems to be working as well. Clicking on it didn't activate anything or even left any warnings in the console.

The following two warning were there on loading the /db/[dbName] path
error
Screenshot_2021-08-09_07-48-17

Add/remove sequence for integer columns

If the column is of type integer add option something like this (whatever makes sense to you)

Screen Shot 2021-08-08 at 11 52 27 AM

  • if column.default && column.default.startsWith('nextval') then column has a sequence
    Screen Shot 2021-08-08 at 11 36 50 AM
  • "start at" is optional (see nextSeqNumber below)

To add a sequence:

mutation MyMutation {
  wbAddOrRemoveColumnSequence(columnName: "id", schemaName: "test_the_daisy_blog", tableName: "authors")
}
  • if nextSeqNumber is not passed then it will automatically calculate the max value of the column or use 1

To remove a sequence:

mutation MyMutation {
  wbAddOrRemoveColumnSequence(
    columnName: "id",
    schemaName: "test_the_daisy_blog",
    tableName: "authors",
    remove: true)
}

Have errors or warnings displayed to the user

Currently when creating an organisation or database, if we do not fill one of the fields, it will not save which is right behaviour. However the reason for the data not being saved is not available to the user. There is no indication in the interface that something went wrong.

If we check the console, the error is there but we can't expect the users to use the console.
graphql-error

We also seem to have a lot of space beneath where we enter database and org details. We could have the warnings there.

extra-space

Create blog demo in Baserow

To get a feel for the Baserow app the best thing to start with is to recreate our simple Blog database

It looks like this:
Screen Shot 2021-08-08 at 12 45 27 AM

You can access it here:

psql -h hh5mh6rdexxdn6.c297djhbbcfn.us-east-1.rds.amazonaws.com -d postgres -U hasurausr
Ha5uraWBStaging

postgres=> \dt test_the_daisy_blog.*
       Schema        |    Name    | Type  |   Owner   
---------------------+------------+-------+-----------
 test_the_daisy_blog | authors    | table | hasurausr
 test_the_daisy_blog | post_links | table | hasurausr
 test_the_daisy_blog | post_tags  | table | hasurausr
 test_the_daisy_blog | posts      | table | hasurausr
 test_the_daisy_blog | tags       | table | hasurausr

postgres=> select * from test_the_daisy_blog.authors;
 id |       name       
----+------------------
  2 | Linus Torvalds
  3 | JK Rowling
  1 | Satoshi Nakamoto

Try recreating this database in Baserow and add a few records.

  • feel free to add any additional tables and columns and links etc as you please to test the different features
  • take notes of anything in the UI that was tedious or clumsy or could be done better in our app

Persisting User Settings/Preferences

Eg: when the user changes the width of a column, that setting needs to be saved to the server so it's persisted for the next time the user signs-in.

Other settings we need to persist include:

  • which columns are displayed (user may want to hide some)
  • the order columns are displayed
  • which column the table is sorted by
  • any columns filters
  • records per page

https://blog.ag-grid.com/persisting-ag-grid-state-with-react-redux/

  • What graphQL methods do we need to save the redux store state?
  • Can we just serialize the store with JSON and save it in the db?
  • Is it best/easiest to send the whole store every time there is a change or do we need to update it incrementally?

eg:

header: [[email protected]]

# By table?
wbUserState(tableName: "alubums")
wbSaveUserSate(tableName: string, values: json)

# Or all tables at once?
wbUserState()
wbSaveUserSate(values: json)

I also found this but not sure if it's what we want:
https://www.cloudsavvyit.com/9778/how-to-persist-your-redux-store/

New auth tenant and client/web signup and updates

Created a new auth0 tenant for dev and invited you as admin - choose "switch tenant" and select development-whitebrick

Screen Shot 2021-07-19 at 7 33 42 PM

1. Update client to use details from new tenant

2. Add a button "Sign up" to client

Screen Shot 2021-07-19 at 7 35 40 PM

3. Add a button "Log in" and "Join Free" (same sign up URL) to web

Screen Shot 2021-07-19 at 7 41 00 PM

Display "Shared with Me" DBs

A user can be granted access to a database even if they are not the owner and not in the owner's organization. Eg:

Screen Shot 2021-06-29 at 1 59 31 PM

Add another row below My Databases called "Databases Shared with me" to display The Daisy Blog

Screen Shot 2021-06-29 at 2 00 18 PM

Add Send Admin Secret to Debug menu

Change "SETTINGS" To "DEBUG"
Screen Shot 2021-06-29 at 2 18 30 PM

  • Add a checkbox or toggle "Send Admin Secret" below Refresh Token
  • Only send the X-Hasura-Admin-Secret header in requests when this is checked
  • Only show this debug menu when gatsby is in develop mode

Refactor v1

Tidy up and refactor code ready for beta release

Record View

@harshithpabbati

The "Viewing data from..." Side pop out view is great - a few changes:

Screen Shot 2021-08-11 at 4 57 13 PM

  • All IDs in all tables should be clickable to view the record in the side bar. It can be useful to see the whole record details in a vertical display, especially if the user chooses to hide many columns in the table display
  • Make the ID clickable rather than the <> button

Screen Shot 2021-08-11 at 4 57 23 PM

  • Allowing editing (updating) of the fields will be very useful

Display implicit vs explicit in Schema and Tables Roles grid

RE: #16 and #17

  • In the table settings / database settings display screen change "Permissions" heading to "User Roles" (sorry - that was my mistake, I was getting confused with terminology)
  • Roles are either explicitly assigned or implicitly assigned (see here)
  • Queries now show implicit roles for schemas and tables - see roleImpliedFrom and userRoleImpliedFrom in queries below

Screen Shot 2021-07-04 at 12 36 00 PM
Screen Shot 2021-07-04 at 11 33 56 AM

We need two different styles of checkmark icons below, one that indicates Explicitly Assigned roles and one that indicates Implicitly Assigned - ie if roleImpliedFrom==null (TableUsers) or userRoleImpliedFrom==null (Schemas) then the role is Explicitly Assigned

User Roles

User Reader Editor Manager Administrator
[email protected]
etc...

When we mouse over the checkmark icon it should display (as tooltip or whatever makes sense) either:
Explicitly Assigned or
Implicitly Assigned from <value>

Displaying schema/organization/table permissions

At first connect call wbCloudContext() and save the whole structure in client memory

  • For now this only has to be done once when client first connects and is mostly static
  • Use this structure to get role names, labels, permission names, descriptions used below
  • Use this instead of hard-coding constants in the client

Remove rles from all edit screens
Screen Shot 2021-07-28 at 1 58 47 PM

Add Members button/screen to tables (so its consistent with organizations and dbs)
Screen Shot 2021-07-28 at 2 09 00 PM

Update members screen:
Screen Shot 2021-07-28 at 2 15 07 PM

  • show Implicitly Assigned from ... or Explicitly Assigned
  • dont worry about filtering/searching name or pagination for now - we can do that later
  • add an invite button to launch flow from #19
  • add info icon (i) next to ROLE table header that pops up grid of roles (y axis) and permissions (x axis) obtained from wbCloudContext - this is so when we change a role in the backend this grid automatically updates

Screen Shot 2021-07-08 at 4 10 39 PM

  • Be sure to display Role labels (as above) rather than role names by looking up from wbCloudContext
  • Be sure to display permission description (as above) rather than permission name by looking up from wbCloudContext

Routes checks and redirects

1. root

We need to redirect the root for hosting purposes

Move the current root page (http://localhost:8000/) to a new route /home (http://localhost:8000/home)
update default AUTH0_CALLBACK=http://localhost:8000/home

When a user visits the root route (eg http://localhost:8000/)
IF the user is not signed in AND there is an entry in .env for URL_ROOT_REDIRECT redirect the user to that value (eg URL_ROOT_REDIRECT="http://google.com")
ELSE redirect the user to /home

2. organization index

when a user requests /<organization_name>
send request:

  wbSchemasByOrganizationOwner(organizationName: $organizationName) {
    name
    role {
      name
      permissions
      impliedFrom
    }
  }

IF response.errors[*].extensions.wbCode == "WB_ORGANIZATION_NOT_FOUND"
display a not found page with the message from the wbContext "WB_ORGANIZATION_URL_NOT_FOUND"

ELSE IF response.errors[*].extensions.wbCode == "WB_FORBIDDEN"
display a not found page with the message from the wbContext "WB_ORGANIZATION_URL_FORBIDDEN"

ELSE
display the list of organization-owned DBs

3. organization-owned database

when a user requests /<organization_name>/<db_name>

wbMySchemaByName(name: $schemaName, organizationName: $organizationName, , withSettings: true)

IF response.errors[*].extensions.wbCode == "WB_ORGANIZATION_NOT_FOUND"
display a not found page with the message from the wbContext "WB_ORGANIZATION_URL_NOT_FOUND"

ELSE IF response.errors[*].extensions.wbCode == "WB_SCHEMA_NOT_FOUND"
display a not found page with the message from the wbContext "WB_SCHEMA_URL_NOT_FOUND"

ELSE IF response.errors[*].extensions.wbCode == "WB_FORBIDDEN"
display a not found page with the message from the wbContext "WB_SCHEMA_URL_FORBIDDEN"

ELSE
load the schema

4. user-owned database

please change /database/ route to /db/

when a user requests /db/ redirect them to the root route /

when a user requests /db/<db_name>

try get the schema:

wbMySchemaByName(name: $schemaName)

IF response.errors[*].extensions.wbCode == "WB_SCHEMA_NOT_FOUND"
display a not found page with the message from the wbContext "WB_SCHEMA_URL_NOT_FOUND"

ELSE IF response.errors[*].extensions.wbCode == "WB_FORBIDDEN"
display a not found page with the message from the wbContext "WB_SCHEMA_URL_FORBIDDEN"

ELSE
load the schema

New user sign-up and profile update

  • Signup should now work - I added a hook in auth0 so after sign-up the user is created in the wbCloud db
  • test_nick_north still gives an infinite redirect so we need to catch that ?error on the query and display to user
  • When a new user has access to zero databases (as below) display the message from wbContext WB_NO_SCHEMAS_FOUND and show the button to create a new database so it's obvious

Screen Shot 2021-07-24 at 4 11 52 PM

- Add a "Profile" link to the user menu above "Settings"

Screen Shot 2021-07-24 at 4 30 59 PM

- When a user views their profile:
E-mail:       [email protected] (can't be edited or changed)
Password:     [Change Password button]
First Name:   [text field]
Last Name:    [text field]
[Update button]
  • Use wbUpdateMyProfile to update first/last name
  • When [Change Password button] you need to send a POST (see below) and display a message to the user from wbContext WB_PASSWORD_RESET_INSTRUCTIONS_SENT

https://auth0.com/docs/connections/database/password-change#use-the-authentication-api
Screen Shot 2021-07-24 at 2 52 20 PM

Messages and error handling

Messages

  • We need to put messages into an external JSON file for easy customization

  • There are two types of messages "WB_* " (messages originating from server) and "WBC_* " (messages originating from client). The client messages are there in case we cant connect to the server at all.

  • When there is a server error (WB_ *): IF there is a custom message in the client messages file then we use that, ELSE we use the default message that is fetched from the wbContext call

  • When there is a client error we only use the message from the messages file

  • Messages should be internationalized and files named accordingly (eg src/intl/en.json) see: https://www.gatsbyjs.com/plugins/gatsby-plugin-intl/

  • IMPORTANT: we will not use URLs to switch the language (ie /en/...). The language should be set in the .env file only. eg something like GATSBY_LANGUAGE=en

// src/intl/en.json
{
  WBC_LOADING: "Loading..." (changed from "Preparing requested page"),
  WBC_NO_CONNECTION: "Could not connect to server ${server}. Please check your Internet connection."
  WBC_MISSING_ENV_VAR: "Environment variable ${var} could not be found. Please check your .env file is configured correctly.
  ...
  // this example below will overwrite the default message supplied in wbContext
  WB_ORGANIZATION_NOT_FOUND: "Organization could not be found."
}

Error Handling

  • Currently if you switch off your wifi/Internet connection and click on a button in the client Gatbsy returns an ugly exception screen below
  • Instead there should be nice error message (from WBC_NO_CONNECTION above) displayed from with an option to "Show details" that display the server it's trying to contact and any other error details (bad gateway, no route to host, timeout etc) to help debug.

Screen Shot 2021-07-20 at 11 30 15 AM

  • We also need to check at startup that all mandatory required ENV vars are present and display WBC_MISSING_ENV_VAR if any are missing

Primary Keys and Foreign Keys

For this example, we have a new very simple DB for blogs ("The Daisy Blog") - it has a small number of test records
simple_blog_db_erd

These relationships can now be discovered with this query:

query MyQuery {
  wbTables(schemaName: "test_the_daisy_blog") {
    name
    label
    columns {
      name
      label
      type
      isPrimaryKey
      foreignKeys {
        columnName
        constraintName
        tableName
      }
      referencedBy {
        columnName
        constraintName
        tableName
      }
    }
  }
}

Use the Hasura console to help visualize the relationships (under "Data")

Screen Shot 2021-06-04 at 5 37 31 PM

Notice how that when a relationship is tracked, it can automatically be JOINed in queries, for example:

Screen Shot 2021-06-04 at 5 42 19 PM

Adding/Removing primary key

  • When a user creates a new column or edits a column, they have the option of setting the "Primary Key" checkbox
  • Adding/removing primary key is done in a separate call to addOrCreateColumn (but to the user it will just be the one process)
        wbCreateOrDeletePrimaryKey(
          schemaName: "test_the_daisy_blog",
          tableName: "posts",
          columnNames: ["id"],
        )
  • A primary key may be one or multiple columns
  • Pass del: true to delete the primary key
  • Any existing primary key must be removed before it is re-set

Adding/Removing foreign key

  • When a user creates a new column they have the option of creating a "Foreign Key" (eg adding author_id to posts)
  • The user must name the column (eg author_id) select the parent table (eg authors) and the parent table column (eg ID)
  • Adding/removing a foreign key is done in a separate call to addOrCreateColumn (but to the user it will just be the one process)
        wbAddOrCreateForeignKey(
          schemaName: "test_the_daisy_blog",
          tableName: "posts",
          columnNames: ["author_id"],
          parentTableName: "authors",
          parentColumnNames: ["id"],
          create: true
        )
        wbRemoveOrDeleteForeignKey(
          schemaName: "test_the_daisy_blog",
          tableName: "posts",
          columnNames: ["author_id"],
          parentTableName: "authors",
          delete: true
        )
  • For now the user can only create a foreign key with a single column
  • Any existing foreign key must be removed before it is re-set
  • "Adding" (create: false) doesn't call the SQL only the Hasura tracking and is used for existing DB imports - ignore this for now
  • "Removing" (delete: false) doesn't call the SQL only the Hasura tracking and is used for existing DB imports - ignore this for now

Staging deployment

  1. Download and install AWS CLI
  2. Add credentials
$ cat ~/.aws/credentials 
[wb-client-deploy]
aws_access_key_id = 
aws_secret_access_key = 
  1. Set URL_ROOT_REDIRECT=https://hello-staging.whitebrick.com in .env
  2. Create deploy script for client:
$ cat ~/git/whitebrick/deploy_staging.sh 
# !/usr/bin/env bash

echo -e "\n\nBuilding gatsby...\n"

gatsby build

if [ $? -ne 0 ]; then
  echo -e "\nThe command 'gatsby build' failed.\n"
  exit 1
fi

cd public
aws s3 sync . s3://staging.whitebrick.com --delete --profile wb-client-deploy
aws cloudfront create-invalidation --distribution-id E3TH44CM96PJ5D --paths "/*" --profile wb-client-deploy
  1. Add deploy_staging.sh to .gitignore

  2. Test bash ./deploy_staging.sh and browse to https://staging.whitebrick.com

  3. Create script for web:

$ cat ~/git/whitebrick-web/deploy_staging.sh 
# !/usr/bin/env bash

echo -e "\n\nBuilding gatsby...\n"

gatsby build

if [ $? -ne 0 ]; then
  echo -e "\nThe command 'gatsby build' failed.\n"
  exit 1
fi

cd public
aws s3 sync . s3://hello-staging.whitebrick.com --delete --profile wb-client-deploy
aws cloudfront create-invalidation --distribution-id E33MPR30UTFWD6 --paths "/*" --profile wb-client-deploy
  1. Add deploy_staging.sh to .gitignore
  2. Test bash ./deploy_staging.sh and browse to https://hello-staging.whitebrick.com

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.