{"id":13475704,"url":"https://github.com/react-backoffice/backoffice","last_synced_at":"2025-03-27T00:31:43.628Z","repository":{"id":39559287,"uuid":"114143871","full_name":"react-backoffice/backoffice","owner":"react-backoffice","description":"React GUI-Framework based on Material UI; provides a couple of components for back-office apps (CRUD-based APIs)","archived":false,"fork":false,"pushed_at":"2023-01-03T16:42:44.000Z","size":5731,"stargazers_count":23,"open_issues_count":21,"forks_count":8,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-08-01T16:39:35.009Z","etag":null,"topics":["component-library","crud","crud-gui","dashboard","material-ui","react","react-router","reactjs"],"latest_commit_sha":null,"homepage":"https://backoffice-drublic.herokuapp.com/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/react-backoffice.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-13T16:29:17.000Z","updated_at":"2023-09-11T18:55:40.000Z","dependencies_parsed_at":"2023-02-01T08:00:49.362Z","dependency_job_id":null,"html_url":"https://github.com/react-backoffice/backoffice","commit_stats":null,"previous_names":[],"tags_count":100,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-backoffice%2Fbackoffice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-backoffice%2Fbackoffice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-backoffice%2Fbackoffice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/react-backoffice%2Fbackoffice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/react-backoffice","download_url":"https://codeload.github.com/react-backoffice/backoffice/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245760797,"owners_count":20667887,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component-library","crud","crud-gui","dashboard","material-ui","react","react-router","reactjs"],"created_at":"2024-07-31T16:01:22.766Z","updated_at":"2025-03-27T00:31:43.331Z","avatar_url":"https://github.com/react-backoffice.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"Backoffice is a Framework based on [Material UI](https://material-ui-next.com),\na Material Design React implementation that provides a couple of components you\nmight want to use in a backoffice app.\n\n![](.presentational/header.png)\n\nBackoffice also uses `react-router-dom`, `@material-ui/icons`, `material-ui-picker` and some more OSS.\n\n[![Build Status](https://travis-ci.org/drublic/backoffice.svg?branch=master)](https://travis-ci.org/drublic/backoffice)\n[![codecov](https://codecov.io/gh/drublic/backoffice/branch/master/graph/badge.svg)](https://codecov.io/gh/drublic/backoffice)\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fdrublic%2Fbackoffice.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fdrublic%2Fbackoffice?ref=badge_shield)\n\n## Purpose\n\nThe 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.\n\nIf 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\".\n\n## Usage\n\n### Installing\n\nIf you use yarn, just run the following command in your project’s root directory.\n\n    yarn add backoffice\n\nOr using npm:\n\n    npm install --save backoffice\n\n### Using components\n\nYou need to create your own React application, that takes care of routing (at least for now), handling state and so on.\n\nWithin any of your components you can use a given component by importing it to your application:\n\n```javascript\nimport Menu from \"backoffice/Menu\";\n```\n\nYou can then use the component within your render logic:\n\n```javascript\nconst MyMenu = ({ menuData, redirectTo }) =\u003e (\n  \u003cMenu data={menuData} redirectTo={redirectTo} /\u003e\n);\n```\n\n## Examples \u0026 Demo\n\nYou can find examples in [`examples/`](./examples/).\n\n## Components\n\n### AppContainer\n\nThe AppContainer provides the generic styling as well as the possiblity to povided your own theme (based on [Material UI's colors](https://material-ui-next.com/style/color/)).\n\n- `theme: Theme`, theme configuration, theme palette as described [here](https://material-ui-next.com/style/color/)\n\nYou could use the AppContainer-Component like this:\n\n```javascript\nimport React from \"react\";\nimport AppContainer from \"backoffice/AppContainer\";\n\nimport { indigo, amber } from \"@material-ui/core/colors\";\n\nconst theme = {\n  palette: {\n    primary: {\n      light: indigo[300],\n      main: indigo[500],\n      dark: indigo[700],\n    },\n    secondary: {\n      light: amber[300],\n      main: amber[500],\n      dark: amber[700],\n    },\n  },\n};\n\nconst MyApp = () =\u003e (\n  \u003cAppContainer theme={theme}\u003eThis is my application\u003c/AppContainer\u003e\n);\n```\n\n### Base\n\nA page usually needs some default baseline (header aso). The Base Component provides this functionality.\n\nChildren are rendered as content.\n\n- `title: string`, Title that is shon in header\n- `menuData: MenuItem[]`, Same as in `Menu`, please see below\n- `rightContent?: node`, React element that is rendered on the right side of the header\n- `isHeaderFixed?: boolean`, Is header fixed?, default `true`\n- `hasHeader?: boolean`, Is header included, default `true`\n\n```javascript\nimport { Base } from \"backoffice\";\n\nconst base = () =\u003e (\n  \u003cBase title=\"Foobar\" menuData={[]}\u003e\n    Content\n  \u003c/Base\u003e\n);\n```\n\n### AddButton\n\nButton in the bottom right, that let's you link to a new page\n\n- `onClick: function`, handle click on Add Button\n\n### BackButton\n\nA Button to go \"back\" to a given url\n\n- `url: string`, where to go next\n\n```javascript\nimport { BackButton } from \"backoffice\";\n\nconst backButton = () =\u003e \u003cBackButton url=\"/go-back\" /\u003e;\n```\n\n### Confirm\n\nA dialog box to confirm something with a user\n\n- `isOpen: boolean`, is the confirm dialog open, default `false`\n- `title: string`, title, optional\n- `description: string`, description text\n- `agreeText: string`, Text for agree button, default `Agree`\n- `disagreeText: string`, Text for disagree button, default `Disagree`\n- `onConfirm: function`, handler when user confirms dialog\n- `onClose: function`, handler when user closes dialog\n- `hasCloseButton: boolean`, hide close button if `false`, defaults to `true`\n\n```javascript\nimport { Confirm } from \"backoffice\";\n\nconst confirm = ({ isOpen, onConfirm }) =\u003e (\n  \u003cConfirm\n    isOpen={isOpen}\n    description=\"Are you sure you want to delete the entry?\"\n    onConfirm={onConfirm}\n  /\u003e\n);\n```\n\n### Dashboard\n\nDashboard-like overview page\n\nYou can find [example data here](./__tests__/data/dashboard.js).\n\n#### Options\n\n- `data: DashboardData`, data that describes the dashboard\n\n#### DashboardData\n\n- `title: string`, Title as headline\n- `description?: string`, Description of DashboardGroups that are upcoming\n- `groups: DashboardGroup[]`, Groups of content-teasers that should be rendered\n\n#### DashboardGroup\n\n- `id: string`, Name of the upcoming group\n- `title: string`, Title as headline of the next group\n- `cards: DashboardCard[]`, Data to render teaser elements\n\n#### DashboardCard\n\n- `title: string`, Title of the card\n- `description?: string`, A description text\n- `icon?: function`, An icon element that you want to display next to the title\n- `isDisabled?: function`, Should element be disabled?, default `false`\n\n#### Usage\n\n```javascript\nimport { Dashboard } from \"backoffice\";\n\nimport data from \"./__tests__/data/dashboard.js\";\n\nconst dashboard = () =\u003e \u003cDashboard data={data} /\u003e;\n```\n\n### Drawer\n\nElement that has an (off-canvas) menu\n\n- `data: MenuItem[]`, menu data\n- `isOpen?: boolean`, is the drawer open?, default `false`\n- `onClose: function`, what happens when drawer is closed\n- `redirectTo: function`, what happens when clicking on a link\n  - Parameter: `url: string`, as set in MenuItem\n\n```javascript\nimport { Drawer } from \"backoffice\";\n\nimport data from \"./__tests__/data/menu.js\";\n\nconst drawer = ({ onClose, redirectTo }) =\u003e (\n  \u003cDrawer data={data} isOpen onClose={onClose} redirectTo={redirectTo} /\u003e\n);\n```\n\n### Form\n\nForm components.\n\nAn example of data can [be found here](./__tests__/data/form.jsx).\n\n- `form: (FormGroup | FormField)[]`, form configuration\n- `data: FormDataObject`, data for prefilling form\n- `onDataChanged?: function`, handle a change of a field (input, selection, …)\n- `onSubmit: function`, handle click on submit data\n- `submitText: string`: Submit button text\n- `isFixedSubmitButton?: boolean`, is submit button fixed in right bottom corner?, default `false`\n- `useFormElement?: boolean`, use a form element or a div, default `true`\n\n#### FormGroup\n\n- `id: string`, identifier of the group\n- `group: boolean`, group the following elements into one section\n- `title: string`, title of the group\n- `integrated: boolean`, is group integrated in parent (true) or wrapped in paper\n- `isVisible: boolean`, should group be visible?\n- `data: FormField[]`\n\n#### FormField\n\n- `id: string`, identifier of the field (concatenated with `FormGroup.id` if set)\n- `type: ENUM( 'select' | 'list' | 'multiline' | 'text' | 'date' | 'time' | 'datetime' | 'email' | 'number' | 'switch' | 'password' | 'url' | 'content' | 'empty' )`, default: `text`\n- `title: string`, label of field\n- `width: ENUM('small' | 'mid' | 'full')`, default: `full`\n- `value: string | string[]`, default value of a field\n- `isRequired: boolean`, is filling this field required, default: false\n- `validators: ENUM('date', 'machinereadable')[]`, validate a field’s input value\n- `isVisible: boolean`, should element be visible?\n- `options: string[]`, options of a field of type `select`\n- `format: string`, formation of a field of type `date`, `time` or `datetime`, uses [Moment.js](https://momentjs.com/docs/#/parsing/string-format/)\n- `rows: number`, height of multiline text-field\n- `completeFrom: (FormFieldCompleteFrom | string)[]`, list for autocompletion\n- `renderElement: function`, element that should be rendered of a field of type `list`\n- `getAdditionalValue: function`, transform any value before rendering\n- `onBeforeSubmit: function`, allow content to get changed before submitting data\n- `isDisabled?: boolean`, true if this field should be disbaled, default: `false`\n\n#### FormFieldCompleteFrom\n\n- `title: string`, display as text\n- `tooltip: string`, tooltip text, also used as secondary text in autocomplete\n\n#### FormDataObject\n\nThe object holds all values, and errors based on the name of a given form field.\n\n- `value: any`\n\n```javascript\n{\n  formFieldName: {\n    value: \"foo\";\n  }\n}\n```\n\n#### Usage\n\n```javascript\nimport { Form } from \"backoffice\";\n\nimport fieldData from \"./__tests__/data/formFieldData\";\nimport formData from \"./__tests__/data/form.jsx\";\n\nconst form = ({ onSubmit }) =\u003e (\n  \u003cForm\n    data={fieldData}\n    form={formData}\n    onSubmit={onSubmit}\n    submitText=\"Save the form\"\n  \u003e\n    \u003cp\u003eThis is a very special form with additional content.\u003c/p\u003e\n  \u003c/Form\u003e\n);\n```\n\n### Header\n\nHeader element, used by `Base` component.\n\n- `isOpen?: boolean`, is sidebar opened?, default `false`\n- `title: string`, title to show next to menu icon\n- `isFixed: boolean`, should the header be fixed when scrolling?\n- `onDrawerOpen: function`, called when menu is toggled\n- `onClick: function`, click on title\n- `children?: Elements`, content which is shown on the right hand side of the header\n\n```javascript\nimport { Header } from \"backoffice\";\n\nconst header = ({ onDrawerOpen, onClick }) =\u003e (\n  \u003cHeader\n    title=\"My App\"\n    onDrawerOpen={onDrawerOpen}\n    onClick={onClick}\n    isOpen={false}\n    isFixed\n  \u003e\n    Beta\n  \u003c/Header\u003e\n);\n```\n\n### Listing\n\nData-Table to display data.\n\n- `id?: string`, id for list\n- `title?: string`, title to show for listing section\n- `headers: ListingHeader[]`, use for headers in listing\n- `data: any[]`, data to display in table\n- `order?: ENUM(asc | desc)`, direction in which to sort values, default `asc`\n- `orderBy: string`, field name to use for sorting the table\n- `page?: number`, page to show in current listing, default `0`\n- `rowsPerPage?: number`, number of rows per page to show, default `10`\n- `hasLoader?: boolean`, should a loader be displayed in table, default `false`\n- `renderToolbarContent?: (selected) =\u003e ReactElement | null`, content to show in the toolbar (visible if content column is selected)\n- `onUpdateSelection: function`, is called if a selection of a line is changed\n- `isIntegrated?: bool`, show Listing on Paper or integrated, default: false\n- `rowsPerPage: number`, number of rows to show per page, default `10`\n- `rowsPerPageOptions: number[]`, possible values for `rowsPerPage` for the user to choose from, default `[10, 25, 50, 100]`\n- `onClick: function`, clicking on a column\n\n#### ListingHeader\n\n- `id: string`, name of the header (matches against `data[].id`)\n- `label: string`, value to display in row header\n- `isPaddingDisabled?: boolean`, should the field be displayed condensed, default `false`\n- `isSearchable?: boolean`, is this value searchable?, default `false`\n- `isNumeric?: boolean`, is this value like a number?, default `false`\n- `transformContent?: function`, transform the content of each `data[]` entry before displaying\n\n#### Usage\n\n```javascript\nimport { Listing } from 'backoffice'\n\nimport listingData from './__tests__/data/listing_data'\nimport listingHeaders from './__tests__/data/listing_headers'\n\nconst listing = ({ onClick, onUpdateSelection }) =\u003e {\n  \u003cListing\n    title=\"Christmas Time\"\n    data={listingData}\n    headers={listingHeaders}\n    orderBy=\"username\"\n    onClick={onClick}\n    hasLoader\n    onUpdateSelection={onUpdateSelection}\n    toolbarContent={(\n      \u003cTooltip title=\"Delete\"\u003e\n        \u003cIconButton aria-label=\"Delete\"\u003e\n          \u003cDeleteIcon /\u003e\n        \u003c/IconButton\u003e\n      \u003c/Tooltip\u003e\n    )}\n  /\u003e\n)\n```\n\n### Menu\n\nA menu that lists entries\n\n- `data: MenuItem[]`, data to render the menu\n- `redirectTo: function`, called when clicked on an item\n\n### MenuItem\n\n- `type: ENUM('link' | 'divider')`\n- `url: string`, url to link to\n- `title: string`, title to display\n- `icon?: ReactElement | null`, icon which should be displayed before title\n- `isDisabled?: boolean`, if true, item will not be clickable, default `false`\n\n### NoMatch\n\nA content-snippet for 404 pages\n\n- `title: string`, title of the page\n- `description: node`, element that is the content\n\n```javascript\nimport { NoMatch } from \"backoffice\";\n\nconst noMatch = () =\u003e \u003cNoMatch title=\"Title\" description={\u003cp\u003eDesc\u003c/p\u003e} /\u003e;\n```\n\n### Snackbar\n\nShow an error in the left hand corner\n\n- `isOpen: boolean`, is the snackbar open?\n- `message: string`, message to show with snackbar\n\n```javascript\nimport { Snackbar } from \"backoffice\";\n\nconst snackbar = () =\u003e \u003cSnackbar isOpen message=\"Message\" /\u003e;\n```\n\n### Tabs\n\nTab elements\n\n- `isScrollable?: boolean`, is tab header area scrollable, default `false`\n- `data: Tab[]`, all tabs\n\n#### Tab\n\n- `title: string`, title of a tab\n- `id: string`, identifier for tab\n- `content: node`, elements to show as content\n\n#### Usage\n\n```javascript\nimport { Tabs } from \"backoffice\";\n\nconst tabs = () =\u003e (\n  \u003cTabs\n    data={[\n      {\n        title: \"Title\",\n        content: \u003cp\u003eContent\u003c/p\u003e,\n      },\n    ]}\n  /\u003e\n);\n```\n\n## License\n\nThis framework is licensed under [MIT](./LICENSE)\n\n[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fdrublic%2Fbackoffice.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fdrublic%2Fbackoffice?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-backoffice%2Fbackoffice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freact-backoffice%2Fbackoffice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freact-backoffice%2Fbackoffice/lists"}