├── .eslintignore ├── .eslintrc ├── .github ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE │ ├── Bug_report.md │ ├── Custom.md │ └── Feature_request.md └── workflows │ ├── codeql-analysis.yml │ └── test.yml ├── .gitignore ├── .gitpod.yml ├── .huskyrc ├── .lintstagedrc ├── .prettierignore ├── .prettierrc.js ├── .storybook ├── main.js └── preview-head.html ├── .yarn ├── plugins │ └── @yarnpkg │ │ └── plugin-interactive-tools.cjs └── releases │ └── yarn-3.1.1.cjs ├── .yarnrc.yml ├── CHANGELOG.md ├── LICENSE.md ├── Makefile ├── README.md ├── UPGRADE.md ├── __mocks__ └── @popperjs │ └── core.ts ├── cypress ├── .eslintrc ├── cypress.config.js ├── cypress.json ├── e2e │ ├── auth.cy.js │ ├── create.cy.js │ ├── custom-forms.cy.js │ ├── customPages.cy.js │ ├── edit.cy.js │ ├── list.cy.js │ ├── navigation.cy.js │ ├── permissions.cy.js │ ├── show.cy.js │ └── tabs-with-routing.cy.js ├── integration │ ├── auth.js │ ├── create.js │ ├── custom-forms.js │ ├── customPages.js │ ├── edit.js │ ├── list.js │ ├── navigation.js │ ├── permissions.js │ ├── show.js │ └── tabs-with-routing.js ├── package.json ├── plugins │ └── index.js ├── server.js ├── start.js ├── support │ ├── CreatePage.js │ ├── CustomFormPage.js │ ├── CustomPage.js │ ├── EditPage.js │ ├── ListPage.js │ ├── LoginPage.js │ ├── ShowPage.js │ └── index.js ├── tsconfig.json └── webpack.config.js ├── docs ├── 404.html ├── AccordionForm.md ├── Actions.md ├── Admin.md ├── AdvancedTutorials.md ├── AppBar.md ├── Architecture.md ├── ArrayField.md ├── ArrayInput.md ├── AuthProviderList.md ├── AuthProviderWriting.md ├── AuthRBAC.md ├── Authenticated.md ├── Authentication.md ├── AutocompleteArrayInput.md ├── AutocompleteInput.md ├── BooleanField.md ├── BooleanInput.md ├── Breadcrumb.md ├── Buttons.md ├── Caching.md ├── Calendar.md ├── CheckboxGroupInput.md ├── ChipField.md ├── CloneButton.md ├── Community.md ├── Configurable.md ├── Confirm.md ├── ContainerLayout.md ├── Count.md ├── Create.md ├── CreateBase.md ├── CreateDialog.md ├── CreateInDialogButton.md ├── CreateReactApp.md ├── CustomRoutes.md ├── DataProviderIntroduction.md ├── DataProviderList.md ├── DataProviderLive.md ├── DataProviderWriting.md ├── DataProviders.md ├── Datagrid.md ├── DateField.md ├── DateInput.md ├── DateTimeInput.md ├── Demos.md ├── DualListInput.md ├── Ecosystem.md ├── Edit.md ├── EditBase.md ├── EditDialog.md ├── EditGuesser.md ├── EditInDialogButton.md ├── EditLive.md ├── EditTutorial.md ├── EditableDatagrid.md ├── EmailField.md ├── FAQ.md ├── Features.md ├── Fields.md ├── FieldsForRelationships.md ├── FileField.md ├── FileInput.md ├── FilterButton.md ├── FilterForm.md ├── FilterList.md ├── FilterLiveSearch.md ├── FilteringTutorial.md ├── Form.md ├── FunctionField.md ├── HorizontalMenu.md ├── IconMenu.md ├── IfCanAccess.md ├── ImageField.md ├── ImageInput.md ├── Inputs.md ├── JsonSchemaForm.md ├── Labeled.md ├── Layout.md ├── List.md ├── ListBase.md ├── ListButton.md ├── ListGuesser.md ├── ListLive.md ├── ListTutorial.md ├── LocalesMenuButton.md ├── LongForm.md ├── MarkdownField.md ├── MarkdownInput.md ├── Menu.md ├── MenuLive.md ├── MultiLevelMenu.md ├── NextJs.md ├── NullableBooleanInput.md ├── NumberField.md ├── NumberInput.md ├── Pagination.md ├── PasswordInput.md ├── Permissions.md ├── RadioButtonGroupInput.md ├── Readme.md ├── Realtime.md ├── RealtimeDataProvider.md ├── Reference.md ├── ReferenceArrayField.md ├── ReferenceArrayInput.md ├── ReferenceField.md ├── ReferenceInput.md ├── ReferenceManyCount.md ├── ReferenceManyField.md ├── ReferenceManyInput.md ├── ReferenceManyToManyField.md ├── ReferenceManyToManyInput.md ├── ReferenceOneField.md ├── Remix.md ├── Resource.md ├── RichTextField.md ├── RichTextInput.md ├── Routing.md ├── SaveButton.md ├── SavedQueriesList.md ├── Search.md ├── SelectArrayInput.md ├── SelectColumnsButton.md ├── SelectField.md ├── SelectInput.md ├── Show.md ├── ShowBase.md ├── ShowGuesser.md ├── ShowInDialogButton.md ├── ShowLive.md ├── ShowTutorial.md ├── SimpleForm.md ├── SimpleFormIterator.md ├── SimpleList.md ├── SimpleShowLayout.md ├── SingleFieldList.md ├── SortButton.md ├── StackedFilters.md ├── Store.md ├── TabbedForm.md ├── TabbedShowLayout.md ├── TextField.md ├── TextInput.md ├── Theming.md ├── TimeInput.md ├── ToggleThemeButton.md ├── Toolbar.md ├── TranslatableFields.md ├── TranslatableInputs.md ├── Translation.md ├── TranslationLocales.md ├── TranslationSetup.md ├── TranslationTranslating.md ├── TranslationWriting.md ├── TreeWithDetails.md ├── Tutorial.md ├── UnitTesting.md ├── Upgrade.md ├── UrlField.md ├── Validation.md ├── Vite.md ├── WithPermissions.md ├── WithRecord.md ├── WizardForm.md ├── WrapperField.md ├── _includes │ ├── nav.html │ ├── ra-monochrome.svg │ └── versions.html ├── _layouts │ └── default.html ├── assets │ └── logo_white.png ├── canAccess.md ├── css │ ├── docsearch.css │ ├── materialize.min.css │ ├── prism.css │ ├── style-v12.css │ ├── style-v13.css │ ├── syntax.css │ └── tocbot.css ├── documentation.html ├── img │ ├── ArrayInput-global-validation.png │ ├── CRUD.webm │ ├── CheckboxGroupInput-labelPlacement.png │ ├── CheckboxGroupInput-options.png │ ├── CheckboxGroupInput-row.png │ ├── CollaborativeDemo.mp4 │ ├── DatagridConfigurable.gif │ ├── EditLive.png │ ├── FormTab-dynamic-label.png │ ├── ListLive.png │ ├── LocalesMenuButton.gif │ ├── MenuLive.png │ ├── RealtimeMenu.png │ ├── SaveButton.png │ ├── SavedQueriesList.gif │ ├── SelectColumnsButton.gif │ ├── ShowLive.png │ ├── SimpleFormConfigurable.gif │ ├── SimpleListConfigurable.gif │ ├── TabbedForm-layout.png │ ├── ToggleThemeButton.gif │ ├── Toolbar.png │ ├── accessibility.webp │ ├── actions-toolbar.png │ ├── array-input-block.png │ ├── array-input-item-label.png │ ├── array-input.gif │ ├── aside.png │ ├── autocomplete-array-input-create.gif │ ├── autocomplete-array-input.gif │ ├── autocomplete-input.gif │ ├── blog_demo.png │ ├── boolean-field.png │ ├── boolean-input.gif │ ├── boolean-input.png │ ├── bulk-actions-toolbar.gif │ ├── bulk-delete-button.png │ ├── bulk-export-button.png │ ├── checkbox-group-input.gif │ ├── checkbox-group-input.png │ ├── chip-field.png │ ├── confirm-dialog.png │ ├── count.webp │ ├── create-button-fab.png │ ├── create-button.png │ ├── create-view.png │ ├── custom-form-layout.png │ ├── custom-iterator.png │ ├── custom-menu.gif │ ├── custom-menu.png │ ├── custom-switch-icon.png │ ├── custom_appbar.png │ ├── dark-theme.png │ ├── dashboard.png │ ├── data-provider.png │ ├── datagrid_expand.gif │ ├── date-input.gif │ ├── date-picker.gif │ ├── date-time-input.gif │ ├── dense.webp │ ├── disabled-input.png │ ├── edit-button.png │ ├── edit-from-react-to-react-admin.webp │ ├── edit-view-example.png │ ├── edit-view.png │ ├── editable-post.png │ ├── error.webp │ ├── export-button.gif │ ├── export-button.png │ ├── field-addlabel.png │ ├── file-input.png │ ├── filter-live-search.gif │ ├── filter-sidebar.gif │ ├── filter_with_submit.gif │ ├── filters.gif │ ├── form-toolbar.png │ ├── guessed-edit.png │ ├── guessed-list.png │ ├── guessed-show.png │ ├── identity.png │ ├── image-input.png │ ├── input-full-width.png │ ├── input-helper-text.png │ ├── inputs.webp │ ├── layout-component.gif │ ├── layout-responsive.gif │ ├── list-button.png │ ├── list-empty.png │ ├── list-from-react-to-react-admin.webp │ ├── list-view.jpg │ ├── list_filter.gif │ ├── list_with_customized_css.png │ ├── locks-demo.gif │ ├── login-form.png │ ├── login.gif │ ├── logout.gif │ ├── long-text-input.png │ ├── markdown-input.gif │ ├── menu-with-dashboard.webp │ ├── menu.svg │ ├── menu.webp │ ├── mobile-post-list.png │ ├── navidrome.png │ ├── nextjs-file-structure.png │ ├── nextjs-react-admin.webp │ ├── nextjs-setup.webp │ ├── not-found.png │ ├── notification.webp │ ├── nullable-boolean-input-null-label.png │ ├── nullable-boolean-input.gif │ ├── number-field.webp │ ├── number-input.gif │ ├── openid-connect-example.png │ ├── pagination-buttons.gif │ ├── password-input-visible.png │ ├── password-input.png │ ├── post-deletion.png │ ├── post-edition.png │ ├── post-show.png │ ├── premium.svg │ ├── quick_filters.gif │ ├── ra-longform-cardinality.png │ ├── ra-longform-overview.gif │ ├── ra-rbac.mp4 │ ├── ra-tree.gif │ ├── radio-button-group-input-row.gif │ ├── radio-button-group-input.gif │ ├── react-admin-demo-still.png │ ├── react-query-devtools.png │ ├── reference-array-field.png │ ├── reference-array-input.gif │ ├── reference-field-link.png │ ├── reference-field.png │ ├── reference-input-filter.webm │ ├── reference-input.gif │ ├── reference-many-field-datagrid.png │ ├── reference-many-field-single-field-list.png │ ├── reference-many-input.gif │ ├── reference-one-field-many.png │ ├── reference-one-field.png │ ├── reference-posts.png │ ├── reference_field_show.png │ ├── reference_many_count.webp │ ├── reference_many_field.png │ ├── remix-structure.png │ ├── resettable-long-text-input.png │ ├── resettable-select-input.png │ ├── resettable-text-input.gif │ ├── responsive-list.gif │ ├── responsive.webm │ ├── rich-text-field.png │ ├── rich-text-input.gif │ ├── search_input.gif │ ├── select-array-input-create.gif │ ├── select-array-input.gif │ ├── select-input.gif │ ├── show-button.png │ ├── show-view.png │ ├── simple-form-iterator-fullWidth-false.png │ ├── simple-form-iterator-fullWidth.png │ ├── simple-form-iterator-inline.png │ ├── simple-form-iterator-not-inline.png │ ├── simple-form.png │ ├── simple-list.gif │ ├── simple-post-list.png │ ├── simple-user-list.png │ ├── simpleform-layout.png │ ├── singlefieldlist-datagrid.png │ ├── singlefieldlist.png │ ├── sort-button.gif │ ├── sort-column-header.gif │ ├── sx-class-name.png │ ├── sx-documentation.png │ ├── tabbed-form.gif │ ├── tabbed-show.gif │ ├── text-input.gif │ ├── time-input-edge.gif │ ├── time-input-firefox.gif │ ├── translatable-input.gif │ ├── translation.gif │ ├── treewithdetails.gif │ ├── tutorial_custom_styles.png │ ├── tutorial_edit_guesser.gif │ ├── tutorial_empty.png │ ├── tutorial_guessed_list.png │ ├── tutorial_guessed_post_list.png │ ├── tutorial_list_user_name.png │ ├── tutorial_mobile_post_list.gif │ ├── tutorial_mobile_user_list.gif │ ├── tutorial_overview.gif │ ├── tutorial_post_create.gif │ ├── tutorial_post_edit_undo.gif │ ├── tutorial_post_list_less_columns.png │ ├── tutorial_post_title.png │ ├── tutorial_simple_list.webp │ ├── tutorial_url_field.png │ ├── tutorial_user_list_responsive.gif │ ├── tutorial_users_list.png │ ├── tutorial_users_list_selected_columns.png │ ├── typescript.webm │ ├── use-notify-node.png │ ├── useInfiniteGetList.gif │ ├── useLockOnCall.gif │ ├── useLockOnMount.gif │ ├── useSubscribe.gif │ ├── useSubscribeCallback.gif │ ├── useSubscribeOnce.gif │ ├── useSubscribeOnceCallback.gif │ ├── useSubscribeToRecord.gif │ ├── useSubscribeToRecordList.gif │ ├── useSubscribeUnsubscribe.gif │ └── warn_when_unsaved_changes.png ├── js │ ├── materialize.min.js │ ├── prism.js │ └── ra-doc-exec.js ├── navigation.html ├── useAuthProvider.md ├── useAuthState.md ├── useAuthenticated.md ├── useCanAccess.md ├── useChoicesContext.md ├── useCreate.md ├── useCreateContext.md ├── useCreateController.md ├── useDataProvider.md ├── useDelete.md ├── useDeleteMany.md ├── useEditContext.md ├── useEditController.md ├── useGetIdentity.md ├── useGetList.md ├── useGetListLive.md ├── useGetLock.md ├── useGetLockLive.md ├── useGetLocks.md ├── useGetLocksLive.md ├── useGetMany.md ├── useGetManyReference.md ├── useGetOne.md ├── useGetOneLive.md ├── useGetRecordId.md ├── useGetTree.md ├── useInfiniteGetList.md ├── useInput.md ├── useList.md ├── useListContext.md ├── useListController.md ├── useLocaleState.md ├── useLock.md ├── useLockOnCall.md ├── useLockOnMount.md ├── useLogin.md ├── useLogout.md ├── useNotify.md ├── usePermissions.md ├── usePublish.md ├── useRecordContext.md ├── useRedirect.md ├── useRefresh.md ├── useRemoveFromStore.md ├── useResetStore.md ├── useSaveContext.md ├── useShowContext.md ├── useShowController.md ├── useStore.md ├── useStoreContext.md ├── useSubscribe.md ├── useSubscribeCallback.md ├── useSubscribeToRecord.md ├── useSubscribeToRecordList.md ├── useTranslate.md ├── useUnlock.md ├── useUnselect.md ├── useUnselectAll.md ├── useUpdate.md ├── useUpdateMany.md └── withLifecycleCallbacks.md ├── examples ├── README.md ├── crm │ ├── .env │ ├── .gitignore │ ├── README.md │ ├── build.js │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── logo192.png │ │ ├── logo512.png │ │ ├── logos │ │ │ ├── 0.png │ │ │ ├── 1.png │ │ │ ├── 10.png │ │ │ ├── 11.png │ │ │ ├── 12.png │ │ │ ├── 13.png │ │ │ ├── 14.png │ │ │ ├── 15.png │ │ │ ├── 16.png │ │ │ ├── 17.png │ │ │ ├── 18.png │ │ │ ├── 19.png │ │ │ ├── 2.png │ │ │ ├── 20.png │ │ │ ├── 21.png │ │ │ ├── 22.png │ │ │ ├── 23.png │ │ │ ├── 24.png │ │ │ ├── 25.png │ │ │ ├── 26.png │ │ │ ├── 27.png │ │ │ ├── 28.png │ │ │ ├── 29.png │ │ │ ├── 3.png │ │ │ ├── 30.png │ │ │ ├── 31.png │ │ │ ├── 32.png │ │ │ ├── 33.png │ │ │ ├── 34.png │ │ │ ├── 35.png │ │ │ ├── 36.png │ │ │ ├── 37.png │ │ │ ├── 38.png │ │ │ ├── 39.png │ │ │ ├── 4.png │ │ │ ├── 40.png │ │ │ ├── 41.png │ │ │ ├── 42.png │ │ │ ├── 43.png │ │ │ ├── 44.png │ │ │ ├── 45.png │ │ │ ├── 46.png │ │ │ ├── 47.png │ │ │ ├── 48.png │ │ │ ├── 49.png │ │ │ ├── 5.png │ │ │ ├── 50.png │ │ │ ├── 51.png │ │ │ ├── 52.png │ │ │ ├── 53.png │ │ │ ├── 54.png │ │ │ ├── 55.png │ │ │ ├── 6.png │ │ │ ├── 7.png │ │ │ ├── 8.png │ │ │ ├── 9.png │ │ │ └── Readme.md │ │ ├── manifest.json │ │ └── robots.txt │ ├── src │ │ ├── App.tsx │ │ ├── Header.tsx │ │ ├── Layout.tsx │ │ ├── authProvider.ts │ │ ├── companies │ │ │ ├── CompanyAside.tsx │ │ │ ├── CompanyAvatar.tsx │ │ │ ├── CompanyCard.tsx │ │ │ ├── CompanyCreate.tsx │ │ │ ├── CompanyEdit.tsx │ │ │ ├── CompanyForm.tsx │ │ │ ├── CompanyList.tsx │ │ │ ├── CompanyListFilter.tsx │ │ │ ├── CompanyShow.tsx │ │ │ ├── GridList.tsx │ │ │ ├── LogoField.tsx │ │ │ ├── index.ts │ │ │ ├── sectors.ts │ │ │ └── sizes.ts │ │ ├── contacts │ │ │ ├── Avatar.tsx │ │ │ ├── ContactAside.tsx │ │ │ ├── ContactCreate.tsx │ │ │ ├── ContactEdit.tsx │ │ │ ├── ContactInputs.tsx │ │ │ ├── ContactList.tsx │ │ │ ├── ContactListFilter.tsx │ │ │ ├── ContactShow.tsx │ │ │ ├── TagsList.tsx │ │ │ ├── TagsListEdit.tsx │ │ │ └── index.tsx │ │ ├── dashboard │ │ │ ├── Dashboard.tsx │ │ │ ├── DealsChart.tsx │ │ │ ├── DealsPipeline.tsx │ │ │ ├── HotContacts.tsx │ │ │ ├── LatestNotes.tsx │ │ │ └── Welcome.tsx │ │ ├── dataGenerator │ │ │ ├── companies.ts │ │ │ ├── contactNotes.ts │ │ │ ├── contacts.ts │ │ │ ├── dealNotes.ts │ │ │ ├── deals.ts │ │ │ ├── finalize.ts │ │ │ ├── index.ts │ │ │ ├── sales.ts │ │ │ ├── tags.ts │ │ │ ├── tasks.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── dataProvider.ts │ │ ├── deals │ │ │ ├── ContactList.tsx │ │ │ ├── DealCard.tsx │ │ │ ├── DealColumn.tsx │ │ │ ├── DealCreate.tsx │ │ │ ├── DealList.tsx │ │ │ ├── DealListContent.tsx │ │ │ ├── DealShow.tsx │ │ │ ├── OnlyMineInput.tsx │ │ │ ├── index.ts │ │ │ ├── stages.ts │ │ │ └── types.ts │ │ ├── index.tsx │ │ ├── logo.svg │ │ ├── misc │ │ │ └── Status.tsx │ │ ├── notes │ │ │ ├── NewNote.tsx │ │ │ ├── Note.tsx │ │ │ ├── NotesIterator.tsx │ │ │ ├── StatusSelector.tsx │ │ │ └── index.ts │ │ ├── react-app-env.d.ts │ │ ├── reportWebVitals.js │ │ ├── setupTests.js │ │ ├── tags │ │ │ └── colors.ts │ │ └── types.ts │ └── tsconfig.json ├── data-generator │ ├── LICENSE.md │ ├── README.md │ ├── package.json │ ├── src │ │ ├── categories.ts │ │ ├── commands.ts │ │ ├── customers.ts │ │ ├── finalize.ts │ │ ├── index.ts │ │ ├── invoices.ts │ │ ├── products.ts │ │ ├── reviews.ts │ │ └── utils.ts │ └── tsconfig.json ├── demo │ ├── .env │ ├── .gitignore │ ├── README.md │ ├── build.js │ ├── index.html │ ├── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── index.html │ │ └── manifest.json │ ├── src │ │ ├── App.tsx │ │ ├── authProvider.ts │ │ ├── categories │ │ │ ├── CategoryEdit.tsx │ │ │ ├── CategoryList.tsx │ │ │ ├── LinkToRelatedProducts.tsx │ │ │ └── index.ts │ │ ├── configuration │ │ │ └── Configuration.tsx │ │ ├── dashboard │ │ │ ├── CardWithIcon.tsx │ │ │ ├── Dashboard.tsx │ │ │ ├── MonthlyRevenue.tsx │ │ │ ├── NbNewOrders.tsx │ │ │ ├── NewCustomers.tsx │ │ │ ├── OrderChart.tsx │ │ │ ├── PendingOrder.tsx │ │ │ ├── PendingOrders.tsx │ │ │ ├── PendingReviews.tsx │ │ │ ├── Welcome.tsx │ │ │ ├── cartouche.png │ │ │ ├── cartoucheDark.png │ │ │ ├── index.ts │ │ │ └── welcome_illustration.svg │ │ ├── data-generator-retail.d.ts │ │ ├── dataProvider │ │ │ ├── graphql.ts │ │ │ ├── index.ts │ │ │ └── rest.ts │ │ ├── fakeServer │ │ │ ├── graphql.ts │ │ │ ├── index.ts │ │ │ └── rest.ts │ │ ├── fakerest.d.ts │ │ ├── i18n │ │ │ ├── en.ts │ │ │ └── fr.ts │ │ ├── index.tsx │ │ ├── invoices │ │ │ ├── InvoiceList.tsx │ │ │ ├── InvoiceShow.tsx │ │ │ └── index.ts │ │ ├── json-graphql-server.d.ts │ │ ├── layout │ │ │ ├── AppBar.tsx │ │ │ ├── Layout.tsx │ │ │ ├── Login.tsx │ │ │ ├── Logo.tsx │ │ │ ├── Menu.tsx │ │ │ ├── SubMenu.tsx │ │ │ ├── index.ts │ │ │ └── themes.ts │ │ ├── orders │ │ │ ├── Basket.tsx │ │ │ ├── MobileGrid.tsx │ │ │ ├── NbItemsField.tsx │ │ │ ├── OrderEdit.tsx │ │ │ ├── OrderList.tsx │ │ │ ├── TableCellRight.tsx │ │ │ ├── Totals.tsx │ │ │ └── index.ts │ │ ├── products │ │ │ ├── Aside.tsx │ │ │ ├── GridList.tsx │ │ │ ├── Poster.tsx │ │ │ ├── ProductCreate.tsx │ │ │ ├── ProductEdit.tsx │ │ │ ├── ProductEditDetails.tsx │ │ │ ├── ProductList.tsx │ │ │ ├── ProductRefField.tsx │ │ │ ├── ProductReferenceField.tsx │ │ │ ├── ThumbnailField.tsx │ │ │ └── index.tsx │ │ ├── react-app-env.d.ts │ │ ├── reviews │ │ │ ├── AcceptButton.tsx │ │ │ ├── BulkAcceptButton.tsx │ │ │ ├── BulkRejectButton.tsx │ │ │ ├── RejectButton.tsx │ │ │ ├── ReviewEdit.tsx │ │ │ ├── ReviewEditToolbar.tsx │ │ │ ├── ReviewItem.tsx │ │ │ ├── ReviewList.tsx │ │ │ ├── ReviewListDesktop.tsx │ │ │ ├── ReviewListMobile.tsx │ │ │ ├── StarRatingField.tsx │ │ │ ├── index.ts │ │ │ ├── reviewFilters.tsx │ │ │ └── rowStyle.tsx │ │ ├── segments │ │ │ ├── LinkToRelatedCustomers.tsx │ │ │ ├── Segments.tsx │ │ │ └── data.ts │ │ ├── types.ts │ │ └── visitors │ │ │ ├── AddressField.tsx │ │ │ ├── Aside.tsx │ │ │ ├── AvatarField.tsx │ │ │ ├── ColoredNumberField.tsx │ │ │ ├── CustomerLinkField.tsx │ │ │ ├── CustomerReferenceField.tsx │ │ │ ├── FullNameField.tsx │ │ │ ├── MobileGrid.tsx │ │ │ ├── SegmentInput.tsx │ │ │ ├── SegmentsField.tsx │ │ │ ├── SegmentsInput.tsx │ │ │ ├── VisitorCreate.tsx │ │ │ ├── VisitorEdit.tsx │ │ │ ├── VisitorList.tsx │ │ │ ├── VisitorListAside.tsx │ │ │ ├── index.ts │ │ │ └── segments.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── no-code │ ├── index.html │ ├── package.json │ ├── src │ │ ├── favicon.svg │ │ └── main.tsx │ ├── tsconfig.json │ └── vite.config.ts ├── simple │ ├── .babelrc │ ├── .gitignore │ ├── README.md │ ├── index-webpack.html │ ├── index.html │ ├── package.json │ ├── sandbox.config.json │ ├── src │ │ ├── Layout.tsx │ │ ├── addUploadFeature.tsx │ │ ├── authProvider.tsx │ │ ├── comments │ │ │ ├── CommentCreate.tsx │ │ │ ├── CommentEdit.tsx │ │ │ ├── CommentList.tsx │ │ │ ├── CommentShow.tsx │ │ │ ├── PostPreview.tsx │ │ │ ├── PostQuickCreate.tsx │ │ │ ├── PostQuickCreateCancelButton.tsx │ │ │ ├── PostReferenceInput.tsx │ │ │ └── index.tsx │ │ ├── customRouteLayout.tsx │ │ ├── customRouteNoLayout.tsx │ │ ├── data.tsx │ │ ├── dataProvider.tsx │ │ ├── i18n │ │ │ ├── en.ts │ │ │ ├── fr.ts │ │ │ └── index.ts │ │ ├── i18nProvider.tsx │ │ ├── index.tsx │ │ ├── polyfills.ts │ │ ├── posts │ │ │ ├── PostCreate.tsx │ │ │ ├── PostEdit.tsx │ │ │ ├── PostList.tsx │ │ │ ├── PostShow.tsx │ │ │ ├── PostTitle.tsx │ │ │ ├── ResetViewsButton.tsx │ │ │ ├── TagReferenceInput.tsx │ │ │ └── index.tsx │ │ ├── tags │ │ │ ├── TagCreate.tsx │ │ │ ├── TagEdit.tsx │ │ │ ├── TagList.tsx │ │ │ ├── TagShow.tsx │ │ │ └── index.tsx │ │ ├── users │ │ │ ├── Aside.tsx │ │ │ ├── UserCreate.tsx │ │ │ ├── UserEdit.tsx │ │ │ ├── UserEditEmbedded.tsx │ │ │ ├── UserList.tsx │ │ │ ├── UserShow.tsx │ │ │ ├── UserTitle.tsx │ │ │ └── index.tsx │ │ └── validators.tsx │ ├── tsconfig.json │ ├── vite.config.js │ └── webpack.config.js └── tutorial │ ├── .env │ ├── .gitignore │ ├── README.md │ ├── index.html │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json │ ├── src │ ├── App.js │ ├── App.tsx │ ├── Dashboard.js │ ├── Dashboard.tsx │ ├── MyUrlField.tsx │ ├── assets │ │ └── react.svg │ ├── authProvider.js │ ├── authProvider.ts │ ├── index.css │ ├── index.js │ ├── index.module.css │ ├── logo.svg │ ├── main.tsx │ ├── posts.js │ ├── posts.tsx │ ├── registerServiceWorker.js │ ├── users.js │ ├── users.tsx │ └── vite-env.d.ts │ ├── tsconfig.json │ ├── tsconfig.node.json │ └── vite.config.ts ├── jest.config.js ├── lerna.json ├── package.json ├── packages ├── ra-core │ ├── README.md │ ├── package.json │ ├── src │ │ ├── auth │ │ │ ├── AuthContext.tsx │ │ │ ├── Authenticated.spec.tsx │ │ │ ├── Authenticated.tsx │ │ │ ├── WithPermissions.tsx │ │ │ ├── convertLegacyAuthProvider.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── useAuthProvider.ts │ │ │ ├── useAuthState.spec.tsx │ │ │ ├── useAuthState.ts │ │ │ ├── useAuthenticated.spec.tsx │ │ │ ├── useAuthenticated.ts │ │ │ ├── useCheckAuth.spec.tsx │ │ │ ├── useCheckAuth.ts │ │ │ ├── useGetIdentity.spec.tsx │ │ │ ├── useGetIdentity.stories.tsx │ │ │ ├── useGetIdentity.ts │ │ │ ├── useGetPermissions.ts │ │ │ ├── useHandleAuthCallback.spec.tsx │ │ │ ├── useHandleAuthCallback.ts │ │ │ ├── useLogin.spec.tsx │ │ │ ├── useLogin.ts │ │ │ ├── useLogout.spec.tsx │ │ │ ├── useLogout.ts │ │ │ ├── useLogoutIfAccessDenied.spec.tsx │ │ │ ├── useLogoutIfAccessDenied.ts │ │ │ ├── usePermissions.spec.tsx │ │ │ ├── usePermissions.ts │ │ │ ├── usePermissionsOptimized.spec.tsx │ │ │ └── usePermissionsOptimized.ts │ │ ├── controller │ │ │ ├── button │ │ │ │ ├── index.ts │ │ │ │ ├── useDeleteWithConfirmController.spec.tsx │ │ │ │ ├── useDeleteWithConfirmController.tsx │ │ │ │ ├── useDeleteWithUndoController.spec.tsx │ │ │ │ └── useDeleteWithUndoController.tsx │ │ │ ├── checkMinimumRequiredProps.tsx │ │ │ ├── create │ │ │ │ ├── CreateBase.spec.tsx │ │ │ │ ├── CreateBase.tsx │ │ │ │ ├── CreateContext.tsx │ │ │ │ ├── CreateContextProvider.tsx │ │ │ │ ├── CreateController.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── useCreateContext.tsx │ │ │ │ ├── useCreateController.spec.tsx │ │ │ │ └── useCreateController.ts │ │ │ ├── edit │ │ │ │ ├── EditBase.spec.tsx │ │ │ │ ├── EditBase.tsx │ │ │ │ ├── EditContext.tsx │ │ │ │ ├── EditContextProvider.tsx │ │ │ │ ├── EditController.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── useEditContext.tsx │ │ │ │ ├── useEditController.spec.tsx │ │ │ │ └── useEditController.ts │ │ │ ├── field │ │ │ │ ├── index.ts │ │ │ │ ├── useReferenceArrayFieldController.spec.tsx │ │ │ │ ├── useReferenceArrayFieldController.ts │ │ │ │ ├── useReferenceManyFieldController.spec.tsx │ │ │ │ ├── useReferenceManyFieldController.ts │ │ │ │ ├── useReferenceOneFieldController.spec.tsx │ │ │ │ └── useReferenceOneFieldController.tsx │ │ │ ├── index.ts │ │ │ ├── input │ │ │ │ ├── index.ts │ │ │ │ ├── referenceDataStatus.spec.ts │ │ │ │ ├── referenceDataStatus.ts │ │ │ │ ├── types.ts │ │ │ │ ├── useReferenceArrayInputController.spec.tsx │ │ │ │ ├── useReferenceArrayInputController.ts │ │ │ │ ├── useReferenceInputController.spec.tsx │ │ │ │ ├── useReferenceInputController.ts │ │ │ │ └── useReferenceParams.ts │ │ │ ├── list │ │ │ │ ├── ListBase.tsx │ │ │ │ ├── ListContext.tsx │ │ │ │ ├── ListContextProvider.tsx │ │ │ │ ├── ListController.tsx │ │ │ │ ├── ListFilterContext.tsx │ │ │ │ ├── ListPaginationContext.tsx │ │ │ │ ├── ListSortContext.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── queryReducer.spec.ts │ │ │ │ ├── queryReducer.ts │ │ │ │ ├── useExpanded.spec.tsx │ │ │ │ ├── useExpanded.tsx │ │ │ │ ├── useList.spec.tsx │ │ │ │ ├── useList.ts │ │ │ │ ├── useListContext.spec.tsx │ │ │ │ ├── useListContext.ts │ │ │ │ ├── useListController.spec.tsx │ │ │ │ ├── useListController.storeKey.spec.tsx │ │ │ │ ├── useListController.storeKey.stories.tsx │ │ │ │ ├── useListController.ts │ │ │ │ ├── useListFilterContext.ts │ │ │ │ ├── useListPaginationContext.ts │ │ │ │ ├── useListParams.spec.tsx │ │ │ │ ├── useListParams.ts │ │ │ │ ├── useListSortContext.ts │ │ │ │ ├── useRecordSelection.spec.tsx │ │ │ │ ├── useRecordSelection.ts │ │ │ │ ├── useUnselect.ts │ │ │ │ └── useUnselectAll.ts │ │ │ ├── record │ │ │ │ ├── OptionalRecordContextProvider.tsx │ │ │ │ ├── RecordContext.tsx │ │ │ │ ├── WithRecord.tsx │ │ │ │ ├── index.ts │ │ │ │ └── useRecordContext.ts │ │ │ ├── saveContext │ │ │ │ ├── SaveContext.ts │ │ │ │ ├── SaveContextProvider.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── useMutationMiddlewares.ts │ │ │ │ ├── usePickSaveContext.ts │ │ │ │ ├── useRegisterMutationMiddleware.ts │ │ │ │ └── useSaveContext.ts │ │ │ ├── show │ │ │ │ ├── ShowBase.tsx │ │ │ │ ├── ShowContext.tsx │ │ │ │ ├── ShowContextProvider.tsx │ │ │ │ ├── ShowController.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── useShowContext.tsx │ │ │ │ ├── useShowController.spec.tsx │ │ │ │ └── useShowController.ts │ │ │ ├── useFilterState.spec.tsx │ │ │ ├── useFilterState.ts │ │ │ ├── usePaginationState.spec.ts │ │ │ ├── usePaginationState.ts │ │ │ ├── useReference.spec.tsx │ │ │ ├── useReference.ts │ │ │ ├── useSortState.spec.ts │ │ │ └── useSortState.ts │ │ ├── core │ │ │ ├── CoreAdmin.spec.tsx │ │ │ ├── CoreAdmin.tsx │ │ │ ├── CoreAdminContext.tsx │ │ │ ├── CoreAdminRoutes.spec.tsx │ │ │ ├── CoreAdminRoutes.tsx │ │ │ ├── CoreAdminUI.tsx │ │ │ ├── CustomRoutes.authenticated.stories.tsx │ │ │ ├── CustomRoutes.spec.tsx │ │ │ ├── CustomRoutes.tsx │ │ │ ├── CustomRoutes.unauthenticated.stories.tsx │ │ │ ├── CustomRoutes.withLayout.stories.tsx │ │ │ ├── Resource.spec.tsx │ │ │ ├── Resource.tsx │ │ │ ├── ResourceContext.ts │ │ │ ├── ResourceContextProvider.tsx │ │ │ ├── ResourceDefinitionContext.tsx │ │ │ ├── index.ts │ │ │ ├── useConfigureAdminRouterFromChildren.spec.tsx │ │ │ ├── useConfigureAdminRouterFromChildren.tsx │ │ │ ├── useGetRecordRepresentation.spec.tsx │ │ │ ├── useGetRecordRepresentation.ts │ │ │ ├── useGetResourceLabel.spec.tsx │ │ │ ├── useGetResourceLabel.ts │ │ │ ├── useResourceContext.ts │ │ │ ├── useResourceDefinition.spec.tsx │ │ │ ├── useResourceDefinition.ts │ │ │ ├── useResourceDefinitionContext.ts │ │ │ ├── useResourceDefinitions.spec.tsx │ │ │ └── useResourceDefinitions.ts │ │ ├── dataProvider │ │ │ ├── DataProviderContext.ts │ │ │ ├── HttpError.ts │ │ │ ├── combineDataProviders.spec.ts │ │ │ ├── combineDataProviders.ts │ │ │ ├── convertLegacyDataProvider.spec.ts │ │ │ ├── convertLegacyDataProvider.ts │ │ │ ├── dataFetchActions.ts │ │ │ ├── defaultDataProvider.ts │ │ │ ├── fetch.spec.ts │ │ │ ├── fetch.ts │ │ │ ├── getFetchType.ts │ │ │ ├── index.ts │ │ │ ├── testDataProvider.ts │ │ │ ├── undoableEventEmitter.ts │ │ │ ├── useCreate.spec.tsx │ │ │ ├── useCreate.ts │ │ │ ├── useDataProvider.spec.tsx │ │ │ ├── useDataProvider.ts │ │ │ ├── useDelete.optimistic.stories.tsx │ │ │ ├── useDelete.pessimistic.stories.tsx │ │ │ ├── useDelete.spec.tsx │ │ │ ├── useDelete.ts │ │ │ ├── useDelete.undoable.stories.tsx │ │ │ ├── useDeleteMany.spec.tsx │ │ │ ├── useDeleteMany.ts │ │ │ ├── useGetList.spec.tsx │ │ │ ├── useGetList.ts │ │ │ ├── useGetMany.spec.tsx │ │ │ ├── useGetMany.ts │ │ │ ├── useGetManyAggregate.spec.tsx │ │ │ ├── useGetManyAggregate.ts │ │ │ ├── useGetManyReference.ts │ │ │ ├── useGetOne.spec.tsx │ │ │ ├── useGetOne.ts │ │ │ ├── useGetRecordId.spec.tsx │ │ │ ├── useGetRecordId.ts │ │ │ ├── useInfiniteGetList.spec.tsx │ │ │ ├── useInfiniteGetList.stories.tsx │ │ │ ├── useInfiniteGetList.ts │ │ │ ├── useIsDataLoaded.ts │ │ │ ├── useLoading.ts │ │ │ ├── useRefresh.ts │ │ │ ├── useUpdate.optimistic.stories.tsx │ │ │ ├── useUpdate.pessimistic.stories.tsx │ │ │ ├── useUpdate.spec.tsx │ │ │ ├── useUpdate.ts │ │ │ ├── useUpdate.undoable.stories.tsx │ │ │ ├── useUpdateMany.spec.tsx │ │ │ ├── useUpdateMany.ts │ │ │ ├── validateResponseFormat.ts │ │ │ ├── withLifecycleCallbacks.spec.ts │ │ │ └── withLifecycleCallbacks.ts │ │ ├── export │ │ │ ├── ExporterContext.ts │ │ │ ├── defaultExporter.ts │ │ │ ├── downloadCSV.ts │ │ │ ├── fetchRelatedRecords.spec.ts │ │ │ ├── fetchRelatedRecords.ts │ │ │ └── index.ts │ │ ├── form │ │ │ ├── Form.spec.tsx │ │ │ ├── Form.stories.tsx │ │ │ ├── Form.tsx │ │ │ ├── FormDataConsumer.spec.tsx │ │ │ ├── FormDataConsumer.tsx │ │ │ ├── FormGroupContext.ts │ │ │ ├── FormGroupContextProvider.tsx │ │ │ ├── FormGroupsContext.tsx │ │ │ ├── FormGroupsProvider.tsx │ │ │ ├── ValidationError.spec.tsx │ │ │ ├── ValidationError.tsx │ │ │ ├── choices │ │ │ │ ├── ChoicesContext.ts │ │ │ │ ├── ChoicesContextProvider.tsx │ │ │ │ ├── index.ts │ │ │ │ └── useChoicesContext.ts │ │ │ ├── getFormInitialValues.spec.ts │ │ │ ├── getFormInitialValues.ts │ │ │ ├── getSimpleValidationResolver.spec.ts │ │ │ ├── getSimpleValidationResolver.ts │ │ │ ├── index.ts │ │ │ ├── isRequired.ts │ │ │ ├── sanitizeEmptyValues.spec.ts │ │ │ ├── sanitizeEmptyValues.ts │ │ │ ├── setSubmissionErrors.spec.ts │ │ │ ├── setSubmissionErrors.ts │ │ │ ├── types.ts │ │ │ ├── useApplyInputDefaultValues.ts │ │ │ ├── useAugmentedForm.ts │ │ │ ├── useChoices.spec.tsx │ │ │ ├── useChoices.tsx │ │ │ ├── useFormGroup.spec.tsx │ │ │ ├── useFormGroup.ts │ │ │ ├── useFormGroupContext.ts │ │ │ ├── useFormGroups.ts │ │ │ ├── useGetValidationErrorMessage.ts │ │ │ ├── useInitializeFormWithRecord.ts │ │ │ ├── useInput.spec.tsx │ │ │ ├── useInput.ts │ │ │ ├── useIsFormInvalid.ts │ │ │ ├── useNotifyIsFormInvalid.ts │ │ │ ├── useSuggestions.spec.ts │ │ │ ├── useSuggestions.ts │ │ │ ├── useWarnWhenUnsavedChanges.spec.tsx │ │ │ ├── useWarnWhenUnsavedChanges.tsx │ │ │ ├── validate.spec.ts │ │ │ └── validate.ts │ │ ├── i18n │ │ │ ├── I18nContext.ts │ │ │ ├── I18nContextProvider.tsx │ │ │ ├── TestTranslationProvider.tsx │ │ │ ├── TranslatableContext.ts │ │ │ ├── TranslatableContextProvider.tsx │ │ │ ├── TranslationMessages.ts │ │ │ ├── TranslationUtils.spec.ts │ │ │ ├── TranslationUtils.ts │ │ │ ├── index.ts │ │ │ ├── substituteTokens.ts │ │ │ ├── useI18nProvider.ts │ │ │ ├── useLocale.tsx │ │ │ ├── useLocaleState.tsx │ │ │ ├── useLocales.ts │ │ │ ├── useSetLocale.spec.tsx │ │ │ ├── useSetLocale.tsx │ │ │ ├── useTranslatable.ts │ │ │ ├── useTranslatableContext.ts │ │ │ ├── useTranslate.spec.tsx │ │ │ ├── useTranslate.ts │ │ │ └── useTranslateLabel.ts │ │ ├── index.ts │ │ ├── inference │ │ │ ├── InferredElement.spec.tsx │ │ │ ├── InferredElement.ts │ │ │ ├── assertions.ts │ │ │ ├── getElementsFromRecords.ts │ │ │ ├── getValuesFromRecords.spec.ts │ │ │ ├── getValuesFromRecords.ts │ │ │ ├── index.ts │ │ │ ├── inferElementFromValues.spec.tsx │ │ │ ├── inferElementFromValues.tsx │ │ │ ├── inferTypeFromValues.ts │ │ │ ├── inferTypesFromValues.spec.ts │ │ │ └── types.ts │ │ ├── notification │ │ │ ├── AddNotificationContext.tsx │ │ │ ├── NotificationContext.ts │ │ │ ├── NotificationContextProvider.tsx │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── useAddNotificationContext.tsx │ │ │ ├── useNotificationContext.ts │ │ │ ├── useNotify.spec.tsx │ │ │ ├── useNotify.stories.tsx │ │ │ └── useNotify.ts │ │ ├── preferences │ │ │ ├── PreferenceKeyContext.tsx │ │ │ ├── PreferencesEditorContext.tsx │ │ │ ├── PreferencesEditorContextProvider.tsx │ │ │ ├── index.ts │ │ │ ├── usePreference.ts │ │ │ ├── usePreferenceInput.ts │ │ │ ├── usePreferencesEditor.ts │ │ │ └── useSetInspectorTitle.ts │ │ ├── routing │ │ │ ├── AdminRouter.tsx │ │ │ ├── BasenameContext.ts │ │ │ ├── BasenameContextProvider.tsx │ │ │ ├── HistoryRouter.tsx │ │ │ ├── index.ts │ │ │ ├── linkToRecord.spec.ts │ │ │ ├── linkToRecord.ts │ │ │ ├── resolveRedirectTo.spec.ts │ │ │ ├── resolveRedirectTo.ts │ │ │ ├── types.ts │ │ │ ├── useBasename.ts │ │ │ ├── useCreatePath.spec.tsx │ │ │ ├── useCreatePath.stories.tsx │ │ │ ├── useCreatePath.ts │ │ │ ├── useRedirect.spec.tsx │ │ │ ├── useRedirect.ts │ │ │ └── useScrollToTop.tsx │ │ ├── store │ │ │ ├── README.md │ │ │ ├── StoreContext.tsx │ │ │ ├── StoreContextProvider.tsx │ │ │ ├── StoreSetter.tsx │ │ │ ├── index.ts │ │ │ ├── localStorageStore.spec.ts │ │ │ ├── localStorageStore.spec.tsx │ │ │ ├── localStorageStore.stories.tsx │ │ │ ├── localStorageStore.ts │ │ │ ├── memoryStore.spec.ts │ │ │ ├── memoryStore.stories.tsx │ │ │ ├── memoryStore.tsx │ │ │ ├── types.ts │ │ │ ├── useRemoveFromStore.ts │ │ │ ├── useRemoveItemsFromStore.ts │ │ │ ├── useResetStore.ts │ │ │ ├── useStore.spec.tsx │ │ │ ├── useStore.stories.tsx │ │ │ ├── useStore.ts │ │ │ └── useStoreContext.ts │ │ ├── storybook │ │ │ ├── FakeBrowser.tsx │ │ │ └── data.ts │ │ ├── types.ts │ │ └── util │ │ │ ├── ComponentPropType.ts │ │ │ ├── FieldTitle.spec.tsx │ │ │ ├── FieldTitle.tsx │ │ │ ├── LabelPrefixContext.ts │ │ │ ├── LabelPrefixContextProvider.tsx │ │ │ ├── Ready.tsx │ │ │ ├── escapePath.ts │ │ │ ├── getFieldLabelTranslationArgs.spec.ts │ │ │ ├── getFieldLabelTranslationArgs.ts │ │ │ ├── getMutationMode.ts │ │ │ ├── getValue.spec.ts │ │ │ ├── getValue.ts │ │ │ ├── hooks.ts │ │ │ ├── index.ts │ │ │ ├── mergeRefs.ts │ │ │ ├── removeEmpty.spec.ts │ │ │ ├── removeEmpty.ts │ │ │ ├── removeKey.spec.ts │ │ │ ├── removeKey.ts │ │ │ ├── shallowEqual.ts │ │ │ ├── useEvent.spec.tsx │ │ │ ├── useEvent.ts │ │ │ ├── useEventCallback.ts │ │ │ ├── useLabelPrefix.ts │ │ │ ├── useWhyDidYouUpdate.ts │ │ │ └── warning.ts │ └── tsconfig.json ├── ra-data-fakerest │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── ra-data-graphql-simple │ ├── README.md │ ├── package.json │ ├── src │ │ ├── buildGqlQuery.test.ts │ │ ├── buildGqlQuery.ts │ │ ├── buildQuery.test.ts │ │ ├── buildQuery.ts │ │ ├── buildVariables.test.ts │ │ ├── buildVariables.ts │ │ ├── getFinalType.test.ts │ │ ├── getFinalType.ts │ │ ├── getResponseParser.test.ts │ │ ├── getResponseParser.ts │ │ ├── index.ts │ │ ├── isList.test.ts │ │ ├── isList.ts │ │ ├── isRequired.test.ts │ │ └── isRequired.ts │ └── tsconfig.json ├── ra-data-graphql │ ├── README.md │ ├── package.json │ ├── src │ │ ├── buildApolloClient.ts │ │ ├── constants.ts │ │ ├── index.test.ts │ │ ├── index.ts │ │ ├── introspection.test.ts │ │ └── introspection.ts │ └── tsconfig.json ├── ra-data-json-server │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── ra-data-localforage │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── ra-data-localstorage │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── ra-data-simple-rest │ ├── README.md │ ├── package.json │ ├── src │ │ ├── index.spec.ts │ │ └── index.ts │ └── tsconfig.json ├── ra-i18n-polyglot │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── ra-input-rich-text │ ├── README.md │ ├── assets │ │ └── demo.gif │ ├── package.json │ ├── src │ │ ├── RichTextInput.spec.tsx │ │ ├── RichTextInput.stories.tsx │ │ ├── RichTextInput.tsx │ │ ├── RichTextInputToolbar.tsx │ │ ├── TiptapEditorContext.tsx │ │ ├── TiptapEditorProvider.tsx │ │ ├── buttons │ │ │ ├── AlignmentButtons.tsx │ │ │ ├── ClearButtons.tsx │ │ │ ├── ColorButtons.tsx │ │ │ ├── FormatButtons.tsx │ │ │ ├── ImageButtons.tsx │ │ │ ├── LevelSelect.tsx │ │ │ ├── LinkButtons.tsx │ │ │ ├── ListButtons.tsx │ │ │ ├── QuoteButtons.tsx │ │ │ ├── index.ts │ │ │ └── useEditorSelection.ts │ │ ├── index.ts │ │ └── useTiptapEditor.ts │ └── tsconfig.json ├── ra-language-english │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── ra-language-french │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ └── tsconfig.json ├── ra-no-code │ ├── README.md │ ├── assets │ │ ├── ra-customers.csv │ │ ├── ra-orders-1.csv │ │ └── ra-orders-2.csv │ ├── package.json │ ├── src │ │ ├── Admin.spec.tsx │ │ ├── Admin.tsx │ │ ├── ApplicationContext.tsx │ │ ├── ApplicationsDashboard │ │ │ ├── ApplicationsDashboard.tsx │ │ │ ├── NewApplicationForm.tsx │ │ │ ├── applicationStorage.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── ResourceConfiguration │ │ │ ├── ConfigurationInputsFromFieldDefinition.tsx │ │ │ ├── FieldConfiguration │ │ │ │ ├── FieldTypeInput.tsx │ │ │ │ ├── FieldViewsInput.tsx │ │ │ │ └── index.ts │ │ │ ├── FieldConfigurationFormSection.tsx │ │ │ ├── FieldConfigurationTab.tsx │ │ │ ├── ResourceConfiguration.tsx │ │ │ ├── ResourceConfigurationContext.ts │ │ │ ├── ResourceConfigurationProvider.tsx │ │ │ ├── getFieldDefinitionsFromRecords.ts │ │ │ ├── index.ts │ │ │ ├── useResourceConfiguration.ts │ │ │ └── useResourcesConfiguration.ts │ │ ├── Root.tsx │ │ ├── builders │ │ │ ├── Create.tsx │ │ │ ├── Edit.tsx │ │ │ ├── List.tsx │ │ │ ├── ReferenceInputChildFromDefinition.tsx │ │ │ ├── Show.tsx │ │ │ ├── getFieldFromFieldDefinition.tsx │ │ │ ├── getInputFromFieldDefinition.tsx │ │ │ └── index.ts │ │ ├── index.ts │ │ └── ui │ │ │ ├── Appbar.tsx │ │ │ ├── ExitApplicationMenu.tsx │ │ │ ├── ImportResourceDialog.tsx │ │ │ ├── Layout.tsx │ │ │ ├── Menu.tsx │ │ │ ├── NewResourceMenuItem.tsx │ │ │ ├── Ready.tsx │ │ │ ├── ResourceMenuItem.tsx │ │ │ ├── UserMenu.tsx │ │ │ ├── index.ts │ │ │ └── useImportResourceFromCsv.tsx │ └── tsconfig.json ├── ra-ui-materialui │ ├── README.md │ ├── package.json │ ├── src │ │ ├── AdminContext.tsx │ │ ├── AdminUI.tsx │ │ ├── Labeled.spec.tsx │ │ ├── Labeled.stories.tsx │ │ ├── Labeled.tsx │ │ ├── Link.tsx │ │ ├── auth │ │ │ ├── AuthCallback.tsx │ │ │ ├── AuthError.stories.tsx │ │ │ ├── AuthError.tsx │ │ │ ├── Login.tsx │ │ │ ├── LoginForm.tsx │ │ │ ├── Logout.spec.tsx │ │ │ ├── Logout.stories.tsx │ │ │ ├── Logout.tsx │ │ │ └── index.ts │ │ ├── button │ │ │ ├── BulkDeleteButton.tsx │ │ │ ├── BulkDeleteWithConfirmButton.tsx │ │ │ ├── BulkDeleteWithUndoButton.tsx │ │ │ ├── BulkExportButton.spec.tsx │ │ │ ├── BulkExportButton.tsx │ │ │ ├── BulkUpdateButton.tsx │ │ │ ├── BulkUpdateWithConfirmButton.tsx │ │ │ ├── BulkUpdateWithUndoButton.tsx │ │ │ ├── Button.stories.tsx │ │ │ ├── Button.tsx │ │ │ ├── CloneButton.spec.tsx │ │ │ ├── CloneButton.tsx │ │ │ ├── CreateButton.spec.tsx │ │ │ ├── CreateButton.tsx │ │ │ ├── DeleteButton.tsx │ │ │ ├── DeleteWithConfirmButton.spec.tsx │ │ │ ├── DeleteWithConfirmButton.tsx │ │ │ ├── DeleteWithUndoButton.spec.tsx │ │ │ ├── DeleteWithUndoButton.tsx │ │ │ ├── EditButton.tsx │ │ │ ├── ExportButton.spec.tsx │ │ │ ├── ExportButton.tsx │ │ │ ├── IconButtonWithTooltip.tsx │ │ │ ├── ListButton.tsx │ │ │ ├── LocalesMenuButton.spec.tsx │ │ │ ├── LocalesMenuButton.stories.tsx │ │ │ ├── LocalesMenuButton.tsx │ │ │ ├── RefreshButton.tsx │ │ │ ├── RefreshIconButton.tsx │ │ │ ├── SaveButton.spec.tsx │ │ │ ├── SaveButton.tsx │ │ │ ├── ShowButton.tsx │ │ │ ├── SkipNavigationButton.tsx │ │ │ ├── SortButton.tsx │ │ │ ├── ToggleThemeButton.stories.tsx │ │ │ ├── ToggleThemeButton.tsx │ │ │ └── index.ts │ │ ├── defaultTheme.ts │ │ ├── detail │ │ │ ├── Create.spec.tsx │ │ │ ├── Create.tsx │ │ │ ├── CreateActions.tsx │ │ │ ├── CreateView.tsx │ │ │ ├── Edit.spec.tsx │ │ │ ├── Edit.tsx │ │ │ ├── EditActions.tsx │ │ │ ├── EditGuesser.spec.tsx │ │ │ ├── EditGuesser.tsx │ │ │ ├── EditView.tsx │ │ │ ├── Show.spec.tsx │ │ │ ├── Show.stories.tsx │ │ │ ├── Show.tsx │ │ │ ├── ShowActions.tsx │ │ │ ├── ShowGuesser.spec.tsx │ │ │ ├── ShowGuesser.tsx │ │ │ ├── ShowView.tsx │ │ │ ├── SimpleShowLayout.spec.tsx │ │ │ ├── SimpleShowLayout.stories.tsx │ │ │ ├── SimpleShowLayout.tsx │ │ │ ├── Tab.tsx │ │ │ ├── TabbedShowLayout.spec.tsx │ │ │ ├── TabbedShowLayout.stories.tsx │ │ │ ├── TabbedShowLayout.tsx │ │ │ ├── TabbedShowLayoutTabs.tsx │ │ │ ├── editFieldTypes.tsx │ │ │ ├── index.ts │ │ │ └── showFieldTypes.tsx │ │ ├── field │ │ │ ├── ArrayField.spec.tsx │ │ │ ├── ArrayField.tsx │ │ │ ├── BooleanField.spec.tsx │ │ │ ├── BooleanField.tsx │ │ │ ├── ChipField.spec.tsx │ │ │ ├── ChipField.tsx │ │ │ ├── DateField.spec.tsx │ │ │ ├── DateField.tsx │ │ │ ├── EmailField.spec.tsx │ │ │ ├── EmailField.tsx │ │ │ ├── FileField.spec.tsx │ │ │ ├── FileField.tsx │ │ │ ├── FunctionField.spec.tsx │ │ │ ├── FunctionField.tsx │ │ │ ├── ImageField.spec.tsx │ │ │ ├── ImageField.tsx │ │ │ ├── NumberField.spec.tsx │ │ │ ├── NumberField.tsx │ │ │ ├── ReferenceArrayField.spec.tsx │ │ │ ├── ReferenceArrayField.stories.tsx │ │ │ ├── ReferenceArrayField.tsx │ │ │ ├── ReferenceField.spec.tsx │ │ │ ├── ReferenceField.stories.tsx │ │ │ ├── ReferenceField.tsx │ │ │ ├── ReferenceManyCount.spec.tsx │ │ │ ├── ReferenceManyCount.stories.tsx │ │ │ ├── ReferenceManyCount.tsx │ │ │ ├── ReferenceManyField.spec.tsx │ │ │ ├── ReferenceManyField.stories.tsx │ │ │ ├── ReferenceManyField.tsx │ │ │ ├── ReferenceOneField.spec.tsx │ │ │ ├── ReferenceOneField.stories.tsx │ │ │ ├── ReferenceOneField.tsx │ │ │ ├── RichTextField.spec.tsx │ │ │ ├── RichTextField.stories.tsx │ │ │ ├── RichTextField.tsx │ │ │ ├── SelectField.spec.tsx │ │ │ ├── SelectField.tsx │ │ │ ├── TextField.spec.tsx │ │ │ ├── TextField.tsx │ │ │ ├── TranslatableFields.spec.tsx │ │ │ ├── TranslatableFields.tsx │ │ │ ├── TranslatableFieldsTab.tsx │ │ │ ├── TranslatableFieldsTabContent.tsx │ │ │ ├── TranslatableFieldsTabs.tsx │ │ │ ├── UrlField.spec.tsx │ │ │ ├── UrlField.tsx │ │ │ ├── WrapperField.tsx │ │ │ ├── index.ts │ │ │ ├── sanitizeFieldRestProps.ts │ │ │ └── types.ts │ │ ├── form │ │ │ ├── FormTab.spec.tsx │ │ │ ├── FormTab.tsx │ │ │ ├── FormTabHeader.tsx │ │ │ ├── SimpleForm.spec.tsx │ │ │ ├── SimpleForm.stories.tsx │ │ │ ├── SimpleForm.tsx │ │ │ ├── SimpleFormConfigurable.spec.tsx │ │ │ ├── SimpleFormConfigurable.stories.tsx │ │ │ ├── SimpleFormConfigurable.tsx │ │ │ ├── SimpleFormEditor.tsx │ │ │ ├── TabbedForm.spec.tsx │ │ │ ├── TabbedForm.stories.tsx │ │ │ ├── TabbedForm.tsx │ │ │ ├── TabbedFormTabs.tsx │ │ │ ├── TabbedFormView.tsx │ │ │ ├── Toolbar.tsx │ │ │ ├── index.tsx │ │ │ └── useFormRootPath.ts │ │ ├── index.ts │ │ ├── input │ │ │ ├── ArrayInput │ │ │ │ ├── AddItemButton.tsx │ │ │ │ ├── ArrayInput.spec.tsx │ │ │ │ ├── ArrayInput.stories.tsx │ │ │ │ ├── ArrayInput.tsx │ │ │ │ ├── ArrayInputContext.ts │ │ │ │ ├── ClearArrayButton.tsx │ │ │ │ ├── ReOrderButtons.tsx │ │ │ │ ├── RemoveItemButton.tsx │ │ │ │ ├── SimpleFormIterator.spec.tsx │ │ │ │ ├── SimpleFormIterator.stories.tsx │ │ │ │ ├── SimpleFormIterator.tsx │ │ │ │ ├── SimpleFormIteratorContext.ts │ │ │ │ ├── SimpleFormIteratorItem.tsx │ │ │ │ ├── SimpleFormIteratorItemContext.ts │ │ │ │ ├── index.ts │ │ │ │ ├── useArrayInput.ts │ │ │ │ ├── useSimpleFormIterator.ts │ │ │ │ ├── useSimpleFormIteratorItem.ts │ │ │ │ └── useSimpleFormIteratorStyles.ts │ │ │ ├── AutocompleteArrayInput.spec.tsx │ │ │ ├── AutocompleteArrayInput.stories.tsx │ │ │ ├── AutocompleteArrayInput.tsx │ │ │ ├── AutocompleteInput.spec.tsx │ │ │ ├── AutocompleteInput.stories.tsx │ │ │ ├── AutocompleteInput.tsx │ │ │ ├── BooleanInput.spec.tsx │ │ │ ├── BooleanInput.stories.tsx │ │ │ ├── BooleanInput.tsx │ │ │ ├── CheckboxGroupInput.spec.tsx │ │ │ ├── CheckboxGroupInput.stories.tsx │ │ │ ├── CheckboxGroupInput.tsx │ │ │ ├── CheckboxGroupInputItem.tsx │ │ │ ├── CommonInputProps.ts │ │ │ ├── DatagridInput.stories.tsx │ │ │ ├── DatagridInput.tsx │ │ │ ├── DateInput.spec.tsx │ │ │ ├── DateInput.stories.tsx │ │ │ ├── DateInput.tsx │ │ │ ├── DateTimInput.stories.tsx │ │ │ ├── DateTimeInput.spec.tsx │ │ │ ├── DateTimeInput.stories.tsx │ │ │ ├── DateTimeInput.tsx │ │ │ ├── FileInput.spec.tsx │ │ │ ├── FileInput.stories.tsx │ │ │ ├── FileInput.tsx │ │ │ ├── FileInputPreview.spec.tsx │ │ │ ├── FileInputPreview.tsx │ │ │ ├── ImageInput.spec.tsx │ │ │ ├── ImageInput.stories.tsx │ │ │ ├── ImageInput.tsx │ │ │ ├── ImageInputPreview.ts │ │ │ ├── InputHelperText.spec.tsx │ │ │ ├── InputHelperText.tsx │ │ │ ├── InputPropTypes.ts │ │ │ ├── LoadingInput.tsx │ │ │ ├── NullableBooleanInput.spec.tsx │ │ │ ├── NullableBooleanInput.stories.tsx │ │ │ ├── NullableBooleanInput.tsx │ │ │ ├── NumberInput.spec.tsx │ │ │ ├── NumberInput.stories.tsx │ │ │ ├── NumberInput.tsx │ │ │ ├── PasswordInput.tsx │ │ │ ├── RadioButtonGroupInput.spec.tsx │ │ │ ├── RadioButtonGroupInput.stories.tsx │ │ │ ├── RadioButtonGroupInput.tsx │ │ │ ├── RadioButtonGroupInputItem.tsx │ │ │ ├── ReferenceArrayInput.spec.tsx │ │ │ ├── ReferenceArrayInput.stories.tsx │ │ │ ├── ReferenceArrayInput.tsx │ │ │ ├── ReferenceError.tsx │ │ │ ├── ReferenceInput.spec.tsx │ │ │ ├── ReferenceInput.stories.tsx │ │ │ ├── ReferenceInput.tsx │ │ │ ├── ResettableTextField.tsx │ │ │ ├── SearchInput.spec.tsx │ │ │ ├── SearchInput.tsx │ │ │ ├── SelectArrayInput.spec.tsx │ │ │ ├── SelectArrayInput.stories.tsx │ │ │ ├── SelectArrayInput.tsx │ │ │ ├── SelectInput.spec.tsx │ │ │ ├── SelectInput.stories.tsx │ │ │ ├── SelectInput.tsx │ │ │ ├── TextInput.spec.tsx │ │ │ ├── TextInput.stories.tsx │ │ │ ├── TextInput.tsx │ │ │ ├── TimeInput.spec.tsx │ │ │ ├── TimeInput.stories.tsx │ │ │ ├── TimeInput.tsx │ │ │ ├── TranslatableInputs.spec.tsx │ │ │ ├── TranslatableInputs.tsx │ │ │ ├── TranslatableInputsTab.tsx │ │ │ ├── TranslatableInputsTabContent.tsx │ │ │ ├── TranslatableInputsTabs.tsx │ │ │ ├── common.stories.tsx │ │ │ ├── index.ts │ │ │ ├── sanitizeInputRestProps.ts │ │ │ └── useSupportCreateSuggestion.tsx │ │ ├── layout │ │ │ ├── AppBar.tsx │ │ │ ├── CardContentInner.tsx │ │ │ ├── Confirm.tsx │ │ │ ├── DashboardMenuItem.tsx │ │ │ ├── DeviceTestWrapper.tsx │ │ │ ├── Error.tsx │ │ │ ├── HideOnScroll.tsx │ │ │ ├── Layout.tsx │ │ │ ├── LinearProgress.tsx │ │ │ ├── Loading.tsx │ │ │ ├── LoadingIndicator.tsx │ │ │ ├── LoadingPage.tsx │ │ │ ├── Menu.stories.tsx │ │ │ ├── Menu.tsx │ │ │ ├── MenuItemLink.tsx │ │ │ ├── NotFound.tsx │ │ │ ├── Notification.stories.tsx │ │ │ ├── Notification.tsx │ │ │ ├── PageTitle.tsx │ │ │ ├── PageTitleConfigurable.tsx │ │ │ ├── ResourceMenuItem.spec.tsx │ │ │ ├── ResourceMenuItem.tsx │ │ │ ├── Sidebar.tsx │ │ │ ├── SidebarToggleButton.tsx │ │ │ ├── Theme │ │ │ │ ├── ThemeProvider.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── useTheme.spec.tsx │ │ │ │ └── useTheme.ts │ │ │ ├── Title.tsx │ │ │ ├── TopToolbar.tsx │ │ │ ├── UserMenu.tsx │ │ │ ├── UserMenuContext.ts │ │ │ ├── UserMenuContextProvider.tsx │ │ │ ├── index.ts │ │ │ ├── useResetErrorBoundaryOnLocationChange.ts │ │ │ ├── useSidebarState.ts │ │ │ └── useUserMenu.ts │ │ ├── list │ │ │ ├── BulkActionsToolbar.tsx │ │ │ ├── Count.spec.tsx │ │ │ ├── Count.stories.tsx │ │ │ ├── Count.tsx │ │ │ ├── Empty.tsx │ │ │ ├── FilterContext.tsx │ │ │ ├── List.spec.tsx │ │ │ ├── List.stories.tsx │ │ │ ├── List.tsx │ │ │ ├── ListActions.tsx │ │ │ ├── ListGuesser.spec.tsx │ │ │ ├── ListGuesser.stories.tsx │ │ │ ├── ListGuesser.tsx │ │ │ ├── ListNoResults.tsx │ │ │ ├── ListToolbar.tsx │ │ │ ├── ListView.tsx │ │ │ ├── Placeholder.tsx │ │ │ ├── SimpleList.spec.tsx │ │ │ ├── SimpleList.tsx │ │ │ ├── SimpleList │ │ │ │ ├── SimpleList.spec.tsx │ │ │ │ ├── SimpleList.stories.tsx │ │ │ │ ├── SimpleList.tsx │ │ │ │ ├── SimpleListConfigurable.stories.tsx │ │ │ │ ├── SimpleListConfigurable.tsx │ │ │ │ ├── SimpleListEditor.tsx │ │ │ │ ├── SimpleListLoading.tsx │ │ │ │ └── index.ts │ │ │ ├── SimpleListLoading.tsx │ │ │ ├── SingleFieldList.spec.tsx │ │ │ ├── SingleFieldList.tsx │ │ │ ├── datagrid │ │ │ │ ├── Datagrid.spec.tsx │ │ │ │ ├── Datagrid.stories.tsx │ │ │ │ ├── Datagrid.tsx │ │ │ │ ├── DatagridBody.tsx │ │ │ │ ├── DatagridCell.spec.tsx │ │ │ │ ├── DatagridCell.tsx │ │ │ │ ├── DatagridConfigurable.spec.tsx │ │ │ │ ├── DatagridConfigurable.stories.tsx │ │ │ │ ├── DatagridConfigurable.tsx │ │ │ │ ├── DatagridContext.ts │ │ │ │ ├── DatagridContextProvider.tsx │ │ │ │ ├── DatagridEditor.tsx │ │ │ │ ├── DatagridHeader.tsx │ │ │ │ ├── DatagridHeaderCell.spec.tsx │ │ │ │ ├── DatagridHeaderCell.tsx │ │ │ │ ├── DatagridLoading.tsx │ │ │ │ ├── DatagridRow.spec.tsx │ │ │ │ ├── DatagridRow.tsx │ │ │ │ ├── ExpandAllButton.spec.tsx │ │ │ │ ├── ExpandAllButton.tsx │ │ │ │ ├── ExpandRowButton.tsx │ │ │ │ ├── SelectColumnsButton.spec.tsx │ │ │ │ ├── SelectColumnsButton.stories.tsx │ │ │ │ ├── SelectColumnsButton.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── useDatagridContext.ts │ │ │ │ └── useDatagridStyles.tsx │ │ │ ├── filter │ │ │ │ ├── AddSavedQueryDialog.tsx │ │ │ │ ├── AddSavedQueryIconButton.tsx │ │ │ │ ├── Filter.spec.tsx │ │ │ │ ├── Filter.tsx │ │ │ │ ├── FilterButton.spec.tsx │ │ │ │ ├── FilterButton.stories.tsx │ │ │ │ ├── FilterButton.tsx │ │ │ │ ├── FilterButtonMenuItem.tsx │ │ │ │ ├── FilterForm.spec.tsx │ │ │ │ ├── FilterForm.tsx │ │ │ │ ├── FilterFormInput.tsx │ │ │ │ ├── FilterList.stories.tsx │ │ │ │ ├── FilterList.tsx │ │ │ │ ├── FilterListItem.spec.tsx │ │ │ │ ├── FilterListItem.tsx │ │ │ │ ├── FilterLiveSearch.tsx │ │ │ │ ├── RemoveSavedQueryDialog.tsx │ │ │ │ ├── RemoveSavedQueryIconButton.tsx │ │ │ │ ├── SavedQueriesList.stories.tsx │ │ │ │ ├── SavedQueriesList.tsx │ │ │ │ ├── SavedQueryFilterListItem.tsx │ │ │ │ ├── index.ts │ │ │ │ └── useSavedQueries.ts │ │ │ ├── index.ts │ │ │ ├── listFieldTypes.tsx │ │ │ └── pagination │ │ │ │ ├── Pagination.spec.tsx │ │ │ │ ├── Pagination.tsx │ │ │ │ ├── PaginationActions.spec.tsx │ │ │ │ ├── PaginationActions.tsx │ │ │ │ ├── PaginationLimit.tsx │ │ │ │ └── index.ts │ │ ├── preferences │ │ │ ├── Configurable.spec.tsx │ │ │ ├── Configurable.stories.tsx │ │ │ ├── Configurable.tsx │ │ │ ├── FieldToggle.tsx │ │ │ ├── FieldsSelector.tsx │ │ │ ├── Inspector.spec.tsx │ │ │ ├── Inspector.stories.tsx │ │ │ ├── Inspector.tsx │ │ │ ├── InspectorButton.tsx │ │ │ ├── InspectorRoot.tsx │ │ │ └── index.ts │ │ └── types.ts │ └── tsconfig.json └── react-admin │ ├── README.md │ ├── package.json │ ├── src │ ├── Admin.spec.tsx │ ├── Admin.stories.tsx │ ├── Admin.tsx │ ├── Resource.stories.tsx │ ├── defaultI18nProvider.spec.ts │ ├── defaultI18nProvider.ts │ └── index.ts │ └── tsconfig.json ├── scripts └── vercel-storybook.sh ├── test-global-setup.js ├── test-setup.js ├── tsconfig.json ├── vercel.json └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | lib 4 | esm 5 | prism.js 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F4AC Support Question" 3 | about: If you have a "How to" question, please check out StackOverflow or Discord! 4 | 5 | --- 6 | 7 | We primarily use GitHub as an issue tracker; for usage and support questions, please use StackOverflow(https://stackoverflow.com/questions/tagged/react-admin using the tag `react-admin`) or the react-admin Discord Server(https://discord.gg/GeZF9sqh3N). Thanks! 😁. 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | yarn-error.log 3 | lerna-debug.log 4 | node_modules 5 | lib 6 | esm 7 | es6 8 | dist 9 | docs/_site/ 10 | docs/.jekyll-metadata 11 | docs/.jekyll-cache 12 | packages/react-admin/docs 13 | examples/**/static 14 | examples/**/dist 15 | cypress/videos 16 | cypress/screenshots 17 | /public 18 | /storybook-static 19 | .pnp.* 20 | .yarn/* 21 | !.yarn/patches 22 | !.yarn/plugins 23 | !.yarn/releases 24 | !.yarn/sdks 25 | !.yarn/versions 26 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | tasks: 2 | - init: make install 3 | command: make run 4 | ports: 5 | - port: 8080 6 | onOpen: open-preview 7 | -------------------------------------------------------------------------------- /.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{js,jsx,ts,tsx}": [ 3 | "eslint --fix", 4 | "git add", 5 | ], 6 | "*.{json,css,md}": [ 7 | "prettier", 8 | "git add" 9 | ] 10 | } -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | *.md 2 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSpacing: true, 4 | jsxBracketSameLine: false, 5 | jsxSingleQuote: false, 6 | printWidth: 80, 7 | quoteProps: 'as-needed', 8 | rangeStart: 0, 9 | rangeEnd: Infinity, 10 | semi: true, 11 | singleQuote: true, 12 | tabWidth: 4, 13 | trailingComma: 'es5', 14 | useTabs: false 15 | } 16 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: 0 2 | 3 | enableGlobalCache: true 4 | 5 | nodeLinker: node-modules 6 | 7 | plugins: 8 | - path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs 9 | spec: "@yarnpkg/plugin-interactive-tools" 10 | 11 | yarnPath: .yarn/releases/yarn-3.1.1.cjs 12 | -------------------------------------------------------------------------------- /UPGRADE.md: -------------------------------------------------------------------------------- 1 | See the upgrade guide in the react-admin v4 documentation: https://marmelab.com/react-admin/doc/4.0/Readme.html -------------------------------------------------------------------------------- /__mocks__/@popperjs/core.ts: -------------------------------------------------------------------------------- 1 | const mock = () => { 2 | const PopperJS = jest.requireActual('@popperjs/core'); 3 | return { 4 | placements: PopperJS.placements, 5 | destroy: () => {}, 6 | scheduleUpdate: () => {}, 7 | forceUpdate: () => {}, 8 | render: function (this: any) { 9 | return this.$options._renderChildren; 10 | }, 11 | }; 12 | }; 13 | 14 | export default mock; 15 | export { mock as createPopper }; 16 | -------------------------------------------------------------------------------- /cypress/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.eslintrc", 3 | "plugins": ["cypress"], 4 | "env": { 5 | "cypress/globals": true 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /cypress/cypress.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseUrl": "http://localhost:8080", 3 | "fixturesFolder": "fixtures", 4 | "integrationFolder": "integration", 5 | "pluginsFile": "plugins/index.js", 6 | "screenshotsFolder": "screenshots", 7 | "supportFile": "support/index.js", 8 | "videosFolder": "videos", 9 | "viewportWidth": 1280, 10 | "viewportHeight": 720, 11 | "blockHosts": ["source.unsplash.com"] 12 | } 13 | -------------------------------------------------------------------------------- /cypress/e2e/show.cy.js: -------------------------------------------------------------------------------- 1 | import showPageFactory from '../support/ShowPage'; 2 | 3 | describe('Show Page', () => { 4 | const ShowPage = showPageFactory('/#/posts/10/show'); 5 | 6 | it('should fill the page with data from the fetched record', () => { 7 | ShowPage.navigate(); 8 | cy.contains('Totam vel quasi a odio et nihil'); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /cypress/integration/show.js: -------------------------------------------------------------------------------- 1 | import showPageFactory from '../support/ShowPage'; 2 | 3 | describe('Show Page', () => { 4 | const ShowPage = showPageFactory('/#/posts/10/show'); 5 | 6 | it('should fill the page with data from the fetched record', () => { 7 | ShowPage.navigate(); 8 | cy.contains('Totam vel quasi a odio et nihil'); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /cypress/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "e2e", 4 | "version": "0.1.0", 5 | "scripts": { 6 | "start": "cypress open", 7 | "test": "yarn node ./start.js" 8 | }, 9 | "devDependencies": { 10 | "@cypress/webpack-preprocessor": "^5.10.0", 11 | "cypress": "^10.9.0", 12 | "cypress-plugin-tab": "^1.0.5", 13 | "express": "~4.17.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cypress/support/CustomPage.js: -------------------------------------------------------------------------------- 1 | export default url => ({ 2 | elements: { 3 | appLoader: '.app-loader', 4 | total: '.total', 5 | layout: '.layout', 6 | }, 7 | 8 | navigate() { 9 | cy.visit(url); 10 | }, 11 | 12 | getTotal() { 13 | return cy.get(this.elements.total); 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /cypress/support/LoginPage.js: -------------------------------------------------------------------------------- 1 | export default url => ({ 2 | elements: { 3 | username: "input[name='username']", 4 | password: "input[name='password']", 5 | submitButton: 'button', 6 | }, 7 | 8 | navigate() { 9 | cy.visit(url); 10 | this.waitUntilVisible(); 11 | }, 12 | 13 | waitUntilVisible() { 14 | cy.get(this.elements.username); 15 | }, 16 | 17 | login(username = 'login', password = 'password') { 18 | cy.get(this.elements.username).type(username); 19 | cy.get(this.elements.password).type(password); 20 | cy.get(this.elements.submitButton).click(); 21 | }, 22 | }); 23 | -------------------------------------------------------------------------------- /cypress/support/index.js: -------------------------------------------------------------------------------- 1 | require('cypress-plugin-tab'); 2 | -------------------------------------------------------------------------------- /cypress/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "rootDir": "e2e" 5 | }, 6 | "types": ["cypress", "node"] 7 | } 8 | -------------------------------------------------------------------------------- /cypress/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | resolve: { 3 | extensions: ['.js'], 4 | }, 5 | module: { 6 | rules: [ 7 | { 8 | test: /\.js$/, 9 | exclude: [/node_modules/], 10 | }, 11 | ], 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /docs/EmailField.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "The EmailField Component" 4 | --- 5 | 6 | # `` 7 | 8 | `` displays an email as a MUI's `` component. 9 | 10 | ```jsx 11 | import { EmailField } from 'react-admin'; 12 | 13 | 14 | ``` 15 | -------------------------------------------------------------------------------- /docs/UrlField.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "The UrlField Component" 4 | --- 5 | 6 | # `` 7 | 8 | 9 | `` displays a url in a MUI's `` component. 10 | 11 | ```jsx 12 | import { UrlField } from 'react-admin'; 13 | 14 | 15 | ``` 16 | -------------------------------------------------------------------------------- /docs/assets/logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/assets/logo_white.png -------------------------------------------------------------------------------- /docs/img/ArrayInput-global-validation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/ArrayInput-global-validation.png -------------------------------------------------------------------------------- /docs/img/CRUD.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/CRUD.webm -------------------------------------------------------------------------------- /docs/img/CheckboxGroupInput-labelPlacement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/CheckboxGroupInput-labelPlacement.png -------------------------------------------------------------------------------- /docs/img/CheckboxGroupInput-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/CheckboxGroupInput-options.png -------------------------------------------------------------------------------- /docs/img/CheckboxGroupInput-row.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/CheckboxGroupInput-row.png -------------------------------------------------------------------------------- /docs/img/CollaborativeDemo.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/CollaborativeDemo.mp4 -------------------------------------------------------------------------------- /docs/img/DatagridConfigurable.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/DatagridConfigurable.gif -------------------------------------------------------------------------------- /docs/img/EditLive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/EditLive.png -------------------------------------------------------------------------------- /docs/img/FormTab-dynamic-label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/FormTab-dynamic-label.png -------------------------------------------------------------------------------- /docs/img/ListLive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/ListLive.png -------------------------------------------------------------------------------- /docs/img/LocalesMenuButton.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/LocalesMenuButton.gif -------------------------------------------------------------------------------- /docs/img/MenuLive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/MenuLive.png -------------------------------------------------------------------------------- /docs/img/RealtimeMenu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/RealtimeMenu.png -------------------------------------------------------------------------------- /docs/img/SaveButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/SaveButton.png -------------------------------------------------------------------------------- /docs/img/SavedQueriesList.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/SavedQueriesList.gif -------------------------------------------------------------------------------- /docs/img/SelectColumnsButton.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/SelectColumnsButton.gif -------------------------------------------------------------------------------- /docs/img/ShowLive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/ShowLive.png -------------------------------------------------------------------------------- /docs/img/SimpleFormConfigurable.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/SimpleFormConfigurable.gif -------------------------------------------------------------------------------- /docs/img/SimpleListConfigurable.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/SimpleListConfigurable.gif -------------------------------------------------------------------------------- /docs/img/TabbedForm-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/TabbedForm-layout.png -------------------------------------------------------------------------------- /docs/img/ToggleThemeButton.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/ToggleThemeButton.gif -------------------------------------------------------------------------------- /docs/img/Toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/Toolbar.png -------------------------------------------------------------------------------- /docs/img/accessibility.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/accessibility.webp -------------------------------------------------------------------------------- /docs/img/actions-toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/actions-toolbar.png -------------------------------------------------------------------------------- /docs/img/array-input-block.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/array-input-block.png -------------------------------------------------------------------------------- /docs/img/array-input-item-label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/array-input-item-label.png -------------------------------------------------------------------------------- /docs/img/array-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/array-input.gif -------------------------------------------------------------------------------- /docs/img/aside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/aside.png -------------------------------------------------------------------------------- /docs/img/autocomplete-array-input-create.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/autocomplete-array-input-create.gif -------------------------------------------------------------------------------- /docs/img/autocomplete-array-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/autocomplete-array-input.gif -------------------------------------------------------------------------------- /docs/img/autocomplete-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/autocomplete-input.gif -------------------------------------------------------------------------------- /docs/img/blog_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/blog_demo.png -------------------------------------------------------------------------------- /docs/img/boolean-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/boolean-field.png -------------------------------------------------------------------------------- /docs/img/boolean-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/boolean-input.gif -------------------------------------------------------------------------------- /docs/img/boolean-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/boolean-input.png -------------------------------------------------------------------------------- /docs/img/bulk-actions-toolbar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/bulk-actions-toolbar.gif -------------------------------------------------------------------------------- /docs/img/bulk-delete-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/bulk-delete-button.png -------------------------------------------------------------------------------- /docs/img/bulk-export-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/bulk-export-button.png -------------------------------------------------------------------------------- /docs/img/checkbox-group-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/checkbox-group-input.gif -------------------------------------------------------------------------------- /docs/img/checkbox-group-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/checkbox-group-input.png -------------------------------------------------------------------------------- /docs/img/chip-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/chip-field.png -------------------------------------------------------------------------------- /docs/img/confirm-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/confirm-dialog.png -------------------------------------------------------------------------------- /docs/img/count.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/count.webp -------------------------------------------------------------------------------- /docs/img/create-button-fab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/create-button-fab.png -------------------------------------------------------------------------------- /docs/img/create-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/create-button.png -------------------------------------------------------------------------------- /docs/img/create-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/create-view.png -------------------------------------------------------------------------------- /docs/img/custom-form-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/custom-form-layout.png -------------------------------------------------------------------------------- /docs/img/custom-iterator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/custom-iterator.png -------------------------------------------------------------------------------- /docs/img/custom-menu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/custom-menu.gif -------------------------------------------------------------------------------- /docs/img/custom-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/custom-menu.png -------------------------------------------------------------------------------- /docs/img/custom-switch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/custom-switch-icon.png -------------------------------------------------------------------------------- /docs/img/custom_appbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/custom_appbar.png -------------------------------------------------------------------------------- /docs/img/dark-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/dark-theme.png -------------------------------------------------------------------------------- /docs/img/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/dashboard.png -------------------------------------------------------------------------------- /docs/img/data-provider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/data-provider.png -------------------------------------------------------------------------------- /docs/img/datagrid_expand.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/datagrid_expand.gif -------------------------------------------------------------------------------- /docs/img/date-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/date-input.gif -------------------------------------------------------------------------------- /docs/img/date-picker.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/date-picker.gif -------------------------------------------------------------------------------- /docs/img/date-time-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/date-time-input.gif -------------------------------------------------------------------------------- /docs/img/dense.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/dense.webp -------------------------------------------------------------------------------- /docs/img/disabled-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/disabled-input.png -------------------------------------------------------------------------------- /docs/img/edit-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/edit-button.png -------------------------------------------------------------------------------- /docs/img/edit-from-react-to-react-admin.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/edit-from-react-to-react-admin.webp -------------------------------------------------------------------------------- /docs/img/edit-view-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/edit-view-example.png -------------------------------------------------------------------------------- /docs/img/edit-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/edit-view.png -------------------------------------------------------------------------------- /docs/img/editable-post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/editable-post.png -------------------------------------------------------------------------------- /docs/img/error.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/error.webp -------------------------------------------------------------------------------- /docs/img/export-button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/export-button.gif -------------------------------------------------------------------------------- /docs/img/export-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/export-button.png -------------------------------------------------------------------------------- /docs/img/field-addlabel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/field-addlabel.png -------------------------------------------------------------------------------- /docs/img/file-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/file-input.png -------------------------------------------------------------------------------- /docs/img/filter-live-search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/filter-live-search.gif -------------------------------------------------------------------------------- /docs/img/filter-sidebar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/filter-sidebar.gif -------------------------------------------------------------------------------- /docs/img/filter_with_submit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/filter_with_submit.gif -------------------------------------------------------------------------------- /docs/img/filters.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/filters.gif -------------------------------------------------------------------------------- /docs/img/form-toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/form-toolbar.png -------------------------------------------------------------------------------- /docs/img/guessed-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/guessed-edit.png -------------------------------------------------------------------------------- /docs/img/guessed-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/guessed-list.png -------------------------------------------------------------------------------- /docs/img/guessed-show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/guessed-show.png -------------------------------------------------------------------------------- /docs/img/identity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/identity.png -------------------------------------------------------------------------------- /docs/img/image-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/image-input.png -------------------------------------------------------------------------------- /docs/img/input-full-width.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/input-full-width.png -------------------------------------------------------------------------------- /docs/img/input-helper-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/input-helper-text.png -------------------------------------------------------------------------------- /docs/img/inputs.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/inputs.webp -------------------------------------------------------------------------------- /docs/img/layout-component.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/layout-component.gif -------------------------------------------------------------------------------- /docs/img/layout-responsive.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/layout-responsive.gif -------------------------------------------------------------------------------- /docs/img/list-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/list-button.png -------------------------------------------------------------------------------- /docs/img/list-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/list-empty.png -------------------------------------------------------------------------------- /docs/img/list-from-react-to-react-admin.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/list-from-react-to-react-admin.webp -------------------------------------------------------------------------------- /docs/img/list-view.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/list-view.jpg -------------------------------------------------------------------------------- /docs/img/list_filter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/list_filter.gif -------------------------------------------------------------------------------- /docs/img/list_with_customized_css.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/list_with_customized_css.png -------------------------------------------------------------------------------- /docs/img/locks-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/locks-demo.gif -------------------------------------------------------------------------------- /docs/img/login-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/login-form.png -------------------------------------------------------------------------------- /docs/img/login.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/login.gif -------------------------------------------------------------------------------- /docs/img/logout.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/logout.gif -------------------------------------------------------------------------------- /docs/img/long-text-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/long-text-input.png -------------------------------------------------------------------------------- /docs/img/markdown-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/markdown-input.gif -------------------------------------------------------------------------------- /docs/img/menu-with-dashboard.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/menu-with-dashboard.webp -------------------------------------------------------------------------------- /docs/img/menu.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/menu.webp -------------------------------------------------------------------------------- /docs/img/mobile-post-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/mobile-post-list.png -------------------------------------------------------------------------------- /docs/img/navidrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/navidrome.png -------------------------------------------------------------------------------- /docs/img/nextjs-file-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/nextjs-file-structure.png -------------------------------------------------------------------------------- /docs/img/nextjs-react-admin.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/nextjs-react-admin.webp -------------------------------------------------------------------------------- /docs/img/nextjs-setup.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/nextjs-setup.webp -------------------------------------------------------------------------------- /docs/img/not-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/not-found.png -------------------------------------------------------------------------------- /docs/img/notification.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/notification.webp -------------------------------------------------------------------------------- /docs/img/nullable-boolean-input-null-label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/nullable-boolean-input-null-label.png -------------------------------------------------------------------------------- /docs/img/nullable-boolean-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/nullable-boolean-input.gif -------------------------------------------------------------------------------- /docs/img/number-field.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/number-field.webp -------------------------------------------------------------------------------- /docs/img/number-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/number-input.gif -------------------------------------------------------------------------------- /docs/img/openid-connect-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/openid-connect-example.png -------------------------------------------------------------------------------- /docs/img/pagination-buttons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/pagination-buttons.gif -------------------------------------------------------------------------------- /docs/img/password-input-visible.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/password-input-visible.png -------------------------------------------------------------------------------- /docs/img/password-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/password-input.png -------------------------------------------------------------------------------- /docs/img/post-deletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/post-deletion.png -------------------------------------------------------------------------------- /docs/img/post-edition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/post-edition.png -------------------------------------------------------------------------------- /docs/img/post-show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/post-show.png -------------------------------------------------------------------------------- /docs/img/quick_filters.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/quick_filters.gif -------------------------------------------------------------------------------- /docs/img/ra-longform-cardinality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/ra-longform-cardinality.png -------------------------------------------------------------------------------- /docs/img/ra-longform-overview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/ra-longform-overview.gif -------------------------------------------------------------------------------- /docs/img/ra-rbac.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/ra-rbac.mp4 -------------------------------------------------------------------------------- /docs/img/ra-tree.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/ra-tree.gif -------------------------------------------------------------------------------- /docs/img/radio-button-group-input-row.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/radio-button-group-input-row.gif -------------------------------------------------------------------------------- /docs/img/radio-button-group-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/radio-button-group-input.gif -------------------------------------------------------------------------------- /docs/img/react-admin-demo-still.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/react-admin-demo-still.png -------------------------------------------------------------------------------- /docs/img/react-query-devtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/react-query-devtools.png -------------------------------------------------------------------------------- /docs/img/reference-array-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-array-field.png -------------------------------------------------------------------------------- /docs/img/reference-array-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-array-input.gif -------------------------------------------------------------------------------- /docs/img/reference-field-link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-field-link.png -------------------------------------------------------------------------------- /docs/img/reference-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-field.png -------------------------------------------------------------------------------- /docs/img/reference-input-filter.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-input-filter.webm -------------------------------------------------------------------------------- /docs/img/reference-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-input.gif -------------------------------------------------------------------------------- /docs/img/reference-many-field-datagrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-many-field-datagrid.png -------------------------------------------------------------------------------- /docs/img/reference-many-field-single-field-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-many-field-single-field-list.png -------------------------------------------------------------------------------- /docs/img/reference-many-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-many-input.gif -------------------------------------------------------------------------------- /docs/img/reference-one-field-many.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-one-field-many.png -------------------------------------------------------------------------------- /docs/img/reference-one-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-one-field.png -------------------------------------------------------------------------------- /docs/img/reference-posts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference-posts.png -------------------------------------------------------------------------------- /docs/img/reference_field_show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference_field_show.png -------------------------------------------------------------------------------- /docs/img/reference_many_count.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference_many_count.webp -------------------------------------------------------------------------------- /docs/img/reference_many_field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/reference_many_field.png -------------------------------------------------------------------------------- /docs/img/remix-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/remix-structure.png -------------------------------------------------------------------------------- /docs/img/resettable-long-text-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/resettable-long-text-input.png -------------------------------------------------------------------------------- /docs/img/resettable-select-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/resettable-select-input.png -------------------------------------------------------------------------------- /docs/img/resettable-text-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/resettable-text-input.gif -------------------------------------------------------------------------------- /docs/img/responsive-list.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/responsive-list.gif -------------------------------------------------------------------------------- /docs/img/responsive.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/responsive.webm -------------------------------------------------------------------------------- /docs/img/rich-text-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/rich-text-field.png -------------------------------------------------------------------------------- /docs/img/rich-text-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/rich-text-input.gif -------------------------------------------------------------------------------- /docs/img/search_input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/search_input.gif -------------------------------------------------------------------------------- /docs/img/select-array-input-create.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/select-array-input-create.gif -------------------------------------------------------------------------------- /docs/img/select-array-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/select-array-input.gif -------------------------------------------------------------------------------- /docs/img/select-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/select-input.gif -------------------------------------------------------------------------------- /docs/img/show-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/show-button.png -------------------------------------------------------------------------------- /docs/img/show-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/show-view.png -------------------------------------------------------------------------------- /docs/img/simple-form-iterator-fullWidth-false.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/simple-form-iterator-fullWidth-false.png -------------------------------------------------------------------------------- /docs/img/simple-form-iterator-fullWidth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/simple-form-iterator-fullWidth.png -------------------------------------------------------------------------------- /docs/img/simple-form-iterator-inline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/simple-form-iterator-inline.png -------------------------------------------------------------------------------- /docs/img/simple-form-iterator-not-inline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/simple-form-iterator-not-inline.png -------------------------------------------------------------------------------- /docs/img/simple-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/simple-form.png -------------------------------------------------------------------------------- /docs/img/simple-list.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/simple-list.gif -------------------------------------------------------------------------------- /docs/img/simple-post-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/simple-post-list.png -------------------------------------------------------------------------------- /docs/img/simple-user-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/simple-user-list.png -------------------------------------------------------------------------------- /docs/img/simpleform-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/simpleform-layout.png -------------------------------------------------------------------------------- /docs/img/singlefieldlist-datagrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/singlefieldlist-datagrid.png -------------------------------------------------------------------------------- /docs/img/singlefieldlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/singlefieldlist.png -------------------------------------------------------------------------------- /docs/img/sort-button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/sort-button.gif -------------------------------------------------------------------------------- /docs/img/sort-column-header.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/sort-column-header.gif -------------------------------------------------------------------------------- /docs/img/sx-class-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/sx-class-name.png -------------------------------------------------------------------------------- /docs/img/sx-documentation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/sx-documentation.png -------------------------------------------------------------------------------- /docs/img/tabbed-form.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tabbed-form.gif -------------------------------------------------------------------------------- /docs/img/tabbed-show.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tabbed-show.gif -------------------------------------------------------------------------------- /docs/img/text-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/text-input.gif -------------------------------------------------------------------------------- /docs/img/time-input-edge.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/time-input-edge.gif -------------------------------------------------------------------------------- /docs/img/time-input-firefox.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/time-input-firefox.gif -------------------------------------------------------------------------------- /docs/img/translatable-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/translatable-input.gif -------------------------------------------------------------------------------- /docs/img/translation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/translation.gif -------------------------------------------------------------------------------- /docs/img/treewithdetails.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/treewithdetails.gif -------------------------------------------------------------------------------- /docs/img/tutorial_custom_styles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_custom_styles.png -------------------------------------------------------------------------------- /docs/img/tutorial_edit_guesser.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_edit_guesser.gif -------------------------------------------------------------------------------- /docs/img/tutorial_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_empty.png -------------------------------------------------------------------------------- /docs/img/tutorial_guessed_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_guessed_list.png -------------------------------------------------------------------------------- /docs/img/tutorial_guessed_post_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_guessed_post_list.png -------------------------------------------------------------------------------- /docs/img/tutorial_list_user_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_list_user_name.png -------------------------------------------------------------------------------- /docs/img/tutorial_mobile_post_list.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_mobile_post_list.gif -------------------------------------------------------------------------------- /docs/img/tutorial_mobile_user_list.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_mobile_user_list.gif -------------------------------------------------------------------------------- /docs/img/tutorial_overview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_overview.gif -------------------------------------------------------------------------------- /docs/img/tutorial_post_create.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_post_create.gif -------------------------------------------------------------------------------- /docs/img/tutorial_post_edit_undo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_post_edit_undo.gif -------------------------------------------------------------------------------- /docs/img/tutorial_post_list_less_columns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_post_list_less_columns.png -------------------------------------------------------------------------------- /docs/img/tutorial_post_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_post_title.png -------------------------------------------------------------------------------- /docs/img/tutorial_simple_list.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_simple_list.webp -------------------------------------------------------------------------------- /docs/img/tutorial_url_field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_url_field.png -------------------------------------------------------------------------------- /docs/img/tutorial_user_list_responsive.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_user_list_responsive.gif -------------------------------------------------------------------------------- /docs/img/tutorial_users_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_users_list.png -------------------------------------------------------------------------------- /docs/img/tutorial_users_list_selected_columns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/tutorial_users_list_selected_columns.png -------------------------------------------------------------------------------- /docs/img/typescript.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/typescript.webm -------------------------------------------------------------------------------- /docs/img/use-notify-node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/use-notify-node.png -------------------------------------------------------------------------------- /docs/img/useInfiniteGetList.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useInfiniteGetList.gif -------------------------------------------------------------------------------- /docs/img/useLockOnCall.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useLockOnCall.gif -------------------------------------------------------------------------------- /docs/img/useLockOnMount.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useLockOnMount.gif -------------------------------------------------------------------------------- /docs/img/useSubscribe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useSubscribe.gif -------------------------------------------------------------------------------- /docs/img/useSubscribeCallback.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useSubscribeCallback.gif -------------------------------------------------------------------------------- /docs/img/useSubscribeOnce.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useSubscribeOnce.gif -------------------------------------------------------------------------------- /docs/img/useSubscribeOnceCallback.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useSubscribeOnceCallback.gif -------------------------------------------------------------------------------- /docs/img/useSubscribeToRecord.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useSubscribeToRecord.gif -------------------------------------------------------------------------------- /docs/img/useSubscribeToRecordList.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useSubscribeToRecordList.gif -------------------------------------------------------------------------------- /docs/img/useSubscribeUnsubscribe.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/useSubscribeUnsubscribe.gif -------------------------------------------------------------------------------- /docs/img/warn_when_unsaved_changes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/docs/img/warn_when_unsaved_changes.png -------------------------------------------------------------------------------- /docs/useResetStore.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "useResetStore" 4 | --- 5 | 6 | # `useResetStore` 7 | 8 | This hook allows to empty the [Store](./Store.md). React-admin uses it at logout. 9 | 10 | ## Syntax 11 | 12 | ```jsx 13 | import { useResetStore } from 'react-admin'; 14 | 15 | const reset = useResetStore(); 16 | reset(); 17 | ``` 18 | 19 | ## Example 20 | 21 | ```jsx 22 | import { useResetStore, Button } from 'react-admin'; 23 | 24 | const ResetButton = () => { 25 | const reset = useResetStore(); 26 | return ( 27 | 30 | ); 31 | }; 32 | ``` 33 | -------------------------------------------------------------------------------- /docs/useStoreContext.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "useStoreContext" 4 | --- 5 | 6 | # `useStoreContext` 7 | 8 | This hook allows to access the global [Store](./Store.md). 9 | 10 | It should not be used directly. Prefer the specialized hooks (`useStore`, `useResetStore`, `useRemoveFromStore`) instead. 11 | 12 | ## Syntax 13 | 14 | ```jsx 15 | import { useStoreContext } from 'react-admin'; 16 | 17 | const store = useStoreContext(); 18 | ``` 19 | -------------------------------------------------------------------------------- /docs/useUnselectAll.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "useUnselectAll" 4 | --- 5 | 6 | # `useUnselectAll` 7 | 8 | This hook returns a function that unselects all lines in the current ``. Pass the name of the resource as argument. 9 | 10 | ```jsx 11 | import { useUnselectAll } from 'react-admin'; 12 | 13 | const UnselectAllButton = () => { 14 | const unselectAll = useUnselectAll('posts'); 15 | const handleClick = () => { 16 | unselectAll(); 17 | } 18 | return ; 19 | }; 20 | ``` 21 | 22 | -------------------------------------------------------------------------------- /examples/crm/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true 2 | -------------------------------------------------------------------------------- /examples/crm/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | .eslintcache 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | -------------------------------------------------------------------------------- /examples/crm/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/favicon.ico -------------------------------------------------------------------------------- /examples/crm/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logo192.png -------------------------------------------------------------------------------- /examples/crm/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logo512.png -------------------------------------------------------------------------------- /examples/crm/public/logos/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/0.png -------------------------------------------------------------------------------- /examples/crm/public/logos/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/1.png -------------------------------------------------------------------------------- /examples/crm/public/logos/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/10.png -------------------------------------------------------------------------------- /examples/crm/public/logos/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/11.png -------------------------------------------------------------------------------- /examples/crm/public/logos/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/12.png -------------------------------------------------------------------------------- /examples/crm/public/logos/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/13.png -------------------------------------------------------------------------------- /examples/crm/public/logos/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/14.png -------------------------------------------------------------------------------- /examples/crm/public/logos/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/15.png -------------------------------------------------------------------------------- /examples/crm/public/logos/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/16.png -------------------------------------------------------------------------------- /examples/crm/public/logos/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/17.png -------------------------------------------------------------------------------- /examples/crm/public/logos/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/18.png -------------------------------------------------------------------------------- /examples/crm/public/logos/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/19.png -------------------------------------------------------------------------------- /examples/crm/public/logos/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/2.png -------------------------------------------------------------------------------- /examples/crm/public/logos/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/20.png -------------------------------------------------------------------------------- /examples/crm/public/logos/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/21.png -------------------------------------------------------------------------------- /examples/crm/public/logos/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/22.png -------------------------------------------------------------------------------- /examples/crm/public/logos/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/23.png -------------------------------------------------------------------------------- /examples/crm/public/logos/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/24.png -------------------------------------------------------------------------------- /examples/crm/public/logos/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/25.png -------------------------------------------------------------------------------- /examples/crm/public/logos/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/26.png -------------------------------------------------------------------------------- /examples/crm/public/logos/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/27.png -------------------------------------------------------------------------------- /examples/crm/public/logos/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/28.png -------------------------------------------------------------------------------- /examples/crm/public/logos/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/29.png -------------------------------------------------------------------------------- /examples/crm/public/logos/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/3.png -------------------------------------------------------------------------------- /examples/crm/public/logos/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/30.png -------------------------------------------------------------------------------- /examples/crm/public/logos/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/31.png -------------------------------------------------------------------------------- /examples/crm/public/logos/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/32.png -------------------------------------------------------------------------------- /examples/crm/public/logos/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/33.png -------------------------------------------------------------------------------- /examples/crm/public/logos/34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/34.png -------------------------------------------------------------------------------- /examples/crm/public/logos/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/35.png -------------------------------------------------------------------------------- /examples/crm/public/logos/36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/36.png -------------------------------------------------------------------------------- /examples/crm/public/logos/37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/37.png -------------------------------------------------------------------------------- /examples/crm/public/logos/38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/38.png -------------------------------------------------------------------------------- /examples/crm/public/logos/39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/39.png -------------------------------------------------------------------------------- /examples/crm/public/logos/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/4.png -------------------------------------------------------------------------------- /examples/crm/public/logos/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/40.png -------------------------------------------------------------------------------- /examples/crm/public/logos/41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/41.png -------------------------------------------------------------------------------- /examples/crm/public/logos/42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/42.png -------------------------------------------------------------------------------- /examples/crm/public/logos/43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/43.png -------------------------------------------------------------------------------- /examples/crm/public/logos/44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/44.png -------------------------------------------------------------------------------- /examples/crm/public/logos/45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/45.png -------------------------------------------------------------------------------- /examples/crm/public/logos/46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/46.png -------------------------------------------------------------------------------- /examples/crm/public/logos/47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/47.png -------------------------------------------------------------------------------- /examples/crm/public/logos/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/48.png -------------------------------------------------------------------------------- /examples/crm/public/logos/49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/49.png -------------------------------------------------------------------------------- /examples/crm/public/logos/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/5.png -------------------------------------------------------------------------------- /examples/crm/public/logos/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/50.png -------------------------------------------------------------------------------- /examples/crm/public/logos/51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/51.png -------------------------------------------------------------------------------- /examples/crm/public/logos/52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/52.png -------------------------------------------------------------------------------- /examples/crm/public/logos/53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/53.png -------------------------------------------------------------------------------- /examples/crm/public/logos/54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/54.png -------------------------------------------------------------------------------- /examples/crm/public/logos/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/55.png -------------------------------------------------------------------------------- /examples/crm/public/logos/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/6.png -------------------------------------------------------------------------------- /examples/crm/public/logos/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/7.png -------------------------------------------------------------------------------- /examples/crm/public/logos/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/8.png -------------------------------------------------------------------------------- /examples/crm/public/logos/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/crm/public/logos/9.png -------------------------------------------------------------------------------- /examples/crm/public/logos/Readme.md: -------------------------------------------------------------------------------- 1 | Logos from https://uilogos.co/ -------------------------------------------------------------------------------- /examples/crm/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /examples/crm/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /examples/crm/src/companies/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-anonymous-default-export */ 2 | import { CompanyList } from './CompanyList'; 3 | import { CompanyCreate } from './CompanyCreate'; 4 | import { CompanyShow } from './CompanyShow'; 5 | import { CompanyEdit } from './CompanyEdit'; 6 | 7 | export default { 8 | list: CompanyList, 9 | create: CompanyCreate, 10 | edit: CompanyEdit, 11 | show: CompanyShow, 12 | }; 13 | -------------------------------------------------------------------------------- /examples/crm/src/companies/sectors.ts: -------------------------------------------------------------------------------- 1 | export const sectors = [ 2 | 'Communication Services', 3 | 'Consumer Discretionary', 4 | 'Consumer Staples', 5 | 'Energy', 6 | 'Financials', 7 | 'Health Care', 8 | 'Industrials', 9 | 'Information Technology', 10 | 'Materials', 11 | 'Real Estate', 12 | 'Utilities', 13 | ].map(sector => ({ id: sector, name: sector })); 14 | -------------------------------------------------------------------------------- /examples/crm/src/companies/sizes.ts: -------------------------------------------------------------------------------- 1 | export const sizes = [ 2 | { id: 1, name: '1 employee' }, 3 | { id: 10, name: '2-9 employees' }, 4 | { id: 50, name: '10-49 employees' }, 5 | { id: 250, name: '50-249 employees' }, 6 | { id: 500, name: '250 or more employees' }, 7 | ]; 8 | -------------------------------------------------------------------------------- /examples/crm/src/contacts/Avatar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Avatar as MuiAvatar } from '@mui/material'; 3 | import { useRecordContext } from 'react-admin'; 4 | 5 | import { Contact } from '../types'; 6 | 7 | export const Avatar = (props: { record?: Contact }) => { 8 | const record = useRecordContext(props); 9 | if (!record) return null; 10 | 11 | return ( 12 | 13 | {record.first_name.charAt(0)} 14 | {record.last_name.charAt(0)} 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /examples/crm/src/contacts/index.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-anonymous-default-export */ 2 | import { ContactShow } from './ContactShow'; 3 | import { ContactList } from './ContactList'; 4 | import { ContactEdit } from './ContactEdit'; 5 | import { ContactCreate } from './ContactCreate'; 6 | 7 | export default { 8 | list: ContactList, 9 | show: ContactShow, 10 | edit: ContactEdit, 11 | create: ContactCreate, 12 | }; 13 | -------------------------------------------------------------------------------- /examples/crm/src/dataGenerator/finalize.ts: -------------------------------------------------------------------------------- 1 | import { Db } from './types'; 2 | 3 | export const finalize = (db: Db) => { 4 | // set contact status according to the latest note 5 | db.contactNotes 6 | .sort((a, b) => new Date(a.date).valueOf() - new Date(b.date).valueOf()) 7 | .forEach(note => { 8 | db.contacts[note.contact_id as number].status = note.status; 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /examples/crm/src/dataGenerator/types.ts: -------------------------------------------------------------------------------- 1 | import { RaRecord } from 'react-admin'; 2 | import { Company, Contact, ContactNote, Deal, Tag } from '../types'; 3 | 4 | export interface Db { 5 | companies: Company[]; 6 | contacts: Contact[]; 7 | contactNotes: ContactNote[]; 8 | deals: Deal[]; 9 | dealNotes: RaRecord[]; 10 | sales: RaRecord[]; 11 | tags: Tag[]; 12 | tasks: RaRecord[]; 13 | } 14 | -------------------------------------------------------------------------------- /examples/crm/src/dataProvider.ts: -------------------------------------------------------------------------------- 1 | import fakerestDataProvider from 'ra-data-fakerest'; 2 | 3 | import generateData from './dataGenerator'; 4 | 5 | const baseDataProvider = fakerestDataProvider(generateData(), true); 6 | 7 | export const dataProvider = new Proxy(baseDataProvider, { 8 | get: (target, name: string) => (resource: string, params: any) => 9 | new Promise(resolve => 10 | setTimeout( 11 | () => resolve(baseDataProvider[name](resource, params)), 12 | 300 13 | ) 14 | ), 15 | }); 16 | -------------------------------------------------------------------------------- /examples/crm/src/deals/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/no-anonymous-default-export */ 2 | import { DealList } from './DealList'; 3 | 4 | export default { 5 | list: DealList, 6 | }; 7 | -------------------------------------------------------------------------------- /examples/crm/src/deals/stages.ts: -------------------------------------------------------------------------------- 1 | export const stages = [ 2 | 'opportunity', 3 | 'proposal-sent', 4 | 'in-negociation', 5 | 'won', 6 | 'lost', 7 | 'delayed', 8 | ]; 9 | 10 | export const stageNames = { 11 | opportunity: 'Opportunity', 12 | 'proposal-sent': 'Proposal Sent', 13 | 'in-negociation': 'In Negociation', 14 | won: 'Won', 15 | lost: 'Lost', 16 | delayed: 'Delayed', 17 | }; 18 | 19 | export const stageChoices = stages.map(type => ({ 20 | id: type, 21 | /* @ts-ignore */ 22 | name: stageNames[type], 23 | })); 24 | -------------------------------------------------------------------------------- /examples/crm/src/deals/types.ts: -------------------------------------------------------------------------------- 1 | export const types = [ 2 | 'Other', 3 | 'Copywriting', 4 | 'Print project', 5 | 'UI Design', 6 | 'Website design', 7 | ]; 8 | 9 | export const typeChoices = types.map(type => ({ id: type, name: type })); 10 | -------------------------------------------------------------------------------- /examples/crm/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | import reportWebVitals from './reportWebVitals'; 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById('root') 11 | ); 12 | 13 | // If you want to start measuring performance in your app, pass a function 14 | // to log results (for example: reportWebVitals(console.log)) 15 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 16 | reportWebVitals(); 17 | -------------------------------------------------------------------------------- /examples/crm/src/notes/index.ts: -------------------------------------------------------------------------------- 1 | export * from './NewNote'; 2 | export * from './NotesIterator'; 3 | export * from './StatusSelector'; 4 | -------------------------------------------------------------------------------- /examples/crm/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/crm/src/reportWebVitals.js: -------------------------------------------------------------------------------- 1 | const reportWebVitals = onPerfEntry => { 2 | if (onPerfEntry && onPerfEntry instanceof Function) { 3 | import('web-vitals').then( 4 | ({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 5 | getCLS(onPerfEntry); 6 | getFID(onPerfEntry); 7 | getFCP(onPerfEntry); 8 | getLCP(onPerfEntry); 9 | getTTFB(onPerfEntry); 10 | } 11 | ); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /examples/crm/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /examples/crm/src/tags/colors.ts: -------------------------------------------------------------------------------- 1 | export const colors = [ 2 | '#eddcd2', 3 | '#fff1e6', 4 | '#fde2e4', 5 | '#fad2e1', 6 | '#c5dedd', 7 | '#dbe7e4', 8 | '#f0efeb', 9 | '#d6e2e9', 10 | '#bcd4e6', 11 | '#99c1de', 12 | ]; 13 | -------------------------------------------------------------------------------- /examples/crm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /examples/data-generator/src/categories.ts: -------------------------------------------------------------------------------- 1 | export default () => [ 2 | { id: 0, name: 'animals' }, 3 | { id: 1, name: 'beard' }, 4 | { id: 2, name: 'business' }, 5 | { id: 3, name: 'cars' }, 6 | { id: 4, name: 'city' }, 7 | { id: 5, name: 'flowers' }, 8 | { id: 6, name: 'food' }, 9 | { id: 7, name: 'nature' }, 10 | { id: 8, name: 'people' }, 11 | { id: 9, name: 'sports' }, 12 | { id: 10, name: 'tech' }, 13 | { id: 11, name: 'travel' }, 14 | { id: 12, name: 'water' }, 15 | ]; 16 | -------------------------------------------------------------------------------- /examples/data-generator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "declaration": true, 7 | "declarationMap": true, 8 | }, 9 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 10 | "include": ["src"] 11 | } 12 | -------------------------------------------------------------------------------- /examples/demo/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true 2 | -------------------------------------------------------------------------------- /examples/demo/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | .eslintcache 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | -------------------------------------------------------------------------------- /examples/demo/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/demo/public/favicon.ico -------------------------------------------------------------------------------- /examples/demo/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /examples/demo/src/categories/index.ts: -------------------------------------------------------------------------------- 1 | import CategoryIcon from '@mui/icons-material/Bookmark'; 2 | 3 | import CategoryList from './CategoryList'; 4 | import CategoryEdit from './CategoryEdit'; 5 | 6 | export default { 7 | list: CategoryList, 8 | edit: CategoryEdit, 9 | icon: CategoryIcon, 10 | }; 11 | -------------------------------------------------------------------------------- /examples/demo/src/dashboard/MonthlyRevenue.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import DollarIcon from '@mui/icons-material/AttachMoney'; 3 | import { useTranslate } from 'react-admin'; 4 | 5 | import CardWithIcon from './CardWithIcon'; 6 | 7 | interface Props { 8 | value?: string; 9 | } 10 | 11 | const MonthlyRevenue = (props: Props) => { 12 | const { value } = props; 13 | const translate = useTranslate(); 14 | return ( 15 | 21 | ); 22 | }; 23 | 24 | export default MonthlyRevenue; 25 | -------------------------------------------------------------------------------- /examples/demo/src/dashboard/NbNewOrders.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import ShoppingCartIcon from '@mui/icons-material/ShoppingCart'; 3 | import { useTranslate } from 'react-admin'; 4 | 5 | import CardWithIcon from './CardWithIcon'; 6 | 7 | interface Props { 8 | value?: number; 9 | } 10 | 11 | const NbNewOrders = (props: Props) => { 12 | const { value } = props; 13 | const translate = useTranslate(); 14 | return ( 15 | 21 | ); 22 | }; 23 | 24 | export default NbNewOrders; 25 | -------------------------------------------------------------------------------- /examples/demo/src/dashboard/cartouche.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/demo/src/dashboard/cartouche.png -------------------------------------------------------------------------------- /examples/demo/src/dashboard/cartoucheDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/demo/src/dashboard/cartoucheDark.png -------------------------------------------------------------------------------- /examples/demo/src/dashboard/index.ts: -------------------------------------------------------------------------------- 1 | import DashboardComponent from './Dashboard'; 2 | 3 | export const Dashboard = DashboardComponent; 4 | -------------------------------------------------------------------------------- /examples/demo/src/data-generator-retail.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'data-generator-retail'; 2 | -------------------------------------------------------------------------------- /examples/demo/src/fakeServer/index.ts: -------------------------------------------------------------------------------- 1 | // only install the mocks once 2 | // this is necessary with react@18 in StrictMode 3 | let fakeServer: any; 4 | 5 | export default (type: string) => { 6 | if (!fakeServer) { 7 | switch (type) { 8 | case 'graphql': 9 | fakeServer = import('./graphql').then(factory => 10 | factory.default() 11 | ); 12 | break; 13 | default: 14 | fakeServer = import('./rest').then(factory => 15 | factory.default() 16 | ); 17 | } 18 | } 19 | return fakeServer; 20 | }; 21 | -------------------------------------------------------------------------------- /examples/demo/src/fakeServer/rest.ts: -------------------------------------------------------------------------------- 1 | import FakeRest from 'fakerest'; 2 | import fetchMock from 'fetch-mock'; 3 | import generateData from 'data-generator-retail'; 4 | 5 | export default () => { 6 | const data = generateData({ serializeDate: true }); 7 | const restServer = new FakeRest.FetchServer('http://localhost:4000'); 8 | if (window) { 9 | window.restServer = restServer; // give way to update data in the console 10 | } 11 | restServer.init(data); 12 | restServer.toggleLogging(); // logging is off by default, enable it 13 | fetchMock.mock('begin:http://localhost:4000', restServer.getHandler()); 14 | return () => fetchMock.restore(); 15 | }; 16 | -------------------------------------------------------------------------------- /examples/demo/src/fakerest.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'fakerest'; 2 | -------------------------------------------------------------------------------- /examples/demo/src/index.tsx: -------------------------------------------------------------------------------- 1 | import 'proxy-polyfill'; 2 | 3 | import * as React from 'react'; 4 | import ReactDOM from 'react-dom'; 5 | 6 | import App from './App'; 7 | 8 | ReactDOM.render(, document.getElementById('root')); 9 | -------------------------------------------------------------------------------- /examples/demo/src/invoices/index.ts: -------------------------------------------------------------------------------- 1 | import InvoiceIcon from '@mui/icons-material/LibraryBooks'; 2 | 3 | import InvoiceList from './InvoiceList'; 4 | 5 | export default { 6 | list: InvoiceList, 7 | icon: InvoiceIcon, 8 | }; 9 | -------------------------------------------------------------------------------- /examples/demo/src/json-graphql-server.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'json-graphql-server'; 2 | -------------------------------------------------------------------------------- /examples/demo/src/layout/Layout.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Layout, LayoutProps } from 'react-admin'; 3 | import AppBar from './AppBar'; 4 | import Menu from './Menu'; 5 | 6 | export default (props: LayoutProps) => ( 7 | 8 | ); 9 | -------------------------------------------------------------------------------- /examples/demo/src/layout/index.ts: -------------------------------------------------------------------------------- 1 | import AppBar from './AppBar'; 2 | import Layout from './Layout'; 3 | import Login from './Login'; 4 | import Menu from './Menu'; 5 | 6 | export { AppBar, Layout, Login, Menu }; 7 | -------------------------------------------------------------------------------- /examples/demo/src/orders/NbItemsField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { FunctionField } from 'react-admin'; 3 | import { Order } from '../types'; 4 | 5 | const render = (record?: Order) => record && record.basket.length; 6 | 7 | const NbItemsField = () => render={render} />; 8 | 9 | NbItemsField.defaultProps = { 10 | label: 'resources.commands.fields.nb_items', 11 | textAlign: 'right', 12 | }; 13 | 14 | export default NbItemsField; 15 | -------------------------------------------------------------------------------- /examples/demo/src/orders/TableCellRight.tsx: -------------------------------------------------------------------------------- 1 | import { styled } from '@mui/material/styles'; 2 | import { TableCell } from '@mui/material'; 3 | 4 | export const TableCellRight = styled(TableCell)({ textAlign: 'right' }); 5 | -------------------------------------------------------------------------------- /examples/demo/src/orders/index.ts: -------------------------------------------------------------------------------- 1 | import OrderIcon from '@mui/icons-material/AttachMoney'; 2 | 3 | import OrderList from './OrderList'; 4 | import OrderEdit from './OrderEdit'; 5 | 6 | export default { 7 | list: OrderList, 8 | edit: OrderEdit, 9 | icon: OrderIcon, 10 | }; 11 | -------------------------------------------------------------------------------- /examples/demo/src/products/Poster.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Card, CardMedia } from '@mui/material'; 3 | import { useRecordContext } from 'react-admin'; 4 | import { Product } from '../types'; 5 | 6 | const Poster = () => { 7 | const record = useRecordContext(); 8 | if (!record) return null; 9 | return ( 10 | 11 | 17 | 18 | ); 19 | }; 20 | 21 | export default Poster; 22 | -------------------------------------------------------------------------------- /examples/demo/src/products/ThumbnailField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { styled } from '@mui/material/styles'; 3 | import { useRecordContext } from 'react-admin'; 4 | import { Product } from '../types'; 5 | 6 | const Img = styled('img')({ 7 | width: 25, 8 | maxWidth: 25, 9 | maxHeight: 25, 10 | verticalAlign: 'middle', 11 | }); 12 | 13 | const ThumbnailField = (props: { source: string; label?: string }) => { 14 | const record = useRecordContext(); 15 | if (!record) return null; 16 | return ; 17 | }; 18 | 19 | export default ThumbnailField; 20 | -------------------------------------------------------------------------------- /examples/demo/src/products/index.tsx: -------------------------------------------------------------------------------- 1 | import ProductIcon from '@mui/icons-material/Collections'; 2 | import ProductList from './ProductList'; 3 | import ProductEdit from './ProductEdit'; 4 | import ProductCreate from './ProductCreate'; 5 | 6 | export default { 7 | list: ProductList, 8 | create: ProductCreate, 9 | edit: ProductEdit, 10 | icon: ProductIcon, 11 | }; 12 | -------------------------------------------------------------------------------- /examples/demo/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/demo/src/reviews/index.ts: -------------------------------------------------------------------------------- 1 | import ReviewIcon from '@mui/icons-material/Comment'; 2 | import ReviewList from './ReviewList'; 3 | 4 | export default { 5 | icon: ReviewIcon, 6 | list: ReviewList, 7 | }; 8 | -------------------------------------------------------------------------------- /examples/demo/src/segments/data.ts: -------------------------------------------------------------------------------- 1 | export default [ 2 | { id: 'compulsive', name: 'resources.segments.data.compulsive' }, 3 | { id: 'collector', name: 'resources.segments.data.collector' }, 4 | { id: 'ordered_once', name: 'resources.segments.data.ordered_once' }, 5 | { id: 'regular', name: 'resources.segments.data.regular' }, 6 | { id: 'returns', name: 'resources.segments.data.returns' }, 7 | { id: 'reviewer', name: 'resources.segments.data.reviewer' }, 8 | ]; 9 | -------------------------------------------------------------------------------- /examples/demo/src/visitors/AddressField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useRecordContext } from 'react-admin'; 3 | import { Customer } from '../types'; 4 | 5 | const AddressField = () => { 6 | const record = useRecordContext(); 7 | 8 | return record ? ( 9 | 10 | {record.address}, {record.city}, {record.stateAbbr} {record.zipcode} 11 | 12 | ) : null; 13 | }; 14 | 15 | export default AddressField; 16 | -------------------------------------------------------------------------------- /examples/demo/src/visitors/ColoredNumberField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useRecordContext, NumberField, NumberFieldProps } from 'react-admin'; 3 | 4 | const ColoredNumberField = (props: NumberFieldProps) => { 5 | const record = useRecordContext(props); 6 | if (!record || !props.source) { 7 | return null; 8 | } 9 | return record[props.source] > 500 ? ( 10 | 11 | ) : ( 12 | 13 | ); 14 | }; 15 | 16 | ColoredNumberField.defaultProps = NumberField.defaultProps; 17 | 18 | export default ColoredNumberField; 19 | -------------------------------------------------------------------------------- /examples/demo/src/visitors/CustomerLinkField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Link, FieldProps, useRecordContext } from 'react-admin'; 3 | 4 | import FullNameField from './FullNameField'; 5 | import { Customer } from '../types'; 6 | 7 | const CustomerLinkField = (props: FieldProps) => { 8 | const record = useRecordContext(); 9 | if (!record) { 10 | return null; 11 | } 12 | return ( 13 | 14 | 15 | 16 | ); 17 | }; 18 | 19 | CustomerLinkField.defaultProps = { 20 | source: 'customer_id', 21 | }; 22 | 23 | export default CustomerLinkField; 24 | -------------------------------------------------------------------------------- /examples/demo/src/visitors/CustomerReferenceField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ReferenceField, ReferenceFieldProps } from 'react-admin'; 3 | 4 | import FullNameField from './FullNameField'; 5 | 6 | const CustomerReferenceField = ( 7 | props: Omit & { 8 | source?: string; 9 | } 10 | ) => ( 11 | 12 | 13 | 14 | ); 15 | 16 | CustomerReferenceField.defaultProps = { 17 | source: 'customer_id', 18 | }; 19 | 20 | export default CustomerReferenceField; 21 | -------------------------------------------------------------------------------- /examples/demo/src/visitors/SegmentInput.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { SelectInput, SelectInputProps } from 'react-admin'; 3 | 4 | import segments from '../segments/data'; 5 | 6 | const SegmentInput = (props: SelectInputProps) => ( 7 | 13 | ); 14 | 15 | export default SegmentInput; 16 | -------------------------------------------------------------------------------- /examples/demo/src/visitors/SegmentsInput.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { SelectArrayInput, SelectArrayInputProps } from 'react-admin'; 3 | 4 | import segments from '../segments/data'; 5 | 6 | const SegmentsInput = (props: SelectArrayInputProps) => ( 7 | 13 | ); 14 | 15 | export default SegmentsInput; 16 | -------------------------------------------------------------------------------- /examples/demo/src/visitors/index.ts: -------------------------------------------------------------------------------- 1 | import VisitorIcon from '@mui/icons-material/People'; 2 | 3 | import VisitorList from './VisitorList'; 4 | import VisitorCreate from './VisitorCreate'; 5 | import VisitorEdit from './VisitorEdit'; 6 | 7 | const resource = { 8 | list: VisitorList, 9 | create: VisitorCreate, 10 | edit: VisitorEdit, 11 | icon: VisitorIcon, 12 | }; 13 | 14 | export default resource; 15 | -------------------------------------------------------------------------------- /examples/demo/src/visitors/segments.ts: -------------------------------------------------------------------------------- 1 | const segments = [ 2 | 'compulsive', 3 | 'collector', 4 | 'ordered_once', 5 | 'regular', 6 | 'returns', 7 | 'reviewer', 8 | ]; 9 | 10 | function capitalizeFirstLetter(string: string) { 11 | return string.charAt(0).toUpperCase() + string.slice(1); 12 | } 13 | 14 | export default segments.map(segment => ({ 15 | id: segment, 16 | name: capitalizeFirstLetter(segment), 17 | })); 18 | -------------------------------------------------------------------------------- /examples/demo/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/no-code/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "no-code", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "yarn vite", 6 | "build": "tsc && vite build", 7 | "serve": "vite preview" 8 | }, 9 | "dependencies": { 10 | "@mui/material": "^5.0.2", 11 | "ra-data-local-storage": "^4.0.0", 12 | "ra-no-code": "^4.0.0", 13 | "react": "^17.0.0", 14 | "react-admin": "^4.0.0", 15 | "react-dom": "^17.0.0" 16 | }, 17 | "devDependencies": { 18 | "@vitejs/plugin-react": "^2.2.0", 19 | "typescript": "^4.4.0", 20 | "vite": "^3.2.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/no-code/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { Root } from 'ra-no-code'; 4 | import { defaultTheme } from 'react-admin'; 5 | import { createTheme } from '@mui/material/styles'; 6 | 7 | // FIXME MUI bug https://github.com/mui-org/material-ui/issues/13394 8 | const theme = createTheme(defaultTheme); 9 | 10 | ReactDOM.render( 11 | 12 | 13 | , 14 | document.getElementById('root') 15 | ); 16 | -------------------------------------------------------------------------------- /examples/no-code/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 5 | "types": ["vite/client", "node"], 6 | "allowJs": false, 7 | "skipLibCheck": false, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react" 18 | }, 19 | "include": ["./src"] 20 | } 21 | -------------------------------------------------------------------------------- /examples/simple/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-react"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/simple/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local -------------------------------------------------------------------------------- /examples/simple/README.md: -------------------------------------------------------------------------------- 1 | # React-admin Simple Example 2 | 3 | This is the application we use for our end-to-end tests, and for reproducing bugs via CodeSandbox. 4 | 5 | ## How to run 6 | 7 | From the react-admin repository: 8 | 9 | ```sh 10 | # install the dependencies for the monorepo 11 | make install 12 | # run the app in extended watch mode (reloads when a change is detected in the app code and in the packages code) 13 | make run-simple 14 | ``` 15 | 16 | And then browse to [http://localhost:8080/](http://localhost:8080/). 17 | 18 | The credentials are **login/password** 19 | -------------------------------------------------------------------------------- /examples/simple/sandbox.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "infiniteLoopProtection": true, 3 | "hardReloadOnChange": false, 4 | "view": "browser", 5 | "template": "node", 6 | "container": { 7 | "node": "14" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/simple/src/comments/index.tsx: -------------------------------------------------------------------------------- 1 | import ChatBubbleIcon from '@mui/icons-material/ChatBubble'; 2 | import CommentCreate from './CommentCreate'; 3 | import CommentEdit from './CommentEdit'; 4 | import CommentList from './CommentList'; 5 | import CommentShow from './CommentShow'; 6 | 7 | export default { 8 | list: CommentList, 9 | create: CommentCreate, 10 | edit: CommentEdit, 11 | show: CommentShow, 12 | icon: ChatBubbleIcon, 13 | }; 14 | -------------------------------------------------------------------------------- /examples/simple/src/i18n/index.ts: -------------------------------------------------------------------------------- 1 | import enMessages from './en'; 2 | import frMessages from './fr'; 3 | 4 | export const en = enMessages; 5 | export const fr = frMessages; 6 | -------------------------------------------------------------------------------- /examples/simple/src/i18nProvider.tsx: -------------------------------------------------------------------------------- 1 | import polyglotI18nProvider from 'ra-i18n-polyglot'; 2 | import englishMessages from './i18n/en'; 3 | 4 | const messages = { 5 | fr: () => import('./i18n/fr').then(messages => messages.default), 6 | }; 7 | 8 | export default polyglotI18nProvider( 9 | locale => { 10 | if (locale === 'fr') { 11 | return messages[locale](); 12 | } 13 | 14 | // Always fallback on english 15 | return englishMessages; 16 | }, 17 | 'en', 18 | [ 19 | { locale: 'en', name: 'English' }, 20 | { locale: 'fr', name: 'Français' }, 21 | ] 22 | ); 23 | -------------------------------------------------------------------------------- /examples/simple/src/polyfills.ts: -------------------------------------------------------------------------------- 1 | import 'react-app-polyfill/ie11'; 2 | import 'react-app-polyfill/stable'; 3 | import 'proxy-polyfill/proxy.min.js'; 4 | -------------------------------------------------------------------------------- /examples/simple/src/posts/PostTitle.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useTranslate, useRecordContext } from 'react-admin'; 3 | 4 | export default () => { 5 | const translate = useTranslate(); 6 | const record = useRecordContext(); 7 | return ( 8 | <> 9 | {record 10 | ? translate('post.edit.title', { title: record.title }) 11 | : ''} 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /examples/simple/src/posts/index.tsx: -------------------------------------------------------------------------------- 1 | import BookIcon from '@mui/icons-material/Book'; 2 | import PostCreate from './PostCreate'; 3 | import PostEdit from './PostEdit'; 4 | import PostList from './PostList'; 5 | import PostShow from './PostShow'; 6 | 7 | export default { 8 | list: PostList, 9 | create: PostCreate, 10 | edit: PostEdit, 11 | show: PostShow, 12 | icon: BookIcon, 13 | recordRepresentation: 'title', 14 | }; 15 | -------------------------------------------------------------------------------- /examples/simple/src/tags/TagCreate.tsx: -------------------------------------------------------------------------------- 1 | /* eslint react/jsx-key: off */ 2 | import * as React from 'react'; 3 | import { 4 | Create, 5 | SimpleFormConfigurable, 6 | TextInput, 7 | required, 8 | TranslatableInputs, 9 | } from 'react-admin'; 10 | 11 | const TagCreate = () => ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | ); 20 | 21 | export default TagCreate; 22 | -------------------------------------------------------------------------------- /examples/simple/src/tags/TagShow.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { 3 | Show, 4 | SimpleShowLayout, 5 | TextField, 6 | TranslatableFields, 7 | BooleanField, 8 | } from 'react-admin'; // eslint-disable-line import/no-unresolved 9 | 10 | const TagShow = () => ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ); 21 | 22 | export default TagShow; 23 | -------------------------------------------------------------------------------- /examples/simple/src/tags/index.tsx: -------------------------------------------------------------------------------- 1 | import TagCreate from './TagCreate'; 2 | import TagEdit from './TagEdit'; 3 | import TagList from './TagList'; 4 | import TagShow from './TagShow'; 5 | 6 | export default { 7 | create: TagCreate, 8 | edit: TagEdit, 9 | list: TagList, 10 | show: TagShow, 11 | recordRepresentation: 'name.en', 12 | }; 13 | -------------------------------------------------------------------------------- /examples/simple/src/users/UserTitle.tsx: -------------------------------------------------------------------------------- 1 | /* eslint react/jsx-key: off */ 2 | import * as React from 'react'; 3 | import { RaRecord, useTranslate } from 'react-admin'; 4 | 5 | const UserTitle = ({ record }: { record?: RaRecord }) => { 6 | const translate = useTranslate(); 7 | return ( 8 | 9 | {record ? translate('user.edit.title', { title: record.name }) : ''} 10 | 11 | ); 12 | }; 13 | 14 | export default UserTitle; 15 | -------------------------------------------------------------------------------- /examples/simple/src/users/index.tsx: -------------------------------------------------------------------------------- 1 | import PeopleIcon from '@mui/icons-material/People'; 2 | import UserCreate from './UserCreate'; 3 | import UserEdit from './UserEdit'; 4 | import UserList from './UserList'; 5 | import UserShow from './UserShow'; 6 | 7 | export default { 8 | list: UserList, 9 | create: UserCreate, 10 | edit: UserEdit, 11 | show: UserShow, 12 | icon: PeopleIcon, 13 | recordRepresentation: record => `${record.name} (${record.role})`, 14 | }; 15 | -------------------------------------------------------------------------------- /examples/simple/src/validators.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | required as createRequiredValidator, 3 | number as createNumberValidator, 4 | } from 'react-admin'; 5 | 6 | export const required = createRequiredValidator(); 7 | export const number = createNumberValidator(); 8 | -------------------------------------------------------------------------------- /examples/simple/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "declaration": true, 7 | "allowJs": false, 8 | "jsx": "react", 9 | "lib": ["es2017", "dom"], 10 | "target": "es2016", 11 | "moduleResolution": "node", 12 | "allowSyntheticDefaultImports": true, 13 | "esModuleInterop": true, 14 | "skipLibCheck": true 15 | }, 16 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 17 | "include": ["src"] 18 | } 19 | -------------------------------------------------------------------------------- /examples/tutorial/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true 2 | -------------------------------------------------------------------------------- /examples/tutorial/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | .eslintcache 19 | 20 | npm-debug.log* 21 | yarn-debug.log* 22 | yarn-error.log* 23 | -------------------------------------------------------------------------------- /examples/tutorial/README.md: -------------------------------------------------------------------------------- 1 | # React-admin tutorial 2 | 3 | This is the application built while following the [tutorial](https://marmelab.com/react-admin/Tutorial.html). 4 | 5 | ## How to run 6 | 7 | After having cloned the react-admin repository, run the following commands: 8 | 9 | ```sh 10 | make install 11 | 12 | make build 13 | 14 | make run-tutorial 15 | ``` 16 | -------------------------------------------------------------------------------- /examples/tutorial/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/tutorial/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tutorial", 3 | "version": "4.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "ra-data-json-server": "^4.5.0", 13 | "react": "^18.2.0", 14 | "react-admin": "^4.5.0", 15 | "react-dom": "^18.2.0" 16 | }, 17 | "devDependencies": { 18 | "@types/react": "^18.0.22", 19 | "@types/react-dom": "^18.0.7", 20 | "@vitejs/plugin-react": "^2.2.0", 21 | "typescript": "^4.6.4", 22 | "vite": "^3.2.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /examples/tutorial/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/examples/tutorial/public/favicon.ico -------------------------------------------------------------------------------- /examples/tutorial/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /examples/tutorial/src/Dashboard.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import Card from '@mui/material/Card'; 3 | import CardContent from '@mui/material/CardContent'; 4 | import CardHeader from '@mui/material/CardHeader'; 5 | 6 | export default () => ( 7 | 8 | 9 | Lorem ipsum sic dolor amet... 10 | 11 | ); 12 | -------------------------------------------------------------------------------- /examples/tutorial/src/Dashboard.tsx: -------------------------------------------------------------------------------- 1 | import { Card, CardContent, CardHeader } from '@mui/material'; 2 | 3 | export const Dashboard = () => ( 4 | 5 | 6 | Lorem ipsum sic dolor amet... 7 | 8 | ); 9 | -------------------------------------------------------------------------------- /examples/tutorial/src/MyUrlField.tsx: -------------------------------------------------------------------------------- 1 | import { useRecordContext } from 'react-admin'; 2 | import { Link } from '@mui/material'; 3 | import LaunchIcon from '@mui/icons-material/Launch'; 4 | 5 | const MyUrlField = ({ source }: { source: string }) => { 6 | const record = useRecordContext(); 7 | return record ? ( 8 | 9 | {record[source]} 10 | 11 | 12 | ) : null; 13 | }; 14 | 15 | export default MyUrlField; 16 | -------------------------------------------------------------------------------- /examples/tutorial/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | -------------------------------------------------------------------------------- /examples/tutorial/src/index.js: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.module.css'; 4 | import App from './App'; 5 | import registerServiceWorker from './registerServiceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | registerServiceWorker(); 9 | -------------------------------------------------------------------------------- /examples/tutorial/src/index.module.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: sans-serif; 5 | } 6 | -------------------------------------------------------------------------------- /examples/tutorial/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './App'; 4 | import './index.css'; 5 | 6 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 7 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /examples/tutorial/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/tutorial/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"], 20 | "references": [{ "path": "./tsconfig.node.json" }] 21 | } 22 | -------------------------------------------------------------------------------- /examples/tutorial/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /examples/tutorial/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }); 8 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.5.1", 3 | "packages": [ 4 | "examples/data-generator", 5 | "examples/simple", 6 | "packages/*" 7 | ], 8 | "version": "4.8.1" 9 | } 10 | -------------------------------------------------------------------------------- /packages/ra-core/src/auth/AuthContext.tsx: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | import { AuthProvider, UserIdentity } from '../types'; 4 | 5 | const defaultIdentity: UserIdentity = { id: '' }; 6 | 7 | const defaultProvider: AuthProvider = { 8 | login: () => Promise.resolve(), 9 | logout: () => Promise.resolve(), 10 | checkAuth: () => Promise.resolve(), 11 | checkError: () => Promise.resolve(), 12 | getPermissions: () => Promise.resolve(), 13 | getIdentity: () => Promise.resolve(defaultIdentity), 14 | }; 15 | 16 | const AuthContext = createContext(defaultProvider); 17 | 18 | AuthContext.displayName = 'AuthContext'; 19 | 20 | export default AuthContext; 21 | -------------------------------------------------------------------------------- /packages/ra-core/src/auth/types.ts: -------------------------------------------------------------------------------- 1 | export type UserCheck = ( 2 | payload: object, 3 | pathName: string, 4 | routeParams?: object 5 | ) => void; 6 | 7 | export const AUTH_LOGIN = 'AUTH_LOGIN'; 8 | export const AUTH_CHECK = 'AUTH_CHECK'; 9 | export const AUTH_ERROR = 'AUTH_ERROR'; 10 | export const AUTH_LOGOUT = 'AUTH_LOGOUT'; 11 | export const AUTH_GET_PERMISSIONS = 'AUTH_GET_PERMISSIONS'; 12 | 13 | export type AuthActionType = 14 | | typeof AUTH_LOGIN 15 | | typeof AUTH_LOGOUT 16 | | typeof AUTH_ERROR 17 | | typeof AUTH_CHECK 18 | | typeof AUTH_GET_PERMISSIONS; 19 | -------------------------------------------------------------------------------- /packages/ra-core/src/auth/useAuthProvider.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | 3 | import { AuthProvider } from '../types'; 4 | import AuthContext from './AuthContext'; 5 | 6 | export const defaultAuthParams = { 7 | loginUrl: '/login', 8 | afterLoginUrl: '/', 9 | }; 10 | 11 | /** 12 | * Get the authProvider stored in the context 13 | */ 14 | const useAuthProvider = < 15 | AuthProviderType extends AuthProvider = AuthProvider 16 | >(): AuthProviderType => useContext(AuthContext) as AuthProviderType; 17 | 18 | export default useAuthProvider; 19 | -------------------------------------------------------------------------------- /packages/ra-core/src/auth/usePermissionsOptimized.ts: -------------------------------------------------------------------------------- 1 | import usePermissions from './usePermissions'; 2 | 3 | const emptyParams = {}; 4 | 5 | /** 6 | * @deprecated use usePermissions instead 7 | * 8 | * @see usePermissions 9 | */ 10 | const usePermissionsOptimized = (params = emptyParams) => { 11 | return usePermissions(params); 12 | }; 13 | 14 | export default usePermissionsOptimized; 15 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/button/index.ts: -------------------------------------------------------------------------------- 1 | import useDeleteWithUndoController from './useDeleteWithUndoController'; 2 | import useDeleteWithConfirmController from './useDeleteWithConfirmController'; 3 | 4 | export { useDeleteWithUndoController, useDeleteWithConfirmController }; 5 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/create/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CreateBase'; 2 | export * from './CreateContext'; 3 | export * from './CreateContextProvider'; 4 | export * from './CreateController'; 5 | export * from './useCreateContext'; 6 | export * from './useCreateController'; 7 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/edit/index.ts: -------------------------------------------------------------------------------- 1 | export * from './EditBase'; 2 | export * from './EditContext'; 3 | export * from './EditContextProvider'; 4 | export * from './EditController'; 5 | export * from './useEditContext'; 6 | export * from './useEditController'; 7 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/field/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useReferenceArrayFieldController'; 2 | export * from './useReferenceManyFieldController'; 3 | export * from './useReferenceOneFieldController'; 4 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/input/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | getStatusForInput, 3 | getSelectedReferencesStatus, 4 | getStatusForArrayInput, 5 | } from './referenceDataStatus'; 6 | 7 | export * from './useReferenceArrayInputController'; 8 | export * from './useReferenceInputController'; 9 | 10 | export { 11 | getStatusForInput, 12 | getSelectedReferencesStatus, 13 | getStatusForArrayInput, 14 | }; 15 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/input/types.ts: -------------------------------------------------------------------------------- 1 | export interface MatchingReferencesError { 2 | error: string; 3 | } 4 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/list/useUnselect.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react'; 2 | 3 | import { useRecordSelection } from './useRecordSelection'; 4 | import { Identifier } from '../../types'; 5 | 6 | /** 7 | * Hook to Unselect the rows of a datagrid 8 | * 9 | * @example 10 | * 11 | * const unselect = useUnselect('posts'); 12 | * unselect([123, 456]); 13 | */ 14 | export const useUnselect = (resource: string) => { 15 | const [, { unselect }] = useRecordSelection(resource); 16 | return useCallback( 17 | (ids: Identifier[]) => { 18 | unselect(ids); 19 | }, 20 | [unselect] 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/list/useUnselectAll.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react'; 2 | 3 | import { useRecordSelection } from './useRecordSelection'; 4 | 5 | /** 6 | * Hook to unselect all row of a datagrid 7 | * 8 | * @example 9 | * 10 | * const unselectAll = useUnselectAll('posts'); 11 | * unselectAll(); 12 | */ 13 | export const useUnselectAll = (resource: string) => { 14 | const [, { clearSelection }] = useRecordSelection(resource); 15 | return useCallback(() => { 16 | clearSelection(); 17 | }, [clearSelection]); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/record/index.ts: -------------------------------------------------------------------------------- 1 | export * from './RecordContext'; 2 | export * from './useRecordContext'; 3 | export * from './WithRecord'; 4 | export * from './OptionalRecordContextProvider'; 5 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/saveContext/SaveContextProvider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { SaveContext } from './SaveContext'; 3 | 4 | export const SaveContextProvider = ({ children, value }) => ( 5 | {children} 6 | ); 7 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/saveContext/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SaveContext'; 2 | export * from './SaveContextProvider'; 3 | export * from './usePickSaveContext'; 4 | export * from './useSaveContext'; 5 | export * from './useMutationMiddlewares'; 6 | export * from './useRegisterMutationMiddleware'; 7 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/saveContext/useSaveContext.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { SaveContext, SaveContextValue } from './SaveContext'; 3 | /** 4 | * Get the save() function and its status 5 | * 6 | * Used in forms. 7 | * 8 | * @example 9 | * 10 | * const { 11 | * save, 12 | * saving 13 | * } = useSaveContext(); 14 | */ 15 | export const useSaveContext = < 16 | PropsType extends SaveContextValue = SaveContextValue 17 | >( 18 | props?: PropsType 19 | ): SaveContextValue => { 20 | return useContext(SaveContext); 21 | }; 22 | -------------------------------------------------------------------------------- /packages/ra-core/src/controller/show/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ShowBase'; 2 | export * from './ShowContext'; 3 | export * from './ShowContextProvider'; 4 | export * from './ShowController'; 5 | export * from './useShowController'; 6 | export * from './useShowContext'; 7 | -------------------------------------------------------------------------------- /packages/ra-core/src/core/CustomRoutes.tsx: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | 3 | /** 4 | * This component allows you to provide custom routes to the Admin. 5 | * @param props The component props 6 | * @param props.children The custom routes. 7 | * @param props.noLayout A boolean indicating whether to render the routes outside the Layout. Defaults to false. 8 | * @returns Nothing. This is a configuration component. 9 | */ 10 | export const CustomRoutes = (props: CustomRoutesProps) => { 11 | return null; 12 | }; 13 | 14 | CustomRoutes.raName = 'CustomRoutes'; 15 | 16 | export type CustomRoutesProps = { 17 | children: ReactNode; 18 | noLayout?: boolean; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/ra-core/src/core/ResourceContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | /** 4 | * Context to store the current resource name. 5 | * 6 | * Use the useResource() hook to read the context. That's what most components do in react-admin. 7 | * 8 | * @example 9 | * 10 | * import { useResourceContext, useTranslate } from 'ra-core'; 11 | * 12 | * const MyCustomEditTitle = props => { 13 | * const name = useResourceContext(props); 14 | * 15 | * return ( 16 | *

{translate(`${name}.name`)}

17 | * ); 18 | * }; 19 | */ 20 | export const ResourceContext = createContext(undefined); 21 | 22 | export type ResourceContextValue = string; 23 | -------------------------------------------------------------------------------- /packages/ra-core/src/core/index.ts: -------------------------------------------------------------------------------- 1 | export * from './CoreAdmin'; 2 | export * from './CoreAdminContext'; 3 | export * from './CoreAdminRoutes'; 4 | export * from './CoreAdminUI'; 5 | export * from './CustomRoutes'; 6 | export * from './Resource'; 7 | export * from './ResourceContext'; 8 | export * from './ResourceContextProvider'; 9 | export * from './ResourceDefinitionContext'; 10 | export * from './useGetResourceLabel'; 11 | export * from './useResourceDefinitionContext'; 12 | export * from './useResourceContext'; 13 | export * from './useResourceDefinition'; 14 | export * from './useResourceDefinitions'; 15 | export * from './useGetRecordRepresentation'; 16 | -------------------------------------------------------------------------------- /packages/ra-core/src/core/useResourceDefinitionContext.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | 3 | import { ResourceDefinitionContext } from './ResourceDefinitionContext'; 4 | 5 | export const useResourceDefinitionContext = () => 6 | useContext(ResourceDefinitionContext); 7 | -------------------------------------------------------------------------------- /packages/ra-core/src/dataProvider/DataProviderContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | import { DataProvider } from '../types'; 4 | 5 | const DataProviderContext = createContext(null); 6 | 7 | DataProviderContext.displayName = 'DataProviderContext'; 8 | 9 | export default DataProviderContext; 10 | -------------------------------------------------------------------------------- /packages/ra-core/src/dataProvider/HttpError.ts: -------------------------------------------------------------------------------- 1 | class HttpError extends Error { 2 | constructor( 3 | public readonly message, 4 | public readonly status, 5 | public readonly body = null 6 | ) { 7 | super(message); 8 | Object.setPrototypeOf(this, HttpError.prototype); 9 | this.name = this.constructor.name; 10 | if (typeof Error.captureStackTrace === 'function') { 11 | Error.captureStackTrace(this, this.constructor); 12 | } else { 13 | this.stack = new Error(message).stack; 14 | } 15 | this.stack = new Error().stack; 16 | } 17 | } 18 | 19 | export default HttpError; 20 | -------------------------------------------------------------------------------- /packages/ra-core/src/dataProvider/undoableEventEmitter.ts: -------------------------------------------------------------------------------- 1 | import EventEmitter from 'eventemitter3'; 2 | 3 | export default new EventEmitter(); 4 | -------------------------------------------------------------------------------- /packages/ra-core/src/dataProvider/useRefresh.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from 'react'; 2 | import { useQueryClient } from 'react-query'; 3 | 4 | /** 5 | * Hook for triggering a page refresh. Returns a callback function. 6 | * 7 | * The callback invalidates all queries and refetches the active ones. 8 | * Any component depending on react-query data will be re-rendered. 9 | * 10 | * @example 11 | * 12 | * const refresh = useRefresh(); 13 | * const handleClick = () => { 14 | * refresh(); 15 | * }; 16 | */ 17 | export const useRefresh = () => { 18 | const queryClient = useQueryClient(); 19 | return useCallback(() => { 20 | queryClient.invalidateQueries(); 21 | }, [queryClient]); 22 | }; 23 | -------------------------------------------------------------------------------- /packages/ra-core/src/export/ExporterContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | import { Exporter } from '../types'; 4 | import defaultExporter from './defaultExporter'; 5 | 6 | const ExporterContext = createContext(defaultExporter); 7 | 8 | ExporterContext.displayName = 'ExporterContext'; 9 | 10 | export default ExporterContext; 11 | -------------------------------------------------------------------------------- /packages/ra-core/src/export/defaultExporter.ts: -------------------------------------------------------------------------------- 1 | import jsonExport from 'jsonexport/dist'; 2 | 3 | import downloadCSV from './downloadCSV'; 4 | import { Exporter } from '../types'; 5 | 6 | const defaultExporter: Exporter = (data, _, __, resource) => 7 | jsonExport(data, (err, csv) => downloadCSV(csv, resource)); 8 | 9 | export default defaultExporter; 10 | -------------------------------------------------------------------------------- /packages/ra-core/src/export/downloadCSV.ts: -------------------------------------------------------------------------------- 1 | export default (csv, filename) => { 2 | const fakeLink = document.createElement('a'); 3 | fakeLink.style.display = 'none'; 4 | document.body.appendChild(fakeLink); 5 | const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' }); 6 | // @ts-ignore 7 | if (window.navigator && window.navigator.msSaveOrOpenBlob) { 8 | // Manage IE11+ & Edge 9 | // @ts-ignore 10 | window.navigator.msSaveOrOpenBlob(blob, `${filename}.csv`); 11 | } else { 12 | fakeLink.setAttribute('href', URL.createObjectURL(blob)); 13 | fakeLink.setAttribute('download', `${filename}.csv`); 14 | fakeLink.click(); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages/ra-core/src/export/index.ts: -------------------------------------------------------------------------------- 1 | import defaultExporter from './defaultExporter'; 2 | import downloadCSV from './downloadCSV'; 3 | import ExporterContext from './ExporterContext'; 4 | import fetchRelatedRecords from './fetchRelatedRecords'; 5 | 6 | export { defaultExporter, downloadCSV, ExporterContext, fetchRelatedRecords }; 7 | -------------------------------------------------------------------------------- /packages/ra-core/src/form/FormGroupContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | /** 4 | * Context allowing inputs to register to a specific group. 5 | * This enables other components in the group to access group properties such as its 6 | * validation (valid/invalid) or whether its inputs have been updated (dirty/pristine). 7 | * 8 | * This should only be used through a FormGroupContextProvider. 9 | */ 10 | export const FormGroupContext = createContext(undefined); 11 | 12 | export type FormGroupContextValue = string; 13 | -------------------------------------------------------------------------------- /packages/ra-core/src/form/choices/ChoicesContextProvider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ReactNode } from 'react'; 3 | import { ChoicesContext, ChoicesContextValue } from './ChoicesContext'; 4 | 5 | export const ChoicesContextProvider = ({ 6 | children, 7 | value, 8 | }: { 9 | children: ReactNode; 10 | value: ChoicesContextValue; 11 | }) => ( 12 | {children} 13 | ); 14 | -------------------------------------------------------------------------------- /packages/ra-core/src/form/choices/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ChoicesContext'; 2 | export * from './ChoicesContextProvider'; 3 | export * from './useChoicesContext'; 4 | -------------------------------------------------------------------------------- /packages/ra-core/src/form/isRequired.ts: -------------------------------------------------------------------------------- 1 | const isRequired = validate => { 2 | if (validate && validate.isRequired) { 3 | return true; 4 | } 5 | if (Array.isArray(validate)) { 6 | return validate.some(it => it.isRequired); 7 | } 8 | return false; 9 | }; 10 | 11 | export default isRequired; 12 | -------------------------------------------------------------------------------- /packages/ra-core/src/form/types.ts: -------------------------------------------------------------------------------- 1 | export interface InputProps { 2 | addField?: boolean; 3 | defaultValue?: any; 4 | input?: any; 5 | source: string; 6 | } 7 | -------------------------------------------------------------------------------- /packages/ra-core/src/form/useFormGroupContext.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { FormGroupContext } from './FormGroupContext'; 3 | 4 | /** 5 | * Retrieve the name of the form group the consumer belongs to. May be undefined if the consumer is not inside a form group. 6 | */ 7 | export const useFormGroupContext = () => { 8 | const context = useContext(FormGroupContext); 9 | return context; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/ra-core/src/form/useFormGroups.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { FormGroupsContext } from './FormGroupsContext'; 3 | 4 | /** 5 | * Retrieve the form groups management context. Used by inputs to register themselves into a form group. 6 | */ 7 | export const useFormGroups = () => { 8 | const context = useContext(FormGroupsContext); 9 | return context; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/ra-core/src/i18n/I18nContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import { I18nProvider } from '../types'; 3 | import { substituteTokens } from './substituteTokens'; 4 | 5 | export type I18nContextProps = I18nProvider; 6 | 7 | const defaultI18nProvider = { 8 | translate: (key, options) => 9 | options?._ 10 | ? substituteTokens(options._, options) 11 | : substituteTokens(key, options), 12 | changeLocale: () => Promise.resolve(), 13 | getLocale: () => 'en', 14 | }; 15 | 16 | export const I18nContext = createContext(defaultI18nProvider); 17 | 18 | I18nContext.displayName = 'I18nContext'; 19 | -------------------------------------------------------------------------------- /packages/ra-core/src/i18n/TranslatableContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | export const TranslatableContext = createContext< 4 | TranslatableContextValue | undefined 5 | >(undefined); 6 | 7 | export interface TranslatableContextValue { 8 | getLabel: GetTranslatableLabel; 9 | getSource: GetTranslatableSource; 10 | locales: string[]; 11 | selectedLocale: string; 12 | selectLocale: SelectTranslatableLocale; 13 | } 14 | 15 | export type GetTranslatableSource = (field: string, locale?: string) => string; 16 | export type GetTranslatableLabel = (field: string, label?: string) => string; 17 | export type SelectTranslatableLocale = (locale: string) => void; 18 | -------------------------------------------------------------------------------- /packages/ra-core/src/i18n/TranslatableContextProvider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ReactElement, ReactNode } from 'react'; 3 | import { 4 | TranslatableContext, 5 | TranslatableContextValue, 6 | } from './TranslatableContext'; 7 | 8 | export const TranslatableContextProvider = ({ 9 | children, 10 | value, 11 | }: { 12 | children: ReactNode; 13 | value: TranslatableContextValue; 14 | }): ReactElement => { 15 | return ( 16 | 17 | {children} 18 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/ra-core/src/i18n/useI18nProvider.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | 3 | import { I18nContext } from './I18nContext'; 4 | 5 | /** 6 | * Get the i18nProvider instance declared in the component 7 | * 8 | * @example 9 | * 10 | * const CurrentLanguage = () => { 11 | * const i18nProvider = useI18nProvider(); 12 | * const locale = i18nProvider.getLocale(); 13 | * return {locale}; 14 | * }; 15 | */ 16 | export const useI18nProvider = () => useContext(I18nContext); 17 | -------------------------------------------------------------------------------- /packages/ra-core/src/i18n/useLocale.tsx: -------------------------------------------------------------------------------- 1 | import { useLocaleState } from './useLocaleState'; 2 | 3 | /** 4 | * Get the current locale 5 | * 6 | * @example 7 | * 8 | * import { useLocale } from 'react-admin'; 9 | * 10 | * const availableLanguages = { 11 | * en: 'English', 12 | * fr: 'Français', 13 | * } 14 | * const CurrentLanguage = () => { 15 | * const locale = useLocale(); 16 | * return {availableLanguages[locale]}; 17 | * } 18 | * 19 | * @deprecated use useLocaleState instead 20 | */ 21 | export const useLocale = () => { 22 | const [locale] = useLocaleState(); 23 | return locale; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/ra-core/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './auth'; 2 | export * from './controller'; 3 | export * from './core'; 4 | export * from './preferences'; 5 | export * from './dataProvider'; 6 | export * from './export'; 7 | export * from './form'; 8 | export * from './i18n'; 9 | export * from './inference'; 10 | export * from './notification'; 11 | export * from './routing'; 12 | export * from './store'; 13 | export * from './types'; 14 | export * from './util'; 15 | -------------------------------------------------------------------------------- /packages/ra-core/src/inference/index.ts: -------------------------------------------------------------------------------- 1 | import getElementsFromRecords from './getElementsFromRecords'; 2 | import InferredElement from './InferredElement'; 3 | import getValuesFromRecords from './getValuesFromRecords'; 4 | 5 | export * from './inferTypeFromValues'; 6 | export * from './types'; 7 | 8 | export { getElementsFromRecords, getValuesFromRecords, InferredElement }; 9 | -------------------------------------------------------------------------------- /packages/ra-core/src/inference/types.ts: -------------------------------------------------------------------------------- 1 | import { ComponentType } from 'react'; 2 | 3 | export interface InferredType { 4 | type?: ComponentType; 5 | component?: ComponentType; 6 | representation?: (props: any, children: any) => string; 7 | } 8 | 9 | export interface InferredTypeMap { 10 | [key: string]: InferredType | undefined; 11 | } 12 | -------------------------------------------------------------------------------- /packages/ra-core/src/notification/AddNotificationContext.tsx: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | import { NotificationPayload } from './types'; 4 | 5 | export const AddNotificationContext = createContext< 6 | (notification: NotificationPayload) => void 7 | >(() => {}); 8 | -------------------------------------------------------------------------------- /packages/ra-core/src/notification/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AddNotificationContext'; 2 | export * from './NotificationContext'; 3 | export * from './NotificationContextProvider'; 4 | export * from './types'; 5 | export * from './useAddNotificationContext'; 6 | export * from './useNotificationContext'; 7 | export * from './useNotify'; 8 | -------------------------------------------------------------------------------- /packages/ra-core/src/notification/useAddNotificationContext.tsx: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { AddNotificationContext } from './AddNotificationContext'; 3 | 4 | export const useAddNotificationContext = () => 5 | useContext(AddNotificationContext); 6 | -------------------------------------------------------------------------------- /packages/ra-core/src/notification/useNotificationContext.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { NotificationContext } from './NotificationContext'; 3 | 4 | export const useNotificationContext = () => useContext(NotificationContext); 5 | -------------------------------------------------------------------------------- /packages/ra-core/src/preferences/PreferenceKeyContext.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { createContext, useContext } from 'react'; 3 | 4 | export const PreferenceKeyContext = createContext(''); 5 | 6 | export const PreferenceKeyContextProvider = ({ 7 | value = '', 8 | children, 9 | }: { 10 | value?: string; 11 | children: React.ReactNode; 12 | }) => ( 13 | 14 | {children} 15 | 16 | ); 17 | 18 | export const usePreferenceKey = () => { 19 | return useContext(PreferenceKeyContext); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/ra-core/src/preferences/index.ts: -------------------------------------------------------------------------------- 1 | export * from './PreferencesEditorContext'; 2 | export * from './PreferencesEditorContextProvider'; 3 | export * from './usePreference'; 4 | export * from './usePreferencesEditor'; 5 | export * from './usePreferenceInput'; 6 | export * from './useSetInspectorTitle'; 7 | export * from './PreferenceKeyContext'; 8 | -------------------------------------------------------------------------------- /packages/ra-core/src/preferences/usePreferencesEditor.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { 3 | PreferencesEditorContext, 4 | PreferencesEditorContextValue, 5 | } from './PreferencesEditorContext'; 6 | 7 | export const usePreferencesEditor = (): PreferencesEditorContextValue => 8 | useContext(PreferencesEditorContext); 9 | -------------------------------------------------------------------------------- /packages/ra-core/src/preferences/useSetInspectorTitle.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { usePreferencesEditor } from './usePreferencesEditor'; 3 | 4 | /** 5 | * Set inspector title on mount 6 | * 7 | * @example 8 | * useSetInspectorTitle('Datagrid'); 9 | */ 10 | export const useSetInspectorTitle = (title: string, options?: any) => { 11 | const { setTitle } = usePreferencesEditor(); 12 | 13 | useEffect(() => { 14 | setTitle(title, options); 15 | // eslint-disable-next-line react-hooks/exhaustive-deps 16 | }, [title, JSON.stringify(options), setTitle]); 17 | }; 18 | -------------------------------------------------------------------------------- /packages/ra-core/src/routing/BasenameContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | export const BasenameContext = createContext(''); 4 | -------------------------------------------------------------------------------- /packages/ra-core/src/routing/BasenameContextProvider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { BasenameContext } from './BasenameContext'; 3 | 4 | /** 5 | * Set the string to append to all links to the admin app. 6 | * 7 | * Useful when the app is mounted on a sub path, e.g. '/admin'. 8 | * Used internally by the `` component. 9 | * 10 | * @see useBasename 11 | */ 12 | export const BasenameContextProvider = ({ children, basename }) => ( 13 | 14 | {children} 15 | 16 | ); 17 | -------------------------------------------------------------------------------- /packages/ra-core/src/routing/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AdminRouter'; 2 | export * from './BasenameContextProvider'; 3 | export * from './linkToRecord'; 4 | export * from './resolveRedirectTo'; 5 | export * from './useBasename'; 6 | export * from './useCreatePath'; 7 | export * from './useRedirect'; 8 | export * from './useScrollToTop'; 9 | export * from './types'; 10 | -------------------------------------------------------------------------------- /packages/ra-core/src/routing/linkToRecord.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @deprecated use useCreatePath instead 3 | */ 4 | export const linkToRecord = (resource, id, linkType = 'edit') => { 5 | const link = `${resource}/${encodeURIComponent(id)}`; 6 | 7 | if (linkType === 'show') { 8 | return `${link}/show`; 9 | } 10 | 11 | return link; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/ra-core/src/routing/types.ts: -------------------------------------------------------------------------------- 1 | import { RaRecord } from '../types'; 2 | 3 | export type LinkToFunctionType = ( 4 | record: RaRecord, 5 | reference: string 6 | ) => string; 7 | 8 | export type LinkToType = string | false | LinkToFunctionType; 9 | -------------------------------------------------------------------------------- /packages/ra-core/src/store/StoreContext.tsx: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | import { Store } from './types'; 4 | import { memoryStore } from './memoryStore'; 5 | 6 | const defaultStore = memoryStore(); 7 | 8 | export const StoreContext = createContext(defaultStore); 9 | -------------------------------------------------------------------------------- /packages/ra-core/src/store/index.ts: -------------------------------------------------------------------------------- 1 | export * from './localStorageStore'; 2 | export * from './memoryStore'; 3 | export * from './StoreContext'; 4 | export * from './StoreContextProvider'; 5 | export * from './StoreSetter'; 6 | export * from './types'; 7 | export * from './useStore'; 8 | export * from './useStoreContext'; 9 | export * from './useRemoveFromStore'; 10 | export * from './useRemoveItemsFromStore'; 11 | export * from './useResetStore'; 12 | -------------------------------------------------------------------------------- /packages/ra-core/src/store/types.ts: -------------------------------------------------------------------------------- 1 | export interface Store { 2 | setup: () => void; 3 | teardown: () => void; 4 | getItem: (key: string, defaultValue?: T) => T; 5 | setItem: (key: string, value: T) => void; 6 | removeItem: (key: string) => void; 7 | removeItems: (keyPrefix: string) => void; 8 | reset: () => void; 9 | subscribe: (key: string, callback: (value: any) => void) => () => void; 10 | } 11 | -------------------------------------------------------------------------------- /packages/ra-core/src/store/useResetStore.ts: -------------------------------------------------------------------------------- 1 | import { useStoreContext } from './useStoreContext'; 2 | 3 | /** 4 | * Get a callback to remove all items from the store 5 | * 6 | * @example 7 | * import { useResetStore } from 'react-admin'; 8 | * 9 | * const ResetPrefs = () { 10 | * const reset = useResetStore(); 11 | * 12 | * const handleClick = () => { 13 | * reset(); 14 | * }; 15 | * 16 | * return ; 17 | * } 18 | */ 19 | export const useResetStore = () => { 20 | const { reset } = useStoreContext(); 21 | return reset; 22 | }; 23 | -------------------------------------------------------------------------------- /packages/ra-core/src/store/useStoreContext.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | 3 | import { StoreContext } from './StoreContext'; 4 | 5 | /** 6 | * Get the Store stored in the StoreContext 7 | */ 8 | export const useStoreContext = () => useContext(StoreContext); 9 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/ComponentPropType.ts: -------------------------------------------------------------------------------- 1 | import { isValidElementType } from 'react-is'; 2 | 3 | export default (props, propName, componentName) => { 4 | if (props[propName] && !isValidElementType(props[propName])) { 5 | return new Error( 6 | `Invalid prop '${propName}' supplied to '${componentName}': the prop is not a valid React component` 7 | ); 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/LabelPrefixContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | export const LabelPrefixContext = createContext(''); 4 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/LabelPrefixContextProvider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { LabelPrefixContext } from './LabelPrefixContext'; 3 | import { useLabelPrefix } from './useLabelPrefix'; 4 | 5 | export const LabelPrefixContextProvider = ({ 6 | prefix, 7 | concatenate = true, 8 | children, 9 | }) => { 10 | const oldPrefix = useLabelPrefix(); 11 | const newPrefix = 12 | oldPrefix && concatenate ? `${oldPrefix}.${prefix}` : prefix; 13 | return ( 14 | 15 | {children} 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/escapePath.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Escape special characters in path so that react-router Route does not do any special treatment 3 | * 4 | * @see https://github.com/ReactTraining/react-router/blob/v3/docs/guides/RouteMatching.md#path-syntax 5 | * 6 | * @example 7 | * 8 | * escapePath('/foo(bar)') => 'foo\(bar\)' 9 | */ 10 | export default url => url.replace(/(\(|\))/g, '\\$1'); 11 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/getMutationMode.ts: -------------------------------------------------------------------------------- 1 | export const getMutationMode = (mutationMode, undoable) => { 2 | if (mutationMode) { 3 | return mutationMode; 4 | } 5 | switch (undoable) { 6 | case true: 7 | return 'undoable'; 8 | case false: 9 | return 'pessimistic'; 10 | default: 11 | return 'undoable'; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/getValue.spec.ts: -------------------------------------------------------------------------------- 1 | import getValue from './getValue'; 2 | import expect from 'expect'; 3 | 4 | describe('getValue', () => { 5 | it('returns directly the value if it is not an object', () => { 6 | expect(getValue(10, 'foo.bar')).toEqual(10); 7 | }); 8 | it('returns the value at specified path if it is an object', () => { 9 | expect(getValue({ foo: { bar: 10 } }, 'foo.bar')).toEqual(10); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/getValue.ts: -------------------------------------------------------------------------------- 1 | import get from 'lodash/get'; 2 | 3 | export default (value, path) => { 4 | if (typeof value === 'object') { 5 | return get(value, path); 6 | } 7 | 8 | return value; 9 | }; 10 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/mergeRefs.ts: -------------------------------------------------------------------------------- 1 | import { LegacyRef, MutableRefObject, RefCallback } from 'react'; 2 | 3 | // https://github.com/gregberge/react-merge-refs 4 | export function mergeRefs( 5 | refs: Array | LegacyRef> 6 | ): RefCallback { 7 | return value => { 8 | refs.forEach(ref => { 9 | if (typeof ref === 'function') { 10 | ref(value); 11 | } else if (ref != null) { 12 | (ref as MutableRefObject).current = value; 13 | } 14 | }); 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/useLabelPrefix.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { LabelPrefixContext } from './LabelPrefixContext'; 3 | 4 | export const useLabelPrefix = () => useContext(LabelPrefixContext); 5 | -------------------------------------------------------------------------------- /packages/ra-core/src/util/warning.ts: -------------------------------------------------------------------------------- 1 | export default (condition: any, message: string) => { 2 | if (condition && process.env.NODE_ENV !== 'production') { 3 | console.warn(message); // eslint-disable-line 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /packages/ra-core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.stories.ts", 13 | "**/*.stories.tsx", 14 | "**/*.stories.js" 15 | ], 16 | "include": ["src"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/ra-data-fakerest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 9 | "include": ["src"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ra-data-graphql-simple/src/getFinalType.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IntrospectionType, 3 | IntrospectionTypeRef, 4 | IntrospectionNonNullTypeRef, 5 | TypeKind, 6 | } from 'graphql'; 7 | 8 | /** 9 | * Ensure we get the real type even if the root type is NON_NULL or LIST 10 | * @param {GraphQLType} type 11 | */ 12 | const getFinalType = ( 13 | type: IntrospectionType | IntrospectionNonNullTypeRef | IntrospectionTypeRef 14 | ) => { 15 | if (type.kind === TypeKind.NON_NULL || type.kind === TypeKind.LIST) { 16 | return getFinalType(type.ofType); 17 | } 18 | 19 | return type; 20 | }; 21 | 22 | export default getFinalType; 23 | -------------------------------------------------------------------------------- /packages/ra-data-graphql-simple/src/isList.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IntrospectionType, 3 | IntrospectionTypeRef, 4 | IntrospectionNonNullTypeRef, 5 | TypeKind, 6 | } from 'graphql'; 7 | 8 | const isList = ( 9 | type: IntrospectionType | IntrospectionNonNullTypeRef | IntrospectionTypeRef 10 | ) => { 11 | if (type.kind === TypeKind.NON_NULL) { 12 | return isList(type.ofType); 13 | } 14 | 15 | return type.kind === TypeKind.LIST; 16 | }; 17 | 18 | export default isList; 19 | -------------------------------------------------------------------------------- /packages/ra-data-graphql-simple/src/isRequired.ts: -------------------------------------------------------------------------------- 1 | import { 2 | IntrospectionType, 3 | IntrospectionListTypeRef, 4 | IntrospectionTypeRef, 5 | TypeKind, 6 | } from 'graphql'; 7 | 8 | const isRequired = ( 9 | type: IntrospectionType | IntrospectionListTypeRef | IntrospectionTypeRef 10 | ) => { 11 | if (type.kind === TypeKind.LIST) { 12 | return isRequired(type.ofType); 13 | } 14 | 15 | return type.kind === TypeKind.NON_NULL; 16 | }; 17 | 18 | export default isRequired; 19 | -------------------------------------------------------------------------------- /packages/ra-data-graphql-simple/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.test.ts", 13 | "**/*.test.tsx", 14 | "**/*.test.js" 15 | ], 16 | "include": ["src"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/ra-data-graphql/src/constants.ts: -------------------------------------------------------------------------------- 1 | import { 2 | GET_LIST, 3 | GET_ONE, 4 | GET_MANY, 5 | GET_MANY_REFERENCE, 6 | CREATE, 7 | UPDATE, 8 | UPDATE_MANY, 9 | DELETE, 10 | DELETE_MANY, 11 | } from 'ra-core'; 12 | 13 | export const QUERY_TYPES = [GET_LIST, GET_MANY, GET_MANY_REFERENCE, GET_ONE]; 14 | export const MUTATION_TYPES = [ 15 | CREATE, 16 | UPDATE, 17 | DELETE, 18 | UPDATE_MANY, 19 | DELETE_MANY, 20 | ]; 21 | export const ALL_TYPES = QUERY_TYPES.concat(MUTATION_TYPES); 22 | -------------------------------------------------------------------------------- /packages/ra-data-graphql/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": [ 9 | "**/*.spec.ts", 10 | "**/*.spec.tsx", 11 | "**/*.spec.js", 12 | "**/*.test.ts", 13 | "**/*.test.tsx", 14 | "**/*.test.js" 15 | ], 16 | "include": ["src"] 17 | } 18 | -------------------------------------------------------------------------------- /packages/ra-data-json-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 9 | "include": ["src"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ra-data-localforage/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "declaration": true, 7 | "declarationMap": true, 8 | "allowJs": false 9 | }, 10 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 11 | "include": ["src"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/ra-data-localstorage/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 9 | "include": ["src"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ra-data-simple-rest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 9 | "include": ["src"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ra-i18n-polyglot/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 9 | "include": ["src"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ra-input-rich-text/assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ITopGun/B2BAdmin-React/067b4caf5ae98d5d8e6b6f882edf30ea3036f14f/packages/ra-input-rich-text/assets/demo.gif -------------------------------------------------------------------------------- /packages/ra-input-rich-text/src/TiptapEditorContext.tsx: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import { Editor } from '@tiptap/react'; 3 | 4 | export const TiptapEditorContext = createContext(undefined); 5 | -------------------------------------------------------------------------------- /packages/ra-input-rich-text/src/TiptapEditorProvider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Editor } from '@tiptap/react'; 3 | import { TiptapEditorContext } from './TiptapEditorContext'; 4 | 5 | export const TiptapEditorProvider = ({ 6 | children, 7 | value, 8 | }: TiptapEditorProviderProps) => ( 9 | 10 | {children} 11 | 12 | ); 13 | 14 | export type TiptapEditorProviderProps = { 15 | children: React.ReactNode; 16 | value: Editor; 17 | }; 18 | -------------------------------------------------------------------------------- /packages/ra-input-rich-text/src/buttons/index.ts: -------------------------------------------------------------------------------- 1 | export * from './FormatButtons'; 2 | export * from './ListButtons'; 3 | export * from './AlignmentButtons'; 4 | export * from './LinkButtons'; 5 | export * from './QuoteButtons'; 6 | export * from './ClearButtons'; 7 | export * from './LevelSelect'; 8 | export * from './ImageButtons'; 9 | export * from './ColorButtons'; 10 | export * from './useEditorSelection'; 11 | -------------------------------------------------------------------------------- /packages/ra-input-rich-text/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './RichTextInput'; 2 | export * from './buttons'; 3 | export * from './RichTextInputToolbar'; 4 | export * from './TiptapEditorContext'; 5 | export * from './TiptapEditorProvider'; 6 | export * from './useTiptapEditor'; 7 | -------------------------------------------------------------------------------- /packages/ra-input-rich-text/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 9 | "include": ["src"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ra-language-english/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 9 | "include": ["src"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ra-language-french/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 9 | "include": ["src"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ApplicationContext.tsx: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from 'react'; 2 | import { Application } from './ApplicationsDashboard'; 3 | 4 | export type ApplicationContextValue = { 5 | application: Application; 6 | onExit: () => void; 7 | }; 8 | 9 | export const ApplicationContext = createContext( 10 | undefined 11 | ); 12 | 13 | export const useApplication = () => useContext(ApplicationContext); 14 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ApplicationsDashboard/applicationStorage.ts: -------------------------------------------------------------------------------- 1 | export const loadApplicationsFromStorage = () => { 2 | const storedValue = window.localStorage.getItem( 3 | '@@ra-no-code/applications' 4 | ); 5 | 6 | if (storedValue) { 7 | return JSON.parse(storedValue); 8 | } 9 | 10 | return []; 11 | }; 12 | 13 | export const storeApplicationsInStorage = applications => { 14 | window.localStorage.setItem( 15 | '@@ra-no-code/applications', 16 | JSON.stringify(applications) 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ApplicationsDashboard/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ApplicationsDashboard'; 2 | export * from './NewApplicationForm'; 3 | export * from './types'; 4 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ApplicationsDashboard/types.ts: -------------------------------------------------------------------------------- 1 | export type Application = { 2 | name: string; 3 | created_at: Date; 4 | }; 5 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ResourceConfiguration/FieldConfiguration/FieldTypeInput.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { InferenceTypes, SelectInput, SelectInputProps } from 'react-admin'; 3 | 4 | export const FieldTypeInput = (props: SelectInputProps) => ( 5 | 6 | ); 7 | 8 | const INFERENCE_TYPES = InferenceTypes.map(type => ({ 9 | id: type, 10 | name: type, 11 | })); 12 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ResourceConfiguration/FieldConfiguration/index.ts: -------------------------------------------------------------------------------- 1 | export * from './FieldTypeInput'; 2 | export * from './FieldViewsInput'; 3 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ResourceConfiguration/index.ts: -------------------------------------------------------------------------------- 1 | export * from './getFieldDefinitionsFromRecords'; 2 | export * from './ResourceConfiguration'; 3 | export * from './useResourceConfiguration'; 4 | export * from './useResourcesConfiguration'; 5 | export * from './ResourceConfigurationContext'; 6 | export * from './ResourceConfigurationProvider'; 7 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/builders/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Create'; 2 | export * from './Edit'; 3 | export * from './List'; 4 | export * from './getFieldFromFieldDefinition'; 5 | export * from './getInputFromFieldDefinition'; 6 | export * from './Show'; 7 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Admin'; 2 | export * from './ApplicationsDashboard'; 3 | export * from './Root'; 4 | export * from './builders'; 5 | export * from './ResourceConfiguration'; 6 | export * from './ui'; 7 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ui/Appbar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { AppBar as RaAppBar, AppBarProps } from 'react-admin'; 3 | import { UserMenu } from './UserMenu'; 4 | 5 | export const AppBar = (props: AppBarProps) => ( 6 | } /> 7 | ); 8 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ui/Layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Layout as RaLayout, LayoutProps } from 'react-admin'; 3 | import { useResourcesConfiguration } from '../ResourceConfiguration'; 4 | import { Menu } from './Menu'; 5 | import { AppBar } from './Appbar'; 6 | import { Ready } from './Ready'; 7 | 8 | export const Layout = (props: LayoutProps) => { 9 | const [resources] = useResourcesConfiguration(); 10 | const hasResources = !!resources && Object.keys(resources).length > 0; 11 | 12 | if (!hasResources) { 13 | return ; 14 | } 15 | 16 | return ; 17 | }; 18 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ui/Ready.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Ready as RaReady } from 'react-admin'; 3 | import { ImportResourceDialog } from './ImportResourceDialog'; 4 | 5 | export const Ready = () => ( 6 | <> 7 | 8 | 9 | 10 | ); 11 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ui/UserMenu.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { UserMenu as RaUserMenu } from 'react-admin'; 3 | import { ExitApplicationMenu } from './ExitApplicationMenu'; 4 | 5 | export const UserMenu = props => { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /packages/ra-no-code/src/ui/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Layout'; 2 | export * from './Menu'; 3 | export * from './UserMenu'; 4 | export * from './ExitApplicationMenu'; 5 | export * from './ImportResourceDialog'; 6 | export * from './Ready'; 7 | -------------------------------------------------------------------------------- /packages/ra-no-code/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false, 7 | "types": [ 8 | "jest", 9 | "@types/node" 10 | ] 11 | }, 12 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 13 | "include": ["src"] 14 | } 15 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/AdminContext.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { CoreAdminContext, CoreAdminContextProps } from 'ra-core'; 3 | 4 | import { defaultTheme } from './defaultTheme'; 5 | import { ThemeProvider } from './layout/Theme'; 6 | 7 | export const AdminContext = (props: CoreAdminContextProps) => { 8 | const { theme = defaultTheme, children, ...rest } = props; 9 | return ( 10 | 11 | {children} 12 | 13 | ); 14 | }; 15 | 16 | AdminContext.displayName = 'AdminContext'; 17 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/auth/index.ts: -------------------------------------------------------------------------------- 1 | export * from './AuthCallback'; 2 | export * from './AuthError'; 3 | export * from './Login'; 4 | export * from './LoginForm'; 5 | export * from './Logout'; 6 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/detail/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Create'; 2 | export * from './CreateActions'; 3 | export * from './CreateView'; 4 | export * from './Edit'; 5 | export * from './EditActions'; 6 | export * from './editFieldTypes'; 7 | export * from './EditGuesser'; 8 | export * from './EditView'; 9 | export * from './Show'; 10 | export * from './ShowActions'; 11 | export * from './showFieldTypes'; 12 | export * from './ShowGuesser'; 13 | export * from './ShowView'; 14 | export * from './SimpleShowLayout'; 15 | export * from './TabbedShowLayout'; 16 | export * from './TabbedShowLayoutTabs'; 17 | export * from './Tab'; 18 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/field/sanitizeFieldRestProps.ts: -------------------------------------------------------------------------------- 1 | export const sanitizeFieldRestProps: (props: any) => any = ({ 2 | cellClassName, 3 | className, 4 | emptyText, 5 | formClassName, 6 | fullWidth, 7 | headerClassName, 8 | label, 9 | linkType, 10 | link, 11 | locale, 12 | record, 13 | refetch, 14 | resource, 15 | sortable, 16 | sortBy, 17 | sortByOrder, 18 | source, 19 | textAlign, 20 | translateChoice, 21 | ...props 22 | }) => props; 23 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/form/SimpleFormEditor.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useSetInspectorTitle } from 'ra-core'; 3 | 4 | import { FieldsSelector } from '../preferences'; 5 | 6 | export const SimpleFormEditor = () => { 7 | useSetInspectorTitle('ra.inspector.SimpleForm.title', { _: 'Form' }); 8 | 9 | return ; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/form/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './TabbedForm'; 2 | export * from './FormTab'; 3 | export * from './FormTabHeader'; 4 | export * from './SimpleForm'; 5 | export * from './SimpleFormConfigurable'; 6 | export * from './TabbedForm'; 7 | export * from './TabbedFormTabs'; 8 | export * from './TabbedFormView'; 9 | export * from './Toolbar'; 10 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/form/useFormRootPath.ts: -------------------------------------------------------------------------------- 1 | import { matchPath, useLocation } from 'react-router-dom'; 2 | 3 | /** 4 | * This hook infers the tabbed form root path from the current location. 5 | */ 6 | export const useFormRootPath = () => { 7 | const location = useLocation(); 8 | const createMatch = matchPath(':resource/create/*', location.pathname); 9 | const editMatch = matchPath(':resource/:id/*', location.pathname); 10 | 11 | if (createMatch) { 12 | return createMatch.pathnameBase; 13 | } 14 | 15 | if (editMatch) { 16 | return editMatch.pathnameBase; 17 | } 18 | 19 | return ''; 20 | }; 21 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './auth'; 2 | export * from './button'; 3 | export * from './defaultTheme'; 4 | export * from './detail'; 5 | export * from './form'; 6 | export * from './field'; 7 | export * from './input'; 8 | export * from './Labeled'; 9 | export * from './layout'; 10 | export * from './Link'; 11 | export * from './list'; 12 | export * from './preferences'; 13 | export * from './types'; 14 | export * from './AdminUI'; 15 | export * from './AdminContext'; 16 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ArrayInput/ArrayInputContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import { UseFieldArrayReturn } from 'react-hook-form'; 3 | 4 | /** 5 | * A React context that provides access to an ArrayInput methods as provided by react-hook-form 6 | * Useful to create custom array input iterators. 7 | * @see {ArrayInput} 8 | * @see {@link https://react-hook-form.com/api/usefieldarray} 9 | */ 10 | export const ArrayInputContext = createContext( 11 | undefined 12 | ); 13 | 14 | export type ArrayInputContextValue = UseFieldArrayReturn; 15 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ArrayInput/ClearArrayButton.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import ClearIcon from '@mui/icons-material/HighlightOff'; 3 | 4 | import { ButtonProps, IconButtonWithTooltip } from '../../button'; 5 | 6 | export const ClearArrayButton = (props: ButtonProps) => ( 7 | 13 | 14 | 15 | ); 16 | 17 | export default null; 18 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ArrayInput/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ArrayInput'; 2 | export * from './ArrayInputContext'; 3 | export * from './SimpleFormIterator'; 4 | export * from './SimpleFormIteratorContext'; 5 | export * from './SimpleFormIteratorItem'; 6 | export * from './SimpleFormIteratorItemContext'; 7 | export * from './useArrayInput'; 8 | export * from './useSimpleFormIterator'; 9 | export * from './useSimpleFormIteratorItem'; 10 | export * from './useSimpleFormIteratorStyles'; 11 | export * from './AddItemButton'; 12 | export * from './RemoveItemButton'; 13 | export * from './ReOrderButtons'; 14 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ArrayInput/useSimpleFormIterator.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { SimpleFormIteratorContext } from './SimpleFormIteratorContext'; 3 | 4 | /** 5 | * A hook that provides access to a SimpleFormIterator data (the total number of items) and mutators (add, reorder and remove). 6 | * Useful to create custom array input iterators. 7 | * @see {SimpleFormIterator} 8 | * @see {ArrayInput} 9 | */ 10 | export const useSimpleFormIterator = () => 11 | useContext(SimpleFormIteratorContext); 12 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ArrayInput/useSimpleFormIteratorItem.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from 'react'; 2 | import { SimpleFormIteratorItemContext } from './SimpleFormIteratorItemContext'; 3 | 4 | /** 5 | * A hook that provides access to a SimpleFormIterator item meta (its index and the total number of items) and mutators (reorder and remove this remove). 6 | * Useful to create custom array input iterators. 7 | * @see {SimpleFormIterator} 8 | * @see {ArrayInput} 9 | */ 10 | export const useSimpleFormIteratorItem = () => 11 | useContext(SimpleFormIteratorItemContext); 12 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ArrayInput/useSimpleFormIteratorStyles.ts: -------------------------------------------------------------------------------- 1 | export const SimpleFormIteratorPrefix = 'RaSimpleFormIterator'; 2 | 3 | export const SimpleFormIteratorClasses = { 4 | action: `${SimpleFormIteratorPrefix}-action`, 5 | add: `${SimpleFormIteratorPrefix}-add`, 6 | clear: `${SimpleFormIteratorPrefix}-clear`, 7 | form: `${SimpleFormIteratorPrefix}-form`, 8 | index: `${SimpleFormIteratorPrefix}-index`, 9 | inline: `${SimpleFormIteratorPrefix}-inline`, 10 | line: `${SimpleFormIteratorPrefix}-line`, 11 | list: `${SimpleFormIteratorPrefix}-list`, 12 | buttons: `${SimpleFormIteratorPrefix}-buttons`, 13 | }; 14 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/CommonInputProps.ts: -------------------------------------------------------------------------------- 1 | import { InputProps } from 'ra-core'; 2 | 3 | export type CommonInputProps = InputProps & { 4 | cellClassName?: string; 5 | /* 6 | * @deprecated this property is not used anymore 7 | */ 8 | formClassName?: string; 9 | fullWidth?: boolean; 10 | headerCellClassName?: string; 11 | margin?: 'none' | 'dense' | 'normal'; 12 | variant?: 'standard' | 'outlined' | 'filled'; 13 | }; 14 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ImageInputPreview.ts: -------------------------------------------------------------------------------- 1 | import { FileInputPreview } from './FileInputPreview'; 2 | export const ImageInputPreview = FileInputPreview; 3 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/InputPropTypes.ts: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | /** 4 | * Common PropTypes for all react-admin inputs 5 | */ 6 | export const InputPropTypes = { 7 | label: PropTypes.oneOfType([ 8 | PropTypes.string, 9 | PropTypes.bool, 10 | PropTypes.element, 11 | ]), 12 | resource: PropTypes.string, 13 | source: PropTypes.string, 14 | }; 15 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/common.stories.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useWatch } from 'react-hook-form'; 3 | 4 | export const FormInspector = ({ name = 'title' }) => { 5 | const value = useWatch({ name }); 6 | return ( 7 |
8 | {name} value in form:  9 | 10 | {JSON.stringify(value)} ({typeof value}) 11 | 12 |
13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/layout/LoadingPage.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | import { Loading } from './Loading'; 5 | 6 | export const LoadingPage = ({ 7 | loadingPrimary = 'ra.page.loading', 8 | loadingSecondary = 'ra.message.loading', 9 | ...props 10 | }) => ( 11 | 16 | ); 17 | 18 | LoadingPage.propTypes = { 19 | theme: PropTypes.object, 20 | className: PropTypes.string, 21 | loadingPrimary: PropTypes.string, 22 | loadingSecondary: PropTypes.string, 23 | }; 24 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/layout/Theme/index.ts: -------------------------------------------------------------------------------- 1 | export * from './useTheme'; 2 | export * from './ThemeProvider'; 3 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/layout/Theme/useTheme.ts: -------------------------------------------------------------------------------- 1 | import { useStore } from 'ra-core'; 2 | import { ThemeOptions, useTheme as useThemeMUI } from '@mui/material'; 3 | 4 | export type ThemeSetter = (theme: ThemeOptions) => void; 5 | 6 | export const useTheme = ( 7 | themeOverride?: ThemeOptions 8 | ): [ThemeOptions, ThemeSetter] => { 9 | const themeMUI = useThemeMUI(); 10 | const [theme, setter] = useStore('theme', themeOverride); 11 | return [theme || themeMUI, setter]; 12 | }; 13 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/layout/useSidebarState.ts: -------------------------------------------------------------------------------- 1 | import { useStore } from 'ra-core'; 2 | 3 | /** 4 | * A hook that returns the sidebar open state and a function to toggle it. 5 | * 6 | * @example 7 | * const ToggleSidebar = () => { 8 | * const [open, setOpen] = useSidebarState(); 9 | * return ( 10 | * 13 | * ); 14 | * }; 15 | */ 16 | export const useSidebarState = (): useSidebarStateResult => 17 | useStore('sidebar.open', true); 18 | 19 | export type useSidebarStateResult = [boolean, (open: boolean) => void]; 20 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/FilterContext.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export type FilterContextType = React.ReactNode[]; 4 | 5 | /** 6 | * Make filters accessible to sub components 7 | */ 8 | export const FilterContext = React.createContext(undefined); 9 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/ListNoResults.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { memo } from 'react'; 3 | import CardContent from '@mui/material/CardContent'; 4 | import Typography from '@mui/material/Typography'; 5 | import { useResourceContext, useTranslate } from 'ra-core'; 6 | 7 | export const ListNoResults = memo(() => { 8 | const translate = useTranslate(); 9 | const resource = useResourceContext(); 10 | return ( 11 | 12 | 13 | {translate('ra.navigation.no_results', { resource })} 14 | 15 | 16 | ); 17 | }); 18 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/Placeholder.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { styled } from '@mui/material/styles'; 3 | 4 | interface PlaceholderProps { 5 | className?: string; 6 | } 7 | 8 | export const Placeholder = (props: PlaceholderProps) => ( 9 |   10 | ); 11 | 12 | const PREFIX = 'RaPlaceholder'; 13 | 14 | const Root = styled('span', { 15 | name: PREFIX, 16 | overridesResolver: (props, styles) => styles.root, 17 | })(({ theme }) => ({ 18 | backgroundColor: theme.palette.grey[300], 19 | display: 'flex', 20 | })); 21 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/SimpleList/index.ts: -------------------------------------------------------------------------------- 1 | export * from './SimpleList'; 2 | export * from './SimpleListLoading'; 3 | export * from './SimpleListConfigurable'; 4 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/datagrid/DatagridContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import { RaRecord } from 'ra-core'; 3 | 4 | const DatagridContext = createContext({}); 5 | 6 | DatagridContext.displayName = 'DatagridContext'; 7 | 8 | export type DatagridContextValue = { 9 | isRowExpandable?: (record: RaRecord) => boolean; 10 | expandSingle?: boolean; 11 | }; 12 | 13 | export default DatagridContext; 14 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/datagrid/DatagridContextProvider.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactElement, ReactNode } from 'react'; 2 | import DatagridContext, { DatagridContextValue } from './DatagridContext'; 3 | 4 | const DatagridContextProvider = ({ 5 | children, 6 | value, 7 | }: { 8 | children: ReactNode; 9 | value: DatagridContextValue; 10 | }): ReactElement => ( 11 | 12 | {children} 13 | 14 | ); 15 | 16 | export default DatagridContextProvider; 17 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/datagrid/DatagridEditor.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useSetInspectorTitle } from 'ra-core'; 3 | 4 | import { FieldsSelector } from '../../preferences'; 5 | 6 | export const DatagridEditor = () => { 7 | useSetInspectorTitle('ra.inspector.Datagrid.title', { _: 'Datagrid' }); 8 | 9 | return ; 10 | }; 11 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/datagrid/useDatagridContext.ts: -------------------------------------------------------------------------------- 1 | import { useContext, useMemo } from 'react'; 2 | import { DatagridProps } from './Datagrid'; 3 | import DatagridContext, { DatagridContextValue } from './DatagridContext'; 4 | import defaults from 'lodash/defaults'; 5 | 6 | export const useDatagridContext = ( 7 | props?: DatagridProps 8 | ): DatagridContextValue => { 9 | const context = useContext(DatagridContext); 10 | 11 | return useMemo( 12 | () => 13 | defaults( 14 | {}, 15 | props != null ? { isRowExpandable: props.isRowExpandable } : {}, 16 | context 17 | ), 18 | [context, props] 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/filter/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Filter'; 2 | export * from './FilterButton'; 3 | export * from './FilterButtonMenuItem'; 4 | export * from './FilterForm'; 5 | export * from './FilterFormInput'; 6 | export * from './FilterList'; 7 | export * from './FilterListItem'; 8 | export * from './FilterLiveSearch'; 9 | export * from './AddSavedQueryDialog'; 10 | export * from './AddSavedQueryIconButton'; 11 | export * from './RemoveSavedQueryDialog'; 12 | export * from './RemoveSavedQueryIconButton'; 13 | export * from './SavedQueriesList'; 14 | export * from './SavedQueryFilterListItem'; 15 | export * from './useSavedQueries'; 16 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/index.ts: -------------------------------------------------------------------------------- 1 | export * from './BulkActionsToolbar'; 2 | export * from './Count'; 3 | export * from './datagrid'; 4 | export * from './Empty'; 5 | export * from './filter'; 6 | export * from './FilterContext'; 7 | export * from './List'; 8 | export * from './ListActions'; 9 | export * from './listFieldTypes'; 10 | export * from './ListGuesser'; 11 | export * from './ListNoResults'; 12 | export * from './ListToolbar'; 13 | export * from './ListView'; 14 | export * from './pagination'; 15 | export * from './Placeholder'; 16 | export * from './SimpleList'; 17 | export * from './SingleFieldList'; 18 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/pagination/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Pagination'; 2 | export * from './PaginationActions'; 3 | export * from './PaginationLimit'; 4 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/preferences/Inspector.stories.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { PreferencesEditorContextProvider } from 'ra-core'; 3 | import { InspectorButton } from './InspectorButton'; 4 | import { Inspector as InspectorUI } from './Inspector'; 5 | 6 | export default { 7 | title: 'ra-ui-materialui/preferences/Inspector', 8 | }; 9 | 10 | export const Inspector = () => ( 11 | 12 | 13 | 14 | 15 | ); 16 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/preferences/InspectorRoot.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Typography } from '@mui/material'; 3 | import { useTranslate, useSetInspectorTitle } from 'ra-core'; 4 | 5 | export const InspectorRoot = () => { 6 | const translate = useTranslate(); 7 | useSetInspectorTitle('ra.configurable.inspector.title', { 8 | _: 'Inspector', 9 | }); 10 | 11 | return ( 12 | 13 | {translate('ra.configurable.inspector.content', { 14 | _: 'Hover the application UI elements to configure them', 15 | })} 16 | 17 | ); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/preferences/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Configurable'; 2 | export * from './FieldsSelector'; 3 | export * from './FieldToggle'; 4 | export * from './Inspector'; 5 | export * from './InspectorButton'; 6 | export * from './InspectorRoot'; 7 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | }, 7 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js", "**/*.stories.tsx"], 8 | "include": ["src"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/react-admin/src/defaultI18nProvider.ts: -------------------------------------------------------------------------------- 1 | import defaultMessages from 'ra-language-english'; 2 | import polyglotI18nProvider from 'ra-i18n-polyglot'; 3 | 4 | export const defaultI18nProvider = polyglotI18nProvider( 5 | () => defaultMessages, 6 | 'en', 7 | [{ name: 'en', value: 'English' }], 8 | { allowMissing: true } 9 | ); 10 | -------------------------------------------------------------------------------- /packages/react-admin/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './Admin'; 2 | export * from './defaultI18nProvider'; 3 | export * from 'ra-core'; 4 | export * from 'ra-ui-materialui'; 5 | -------------------------------------------------------------------------------- /packages/react-admin/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "lib", 5 | "rootDir": "src", 6 | "allowJs": false 7 | }, 8 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 9 | "include": ["src"] 10 | } 11 | -------------------------------------------------------------------------------- /scripts/vercel-storybook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # storybook builds are allowed in this branch 4 | exit 1; 5 | -------------------------------------------------------------------------------- /test-global-setup.js: -------------------------------------------------------------------------------- 1 | module.exports = async () => { 2 | process.env.TZ = 'Europe/Paris'; 3 | }; 4 | -------------------------------------------------------------------------------- /test-setup.js: -------------------------------------------------------------------------------- 1 | require('raf/polyfill'); 2 | 3 | // Ignore warnings about act() 4 | // See https://github.com/testing-library/react-testing-library/issues/281, 5 | // https://github.com/facebook/react/issues/14769 6 | const originalError = console.error; 7 | jest.spyOn(console, 'error').mockImplementation((...args) => { 8 | if (/Warning.*not wrapped in act/.test(args[0])) { 9 | return; 10 | } 11 | originalError.call(console, ...args); 12 | }); 13 | 14 | /** 15 | * Mock fetch objects Response, Request and Headers 16 | */ 17 | const { Response, Headers, Request } = require('whatwg-fetch'); 18 | 19 | global.Response = Response; 20 | global.Headers = Headers; 21 | global.Request = Request; 22 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "github": { 3 | "silent": true 4 | } 5 | } 6 | --------------------------------------------------------------------------------