Backoffice is a Framework based on Material UI, a Material Design React implementation that provides a couple of components you might want to use in a backoffice app.
Backoffice also uses react-router-dom
, @material-ui/icons
, material-ui-picker
and some more OSS.
The purpose of Backoffice is to provide an easier to use framework to generate applications that are mainly designed for working with data. For example for CRUD-APIs.
If you have a list of data and you want to be able to update and delete entries in the list as well as create new ones (CRUD) Backoffice helps you to build an application in "no time".
If you use yarn, just run the following command in your project’s root directory.
yarn add backoffice
Or using npm:
npm install --save backoffice
You need to create your own React application, that takes care of routing (at least for now), handling state and so on.
Within any of your components you can use a given component by importing it to your application:
import Menu from "backoffice/Menu";
You can then use the component within your render logic:
const MyMenu = ({ menuData, redirectTo }) => (
<Menu data={menuData} redirectTo={redirectTo} />
);
You can find examples in examples/
.
The AppContainer provides the generic styling as well as the possiblity to povided your own theme (based on Material UI's colors).
theme: Theme
, theme configuration, theme palette as described here
You could use the AppContainer-Component like this:
import React from "react";
import AppContainer from "backoffice/AppContainer";
import { indigo, amber } from "@material-ui/core/colors";
const theme = {
palette: {
primary: {
light: indigo[300],
main: indigo[500],
dark: indigo[700],
},
secondary: {
light: amber[300],
main: amber[500],
dark: amber[700],
},
},
};
const MyApp = () => (
<AppContainer theme={theme}>This is my application</AppContainer>
);
A page usually needs some default baseline (header aso). The Base Component provides this functionality.
Children are rendered as content.
title: string
, Title that is shon in headermenuData: MenuItem[]
, Same as inMenu
, please see belowrightContent?: node
, React element that is rendered on the right side of the headerisHeaderFixed?: boolean
, Is header fixed?, defaulttrue
hasHeader?: boolean
, Is header included, defaulttrue
import { Base } from "backoffice";
const base = () => (
<Base title="Foobar" menuData={[]}>
Content
</Base>
);
Button in the bottom right, that let's you link to a new page
onClick: function
, handle click on Add Button
A Button to go "back" to a given url
url: string
, where to go next
import { BackButton } from "backoffice";
const backButton = () => <BackButton url="/go-back" />;
A dialog box to confirm something with a user
isOpen: boolean
, is the confirm dialog open, defaultfalse
title: string
, title, optionaldescription: string
, description textagreeText: string
, Text for agree button, defaultAgree
disagreeText: string
, Text for disagree button, defaultDisagree
onConfirm: function
, handler when user confirms dialogonClose: function
, handler when user closes dialoghasCloseButton: boolean
, hide close button iffalse
, defaults totrue
import { Confirm } from "backoffice";
const confirm = ({ isOpen, onConfirm }) => (
<Confirm
isOpen={isOpen}
description="Are you sure you want to delete the entry?"
onConfirm={onConfirm}
/>
);
Dashboard-like overview page
You can find example data here.
data: DashboardData
, data that describes the dashboard
title: string
, Title as headlinedescription?: string
, Description of DashboardGroups that are upcominggroups: DashboardGroup[]
, Groups of content-teasers that should be rendered
id: string
, Name of the upcoming grouptitle: string
, Title as headline of the next groupcards: DashboardCard[]
, Data to render teaser elements
title: string
, Title of the carddescription?: string
, A description texticon?: function
, An icon element that you want to display next to the titleisDisabled?: function
, Should element be disabled?, defaultfalse
import { Dashboard } from "backoffice";
import data from "./__tests__/data/dashboard.js";
const dashboard = () => <Dashboard data={data} />;
Element that has an (off-canvas) menu
data: MenuItem[]
, menu dataisOpen?: boolean
, is the drawer open?, defaultfalse
onClose: function
, what happens when drawer is closedredirectTo: function
, what happens when clicking on a link- Parameter:
url: string
, as set in MenuItem
- Parameter:
import { Drawer } from "backoffice";
import data from "./__tests__/data/menu.js";
const drawer = ({ onClose, redirectTo }) => (
<Drawer data={data} isOpen onClose={onClose} redirectTo={redirectTo} />
);
Form components.
An example of data can be found here.
form: (FormGroup | FormField)[]
, form configurationdata: FormDataObject
, data for prefilling formonDataChanged?: function
, handle a change of a field (input, selection, …)onSubmit: function
, handle click on submit datasubmitText: string
: Submit button textisFixedSubmitButton?: boolean
, is submit button fixed in right bottom corner?, defaultfalse
useFormElement?: boolean
, use a form element or a div, defaulttrue
id: string
, identifier of the groupgroup: boolean
, group the following elements into one sectiontitle: string
, title of the groupintegrated: boolean
, is group integrated in parent (true) or wrapped in paperisVisible: boolean
, should group be visible?data: FormField[]
id: string
, identifier of the field (concatenated withFormGroup.id
if set)type: ENUM( 'select' | 'list' | 'multiline' | 'text' | 'date' | 'time' | 'datetime' | 'email' | 'number' | 'switch' | 'password' | 'url' | 'content' | 'empty' )
, default:text
title: string
, label of fieldwidth: ENUM('small' | 'mid' | 'full')
, default:full
value: string | string[]
, default value of a fieldisRequired: boolean
, is filling this field required, default: falsevalidators: ENUM('date', 'machinereadable')[]
, validate a field’s input valueisVisible: boolean
, should element be visible?options: string[]
, options of a field of typeselect
format: string
, formation of a field of typedate
,time
ordatetime
, uses Moment.jsrows: number
, height of multiline text-fieldcompleteFrom: (FormFieldCompleteFrom | string)[]
, list for autocompletionrenderElement: function
, element that should be rendered of a field of typelist
getAdditionalValue: function
, transform any value before renderingonBeforeSubmit: function
, allow content to get changed before submitting dataisDisabled?: boolean
, true if this field should be disbaled, default:false
title: string
, display as texttooltip: string
, tooltip text, also used as secondary text in autocomplete
The object holds all values, and errors based on the name of a given form field.
value: any
{
formFieldName: {
value: "foo";
}
}
import { Form } from "backoffice";
import fieldData from "./__tests__/data/formFieldData";
import formData from "./__tests__/data/form.jsx";
const form = ({ onSubmit }) => (
<Form
data={fieldData}
form={formData}
onSubmit={onSubmit}
submitText="Save the form"
>
<p>This is a very special form with additional content.</p>
</Form>
);
Header element, used by Base
component.
isOpen?: boolean
, is sidebar opened?, defaultfalse
title: string
, title to show next to menu iconisFixed: boolean
, should the header be fixed when scrolling?onDrawerOpen: function
, called when menu is toggledonClick: function
, click on titlechildren?: Elements
, content which is shown on the right hand side of the header
import { Header } from "backoffice";
const header = ({ onDrawerOpen, onClick }) => (
<Header
title="My App"
onDrawerOpen={onDrawerOpen}
onClick={onClick}
isOpen={false}
isFixed
>
Beta
</Header>
);
Data-Table to display data.
id?: string
, id for listtitle?: string
, title to show for listing sectionheaders: ListingHeader[]
, use for headers in listingdata: any[]
, data to display in tableorder?: ENUM(asc | desc)
, direction in which to sort values, defaultasc
orderBy: string
, field name to use for sorting the tablepage?: number
, page to show in current listing, default0
rowsPerPage?: number
, number of rows per page to show, default10
hasLoader?: boolean
, should a loader be displayed in table, defaultfalse
renderToolbarContent?: (selected) => ReactElement | null
, content to show in the toolbar (visible if content column is selected)onUpdateSelection: function
, is called if a selection of a line is changedisIntegrated?: bool
, show Listing on Paper or integrated, default: falserowsPerPage: number
, number of rows to show per page, default10
rowsPerPageOptions: number[]
, possible values forrowsPerPage
for the user to choose from, default[10, 25, 50, 100]
onClick: function
, clicking on a column
id: string
, name of the header (matches againstdata[].id
)label: string
, value to display in row headerisPaddingDisabled?: boolean
, should the field be displayed condensed, defaultfalse
isSearchable?: boolean
, is this value searchable?, defaultfalse
isNumeric?: boolean
, is this value like a number?, defaultfalse
transformContent?: function
, transform the content of eachdata[]
entry before displaying
import { Listing } from 'backoffice'
import listingData from './__tests__/data/listing_data'
import listingHeaders from './__tests__/data/listing_headers'
const listing = ({ onClick, onUpdateSelection }) => {
<Listing
title="Christmas Time"
data={listingData}
headers={listingHeaders}
orderBy="username"
onClick={onClick}
hasLoader
onUpdateSelection={onUpdateSelection}
toolbarContent={(
<Tooltip title="Delete">
<IconButton aria-label="Delete">
<DeleteIcon />
</IconButton>
</Tooltip>
)}
/>
)
A menu that lists entries
data: MenuItem[]
, data to render the menuredirectTo: function
, called when clicked on an item
type: ENUM('link' | 'divider')
url: string
, url to link totitle: string
, title to displayicon?: ReactElement | null
, icon which should be displayed before titleisDisabled?: boolean
, if true, item will not be clickable, defaultfalse
A content-snippet for 404 pages
title: string
, title of the pagedescription: node
, element that is the content
import { NoMatch } from "backoffice";
const noMatch = () => <NoMatch title="Title" description={<p>Desc</p>} />;
Show an error in the left hand corner
isOpen: boolean
, is the snackbar open?message: string
, message to show with snackbar
import { Snackbar } from "backoffice";
const snackbar = () => <Snackbar isOpen message="Message" />;
Tab elements
isScrollable?: boolean
, is tab header area scrollable, defaultfalse
data: Tab[]
, all tabs
title: string
, title of a tabid: string
, identifier for tabcontent: node
, elements to show as content
import { Tabs } from "backoffice";
const tabs = () => (
<Tabs
data={[
{
title: "Title",
content: <p>Content</p>,
},
]}
/>
);
This framework is licensed under MIT