├── .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.json ├── 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 ├── AccordionForm.md ├── Actions.md ├── Admin.md ├── AdvancedTutorials.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 ├── Buttons.md ├── Caching.md ├── Calendar.md ├── CheckboxGroupInput.md ├── ChipField.md ├── CloneButton.md ├── Confirm.md ├── Create.md ├── CreateBase.md ├── CreateDialog.md ├── CreateReactApp.md ├── CustomRoutes.md ├── DataProviderIntroduction.md ├── DataProviderList.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 ├── EditTutorial.md ├── EditableDatagrid.md ├── EmailField.md ├── FAQ.md ├── Fields.md ├── FieldsForRelationships.md ├── FileField.md ├── FileInput.md ├── FilterButton.md ├── FilterForm.md ├── FilterList.md ├── FilterLiveSearch.md ├── FilteringTutorial.md ├── Form.md ├── FunctionField.md ├── IconMenu.md ├── ImageField.md ├── ImageInput.md ├── Inputs.md ├── Labeled.md ├── Layout.md ├── List.md ├── ListBase.md ├── ListButton.md ├── ListGuesser.md ├── ListTutorial.md ├── LocalesMenuButton.md ├── LongForm.md ├── MarkdownField.md ├── MarkdownInput.md ├── Menu.md ├── NextJs.md ├── NullableBooleanInput.md ├── NumberField.md ├── NumberInput.md ├── Pagination.md ├── PasswordInput.md ├── Permissions.md ├── RadioButtonGroupInput.md ├── Readme.md ├── Reference.md ├── ReferenceArrayField.md ├── ReferenceArrayInput.md ├── ReferenceField.md ├── ReferenceInput.md ├── ReferenceManyField.md ├── ReferenceManyToManyField.md ├── ReferenceManyToManyInput.md ├── ReferenceOneField.md ├── Remix.md ├── Resource.md ├── RichTextField.md ├── RichTextInput.md ├── Routing.md ├── SaveButton.md ├── SavedQueriesList.md ├── SelectArrayInput.md ├── SelectField.md ├── SelectInput.md ├── Show.md ├── ShowBase.md ├── ShowGuesser.md ├── ShowTutorial.md ├── SimpleForm.md ├── SimpleList.md ├── SimpleShowLayout.md ├── SingleFieldList.md ├── SortButton.md ├── Store.md ├── TabbedForm.md ├── TabbedShowLayout.md ├── TextField.md ├── TextInput.md ├── Theming.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 ├── 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 │ ├── syntax.css │ └── tocbot.css ├── documentation.html ├── img │ ├── FormTab-dynamic-label.png │ ├── LocalesMenuButton.gif │ ├── SaveButton.png │ ├── SavedQueriesList.gif │ ├── TabbedForm-layout.png │ ├── ToggleThemeButton.gif │ ├── Toolbar.png │ ├── actions-toolbar.png │ ├── array-input.gif │ ├── aside.png │ ├── autocomplete-array-input.gif │ ├── autocomplete-input.gif │ ├── blog_demo.png │ ├── boolean-field.png │ ├── boolean-input.png │ ├── bulk-actions-toolbar.gif │ ├── bulk-delete-button.png │ ├── bulk-export-button.png │ ├── checkbox-group-input.png │ ├── chip-field.png │ ├── confirm-dialog.png │ ├── 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-time-input.gif │ ├── disabled-input.png │ ├── edit-button.png │ ├── 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-view.jpg │ ├── list_filter.gif │ ├── list_with_customized_css.png │ ├── 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 │ ├── nullable-boolean-input-null-label.png │ ├── nullable-boolean-input.gif │ ├── 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.gif │ ├── react-admin-demo-still.png │ ├── react-query-devtools.png │ ├── reference-array-field.png │ ├── reference-field.png │ ├── reference-input.gif │ ├── reference-many-field-datagrid.png │ ├── reference-many-field-single-field-list.png │ ├── reference-posts.png │ ├── reference_field_show.png │ ├── reference_many_field.png │ ├── remix-structure.png │ ├── resettable-long-text-input.png │ ├── resettable-select-input.png │ ├── resettable-text-input.gif │ ├── responsive-list.gif │ ├── rich-text-field.png │ ├── rich-text-input.gif │ ├── search_input.gif │ ├── select-array-input.gif │ ├── select-input.gif │ ├── show-button.png │ ├── show-view.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 │ ├── 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_overview.gif │ ├── tutorial_post_create.gif │ ├── tutorial_post_edit_undo.gif │ ├── tutorial_post_list_less_columns.png │ ├── tutorial_post_title.png │ ├── tutorial_url_field.png │ ├── tutorial_users_list.png │ ├── tutorial_users_list_selected_columns.png │ └── warn_when_unsaved_changes.png ├── js │ ├── materialize.min.js │ └── prism.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 ├── useGetMany.md ├── useGetManyReference.md ├── useGetOne.md ├── useList.md ├── useListContext.md ├── useListController.md ├── useLocaleState.md ├── useLogin.md ├── useLogout.md ├── useNotify.md ├── usePermissions.md ├── useRecordContext.md ├── useRedirect.md ├── useRefresh.md ├── useRemoveFromStore.md ├── useResetStore.md ├── useSaveContext.md ├── useShowContext.md ├── useShowController.md ├── useStore.md ├── useStoreContext.md ├── useTranslate.md ├── useUnselect.md ├── useUnselectAll.md ├── useUpdate.md └── useUpdateMany.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 │ ├── 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 ├── 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 │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── index.html │ └── manifest.json │ └── src │ ├── App.js │ ├── Dashboard.js │ ├── authProvider.js │ ├── index.js │ ├── index.module.css │ ├── logo.svg │ ├── posts.js │ ├── registerServiceWorker.js │ └── users.js ├── 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.ts │ │ │ ├── useGetPermissions.ts │ │ │ ├── useLogin.ts │ │ │ ├── useLogout.ts │ │ │ ├── useLogoutIfAccessDenied.spec.tsx │ │ │ ├── useLogoutIfAccessDenied.ts │ │ │ ├── usePermissions.spec.tsx │ │ │ ├── usePermissions.ts │ │ │ ├── usePermissionsOptimized.spec.tsx │ │ │ └── usePermissionsOptimized.ts │ │ ├── controller │ │ │ ├── button │ │ │ │ ├── index.ts │ │ │ │ ├── useDeleteWithConfirmController.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.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.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 │ │ │ ├── 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 │ │ │ ├── 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 │ │ ├── export │ │ │ ├── ExporterContext.ts │ │ │ ├── defaultExporter.ts │ │ │ ├── downloadCSV.ts │ │ │ ├── fetchRelatedRecords.spec.ts │ │ │ ├── fetchRelatedRecords.ts │ │ │ └── index.ts │ │ ├── form │ │ │ ├── Form.spec.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 │ │ │ ├── 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 │ │ │ ├── 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 │ │ │ ├── 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 │ │ │ ├── NotificationContext.ts │ │ │ ├── NotificationContextProvider.tsx │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ ├── useNotificationContext.ts │ │ │ ├── useNotify.spec.tsx │ │ │ └── useNotify.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.tsx │ │ │ ├── localStorageStore.stories.tsx │ │ │ ├── localStorageStore.ts │ │ │ ├── memoryStore.stories.tsx │ │ │ ├── memoryStore.tsx │ │ │ ├── types.ts │ │ │ ├── useRemoveFromStore.ts │ │ │ ├── useResetStore.ts │ │ │ ├── useStore.spec.tsx │ │ │ ├── useStore.stories.tsx │ │ │ ├── useStore.ts │ │ │ └── useStoreContext.ts │ │ ├── storybook │ │ │ └── FakeBrowser.tsx │ │ ├── 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 │ │ │ ├── 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-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.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 │ │ │ ├── Login.tsx │ │ │ ├── LoginForm.tsx │ │ │ ├── Logout.spec.tsx │ │ │ ├── Logout.stories.tsx │ │ │ ├── Logout.tsx │ │ │ └── index.ts │ │ ├── button │ │ │ ├── BulkDeleteButton.tsx │ │ │ ├── BulkDeleteWithConfirmButton.tsx │ │ │ ├── BulkDeleteWithUndoButton.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.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.tsx │ │ │ ├── ReferenceField.spec.tsx │ │ │ ├── ReferenceField.stories.tsx │ │ │ ├── ReferenceField.tsx │ │ │ ├── ReferenceManyField.spec.tsx │ │ │ ├── ReferenceManyField.tsx │ │ │ ├── ReferenceOneField.stories.tsx │ │ │ ├── ReferenceOneField.tsx │ │ │ ├── RichTextField.spec.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 │ │ │ ├── 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 │ │ │ │ ├── ReOrderButtons.tsx │ │ │ │ ├── RemoveItemButton.tsx │ │ │ │ ├── SimpleFormIterator.spec.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.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 │ │ │ ├── NullableBooleanInput.spec.tsx │ │ │ ├── NullableBooleanInput.tsx │ │ │ ├── NumberInput.spec.tsx │ │ │ ├── NumberInput.stories.tsx │ │ │ ├── NumberInput.tsx │ │ │ ├── PasswordInput.tsx │ │ │ ├── RadioButtonGroupInput.spec.tsx │ │ │ ├── RadioButtonGroupInput.tsx │ │ │ ├── RadioButtonGroupInputItem.tsx │ │ │ ├── ReferenceArrayInput.spec.tsx │ │ │ ├── ReferenceArrayInput.stories.tsx │ │ │ ├── ReferenceArrayInput.tsx │ │ │ ├── ReferenceError.tsx │ │ │ ├── ReferenceInput.spec.tsx │ │ │ ├── ReferenceInput.tsx │ │ │ ├── ResettableTextField.tsx │ │ │ ├── SearchInput.tsx │ │ │ ├── SelectArrayInput.spec.tsx │ │ │ ├── SelectArrayInput.tsx │ │ │ ├── SelectInput.spec.tsx │ │ │ ├── SelectInput.tsx │ │ │ ├── TextInput.spec.tsx │ │ │ ├── TextInput.tsx │ │ │ ├── TranslatableInputs.spec.tsx │ │ │ ├── TranslatableInputs.tsx │ │ │ ├── TranslatableInputsTab.tsx │ │ │ ├── TranslatableInputsTabContent.tsx │ │ │ ├── TranslatableInputsTabs.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.tsx │ │ │ ├── Sidebar.tsx │ │ │ ├── SidebarToggleButton.tsx │ │ │ ├── Theme │ │ │ │ ├── ThemeProvider.tsx │ │ │ │ ├── index.ts │ │ │ │ └── useTheme.ts │ │ │ ├── Title.tsx │ │ │ ├── TopToolbar.tsx │ │ │ ├── UserMenu.tsx │ │ │ ├── UserMenuContext.ts │ │ │ ├── UserMenuContextProvider.tsx │ │ │ ├── index.ts │ │ │ ├── useResetErrorBoundaryOnLocationChange.ts │ │ │ ├── useSidebarState.ts │ │ │ └── useUserMenu.ts │ │ ├── list │ │ │ ├── BulkActionsToolbar.tsx │ │ │ ├── Empty.tsx │ │ │ ├── FilterContext.tsx │ │ │ ├── List.spec.tsx │ │ │ ├── List.stories.tsx │ │ │ ├── List.tsx │ │ │ ├── ListActions.tsx │ │ │ ├── ListGuesser.spec.tsx │ │ │ ├── ListGuesser.tsx │ │ │ ├── ListToolbar.tsx │ │ │ ├── ListView.tsx │ │ │ ├── Placeholder.tsx │ │ │ ├── SimpleList.spec.tsx │ │ │ ├── SimpleList.tsx │ │ │ ├── SimpleListLoading.tsx │ │ │ ├── SingleFieldList.spec.tsx │ │ │ ├── SingleFieldList.tsx │ │ │ ├── datagrid │ │ │ │ ├── Datagrid.spec.tsx │ │ │ │ ├── Datagrid.stories.tsx │ │ │ │ ├── Datagrid.tsx │ │ │ │ ├── DatagridBody.tsx │ │ │ │ ├── DatagridCell.spec.tsx │ │ │ │ ├── DatagridCell.tsx │ │ │ │ ├── DatagridContext.ts │ │ │ │ ├── DatagridContextProvider.tsx │ │ │ │ ├── DatagridHeader.tsx │ │ │ │ ├── DatagridHeaderCell.spec.tsx │ │ │ │ ├── DatagridHeaderCell.tsx │ │ │ │ ├── DatagridLoading.tsx │ │ │ │ ├── DatagridRow.spec.tsx │ │ │ │ ├── DatagridRow.tsx │ │ │ │ ├── ExpandRowButton.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 │ │ └── types.ts │ └── tsconfig.json └── react-admin │ ├── README.md │ ├── package.json │ ├── src │ ├── Admin.spec.tsx │ ├── Admin.stories.tsx │ ├── Admin.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! 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`). Thanks! 😁. 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/Feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F680 Feature request" 3 | about: "I have a suggestion (and may want to implement it \U0001F642)!" 4 | 5 | --- 6 | 7 | **Is your feature request related to a problem? Please describe.** 8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 9 | 10 | **Describe the solution you'd like** 11 | A clear and concise description of what you want to happen. 12 | 13 | **Describe alternatives you've considered** 14 | A clear and concise description of any alternative solutions or features you've considered. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.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/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": "^9.1.1", 12 | "cypress-plugin-tab": "^1.0.5", 13 | "express": "~4.16.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cypress/plugins/index.js: -------------------------------------------------------------------------------- 1 | const wp = require('@cypress/webpack-preprocessor'); 2 | 3 | module.exports = on => { 4 | const options = { 5 | webpackOptions: require('../webpack.config'), 6 | }; 7 | on('before:browser:launch', (browser = {}, launchOptions) => { 8 | // Fix for Cypress 4: 9 | // https://docs.cypress.io/api/plugins/browser-launch-api.html#Usage 10 | if (browser.name === 'chrome') { 11 | launchOptions.args.push( 12 | '--disable-blink-features=RootLayerScrolling' 13 | ); 14 | launchOptions.args.push('--disable-gpu'); 15 | launchOptions.args.push('--proxy-bypass-list=<-loopback>'); 16 | return launchOptions; 17 | } 18 | }); 19 | on('file:preprocessor', wp(options)); 20 | }; 21 | -------------------------------------------------------------------------------- /cypress/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const path = require('path'); 3 | 4 | exports.start = () => 5 | new Promise((resolve, reject) => { 6 | const server = express(); 7 | server.use( 8 | '/', 9 | express.static(path.join(__dirname, '../examples/simple/dist')) 10 | ); 11 | 12 | server.on('error', err => { 13 | if (!server.listening) { 14 | return reject(err); 15 | } 16 | 17 | throw err; 18 | }); 19 | 20 | const listeningServer = server.listen(8080); 21 | 22 | // Give some time to enable error catching before resolving (for EADDRINUSE error) 23 | setTimeout(() => { 24 | resolve(listeningServer); 25 | }, 1000); 26 | }); 27 | -------------------------------------------------------------------------------- /cypress/start.js: -------------------------------------------------------------------------------- 1 | const cypress = require('cypress'); 2 | const server = require('./server'); 3 | 4 | return server.start().then(listeningServer => { 5 | // kick off a cypress run 6 | return cypress 7 | .run({ 8 | browser: process.env.BROWSER || 'chrome', 9 | config: { 10 | baseUrl: 'http://localhost:8080', 11 | video: false, 12 | }, 13 | }) 14 | .then(results => { 15 | // stop your server when it's complete 16 | listeningServer.close(); 17 | if (results.totalFailed > 0) { 18 | process.exit(1); 19 | } 20 | }) 21 | .catch(() => { 22 | process.exit(1); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /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": "integration" 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/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/assets/logo_white.png -------------------------------------------------------------------------------- /docs/img/FormTab-dynamic-label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/FormTab-dynamic-label.png -------------------------------------------------------------------------------- /docs/img/LocalesMenuButton.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/LocalesMenuButton.gif -------------------------------------------------------------------------------- /docs/img/SaveButton.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/SaveButton.png -------------------------------------------------------------------------------- /docs/img/SavedQueriesList.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/SavedQueriesList.gif -------------------------------------------------------------------------------- /docs/img/TabbedForm-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/TabbedForm-layout.png -------------------------------------------------------------------------------- /docs/img/ToggleThemeButton.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/ToggleThemeButton.gif -------------------------------------------------------------------------------- /docs/img/Toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/Toolbar.png -------------------------------------------------------------------------------- /docs/img/actions-toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/actions-toolbar.png -------------------------------------------------------------------------------- /docs/img/array-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/array-input.gif -------------------------------------------------------------------------------- /docs/img/aside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/aside.png -------------------------------------------------------------------------------- /docs/img/autocomplete-array-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/autocomplete-array-input.gif -------------------------------------------------------------------------------- /docs/img/autocomplete-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/autocomplete-input.gif -------------------------------------------------------------------------------- /docs/img/blog_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/blog_demo.png -------------------------------------------------------------------------------- /docs/img/boolean-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/boolean-field.png -------------------------------------------------------------------------------- /docs/img/boolean-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/boolean-input.png -------------------------------------------------------------------------------- /docs/img/bulk-actions-toolbar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/bulk-actions-toolbar.gif -------------------------------------------------------------------------------- /docs/img/bulk-delete-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/bulk-delete-button.png -------------------------------------------------------------------------------- /docs/img/bulk-export-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/bulk-export-button.png -------------------------------------------------------------------------------- /docs/img/checkbox-group-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/checkbox-group-input.png -------------------------------------------------------------------------------- /docs/img/chip-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/chip-field.png -------------------------------------------------------------------------------- /docs/img/confirm-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/confirm-dialog.png -------------------------------------------------------------------------------- /docs/img/create-button-fab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/create-button-fab.png -------------------------------------------------------------------------------- /docs/img/create-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/create-button.png -------------------------------------------------------------------------------- /docs/img/create-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/create-view.png -------------------------------------------------------------------------------- /docs/img/custom-form-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/custom-form-layout.png -------------------------------------------------------------------------------- /docs/img/custom-iterator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/custom-iterator.png -------------------------------------------------------------------------------- /docs/img/custom-menu.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/custom-menu.gif -------------------------------------------------------------------------------- /docs/img/custom-menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/custom-menu.png -------------------------------------------------------------------------------- /docs/img/custom-switch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/custom-switch-icon.png -------------------------------------------------------------------------------- /docs/img/custom_appbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/custom_appbar.png -------------------------------------------------------------------------------- /docs/img/dark-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/dark-theme.png -------------------------------------------------------------------------------- /docs/img/dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/dashboard.png -------------------------------------------------------------------------------- /docs/img/data-provider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/data-provider.png -------------------------------------------------------------------------------- /docs/img/datagrid_expand.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/datagrid_expand.gif -------------------------------------------------------------------------------- /docs/img/date-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/date-input.gif -------------------------------------------------------------------------------- /docs/img/date-time-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/date-time-input.gif -------------------------------------------------------------------------------- /docs/img/disabled-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/disabled-input.png -------------------------------------------------------------------------------- /docs/img/edit-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/edit-button.png -------------------------------------------------------------------------------- /docs/img/edit-view-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/edit-view-example.png -------------------------------------------------------------------------------- /docs/img/edit-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/edit-view.png -------------------------------------------------------------------------------- /docs/img/editable-post.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/editable-post.png -------------------------------------------------------------------------------- /docs/img/error.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/error.webp -------------------------------------------------------------------------------- /docs/img/export-button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/export-button.gif -------------------------------------------------------------------------------- /docs/img/export-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/export-button.png -------------------------------------------------------------------------------- /docs/img/field-addlabel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/field-addlabel.png -------------------------------------------------------------------------------- /docs/img/file-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/file-input.png -------------------------------------------------------------------------------- /docs/img/filter-live-search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/filter-live-search.gif -------------------------------------------------------------------------------- /docs/img/filter-sidebar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/filter-sidebar.gif -------------------------------------------------------------------------------- /docs/img/filter_with_submit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/filter_with_submit.gif -------------------------------------------------------------------------------- /docs/img/filters.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/filters.gif -------------------------------------------------------------------------------- /docs/img/form-toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/form-toolbar.png -------------------------------------------------------------------------------- /docs/img/guessed-edit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/guessed-edit.png -------------------------------------------------------------------------------- /docs/img/guessed-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/guessed-list.png -------------------------------------------------------------------------------- /docs/img/guessed-show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/guessed-show.png -------------------------------------------------------------------------------- /docs/img/identity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/identity.png -------------------------------------------------------------------------------- /docs/img/image-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/image-input.png -------------------------------------------------------------------------------- /docs/img/input-full-width.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/input-full-width.png -------------------------------------------------------------------------------- /docs/img/input-helper-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/input-helper-text.png -------------------------------------------------------------------------------- /docs/img/inputs.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/inputs.webp -------------------------------------------------------------------------------- /docs/img/layout-component.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/layout-component.gif -------------------------------------------------------------------------------- /docs/img/layout-responsive.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/layout-responsive.gif -------------------------------------------------------------------------------- /docs/img/list-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/list-button.png -------------------------------------------------------------------------------- /docs/img/list-empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/list-empty.png -------------------------------------------------------------------------------- /docs/img/list-view.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/list-view.jpg -------------------------------------------------------------------------------- /docs/img/list_filter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/list_filter.gif -------------------------------------------------------------------------------- /docs/img/list_with_customized_css.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/list_with_customized_css.png -------------------------------------------------------------------------------- /docs/img/login-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/login-form.png -------------------------------------------------------------------------------- /docs/img/login.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/login.gif -------------------------------------------------------------------------------- /docs/img/logout.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/logout.gif -------------------------------------------------------------------------------- /docs/img/long-text-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/long-text-input.png -------------------------------------------------------------------------------- /docs/img/markdown-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/markdown-input.gif -------------------------------------------------------------------------------- /docs/img/menu-with-dashboard.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/menu-with-dashboard.webp -------------------------------------------------------------------------------- /docs/img/menu.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/menu.webp -------------------------------------------------------------------------------- /docs/img/mobile-post-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/mobile-post-list.png -------------------------------------------------------------------------------- /docs/img/navidrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/navidrome.png -------------------------------------------------------------------------------- /docs/img/nextjs-file-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/nextjs-file-structure.png -------------------------------------------------------------------------------- /docs/img/nextjs-react-admin.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/nextjs-react-admin.webp -------------------------------------------------------------------------------- /docs/img/nextjs-setup.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/nextjs-setup.webp -------------------------------------------------------------------------------- /docs/img/not-found.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/not-found.png -------------------------------------------------------------------------------- /docs/img/nullable-boolean-input-null-label.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/nullable-boolean-input-null-label.png -------------------------------------------------------------------------------- /docs/img/nullable-boolean-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/nullable-boolean-input.gif -------------------------------------------------------------------------------- /docs/img/number-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/number-input.gif -------------------------------------------------------------------------------- /docs/img/openid-connect-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/openid-connect-example.png -------------------------------------------------------------------------------- /docs/img/pagination-buttons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/pagination-buttons.gif -------------------------------------------------------------------------------- /docs/img/password-input-visible.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/password-input-visible.png -------------------------------------------------------------------------------- /docs/img/password-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/password-input.png -------------------------------------------------------------------------------- /docs/img/post-deletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/post-deletion.png -------------------------------------------------------------------------------- /docs/img/post-edition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/post-edition.png -------------------------------------------------------------------------------- /docs/img/post-show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/post-show.png -------------------------------------------------------------------------------- /docs/img/quick_filters.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/quick_filters.gif -------------------------------------------------------------------------------- /docs/img/ra-longform-cardinality.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/ra-longform-cardinality.png -------------------------------------------------------------------------------- /docs/img/ra-longform-overview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/ra-longform-overview.gif -------------------------------------------------------------------------------- /docs/img/ra-rbac.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/ra-rbac.mp4 -------------------------------------------------------------------------------- /docs/img/ra-tree.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/ra-tree.gif -------------------------------------------------------------------------------- /docs/img/radio-button-group-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/radio-button-group-input.gif -------------------------------------------------------------------------------- /docs/img/react-admin-demo-still.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/react-admin-demo-still.png -------------------------------------------------------------------------------- /docs/img/react-query-devtools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/react-query-devtools.png -------------------------------------------------------------------------------- /docs/img/reference-array-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/reference-array-field.png -------------------------------------------------------------------------------- /docs/img/reference-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/reference-field.png -------------------------------------------------------------------------------- /docs/img/reference-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/reference-input.gif -------------------------------------------------------------------------------- /docs/img/reference-many-field-datagrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/reference-many-field-datagrid.png -------------------------------------------------------------------------------- /docs/img/reference-many-field-single-field-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/reference-many-field-single-field-list.png -------------------------------------------------------------------------------- /docs/img/reference-posts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/reference-posts.png -------------------------------------------------------------------------------- /docs/img/reference_field_show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/reference_field_show.png -------------------------------------------------------------------------------- /docs/img/reference_many_field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/reference_many_field.png -------------------------------------------------------------------------------- /docs/img/remix-structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/remix-structure.png -------------------------------------------------------------------------------- /docs/img/resettable-long-text-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/resettable-long-text-input.png -------------------------------------------------------------------------------- /docs/img/resettable-select-input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/resettable-select-input.png -------------------------------------------------------------------------------- /docs/img/resettable-text-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/resettable-text-input.gif -------------------------------------------------------------------------------- /docs/img/responsive-list.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/responsive-list.gif -------------------------------------------------------------------------------- /docs/img/rich-text-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/rich-text-field.png -------------------------------------------------------------------------------- /docs/img/rich-text-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/rich-text-input.gif -------------------------------------------------------------------------------- /docs/img/search_input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/search_input.gif -------------------------------------------------------------------------------- /docs/img/select-array-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/select-array-input.gif -------------------------------------------------------------------------------- /docs/img/select-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/select-input.gif -------------------------------------------------------------------------------- /docs/img/show-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/show-button.png -------------------------------------------------------------------------------- /docs/img/show-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/show-view.png -------------------------------------------------------------------------------- /docs/img/simple-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/simple-form.png -------------------------------------------------------------------------------- /docs/img/simple-list.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/simple-list.gif -------------------------------------------------------------------------------- /docs/img/simple-post-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/simple-post-list.png -------------------------------------------------------------------------------- /docs/img/simple-user-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/simple-user-list.png -------------------------------------------------------------------------------- /docs/img/simpleform-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/simpleform-layout.png -------------------------------------------------------------------------------- /docs/img/singlefieldlist-datagrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/singlefieldlist-datagrid.png -------------------------------------------------------------------------------- /docs/img/singlefieldlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/singlefieldlist.png -------------------------------------------------------------------------------- /docs/img/sort-button.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/sort-button.gif -------------------------------------------------------------------------------- /docs/img/sort-column-header.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/sort-column-header.gif -------------------------------------------------------------------------------- /docs/img/sx-class-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/sx-class-name.png -------------------------------------------------------------------------------- /docs/img/sx-documentation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/sx-documentation.png -------------------------------------------------------------------------------- /docs/img/tabbed-form.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tabbed-form.gif -------------------------------------------------------------------------------- /docs/img/tabbed-show.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tabbed-show.gif -------------------------------------------------------------------------------- /docs/img/text-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/text-input.gif -------------------------------------------------------------------------------- /docs/img/translatable-input.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/translatable-input.gif -------------------------------------------------------------------------------- /docs/img/translation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/translation.gif -------------------------------------------------------------------------------- /docs/img/treewithdetails.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/treewithdetails.gif -------------------------------------------------------------------------------- /docs/img/tutorial_custom_styles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_custom_styles.png -------------------------------------------------------------------------------- /docs/img/tutorial_edit_guesser.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_edit_guesser.gif -------------------------------------------------------------------------------- /docs/img/tutorial_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_empty.png -------------------------------------------------------------------------------- /docs/img/tutorial_guessed_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_guessed_list.png -------------------------------------------------------------------------------- /docs/img/tutorial_guessed_post_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_guessed_post_list.png -------------------------------------------------------------------------------- /docs/img/tutorial_list_user_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_list_user_name.png -------------------------------------------------------------------------------- /docs/img/tutorial_mobile_post_list.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_mobile_post_list.gif -------------------------------------------------------------------------------- /docs/img/tutorial_overview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_overview.gif -------------------------------------------------------------------------------- /docs/img/tutorial_post_create.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_post_create.gif -------------------------------------------------------------------------------- /docs/img/tutorial_post_edit_undo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_post_edit_undo.gif -------------------------------------------------------------------------------- /docs/img/tutorial_post_list_less_columns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_post_list_less_columns.png -------------------------------------------------------------------------------- /docs/img/tutorial_post_title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_post_title.png -------------------------------------------------------------------------------- /docs/img/tutorial_url_field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_url_field.png -------------------------------------------------------------------------------- /docs/img/tutorial_users_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_users_list.png -------------------------------------------------------------------------------- /docs/img/tutorial_users_list_selected_columns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/docs/img/tutorial_users_list_selected_columns.png -------------------------------------------------------------------------------- /docs/img/warn_when_unsaved_changes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/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/useUnselect.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: "useUnselect" 4 | --- 5 | 6 | # `useUnselect` 7 | 8 | This hook returns a function that unselects lines in the current `` that match an array of ids. Pass the name of the resource to the hook as argument. 9 | 10 | ```jsx 11 | import { useListContext, useUnselect } from 'react-admin'; 12 | 13 | const UnselectButton = () => { 14 | const { resource, selectedIds } = useListContext(); 15 | const unselect = useUnselect(resource); 16 | 17 | const handleClick = () => { 18 | unselect(selectedIds); 19 | }; 20 | 21 | return ( 22 | 25 | ); 26 | }; 27 | ``` 28 | 29 | -------------------------------------------------------------------------------- /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/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | ## Contributing 4 | 5 | If you'd like to contribute example applications, you'll likely use [create-react-app](https://github.com/facebookincubator/create-react-app). Unfortunately, you won't be able to initialize your example by running `create-react-app myexample` directly in this directory. This is because `create-react-app` does not work yet with yarn workspaces and lerna. There is a workaround though: 6 | 7 | Initialize your new example application outside react-admin folder then simply move the newly created folder inside the `examples` folder. Finally, run `yarn` at the react-admin root folder. 8 | 9 | **Tip:** Ensure you don't commit a `yarn.lock` inside your new example application folder. 10 | -------------------------------------------------------------------------------- /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/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/favicon.ico -------------------------------------------------------------------------------- /examples/crm/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logo192.png -------------------------------------------------------------------------------- /examples/crm/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logo512.png -------------------------------------------------------------------------------- /examples/crm/public/logos/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/0.png -------------------------------------------------------------------------------- /examples/crm/public/logos/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/1.png -------------------------------------------------------------------------------- /examples/crm/public/logos/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/10.png -------------------------------------------------------------------------------- /examples/crm/public/logos/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/11.png -------------------------------------------------------------------------------- /examples/crm/public/logos/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/12.png -------------------------------------------------------------------------------- /examples/crm/public/logos/13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/13.png -------------------------------------------------------------------------------- /examples/crm/public/logos/14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/14.png -------------------------------------------------------------------------------- /examples/crm/public/logos/15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/15.png -------------------------------------------------------------------------------- /examples/crm/public/logos/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/16.png -------------------------------------------------------------------------------- /examples/crm/public/logos/17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/17.png -------------------------------------------------------------------------------- /examples/crm/public/logos/18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/18.png -------------------------------------------------------------------------------- /examples/crm/public/logos/19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/19.png -------------------------------------------------------------------------------- /examples/crm/public/logos/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/2.png -------------------------------------------------------------------------------- /examples/crm/public/logos/20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/20.png -------------------------------------------------------------------------------- /examples/crm/public/logos/21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/21.png -------------------------------------------------------------------------------- /examples/crm/public/logos/22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/22.png -------------------------------------------------------------------------------- /examples/crm/public/logos/23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/23.png -------------------------------------------------------------------------------- /examples/crm/public/logos/24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/24.png -------------------------------------------------------------------------------- /examples/crm/public/logos/25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/25.png -------------------------------------------------------------------------------- /examples/crm/public/logos/26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/26.png -------------------------------------------------------------------------------- /examples/crm/public/logos/27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/27.png -------------------------------------------------------------------------------- /examples/crm/public/logos/28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/28.png -------------------------------------------------------------------------------- /examples/crm/public/logos/29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/29.png -------------------------------------------------------------------------------- /examples/crm/public/logos/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/3.png -------------------------------------------------------------------------------- /examples/crm/public/logos/30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/30.png -------------------------------------------------------------------------------- /examples/crm/public/logos/31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/31.png -------------------------------------------------------------------------------- /examples/crm/public/logos/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/32.png -------------------------------------------------------------------------------- /examples/crm/public/logos/33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/33.png -------------------------------------------------------------------------------- /examples/crm/public/logos/34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/34.png -------------------------------------------------------------------------------- /examples/crm/public/logos/35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/35.png -------------------------------------------------------------------------------- /examples/crm/public/logos/36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/36.png -------------------------------------------------------------------------------- /examples/crm/public/logos/37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/37.png -------------------------------------------------------------------------------- /examples/crm/public/logos/38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/38.png -------------------------------------------------------------------------------- /examples/crm/public/logos/39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/39.png -------------------------------------------------------------------------------- /examples/crm/public/logos/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/4.png -------------------------------------------------------------------------------- /examples/crm/public/logos/40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/40.png -------------------------------------------------------------------------------- /examples/crm/public/logos/41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/41.png -------------------------------------------------------------------------------- /examples/crm/public/logos/42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/42.png -------------------------------------------------------------------------------- /examples/crm/public/logos/43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/43.png -------------------------------------------------------------------------------- /examples/crm/public/logos/44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/44.png -------------------------------------------------------------------------------- /examples/crm/public/logos/45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/45.png -------------------------------------------------------------------------------- /examples/crm/public/logos/46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/46.png -------------------------------------------------------------------------------- /examples/crm/public/logos/47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/47.png -------------------------------------------------------------------------------- /examples/crm/public/logos/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/48.png -------------------------------------------------------------------------------- /examples/crm/public/logos/49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/49.png -------------------------------------------------------------------------------- /examples/crm/public/logos/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/5.png -------------------------------------------------------------------------------- /examples/crm/public/logos/50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/50.png -------------------------------------------------------------------------------- /examples/crm/public/logos/51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/51.png -------------------------------------------------------------------------------- /examples/crm/public/logos/52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/52.png -------------------------------------------------------------------------------- /examples/crm/public/logos/53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/53.png -------------------------------------------------------------------------------- /examples/crm/public/logos/54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/54.png -------------------------------------------------------------------------------- /examples/crm/public/logos/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/55.png -------------------------------------------------------------------------------- /examples/crm/public/logos/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/6.png -------------------------------------------------------------------------------- /examples/crm/public/logos/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/7.png -------------------------------------------------------------------------------- /examples/crm/public/logos/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/crm/public/logos/8.png -------------------------------------------------------------------------------- /examples/crm/public/logos/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/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/sales.ts: -------------------------------------------------------------------------------- 1 | import { name, internet } from 'faker/locale/en_US'; 2 | 3 | import { Db } from './types'; 4 | 5 | export const generateSales = (db: Db) => { 6 | const randomSales = Array.from(Array(10).keys()).map(id => { 7 | const first_name = name.firstName(); 8 | const last_name = name.lastName(); 9 | const email = internet.email(first_name, last_name); 10 | 11 | return { 12 | id: id + 1, 13 | first_name, 14 | last_name, 15 | email, 16 | }; 17 | }); 18 | return [ 19 | { 20 | id: 0, 21 | first_name: 'Jane', 22 | last_name: 'Doe', 23 | email: 'janedoe@atomic.dev', 24 | }, 25 | ...randomSales, 26 | ]; 27 | }; 28 | -------------------------------------------------------------------------------- /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/misc/Status.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Box } from '@mui/material'; 3 | 4 | const getColorFromStatus = (status: string) => 5 | status === 'cold' 6 | ? '#7dbde8' 7 | : status === 'warm' 8 | ? '#e8cb7d' 9 | : status === 'hot' 10 | ? '#e88b7d' 11 | : status === 'in-contract' 12 | ? '#a4e87d' 13 | : '#000'; 14 | 15 | export const Status = ({ status }: { status: string }) => ( 16 | 25 | ); 26 | -------------------------------------------------------------------------------- /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/src/invoices.ts: -------------------------------------------------------------------------------- 1 | export default db => { 2 | let id = 0; 3 | 4 | return ( 5 | db.commands 6 | .filter(command => command.status !== 'delivered') 7 | // @ts-ignore 8 | .sort((a, b) => new Date(a.date) - new Date(b.date)) 9 | .map(command => ({ 10 | id: id++, 11 | date: command.date, 12 | command_id: command.id, 13 | customer_id: command.customer_id, 14 | total_ex_taxes: command.total_ex_taxes, 15 | delivery_fees: command.delivery_fees, 16 | tax_rate: command.tax_rate, 17 | taxes: command.taxes, 18 | total: command.total, 19 | })) 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /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/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/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/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/examples/demo/src/dashboard/cartouche.png -------------------------------------------------------------------------------- /examples/demo/src/dashboard/cartoucheDark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/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 | /** @jsxRuntime classic */ 2 | import 'react-app-polyfill/ie11'; 3 | import 'react-app-polyfill/stable'; 4 | import 'proxy-polyfill'; 5 | // IE11 needs "jsxRuntime classic" for this initial file which means that "React" needs to be in scope 6 | // https://github.com/facebook/create-react-app/issues/9906 7 | 8 | import * as React from 'react'; 9 | import ReactDOM from 'react-dom'; 10 | 11 | import App from './App'; 12 | 13 | ReactDOM.render(, document.getElementById('root')); 14 | -------------------------------------------------------------------------------- /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 | return ; 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/ProductRefField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Link } from 'react-router-dom'; 3 | import { Link as MuiLink } from '@mui/material'; 4 | import { useRecordContext } from 'react-admin'; 5 | import { Product } from '../types'; 6 | 7 | const ProductRefField = () => { 8 | const record = useRecordContext(); 9 | return record ? ( 10 | 15 | {record.reference} 16 | 17 | ) : null; 18 | }; 19 | 20 | ProductRefField.defaultProps = { 21 | source: 'id', 22 | label: 'Reference', 23 | }; 24 | 25 | export default ProductRefField; 26 | -------------------------------------------------------------------------------- /examples/demo/src/products/ProductReferenceField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ReferenceField, ReferenceFieldProps, TextField } from 'react-admin'; 3 | 4 | interface Props { 5 | source?: string; 6 | } 7 | 8 | const ProductReferenceField = ( 9 | props: Props & 10 | Omit, 'reference' | 'children'> 11 | ) => ( 12 | 18 | 19 | 20 | ); 21 | 22 | ProductReferenceField.defaultProps = { 23 | source: 'product_id', 24 | }; 25 | 26 | export default ProductReferenceField; 27 | -------------------------------------------------------------------------------- /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/AvatarField.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Avatar, SxProps } from '@mui/material'; 3 | import { FieldProps, useRecordContext } from 'react-admin'; 4 | import { Customer } from '../types'; 5 | 6 | interface Props extends FieldProps { 7 | sx?: SxProps; 8 | size?: string; 9 | } 10 | 11 | const AvatarField = ({ size = '25', sx }: Props) => { 12 | const record = useRecordContext(); 13 | if (!record) return null; 14 | return ( 15 | 20 | ); 21 | }; 22 | 23 | export default AvatarField; 24 | -------------------------------------------------------------------------------- /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.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/no-code/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "no-code", 3 | "version": "0.0.1", 4 | "scripts": { 5 | "dev": "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-refresh": "^1.3.1", 19 | "typescript": "^4.4.0", 20 | "vite": "^2.1.5" 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/CommentShow.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { 3 | DateField, 4 | ReferenceField, 5 | Show, 6 | SimpleShowLayout, 7 | TextField, 8 | } from 'react-admin'; // eslint-disable-line import/no-unresolved 9 | 10 | const CommentShow = () => ( 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | 24 | export default CommentShow; 25 | -------------------------------------------------------------------------------- /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/customRouteNoLayout.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useGetList } from 'react-admin'; 3 | 4 | const CustomRouteNoLayout = ({ title = 'Posts' }) => { 5 | const { isLoading, total } = useGetList('posts', { 6 | pagination: { page: 0, perPage: 10 }, 7 | sort: { field: 'id', order: 'ASC' }, 8 | }); 9 | 10 | return ( 11 |
12 |

{title}

13 | {isLoading ? ( 14 |

Loading...

15 | ) : ( 16 |

17 | Found {total} posts ! 18 |

19 | )} 20 |
21 | ); 22 | }; 23 | 24 | export default CustomRouteNoLayout; 25 | -------------------------------------------------------------------------------- /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(locale => { 9 | if (locale === 'fr') { 10 | return messages[locale](); 11 | } 12 | 13 | // Always fallback on english 14 | return englishMessages; 15 | }, 'en'); 16 | -------------------------------------------------------------------------------- /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 | }; 14 | -------------------------------------------------------------------------------- /examples/simple/src/tags/TagCreate.tsx: -------------------------------------------------------------------------------- 1 | /* eslint react/jsx-key: off */ 2 | import * as React from 'react'; 3 | import { 4 | Create, 5 | SimpleForm, 6 | TextField, 7 | TextInput, 8 | required, 9 | TranslatableInputs, 10 | } from 'react-admin'; 11 | 12 | const TagCreate = () => ( 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | 23 | export default TagCreate; 24 | -------------------------------------------------------------------------------- /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 | }; 12 | -------------------------------------------------------------------------------- /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 | }; 14 | -------------------------------------------------------------------------------- /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 run-tutorial 13 | ``` 14 | -------------------------------------------------------------------------------- /examples/tutorial/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tutorial", 3 | "version": "4.0.0", 4 | "private": true, 5 | "dependencies": { 6 | "@mui/icons-material": "^5.0.1", 7 | "@mui/material": "^5.0.2", 8 | "ra-data-json-server": "^4.0.0", 9 | "react": "^17.0.0", 10 | "react-admin": "^4.0.0", 11 | "react-dom": "^17.0.0", 12 | "react-scripts": "^5.0.0" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "eject": "react-scripts eject" 18 | }, 19 | "browserslist": [ 20 | ">0.2%", 21 | "not dead", 22 | "not ie <= 11", 23 | "not op_mini all" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /examples/tutorial/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/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/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 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "lerna": "2.5.1", 3 | "packages": [ 4 | "examples/data-generator", 5 | "examples/simple", 6 | "packages/*" 7 | ], 8 | "version": "4.2.2" 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 = (): AuthProvider => useContext(AuthContext); 15 | 16 | export default useAuthProvider; 17 | -------------------------------------------------------------------------------- /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/index.ts: -------------------------------------------------------------------------------- 1 | export * from './ListBase'; 2 | export * from './ListContext'; 3 | export * from './ListContextProvider'; 4 | export * from './ListController'; 5 | export * from './ListFilterContext'; 6 | export * from './ListPaginationContext'; 7 | export * from './ListSortContext'; 8 | export * from './useList'; 9 | export * from './useListContext'; 10 | export * from './useListController'; 11 | export * from './useListFilterContext'; 12 | export * from './useListPaginationContext'; 13 | export * from './useListParams'; 14 | export * from './useListSortContext'; 15 | export * from './queryReducer'; 16 | export * from './useRecordSelection'; 17 | export * from './useUnselect'; 18 | export * from './useUnselectAll'; 19 | export * from './useExpanded'; 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/core/useResourceDefinitions.ts: -------------------------------------------------------------------------------- 1 | import { ResourceDefinitions } from './ResourceDefinitionContext'; 2 | import { useResourceDefinitionContext } from './useResourceDefinitionContext'; 3 | 4 | /** 5 | * Get the definition of the all resources 6 | * 7 | * @example 8 | * 9 | * const definitions = useResourceDefinitions(); 10 | * console.log(definitions.posts); 11 | * // { 12 | * // name: 'posts', 13 | * // hasList: true, 14 | * // hasEdit: true, 15 | * // hasShow: true, 16 | * // hasCreate: true, 17 | * // options: {}, 18 | * // icon: PostIcon, 19 | * // } 20 | */ 21 | export const useResourceDefinitions = (): ResourceDefinitions => 22 | useResourceDefinitionContext().definitions; 23 | -------------------------------------------------------------------------------- /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/ValidationError.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { 3 | ValidationErrorMessage, 4 | ValidationErrorMessageWithArgs, 5 | } from './validate'; 6 | import { useTranslate } from '../i18n'; 7 | 8 | export interface ValidationErrorProps { 9 | error: ValidationErrorMessage; 10 | } 11 | 12 | const ValidationError = (props: ValidationErrorProps) => { 13 | const { error } = props; 14 | const translate = useTranslate(); 15 | if ((error as ValidationErrorMessageWithArgs).message) { 16 | const { message, args } = error as ValidationErrorMessageWithArgs; 17 | return <>{translate(message, { _: message, ...args })}; 18 | } 19 | 20 | return <>{translate(error as string, { _: error })}; 21 | }; 22 | 23 | export default ValidationError; 24 | -------------------------------------------------------------------------------- /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/form/useInitializeFormWithRecord.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { useFormContext } from 'react-hook-form'; 3 | import getFormInitialValues from './getFormInitialValues'; 4 | 5 | /** 6 | * Restore the record values which should override any default values specified on the form. 7 | */ 8 | export const useInitializeFormWithRecord = (defaultValues, record) => { 9 | const { reset } = useFormContext(); 10 | 11 | useEffect(() => { 12 | if (!record) { 13 | return; 14 | } 15 | const initialValues = getFormInitialValues(defaultValues, record); 16 | reset(initialValues); 17 | }, [reset, JSON.stringify(record, defaultValues)]); // eslint-disable-line react-hooks/exhaustive-deps 18 | }; 19 | -------------------------------------------------------------------------------- /packages/ra-core/src/i18n/I18nContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | import { I18nProvider } from '../types'; 3 | 4 | export type I18nContextProps = I18nProvider; 5 | 6 | export const I18nContext = createContext({ 7 | translate: x => x, 8 | changeLocale: () => Promise.resolve(), 9 | getLocale: () => 'en', 10 | }); 11 | 12 | I18nContext.displayName = 'I18nContext'; 13 | -------------------------------------------------------------------------------- /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/index.ts: -------------------------------------------------------------------------------- 1 | export const DEFAULT_LOCALE = 'en'; 2 | 3 | export * from './TestTranslationProvider'; 4 | export * from './I18nContext'; 5 | export * from './I18nContextProvider'; 6 | export * from './TranslationMessages'; 7 | export * from './TranslatableContext'; 8 | export * from './TranslatableContextProvider'; 9 | export * from './TranslationUtils'; 10 | export * from './useLocaleState'; 11 | export * from './useLocale'; 12 | export * from './useLocales'; 13 | export * from './useSetLocale'; 14 | export * from './useTranslatable'; 15 | export * from './useTranslatableContext'; 16 | export * from './useTranslate'; 17 | export * from './useTranslateLabel'; 18 | export * from './useI18nProvider'; 19 | -------------------------------------------------------------------------------- /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 './core'; 2 | export * from './auth'; 3 | export * from './dataProvider'; 4 | export * from './export'; 5 | export * from './i18n'; 6 | export * from './inference'; 7 | export * from './util'; 8 | export * from './controller'; 9 | export * from './form'; 10 | export * from './notification'; 11 | export * from './store'; 12 | export * from './routing'; 13 | export * from './types'; 14 | -------------------------------------------------------------------------------- /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/index.ts: -------------------------------------------------------------------------------- 1 | export * from './types'; 2 | export * from './useNotify'; 3 | export * from './NotificationContext'; 4 | export * from './NotificationContextProvider'; 5 | export * from './useNotificationContext'; 6 | -------------------------------------------------------------------------------- /packages/ra-core/src/notification/types.ts: -------------------------------------------------------------------------------- 1 | export type NotificationType = 'success' | 'info' | 'warning' | 'error'; 2 | 3 | export interface NotificationOptions { 4 | // The duration in milliseconds the notification is shown 5 | autoHideDuration?: number; 6 | // Arguments used to translate the message 7 | messageArgs?: any; 8 | // If true, the notification shows the message in multiple lines 9 | multiLine?: boolean; 10 | // If true, the notification shows an Undo button 11 | undoable?: boolean; 12 | } 13 | 14 | export interface NotificationPayload { 15 | readonly message: string; 16 | readonly type: NotificationType; 17 | readonly notificationOptions?: NotificationOptions; 18 | } 19 | -------------------------------------------------------------------------------- /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/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/StoreContextProvider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { useEffect } from 'react'; 3 | import { StoreContext } from './StoreContext'; 4 | import { Store } from './types'; 5 | 6 | export const StoreContextProvider = ({ 7 | value: Store, 8 | children, 9 | }: StoreContextProviderProps) => { 10 | useEffect(() => { 11 | Store.setup(); 12 | return () => { 13 | Store.teardown(); 14 | }; 15 | }, [Store]); 16 | 17 | return ( 18 | {children} 19 | ); 20 | }; 21 | 22 | export interface StoreContextProviderProps { 23 | value: Store; 24 | children: React.ReactNode; 25 | } 26 | -------------------------------------------------------------------------------- /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 './useResetStore'; 11 | -------------------------------------------------------------------------------- /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 | reset: () => void; 8 | subscribe: (key: string, callback: (value: any) => void) => () => void; 9 | } 10 | -------------------------------------------------------------------------------- /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/removeEmpty.ts: -------------------------------------------------------------------------------- 1 | import { shallowEqual } from './shallowEqual'; 2 | 3 | const isObject = obj => 4 | obj && Object.prototype.toString.call(obj) === '[object Object]'; 5 | 6 | const isEmpty = obj => 7 | obj instanceof Date 8 | ? false 9 | : obj === '' || 10 | obj === null || 11 | obj === undefined || 12 | shallowEqual(obj, {}); 13 | 14 | const removeEmpty = object => 15 | Object.keys(object).reduce((acc, key) => { 16 | let child = object[key]; 17 | 18 | if (isObject(object[key])) { 19 | child = removeEmpty(object[key]); 20 | } 21 | 22 | return isEmpty(child) ? acc : { ...acc, [key]: child }; 23 | }, {}); 24 | 25 | export default removeEmpty; 26 | -------------------------------------------------------------------------------- /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 | "declaration": true, 7 | "declarationMap": true, 8 | "allowJs": false 9 | }, 10 | "exclude": [ 11 | "**/*.spec.ts", 12 | "**/*.spec.tsx", 13 | "**/*.spec.js", 14 | "**/*.stories.ts", 15 | "**/*.stories.tsx", 16 | "**/*.stories.js" 17 | ], 18 | "include": ["src"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/ra-data-fakerest/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-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 | "declaration": true, 7 | "declarationMap": true, 8 | "allowJs": false 9 | }, 10 | "exclude": [ 11 | "**/*.spec.ts", 12 | "**/*.spec.tsx", 13 | "**/*.spec.js", 14 | "**/*.test.ts", 15 | "**/*.test.tsx", 16 | "**/*.test.js" 17 | ], 18 | "include": ["src"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/ra-data-graphql/src/buildApolloClient.ts: -------------------------------------------------------------------------------- 1 | import { 2 | ApolloClient, 3 | ApolloClientOptions, 4 | HttpLink, 5 | InMemoryCache, 6 | } from '@apollo/client'; 7 | 8 | export default (options: Partial>) => { 9 | if (!options) { 10 | return new ApolloClient({ 11 | cache: new InMemoryCache().restore({}), 12 | }); 13 | } 14 | 15 | const { 16 | cache = new InMemoryCache().restore({}), 17 | uri, 18 | link = !!uri ? new HttpLink({ uri }) : undefined, 19 | ...otherOptions 20 | } = options; 21 | 22 | return new ApolloClient({ 23 | link, 24 | cache, 25 | ...otherOptions, 26 | }); 27 | }; 28 | -------------------------------------------------------------------------------- /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 | "declaration": true, 7 | "declarationMap": true, 8 | "allowJs": false 9 | }, 10 | "exclude": [ 11 | "**/*.spec.ts", 12 | "**/*.spec.tsx", 13 | "**/*.spec.js", 14 | "**/*.test.ts", 15 | "**/*.test.tsx", 16 | "**/*.test.js" 17 | ], 18 | "include": ["src"] 19 | } 20 | -------------------------------------------------------------------------------- /packages/ra-data-json-server/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 | "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-simple-rest/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-i18n-polyglot/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-input-rich-text/assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dev-captain/reactProject/2ae08ece551061f24c8286fe34a43d2ac7556f44/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 | "declaration": true, 7 | "declarationMap": true, 8 | "allowJs": false 9 | }, 10 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 11 | "include": ["src"] 12 | } 13 | -------------------------------------------------------------------------------- /packages/ra-language-english/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-language-french/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-no-code/assets/ra-orders-1.csv: -------------------------------------------------------------------------------- 1 | id,reference,date,customer_id,basket.product_id,basket.quantity,total_ex_taxes,delivery_fees,tax_rate,taxes,total,status,returned 2 | 408,5TFGTA,2021-04-23T02:07:38.273Z,17,87,1,108.28,5.38,0.2,22.73,136.39,ordered,false 3 | ,,,,10,2,,,,,,, 4 | 93,M2GL49,2021-04-19T23:49:46.313Z,750,87,5,92.4,5.61,0.12,11.76,109.77,ordered,false 5 | 413,JTI3CU,2021-04-18T02:56:46.786Z,879,28,2,81.12,6.19,0.12,10.48,97.79,ordered,false 6 | ,,,,35,2,,,,,,, 7 | 421,80EPRZ,2021-04-14T19:53:26.605Z,362,20,1,141.78,3.14,0.17,24.64,169.56,ordered,false 8 | ,,,,97,1,,,,,,, 9 | ,,,,84,2,,,,,,, 10 | 386,WREQLW,2021-04-13T23:33:12.169Z,265,109,1,76.94999999999999,4.25,0.12,9.74,90.94,ordered,false 11 | ,,,,98,1,,,,,,, 12 | -------------------------------------------------------------------------------- /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 { Menu } from './Menu'; 4 | import { AppBar } from './Appbar'; 5 | 6 | export const Layout = (props: LayoutProps) => ( 7 | 8 | ); 9 | -------------------------------------------------------------------------------- /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 | "declaration": true, 7 | "declarationMap": true, 8 | "allowJs": false, 9 | "types": [ 10 | "jest", 11 | "@types/node" 12 | ] 13 | }, 14 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 15 | "include": ["src"] 16 | } 17 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/README.md: -------------------------------------------------------------------------------- 1 | # ra-ui-material 2 | 3 | UI Components for [react-admin](https://marmelab.com/react-admin/) with [MUI](https://mui.com/). 4 | 5 | ## License 6 | 7 | React-admin is licensed under the [MIT License](https://github.com/marmelab/react-admin/blob/master/LICENSE.md), sponsored and supported by [marmelab](https://marmelab.com). 8 | 9 | ## Donate 10 | 11 | This library is free to use, even for commercial purpose. If you want to give back, please talk about it, [help newcomers](https://stackoverflow.com/questions/tagged/react-admin), or contribute code. But the best way to give back is to **donate to a charity**. We recommend [Doctors Without Borders](https://www.doctorswithoutborders.org/). 12 | -------------------------------------------------------------------------------- /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 './Login'; 2 | export * from './LoginForm'; 3 | export * from './Logout'; 4 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/button/Button.stories.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ThemeProvider } from '@mui/material'; 3 | import { createTheme } from '@mui/material/styles'; 4 | import AddIcon from '@mui/icons-material/Add'; 5 | import { Button } from './Button'; 6 | 7 | const theme = createTheme(); 8 | 9 | export default { title: 'ra-ui-materialui/button/Button' }; 10 | 11 | export const Basic = () => ( 12 | 13 | 22 | 23 | ); 24 | -------------------------------------------------------------------------------- /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/index.tsx: -------------------------------------------------------------------------------- 1 | export * from './TabbedForm'; 2 | export * from './FormTab'; 3 | export * from './FormTabHeader'; 4 | export * from './SimpleForm'; 5 | export * from './TabbedForm'; 6 | export * from './TabbedFormTabs'; 7 | export * from './TabbedFormView'; 8 | export * from './Toolbar'; 9 | -------------------------------------------------------------------------------- /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 './Labeled'; 8 | export * from './input'; 9 | export * from './layout'; 10 | export * from './Link'; 11 | export * from './list'; 12 | export * from './types'; 13 | export * from './AdminUI'; 14 | export * from './AdminContext'; 15 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ArrayInput/AddItemButton.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import AddIcon from '@mui/icons-material/AddCircleOutline'; 3 | import { useSimpleFormIterator } from './useSimpleFormIterator'; 4 | 5 | import { Button, ButtonProps } from '../../button'; 6 | 7 | export const AddItemButton = (props: Omit) => { 8 | const { add } = useSimpleFormIterator(); 9 | return ( 10 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /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/RemoveItemButton.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import CloseIcon from '@mui/icons-material/RemoveCircleOutline'; 3 | 4 | import { Button, ButtonProps } from '../../button'; 5 | import { useSimpleFormIteratorItem } from './useSimpleFormIteratorItem'; 6 | 7 | export const RemoveItemButton = (props: Omit) => { 8 | const { remove } = useSimpleFormIteratorItem(); 9 | 10 | return ( 11 | 14 | ); 15 | }; 16 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIteratorContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | /** 4 | * A React context that provides access to a SimpleFormIterator data (the total number of items) and mutators (add, reorder and remove). 5 | * Useful to create custom array input iterators. 6 | * @see {SimpleFormIterator} 7 | * @see {ArrayInput} 8 | */ 9 | export const SimpleFormIteratorContext = createContext< 10 | SimpleFormIteratorContextValue 11 | >(undefined); 12 | 13 | export type SimpleFormIteratorContextValue = { 14 | add: () => void; 15 | remove: (index: number) => void; 16 | reOrder: (index: number, newIndex: number) => void; 17 | source: string; 18 | total: number; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ArrayInput/SimpleFormIteratorItemContext.ts: -------------------------------------------------------------------------------- 1 | import { createContext } from 'react'; 2 | 3 | /** 4 | * A React context that provides access to a SimpleFormIterator item meta (its index and the total number of items) and mutators (reorder and remove this remove). 5 | * Useful to create custom array input iterators. 6 | * @see {SimpleFormIterator} 7 | * @see {ArrayInput} 8 | */ 9 | export const SimpleFormIteratorItemContext = createContext< 10 | SimpleFormIteratorItemContextValue 11 | >(undefined); 12 | 13 | export type SimpleFormIteratorItemContextValue = { 14 | index: number; 15 | total: number; 16 | remove: () => void; 17 | reOrder: (newIndex: number) => void; 18 | }; 19 | -------------------------------------------------------------------------------- /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 | line: `${SimpleFormIteratorPrefix}-line`, 5 | index: `${SimpleFormIteratorPrefix}-index`, 6 | indexContainer: `${SimpleFormIteratorPrefix}-indexContainer`, 7 | form: `${SimpleFormIteratorPrefix}-form`, 8 | action: `${SimpleFormIteratorPrefix}-action`, 9 | leftIcon: `${SimpleFormIteratorPrefix}-leftIcon`, 10 | }; 11 | -------------------------------------------------------------------------------- /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([PropTypes.string, PropTypes.bool]), 8 | resource: PropTypes.string, 9 | source: PropTypes.string, 10 | }; 11 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/input/ReferenceError.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ReactElement } from 'react'; 3 | import PropTypes from 'prop-types'; 4 | import TextField from '@mui/material/TextField'; 5 | 6 | export const ReferenceError = ({ 7 | label, 8 | error, 9 | }: { 10 | label?: string | ReactElement | false; 11 | error: Error; 12 | }) => ( 13 | 20 | ); 21 | 22 | ReferenceError.propTypes = { 23 | error: PropTypes.object.isRequired, 24 | label: PropTypes.oneOfType([ 25 | PropTypes.string, 26 | PropTypes.element, 27 | PropTypes.bool, 28 | ]), 29 | }; 30 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/layout/HideOnScroll.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import useScrollTrigger from '@mui/material/useScrollTrigger'; 4 | import Slide from '@mui/material/Slide'; 5 | 6 | export const HideOnScroll = (props: HideOnScrollProps) => { 7 | const { children } = props; 8 | const trigger = useScrollTrigger(); 9 | return ( 10 | 11 | {children} 12 | 13 | ); 14 | }; 15 | 16 | HideOnScroll.propTypes = { 17 | children: PropTypes.node.isRequired, 18 | }; 19 | 20 | export interface HideOnScrollProps { 21 | children: React.ReactElement; 22 | } 23 | -------------------------------------------------------------------------------- /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 } from '@mui/material'; 3 | 4 | export type ThemeSetter = (theme: ThemeOptions) => void; 5 | 6 | export const useTheme = ( 7 | themeOverride?: ThemeOptions 8 | ): [ThemeOptions, ThemeSetter] => useStore('theme', themeOverride); 9 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/layout/UserMenuContextProvider.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { ReactNode } from 'react'; 3 | import { UserMenuContext, UserMenuContextValue } from './UserMenuContext'; 4 | 5 | /** 6 | * A React context provider that provides access to the user menu context. 7 | * @param props 8 | * @param {ReactNode} props.children 9 | * @param {UserMenuContextValue} props.value The user menu context 10 | */ 11 | export const UserMenuContextProvider = ({ children, value }) => ( 12 | 13 | {children} 14 | 15 | ); 16 | 17 | export type UserMenuContextProviderProps = { 18 | children: ReactNode; 19 | value: UserMenuContextValue; 20 | }; 21 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/layout/useResetErrorBoundaryOnLocationChange.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from 'react'; 2 | import { useLocation } from 'react-router'; 3 | 4 | /** 5 | * A hook to use inside the component passed to FallbackComponent 6 | * of react-error-boundary. It resets the error boundary state whenever 7 | * the location changes 8 | * @param {Function} resetErrorBoundary 9 | */ 10 | export const useResetErrorBoundaryOnLocationChange = ( 11 | resetErrorBoundary: () => void 12 | ) => { 13 | const { pathname } = useLocation(); 14 | const originalPathname = useRef(pathname); 15 | 16 | useEffect(() => { 17 | if (pathname !== originalPathname.current) { 18 | resetErrorBoundary(); 19 | } 20 | }, [pathname, resetErrorBoundary]); 21 | }; 22 | -------------------------------------------------------------------------------- /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/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/datagrid/DatagridCell.spec.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | 4 | import DatagridCell from './DatagridCell'; 5 | 6 | const renderWithTable = element => 7 | render( 8 | 9 | 10 | {element} 11 | 12 |
13 | ); 14 | 15 | describe('', () => { 16 | const Field = () =>
cell
; 17 | 18 | it('should render as a mui component', () => { 19 | const { getByRole } = renderWithTable( 20 | } /> 21 | ); 22 | expect(getByRole('cell').className).toContain('MuiTableCell-root'); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /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/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 './datagrid'; 3 | export * from './Empty'; 4 | export * from './filter'; 5 | export * from './FilterContext'; 6 | export * from './List'; 7 | export * from './ListActions'; 8 | export * from './ListGuesser'; 9 | export * from './ListView'; 10 | export * from './listFieldTypes'; 11 | export * from './ListToolbar'; 12 | export * from './pagination'; 13 | export * from './Placeholder'; 14 | export * from './SimpleList'; 15 | export * from './SimpleListLoading'; 16 | export * from './SingleFieldList'; 17 | -------------------------------------------------------------------------------- /packages/ra-ui-materialui/src/list/pagination/PaginationLimit.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 { useTranslate } from 'ra-core'; 6 | 7 | export const PaginationLimit = memo(() => { 8 | const translate = useTranslate(); 9 | return ( 10 | 11 | 12 | {translate('ra.navigation.no_results')} 13 | 14 | 15 | ); 16 | }); 17 | -------------------------------------------------------------------------------- /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/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", "**/*.stories.tsx"], 10 | "include": ["src"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/react-admin/src/defaultI18nProvider.spec.ts: -------------------------------------------------------------------------------- 1 | import expect from 'expect'; 2 | import { defaultI18nProvider } from './defaultI18nProvider'; 3 | 4 | describe('defaultI18nProvider', () => { 5 | it('should use the English translations', () => { 6 | expect(defaultI18nProvider.translate('ra.action.edit')).toBe('Edit'); 7 | }); 8 | it('should return the input when the translation is missing', () => { 9 | expect(defaultI18nProvider.translate('bar')).toBe('bar'); 10 | }); 11 | it('should not log any warning for missing translations', () => { 12 | const spy = jest.spyOn(console, 'error'); 13 | defaultI18nProvider.translate('foo'); 14 | expect(spy).not.toHaveBeenCalled(); 15 | spy.mockRestore(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /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 | { 8 | allowMissing: true, 9 | } 10 | ); 11 | -------------------------------------------------------------------------------- /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 | "declaration": true, 7 | "declarationMap": true, 8 | "allowJs": false 9 | }, 10 | "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "**/*.spec.js"], 11 | "include": ["src"] 12 | } 13 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------