Git Product home page Git Product logo

budibase / budibase Goto Github PK

View Code? Open in Web Editor NEW
20.7K 211.0 1.4K 473.03 MB

Low code platform for building business apps and workflows in minutes. Supports PostgreSQL, MySQL, MSSQL, MongoDB, Rest API, Docker, K8s, and more 🚀

Home Page: https://budibase.com

License: Other

JavaScript 16.87% HTML 0.08% CSS 0.14% Dockerfile 0.28% Svelte 33.55% Handlebars 0.34% Shell 0.98% TypeScript 47.70% Smarty 0.04% TSQL 0.03%
no-code-platform crud-app crud-application data-application data-apps internal-tools low-code-no-code low-code-platform open-source rest-api-framework

budibase's Introduction

Budibase

Budibase

The low code platform you'll enjoy using

Budibase is an open-source low-code platform that saves engineers 100s of hours building forms, portals, and approval apps, securely.

🤖 🎨 🚀


Budibase design ui

GitHub all releases GitHub release (latest by date) Follow @budibase Code of conduct



✨ Features

Build and ship real software

Unlike other platforms, with Budibase you build and ship single page applications. Budibase applications have performance baked in and can be designed responsively, providing users with a great experience.

Open source and extensible

Budibase is open-source - licensed as GPL v3. This should fill you with confidence that Budibase will always be around. You can also code against Budibase or fork it and make changes as you please, providing a developer-friendly experience.

Load data or start from scratch

Budibase pulls data from multiple sources, including MongoDB, CouchDB, PostgreSQL, MySQL, Airtable, S3, DynamoDB, or a REST API. And unlike other platforms, with Budibase you can start from scratch and create business apps with no data sources. Request new datasources.

Budibase data



Design and build apps with powerful pre-made components

Budibase comes out of the box with beautifully designed, powerful components which you can use like building blocks to build your UI. We also expose many of your favourite CSS styling options so you can go that extra creative mile. Request new component.

Budibase design



Automate processes, integrate with other tools and connect to webhooks

Save time by automating manual processes and workflows. From connecting to webhooks to automating emails, simply tell Budibase what to do and let it work for you. You can easily create new automations for Budibase here or Request new automation.

Integrate with your favorite tools

Budibase integrates with a number of popular tools allowing you to build apps that perfectly fit your stack.

Budibase integrations



Deploy with confidence and security

Budibase is made to scale. With Budibase, you can self-host on your own infrastructure and globally manage users, onboarding, SMTP, apps, groups, theming and more. You can also provide users/groups with an app portal and disseminate user management to the group manager.




Budibase Public API

As with anything that we build in Budibase, our new public API is simple to use, flexible, and introduces new extensibility. To summarize, the Budibase API enables:

  • Budibase as a backend
  • Interoperability

Docs

You can learn more about the Budibase API at the following places:



🏁 Get started

Deploy Budibase using Docker, Kubernetes, and Digital Ocean on your existing infrastructure. Or use Budibase Cloud if you don't need to self-host and would like to get started quickly.



🎓 Learning Budibase

The Budibase documentation lives here.



💬 Community

If you have a question or would like to talk with other Budibase users and join our community, please hop over to Github discussions




❗ Code of conduct

Budibase is dedicated to providing everyone a welcoming, diverse, and harassment-free experience. We expect everyone in the Budibase community to abide by our Code of Conduct. Please read it.



🙌 Contributing to Budibase

From opening a bug report to creating a pull request: every contribution is appreciated and welcomed. If you're planning to implement a new feature or change the API, please create an issue first. This way, we can ensure your work is not in vain. Environment setup instructions are available here.

Not Sure Where to Start?

A good place to start contributing is the First time issues project.

How the repository is organized

Budibase is a monorepo managed by lerna. Lerna manages the building and publishing of the budibase packages. At a high level, here are the packages that make up Budibase.

  • packages/builder - contains code for the budibase builder client-side svelte application.

  • packages/client - A module that runs in the browser responsible for reading JSON definition and creating living, breathing web apps from it.

  • packages/server - The budibase server. This Koa app is responsible for serving the JS for the builder and budibase apps, as well as providing the API for interaction with the database and file system.

For more information, see CONTRIBUTING.md



📝 License

Budibase is open-source, licensed as GPL v3. The client and component libraries are licensed as MPL - so the apps you build can be licensed however you like.



⭐ Stargazers over time

Stargazers over time

If you are having issues between updates of the builder, please use the guide here to clear down your environment.



Contributors ✨

Thanks goes to these wonderful people (emoji key):

Made with contrib.rocks.

budibase's People

Contributors

adrinr avatar andz-bb avatar aptkingston avatar conor-mack avatar conorwebb96 avatar deanhannigan avatar dependabot[bot] avatar flaminwrap avatar ghrehh avatar joebudi avatar jonnymccullagh avatar jvcalderon avatar kevmodrome avatar mbadan avatar melohagan avatar mihailhadzhiev2022 avatar mike12345567 avatar mikesealey avatar mitch-budibase avatar mjashanks avatar mslourens avatar neolpar avatar pclmnt avatar pngwn avatar rory-powell avatar samwho avatar shogunpurple avatar sovlookup avatar starzeus avatar zedascouves avatar

Stargazers

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

Watchers

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

budibase's Issues

Developer Wiki

We could do with a bit more technical documentation for developers and contributors. This is not to be confused with http://docs.budibase.com/, which is more for the end user.

We should create README files under every package, detailing the following:

  • What the package is responsible for
  • How it interfaces with other packages
  • Diagram?
  • Link to relevant user facing docs

A Github Wiki could also be useful on top of this, but open to suggestions.

Babel do a simpler version of this with their monorepo packages. See here for an example.

I'd like to get an idea of which parts of the platform contributors found difficult to understand, and how we can either simplify them or document them sufficiently to make them less so.

Make builder run from server

Currently the builder is run inside an electron app.

Would like this to be served by the server. It should still exist in a project of its own (although in the mono repo - #3 ).

When built, the dist files should get copied to somewhere on the web server.

Additionally, it should make API requests to update the files that it creates - appDefinition.json, access_levels.json, etc.

It would be nice if this api section could be abstracted , so that it can also be used as a desktop app... but happy to ignore this bit for now.

Node 12 & ES6 Style imports

Currently, the server imports budibase core, packaged into a single bundle "budibase-core.umd.js", and importing using require statemtns.

For example, importing core/src/common goes like const common = require("budibase-core/common").

Every other project imports core files directly i.e. import common from "budibase-core/src/common" . Whilst an uglier path, it would be much easier to debug things if we referenced core in this way.

This also means we could simplify (slightly) by not having to manage core packaging (that bit just makes me feel warm and fuzzy)

Add builder dist files, for server package.json, files array

the folder packages/server/builder and all its contents should be included in the npm publish package, but not in the git repo.

this is done using a "files": ["builder/*"] or something like that. It may not be this simple - need to give it a shot

Categorise component properties

Currently, the builder displays a component's properties in a pane on the right hand side. The properties are in one unsorted list. Properties are hard to navigate.

https://storybook.js.org has it's props along the bottom, and are categorized and tabbed. This is much nicer.

This requires

  • Interface as stated above
  • component libraries - component.json should have a "category" capability for props.

Contributor guidelines do not work as stated in docs

see comment: #69 (comment) ... reports:

Anyway, the issue I was trying to address is that the contributor guidelines don't work as-is. Specifically the yarn bootstrap command (which the package.json defines as lerna bootstrap) gives this error...

yarn bootstrap
yarn run v1.21.1
$ lerna bootstrap
'lerna' is not recognized as an internal or external command

Run Action Event Handler

"Actions" are essentially backend plugins - for custom code in the backend.

  • They can be triggered via a POST /my-app/api/executeaction/my-action
  • They accept any parameters - as defined by the action/behaiour itself.

e.g.

POST /my-app/api/executeaction/sendConfirmationEmail

{ "to": "[email protected]" }

they key difference between this event handler and all the others, is the dynamic parameters. users of the builder must be able to add their own key/value pairs as parameters, along with the action name.

Additionally (nice to have), the builder knows all available actions - they are declared in the backend part. a dropdown of allowed actions should be possible.

Frontend - Defining Page Payout

A "Page" has the following responsibilities

  1. Define some basic properties about the index.html .. such as the title, that appears in the browser tab. This can be added to over time.
  2. Define a "Page Layout". This is a base layer of components, which are always visible on the current page.
  3. Render screens
  4. (Future) Manage URLs. A URL should map to a screen. This should probably be tokenized e.g. /customers/<id>

An example of a Page Layout is a "Left Nav"...

  • Nav bar on left, always visible
  • Clicking on a nav item changes the main content (screen) and url

Implementation

  1. Identical to Screens, A page, should have a props property..

{_component: "@budibase...", _children:[ ] }

  1. We should be able the navigate and edit a page's child components, using the same hierarchy control as screens.

  2. At runtime, the budibase-client will pass screenLoaded event and setScreen(screenName) function to the page layout. A page layout should include a component whose responsibility it is to listen to / call these members

  3. On the builder UI, we will need to modify the page layout's component hierarchy, and the page's properties (i.e. name is probably the only one so far)

More Descriptive Component Property Types

When creating a component, we can declare a component's properties (inside the components.json). This is how the build knows which properties are availabe to set.

When defining a property, we give it a "type".. e.g. string, bool, component, array.

We should have more well defined types. Here's a few examples...

color

Used to set a color in css e.g. background-color: rgb(10,10,10)

When a prop is of type color, the builder should display a colour picker control, when setting it

css-border

Used to set CSS Border properties

When a prop is of this type, the builder should display a component that allows setting of multiple properties

  • style
  • color
  • radius-top, radius-bottom etc
  • width-top , width-left etc

etc etc.

I think we could actually teach people basic css properties in this way - its a nice learning tool, and a useful interface

We could go on and on with this - even into css animation properties and all sorts.. ideas welcome, lets start with the basics!

Accessible Components

What do we have to do to make components accessible ?

Is it simply a matter of providing the correct props on fundamental components (divs, inputs etc), and having higher level components (e.g. "Kanban") handle it themselves ?

Accessibility is one of those features that often gets left out as "Non Essential". In future that may not even be an option: https://www.bbc.co.uk/news/technology-46894463

Budibase could excell here - this is one of those features that Budibase could make really easy to get for almost free.

Would love to innovate in this area for the good of humankind

Programattic API Access

Incoming integrations to budibase require Authorization.
How should this be done?

  • Create a user record and supply user/password in header ? Not great practice, but easily implemented
  • HMAC ? JWT

Needs thought out

Delete record type

The builder needs to be able to delete record types (i.e. in the database section).

This has a few knock on effects... of the top of my head:

  • allowedRecordNodeIds - the record types that are considered by an index
  • recursively delete child records
  • front end (not at time of writing) may make calls to APIs to these object
  • front end may be displaying screens based around this data ?
  • Any instances (data) that have been created need to have these object removed from their data.. this should get covered as part of #8

Frontend - Component Layout

Tone of this issue..

Just a note to start. This is all up for discussion, anything written below is a "general direction".

Overview

Layout & Positioning are fundamental concepts that can be applied on every level of a web UI hierarchy.

We would like to make some layout & positioning properties applicable to all components in a stack, regardless of what those components define in their "props".

Definitions (naming open to suggestions):

Layout
This defines how a parent component lays out its children (hence only applies to components whose children === true || children === undefined)

As an example,

button  (parent)
-- icon (child)
-- text (child)

We could define this button as having a grid layout, with 2 columns.

Positioning
This refers to how a component is positioned within its parent . This could include properties such as padding and margin

e.g. If the parent's layout is grid. We should be able to set column start, column end, column span etc.

Layout Types

Something we need to think about, but grid should be the first, and our primary focus. We want to mirror CSS grid here.

Other options could be

  • inline (stack components in a row) (named row maybe ?).
  • block (stack components in a column)

Implementation

Below is a rough mockup... designed to give you a general idea. Please innovate, based on other styles!

Builder Frontend - New frame

We don't have to worry too much about what properties are actually settable... this should be easy to change as we go along.

What's more important is how these layout definitions are applied at build-time and run-time.

1. Output in screens (JSON) file

currently a screen file looks something like:

{
  "name": "Edit Customer",
  "props": {
    "_component": "@budibase/standard-components/div",
    "_children": [ ...components ],
    "className": "some-class",
  }
}

I suggest that we add another "special" property to props, called _layout, which contains the layout and positioning definition (am open to having a _positioning also) ...

{
  "name": "Edit Customer",
  "props": {
    "_component": "@budibase/standard-components/div",
    "_children": [ ...components ],
    "_layout": {
        "type": "grid",
         "columns": ["1fr", "auto", "1fr"],
         "margin": ["10px", "10px", "10px", "10px"]
         ....etc
    },
    "className": "some-class",
  }
}

2. Applying to an app

These layout options ultimately represent static css. So, we need to somehow apply styles to the nodes in the DOM. This is a bit out of my experience, so I am not going to make suggestion on how to do this - i know others have opinions :)

However, for some direction, the creation of components at runtime are done in packages/client/src/createApp.js ... in the _initialiseChildren method (this method is curried and used to create hydrateChildren, insertChildren and appendChildren ).

It would be nice if we could convert the _layout member to css at buildtime, so we are not calculating at runtime. "building" is done in packages/builder/src/userInterface/pagesParsing/buildPropsHierarchy.js

Rethink Builder "Frontend"

Budibase Frontend Rethink

Current Scenario in Brief

You may not have to read this bit, don't get hung up on it.

Currently we have 3 concepts

  1. Components that are imported from a component library. e.g. the "Budibase Material Design Library"
  2. Components that the user creates (listed down the left of the builder). The user will create a component "Based on" a library component (i.e. from No.1 above).
  3. Pages. The main point of a page is to point to an "Entry Component"... a component from No.2 which will be loaded when the app starts. All other components would be a child of this one.

Proposed

We have the following concepts instead

  1. Components that are imported from a component library. e.g. the "Budibase Material Design Library"
  2. Pages. A page will point to a "Root Layout"- see No.3 below (naming up for grabs). A page is actually a an entire front end - i.e. a Single Page Application. In case you are wondering, the use case for having multiple pages is as follows
    • Initially we have 2 pages. "Main" and "Login". When you are not logged in, you will be served "Login", otherwise you will be server "Main". This simplifies the apps SPA that gets created as we dont have to have an "Are you logged in?" workflow in the "Main" SPA.
    • A future use potential use case is the ability to serve different front-ends to different users. E.g. Consider a Football Pitch Booking App. You can server one app to the staff of the company that owns the pitches, and a different app to their customers, who want to book a pitch.
  3. Root Layout. This...
    • defines what gets initially loaded into the index.html, when the app loads
    • controls all other "Screens" (see No.4 below) that are displayed
    • describes a basic layout of the app... e.g. a "Left Nav", and a footer, with a company name and copyright guff.
    • controls URL fragments - i.e. routing
  4. Screens. At any one time, one screen is displayed in the app (loaded into the root layout). This is where you start adding components (from No.1), to create the various parts of your app. This is the lowest level of.

Notable omission

We now no longer have the ability to create our own "components" from the builder (No.2 above, in the current solution).

This means that we are not able to create a reusable "Primary Button", which (for example) previously was simply a "Button" with the class property set to btn btn-primary

When the user wants a primary button, they will have to create a new "Button", and add the class every time they need it.

This does not rule out implementing a feature like this in the future.


UI Concepts

Frontend - Component Presets

We want to introduce a new(ish) concept, called "Presets". This a predefined setup of a component that all get added to a screen in one click (a Macro?).

Note that the name "Presets" is a developer term, and will not be exposed to the user. From the builder, these will still just be under the term "Components".

For example, a Card component is one that often has a Title, Body and Footer... each one of these being it's own container. Upon adding a Card to a screen, we should see the following added to the Screen hierarchy

Card
   Title
       Text
   Body
       Text
   Footer
       Text

Once added to a screen, each of the sub components is it's own component, now unconnected to any higher concept of "Card"... e.g. you may delete Body

Presets are Configurations

So, presets are really just configurations of components. What we would also like (as a stage 2?) is different configurations of the same block.

e.g.

A Container component could have the following configurations:

  • "Three Column Grid"
  • "3 x 3 Grid"
  • "Empty" (i.e. no configuration - configure yourself)

Based on this, I would propose a change....

When you add a component from the right panel, you are always adding presets blocks

Database based presets

A super power of Budibase is that it is full stack. So, when we are building our frontend, the builder knows what is in our backend.

We should leverage this knowledge... some examples...

  1. add 'table' component > select "Customers List" (index) > outputs a table with all "Customers List" columns already created

  2. add 'form' component > select "Customer Record" > outputs a form with all fields, and Save & Cancel Buttons

UI

How this is actually presented in the builder is completely up for discussion!

Here's 2 ideas...

Builder Frontend - Components with presets

or...

Builder Frontend - Components with Presets (with dialog)

Multi Language

We should have a strategy on how to create multi-lingual apps.

If we could make this a first class feature of budibase - and easy to implement via the builder - it would be a feature that massively increases the marketability of our user's apps.

E.g. when creating a label, h1, h2 etc etc - we can choose text for "fr", "en", "de" ?

Also - we should be able to easily hide this feature for apps that only need to be a single language.

This is a feature that is sometimes tricky/messy to implement and therefore often ignored.

Including static files (JS, CSS, manifest.json etc.)

In the builder, we can currently import stylesheets. The styles work when previewing components in the builder, and of course when running the app.

Would like the same feature for javascript files. This could be used for bootstrap.js, or for a savascript snippet for your favourite support-chat service.

Frontend - State Management

Screens created in the front end need connected to data.

E.g. we may have a "Customer List" - a table which displays all customers.

  • Customers are loaded from the API /api/myapp/list/customers .
  • This returns an array of customers, which is stored in memory in your app

We need a way of pointing the table, to that data stored in memory.

There are already mechanisms underneath for "binding" the components to the data. However, there is no easy way to get an overview of what data is being stored & how it is named etc.

Frontend Builder - Store improvements

The store is getting a bit unwieldy. Currently, we have a few different kinds of information all in the same store.

  • Global app config - current component libraries, app structure (pages, screens, etc)
  • Builder state - current page, current screen, current component, etc.
  • Derived state - stuff that is worked out from the combination of the above pages[currentPageName], etc.

I'd suggest splitting these up so the state management is easier to reason about, the derived state never needs directly storing anywhere we can use a derived store to get current information automatically without manually storing it somewhere. i.e. when we update currentPageName or currentScreenName this would automatically update currentFrontendItem (or whatever the correct field is).

We are also triggering side effects when certain state updates, it's pretty difficult to work out what will trigger side-effects (API calls) without reading through each method. It would be nice to isolate these somewhere.

Component Control Flow Expressions

  1. For any "component" prop, we should be able to setup an if ... else binding. I.e. if condition then display component A else display component B
  2. For and "array" from, we should be able to setup an each binding... bound to an array. This would create an array element for each value in the bound array

We should be able to set these up via the builder

Thoughts on implementation welcomed

Only package used components

Currently, the standard components & bootstrap components libraries packages all components into one bundle (each).

THis means that if you only use one component from a component library, we still load the entire library to access that component.

It would be much better if we could only packages the components that we need. This would probably require using a bundler on the server.

Responsive Components

More of a general question / set of guidelines that need thought out.

How do we make components responsive ?

Then approach will obviously vary, depending on the component.

For example, if we have a very high-level component, e.g. a "Kanban" - I would expect the component to handle the responsiveness internally (maybe exposing "screen size breakpoints" as props).

If we are constructing a component from base components - i.e. divs, inputs etc, then maybe "Div" needs props for choosing which children to display based on a media query... there will be a few different approaches.

we will probably need to discover this over time.

Support Validation Rules everywhere

Validation Rules

Currently, the core library supports validation rules, written as javascript expressions. We can write rules against records, which will be checked before a record can be saved.

We should be able to run these rules client side, to produce instance feedback on record validity, before posting to the server.

However, validation rules are not supported in the following areas

  • Builder - need a user interface to create the rules. Should go against a Database > Record.
  • Client library - need an event handler of type "Validate Record" - which runs validation rules against an object store in the store as state
  • Standard components. We need some standard components to display errors messages that are returned by an invalid record. Additionally, we should be able to highlight the field(s) that are invalid. recordApi.validate() (core) returns a message and a field name. Have a look at the core library for the api for this

Templating in binding values

Allow templating inside bound values. Currently, when we want setup a binding to a "Name" property, the binding path (##bbstate) is set to Name ... i.e. You may only bind to a property thats already in the state.

Would like to be able to set the binding path to {{FirstName}} {{Surname}}... where FirstName and Surname are properties of the state. Another nice example would be a potential "Disabled" property of an "Open Record" button could be {{#if SelectedItem !== null}}true{:else}flase{/if}

Note - the server project already uses https://squirrelly.js.org - so lets use again for consistency.

If the built app does not include any templated bindings, we should not fetch the sqirrely library.

Side note / feature creep for later... we could in future plug in custom helpers and filters. For example and Array.map(..) function.

UX - Not obvious that we have to click on "PAGE" to get back to the page properties

See below... when we are viewing a screen, and want to get back to Page, it is not obvious that we must click "PAGE" ... its doesnt look like a link and it has no :hover style change.

In general, its just a bit confusing that we have the page dropdown at the top, that selects the page.... and then this other "PAGE" text which feels a bit random

image

maybe worth considering alongside #93

Client - dynamically load CSS per screen, on screen change

I ran out of time on this and just did the quick version.

Every screen gets a .css file for its components' styling.

Currently, we are linking every css file, when a page is loaded. This is not necessary. We would like to swap css files in and out, depending on which screen is loaded at the time.

There's not too much effort in this. a few hours including tests.

Mono Repo - Builder Project - Move into server project

Would like core, server and builder all live in one repository, as i think this will just be easier.

have started this already in the server (see the /packages folder).

When this is done, the builder project can import files directly from the core project (folder), rather than importing the entire project from core/dist.

This will make the core functionality much more accessible in the builder

Page & Screen Details Pane

Pages and screens both have "meta" information, which apply to the screen and page itself... i.e. not belonging to their child components.

@pngwn describes this nicely here: #82 (comment)

Currently, there is nowhere in the builder to put these values.

Take the following example, where the Page is selected
image

The panel on the right contains tabs "Components" (for adding child components) and "Properties" which is the standard component properties tab (set layout & positioning etc of the Root <div> of the page)

We need somewhere in this panel to put the Page properties.... but only when "PAGE" is selected

I.e. when a child component is selected, this should probably disappear as it is not relevant (or is it? )

The same applies to screens

FrontEnd builder - Better component navigation

Currently it is very difficult to navigate through components.

  • You choose a component from the left hand pane.
  • If it has a subcomponent, you must find which property references this component, and click edit.
  • This gets very messy when you go several child components deep.

Proposed Solutions

  1. From the component preview, we should be able to click a on a subcomponent to open it's properties pane. Maybe we need to highlight an outline/border of the component on hover... of have a clickable icon to open the props for that component

  2. A component treeview would be nice... a view of the currently selected components child components... each expandable. Clicking on a child should display its properties.

Remove dependency on node-gyp

Get rid of dependency of node-gyp.

The need for this comes from a cryptography library called argon2. This is used in server and core. It is used for hashing passwords.

have a look for "node password hashing" for other methods - im pretty sure we don't have to use argon2. I originally choose it as it was recogised as the most secure hashing algorithm at the time.

Builder - Usage Stats

We would like some way of recoring how much time users are spending usng our alpha release.

Features of this would be:

  • Privacy/Annonimity. Respecting the user's privicy is paramount. We shoud record no identifiable information... I'm thinking that all we record is a) Some GUID, represeting the user, generated and saves on installation ... b) Timestamp
  • Everytime the users saves a package (see builderStore/store > savePackage() ) we should ping a server somehwere with above info (developing a simple endpoint is part of this - e.g. an Azure Function App, storing to azure table storage ?
  • Users should be able to turn this off. Preferably by a user interface in the application

All ids - replace with folder list items

Currently, we keep a record of all available records in a collection, in an "allids" file. This is just a list of all record ids in that collection (which can be sharded).

Since implementing this, I had to add a datastore.getFolderContents(path) method - which lists all items in a "folder".

We should now get rid of the "allids" mechanism.

Instead, we should be able to recursively call getFolderContents to iterate through all records.

No public api should change. So, all tests should still pass, except ones that refer to the "allids" files (or shard files) directly.

This new method should respect all existing sharding rules.

Builder - Improved user experience of Code areas

The builder currently has some multiline text inputs, where the user can input javascript.

e.g.

  • Index map
  • index filter
  • Index Shard expression

future:

  • Record validation rules

These inputs have no code formatting, or instruction on how to use them. Thus they are quite opaque in regard to usability.

Lets improve this.

A "no-code" solution is definately on the cards. However, it should be easy to break back into code.

Budibase CLI

For a developer creating a product using budibase, we want a CLI!

For inspiration, see

And many others im sure.

We need to think through the development flow for budibase. In my head, is something like this:

  1. npm install -g budibase-cli installs the budibase CLI, globally
  2. Create folder e.g. budibase-apps ... contains a bunch of folders, one for each of you app
  3. cd budibase-apps
  4. budi init my-crm-app < initialise a new folder called my-crm-app, with the necessary budibase files & structure inside.
  5. Optionally, the developer can create a git repo and anything else they wish
  6. budi dev starts budibase dev server
  7. budi package creates a deployable package
  8. (Future) budi deploy deploys to budibase.com for hosting !!!

Not expecting this all to be tackled at once - this was just an outline of thoughts. Lets be creative!

Have used http://yargs.js.org/ in the past for creating node clis and can vouch for it! just a suggestion.

"Single" record type initialise

We can create a "single" record.... i.e. one that is not part of a collection. A single record in the heirarchy is identified by the property isSingle:true and type:"record"

Currently, a single record is never being initialised. There are 2 places where this should happen

  1. If the single record is on the root level, is should be initialised in appInitialise/initialiseData.js
  2. If it is a child of another record, it should be initialised when a record of that type is created.

templateApi> deleteNode method(s)

Require a method to delete any node fro the heirarchy. This will include

  • A "CanDelete" method, which returns a list of errors (strings), or an empty list if deletion is llowed
  • Removing the node from parent().children

To delete a record, :

  • it must not exist on any index.allowedRecordNodeIds
  • it must not exist on and reference type fields
  • these rules should apply to any child nodes , which will also be deleted

To delete an index:

  • it must not be being used as lookup index for a reference field
  • it must not be a "reverse reference" index

Aggregate Group Nodes ? Should be straight forward

There may be other tidyup thinks that need to happen when a node is deleted. need to think about that

Building, dependencies and package management

We currently have a few issues around package management. Below is how i would like things to work

  1. Common dependencies between packages (e.g. lodash) should be easily kept on the same version. Lerna i think should handle this for us if setup correctly - we are not really using it atm, though it is intalled
  2. Core builds to a dist folder. All other packages have core installed (npm / yarn), and reference this local dist folder directly. When core's package.json chanes, core/dist sometimes also needs to be updated.... maybe just need a better way of referencing the core package. I made it reference the local folder because it was a ain to constantly push the dist folder to a dist repo or npm, before getting an update
  3. I would like to be able to reference core modules directly from builder import {$} from "../core/common" - this woulld eliminate the need for builder to reference the core package (as in 2.)... and ould also be much nicer for debugging

Complete Search

Currently, the core library can be used to search an index. It uses https://lunrjs.com - see core/src/indexApi/listItems.js

This is also available as a server endpoint : POST /:appname/api/listRecords/:indexkey (see server/middleware/routers)

To complete the story, we need to be able to make the client library run the above endpoint

This will probably involve..

  • Create a new "SearchIndex" event handler in the client, which calls the above endpoint
  • Create a new specialized search component, maybe with dynamic fields ?? Remember the "searchPhrase" can be full text, or can be lucene style FirstName: Bob etc

Ideas welcome

Logging and Debugging

We should be able to pass the core library an abstract log(...) method, which outputs logs of different levels. We should then provide some basic server logger e.g. "File Logger" or "Console Logger" for development, and make sure it is pluggable. e.g. people should be able to write a "DataDog logger".

The core library should then use the logger in all sorts of places. Start with exceptions (+ we should look for places to better handle exceptions). We should think about "Debug", "Info" and "Warning" levels, and put these everywhere.

The logger implementation should be responsible for deciding what levels to log, and how (i.e. it should be responsible for reading from config what levels it should care about).

The server should also use the logger for non-core logging - i.e. any server code outside of the core library.

Additionally, the core library should attach HTTP Status codes to certain exceptions. E.g. "Record Not Found" = 404

We should also consider (as a final part ? ) logging the debug/info/warning/error messages from the front end, and sending them to the server. We would need a server endpoint e.g. POST /my-app/api/log. I would suggest that this enpoint require an authenticated session (i.e. not public and open), to avoid this becoming an attack vector.

Builder - Database Heirarchy Navigation

Currently, in the database section, there is a left navigation, which is split into sections for "Records" and "Indexes".

Additionally, if we click on a record, there is an "Indexes" section - which are all the child indexes of that record.

All records and indexes should instead be displayed together in the left navigation - in one big list. Obviously, indexes and records should be visually distinguishable. We should alo be able to see a hierarchy structure (e.g. by indentation) like is currently visible in the records section of the nav.

Respect Access Levels

Currently, a list of user permissions is kept in state (store._bbuser). We should be able to modify components (e.g. hide/disable a button) based on these permissions.

E.g. If a user is able to read a customer record, but not able to save it, the save button on the customer record should be disabled.

The server already respected these rules, so no need to worry about API Authorization here.

There may not be much to do here - could be as simple as exposing an IsAuthorized(...) method somewhere that can be setup by the builder, and used on the client

Complete Support for Aggregates

In the core library. we can declare "aggregates" against indexes. These are "SUM", "COUNTS", MAX etc... e.g. "SUM of all outstanding invoices = £782"

We currenty cannot use these, as do not have-

  • A place to set these up in the builder
  • An HTTP Endpoint on the server to retrieve them e.g. "GET /my-app/api/aggregate/
  • An Event Handler type on the client to fetch them from the server

Have a look in /packages/core/src/templateApi/createNodes

getNewAggregateGroupTemplate() is where you can declare a "Group By" and a filter condition for items in the index. groupBy and filterCondition are both javascript expressions

getNewAggregateTemplate() is where you declare which value to aggregate. aggregatedValue is a javascript expression.

indexApi.aggregates.spec.js shows how aggregate results are retrieved, from the core library.
specHelpers.js > withIndexes(..) shows how aggregates are setup

Document Code with JSDoc

Stage 1

Going to add code documentation of all functions,

  • in core, server and builder.

Stage 2 (maybe a future issue)

Use document code to produce markdown files, and publish to GitBook @ apidocs.budibase.com (does not exist yet)

Unit/Integration Test Setup

We need a way to write tests against our svelte components with jest in the project. This tutorial provides a good outline of how to do that: https://dev.to/jpblancodb/testing-svelte-components-with-jest-53h3.

Steps

  • configure babel correctly in all the packages that we want to write svelte tests in
  • Add svelte-testing-library and wire up the module mappers to compile the svelte files ahead of time
  • Add jest configuration to the package.json of each budibase package or use jest.config.js to set up the correct module mappers for the test runner.

Diff heirarchy and auto update changes

When we update a heirarchy, we need to be able to:

  • Detect what changes have been made to the heirarchy (diff)
  • Use this diff to determine what updates need to be made to the data. I think that the only changes that may need to be made are to rebuild indexes.
  • Run these updates

It would probably be best if the above three items were 3 seperate, callable functions, allowing the visibility to the end user of

  1. These are your changes
  2. These are the updates that must be made to deploy this new heirarchy
  3. "Do you want to run updates now ? "

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.