├── .nojekyll ├── docs └── .nojekyll ├── example-react-app ├── src │ ├── addons.ts │ ├── app │ │ ├── CenteredLoader.module.css │ │ ├── common │ │ │ ├── Centered.module.css │ │ │ └── Centered.tsx │ │ ├── custom-app-layouts │ │ │ └── CustomAppLayouts.module.css │ │ ├── car-cards-with-details │ │ │ └── CarCardsWithDetails.module.css │ │ ├── CenteredLoader.tsx │ │ ├── custom-data-display-components │ │ │ └── CustomDataDisplayComponents.module.css │ │ ├── login │ │ │ └── Login.module.css │ │ ├── blank-screen │ │ │ └── TestBlankScreen.tsx │ │ ├── AppErrorBoundary.tsx │ │ └── home │ │ │ └── HomePage.tsx │ ├── react-app-env.d.ts │ ├── themes │ │ ├── antd-themes │ │ │ └── light.less │ │ └── themes.config.json │ ├── styles.d.ts │ ├── index.css │ ├── jmix │ │ ├── entities │ │ │ ├── scr_Order_1.ts │ │ │ ├── scr_CarDto.ts │ │ │ ├── ScrUserInfo.ts │ │ │ ├── scr_TrickyIdTestEntity.ts │ │ │ ├── scr_Product.ts │ │ │ ├── scr_Customer.ts │ │ │ ├── scr_OrderLine.ts │ │ │ └── scr_Order.ts │ │ └── enums │ │ │ └── enums.ts │ ├── config.ts │ └── hotkeyConfigs.ts ├── tsconfig.prod.json ├── .editorconfig ├── images.d.ts ├── public │ ├── favicon.ico │ └── manifest.json ├── tsconfig.test.json ├── .env.development.local ├── .env.production.local ├── .gitignore └── README.md ├── packages ├── jmix-front-generator │ ├── src │ │ ├── test │ │ │ ├── generator.test.ts │ │ │ ├── fixtures │ │ │ │ ├── templates │ │ │ │ │ ├── EntityManagementEditor.tsx │ │ │ │ │ └── i18nMappings.ts │ │ │ │ ├── react-client │ │ │ │ │ ├── .env.development.local │ │ │ │ │ ├── .env.production.local │ │ │ │ │ └── src │ │ │ │ │ │ └── app │ │ │ │ │ │ └── component │ │ │ │ │ │ └── BlankComponent.tsx │ │ │ │ ├── view-properties--association-o2o.json │ │ │ │ ├── graphql │ │ │ │ │ ├── stringIdEntity.js │ │ │ │ │ └── carEntity.js │ │ │ │ ├── answers │ │ │ │ │ ├── string-id-management-table.js │ │ │ │ │ ├── int-id-management-table.json │ │ │ │ │ └── string-id-management-table-no-id-name.json │ │ │ │ └── query-model-car.json │ │ │ └── common │ │ │ │ └── test-utils.ts │ │ ├── generators │ │ │ ├── react-typescript │ │ │ │ ├── app │ │ │ │ │ ├── template │ │ │ │ │ │ ├── src │ │ │ │ │ │ │ ├── addons.ts │ │ │ │ │ │ │ ├── routing.ts │ │ │ │ │ │ │ ├── react-app-env.d.ts │ │ │ │ │ │ │ ├── themes │ │ │ │ │ │ │ │ └── antd-themes │ │ │ │ │ │ │ │ │ └── light.less │ │ │ │ │ │ │ ├── app │ │ │ │ │ │ │ │ ├── CenteredLoader.module.css │ │ │ │ │ │ │ │ ├── common │ │ │ │ │ │ │ │ │ ├── Centered.module.css │ │ │ │ │ │ │ │ │ └── Centered.tsx │ │ │ │ │ │ │ │ ├── CenteredLoader.tsx │ │ │ │ │ │ │ │ ├── login │ │ │ │ │ │ │ │ │ └── Login.module.css │ │ │ │ │ │ │ │ ├── AppErrorBoundary.tsx │ │ │ │ │ │ │ │ └── home │ │ │ │ │ │ │ │ │ └── HomePage.tsx │ │ │ │ │ │ │ ├── styles.d.ts │ │ │ │ │ │ │ ├── index.css │ │ │ │ │ │ │ ├── dev │ │ │ │ │ │ │ │ └── previews.tsx │ │ │ │ │ │ │ ├── config.ts │ │ │ │ │ │ │ └── hotkeyConfigs.ts │ │ │ │ │ │ ├── tsconfig.prod.json │ │ │ │ │ │ ├── .editorconfig │ │ │ │ │ │ ├── _editorconfig │ │ │ │ │ │ ├── images.d.ts │ │ │ │ │ │ ├── tsconfig.test.json │ │ │ │ │ │ ├── public │ │ │ │ │ │ │ ├── favicon.ico │ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ │ ├── _gitignore │ │ │ │ │ │ ├── .env.development.local │ │ │ │ │ │ ├── .env.production.local │ │ │ │ │ │ └── README.md │ │ │ │ │ └── options.ts │ │ │ │ ├── info.json │ │ │ │ ├── entity-cards │ │ │ │ │ └── options.ts │ │ │ │ ├── common │ │ │ │ │ ├── base-entity-screen-generator │ │ │ │ │ │ ├── template-model.ts │ │ │ │ │ │ └── params.ts │ │ │ │ │ └── questions.ts │ │ │ │ ├── structure │ │ │ │ │ ├── options.ts │ │ │ │ │ └── structure.svg │ │ │ │ ├── blank-screen │ │ │ │ │ ├── options.ts │ │ │ │ │ ├── blank.svg │ │ │ │ │ ├── template │ │ │ │ │ │ └── Component.tsx │ │ │ │ │ └── answers.ts │ │ │ │ ├── entity-calendar │ │ │ │ │ └── options.ts │ │ │ │ ├── entity-cards-grid │ │ │ │ │ └── options.ts │ │ │ │ ├── entity-form-wizard │ │ │ │ │ ├── options.ts │ │ │ │ │ └── entity-form-wizard.svg │ │ │ │ ├── entity-cards-with-details │ │ │ │ │ └── template │ │ │ │ │ │ └── CardsWithDetails.module.css │ │ │ │ ├── entity-browser │ │ │ │ │ └── entity-browser.svg │ │ │ │ ├── entity-multi-selection-table │ │ │ │ │ └── entity-multi-selection-table.svg │ │ │ │ ├── entity-table-with-filters │ │ │ │ │ └── entity-multi-selection-table.svg │ │ │ │ ├── generator-customization │ │ │ │ │ └── generator-customization.svg │ │ │ │ ├── entity-editor │ │ │ │ │ └── entity-editor.svg │ │ │ │ └── remove-addon │ │ │ │ │ └── write.ts │ │ │ ├── sdk │ │ │ │ ├── info.json │ │ │ │ ├── all │ │ │ │ │ └── write.ts │ │ │ │ └── model │ │ │ │ │ └── write.ts │ │ │ └── react-native │ │ │ │ ├── info.json │ │ │ │ └── app │ │ │ │ └── template │ │ │ │ ├── assets │ │ │ │ ├── icon.png │ │ │ │ └── splash.png │ │ │ │ ├── babel.config.js │ │ │ │ ├── .gitignore │ │ │ │ ├── .env │ │ │ │ ├── styles │ │ │ │ └── palette.ts │ │ │ │ ├── rest │ │ │ │ ├── errorCodes.ts │ │ │ │ └── rest.ts │ │ │ │ ├── util │ │ │ │ └── base64.ts │ │ │ │ ├── tsconfig.json │ │ │ │ ├── components │ │ │ │ └── Example.tsx │ │ │ │ └── App.tsx │ │ ├── building-blocks │ │ │ ├── stages │ │ │ │ ├── writing │ │ │ │ │ └── pieces │ │ │ │ │ │ └── entity-management │ │ │ │ │ │ └── entity-management.ts │ │ │ │ ├── answers │ │ │ │ │ └── pieces │ │ │ │ │ │ └── EmptyAnswers.ts │ │ │ │ ├── template-model │ │ │ │ │ └── pieces │ │ │ │ │ │ └── EmptyTemplateModel.ts │ │ │ │ └── options │ │ │ │ │ ├── pieces │ │ │ │ │ ├── dir-shift.ts │ │ │ │ │ └── component.ts │ │ │ │ │ └── defaultGetOptions.ts │ │ │ ├── includes │ │ │ │ └── FieldImports.ejs │ │ │ ├── util │ │ │ │ ├── attribute-types.ts │ │ │ │ ├── dollars-to-underscores.test.ts │ │ │ │ ├── to-fat-snake-case.ts │ │ │ │ └── dollars-to-underscores.ts │ │ │ └── YeomanGenerator.ts │ │ └── common │ │ │ ├── cli │ │ │ └── cli.ts │ │ │ └── constants.ts │ ├── .npmignore │ ├── .editorconfig │ ├── test │ │ ├── mocha.opts │ │ └── integration │ │ │ ├── expect │ │ │ ├── enums │ │ │ │ └── enums.ts │ │ │ └── entities │ │ │ │ └── ScrUserInfo.ts │ │ │ └── fixtures │ │ │ ├── sdk │ │ │ └── tsconfig.json │ │ │ └── projectModel-empty.json │ ├── .gitignore │ ├── scripts │ │ └── copy-templates.js │ ├── tsconfig.declarations.json │ ├── custom_types │ │ └── inquirer.d.ts │ ├── bin │ │ └── gen-jmix-front.js │ ├── README.md │ ├── .nycrc.yaml │ └── tsconfig_strict.json ├── jmix-addon-data-tools │ ├── .gitignore │ └── src │ │ ├── entity-inspector │ │ ├── screens │ │ │ ├── Screens.less │ │ │ └── index.ts │ │ ├── entity-data-editor │ │ │ ├── EntityDataEditor.less │ │ │ ├── fields │ │ │ │ ├── index.ts │ │ │ │ └── Fields.less │ │ │ ├── index.ts │ │ │ ├── association-2o │ │ │ │ ├── index.ts │ │ │ │ └── Association2O.less │ │ │ └── composition-field │ │ │ │ ├── index.ts │ │ │ │ ├── composition-o2m │ │ │ │ └── index.ts │ │ │ │ └── composition-o2o │ │ │ │ └── index.ts │ │ ├── breadcrumbs │ │ │ ├── index.ts │ │ │ └── Breadcrumbs.less │ │ ├── entity-select │ │ │ ├── index.ts │ │ │ └── EntitySelect.less │ │ ├── entity-data-viewer │ │ │ └── index.ts │ │ └── entity-inspector-main │ │ │ └── index.ts │ │ └── custom.d.ts ├── jmix-react-web │ ├── .eslintignore │ ├── .gitignore │ ├── .eslintrc.json │ ├── .editorconfig │ └── src │ │ ├── ui │ │ ├── entity-property │ │ │ └── EntityPropery.module.less │ │ ├── MultilineText.tsx │ │ ├── Label.tsx │ │ ├── single-content-area │ │ │ └── SingleContentArea.tsx │ │ └── Menu │ │ │ └── MenuPermContainer.tsx │ │ ├── util │ │ ├── useNoop.ts │ │ ├── files.ts │ │ ├── regex.ts │ │ └── copyToClipboard.ts │ │ ├── custom.d.ts │ │ ├── test │ │ └── styleMock.ts │ │ ├── hotkeys │ │ └── hotkeyConfig.ts │ │ ├── crud │ │ ├── editor │ │ │ └── EntityEditorProps.ts │ │ └── list │ │ │ ├── EntityListProps.ts │ │ │ ├── ui-callbacks │ │ │ ├── useSelectionChangeCallback.ts │ │ │ ├── useFilterChangeCallback.ts │ │ │ └── useSortOrderChangeCallback.ts │ │ │ └── util │ │ │ ├── getEntityInstanceById.ts │ │ │ └── getSubmitBtnCaption.ts │ │ ├── screen-registration │ │ └── registry.ts │ │ └── common │ │ └── JmixServerValidationErrors.ts ├── jmix-rest │ ├── examples │ │ └── node │ │ │ ├── README.md │ │ │ ├── package.json │ │ │ └── index.js │ ├── .editorconfig │ ├── .snyk │ ├── .gitignore │ ├── jest.config.js │ ├── test │ │ └── listeners.spec.js │ ├── src │ │ ├── error.ts │ │ └── filter.ts │ └── tsconfig.json ├── jmix-react-antd │ ├── src │ │ ├── test │ │ │ ├── polyfills.js │ │ │ └── styleMock.ts │ │ ├── ui │ │ │ ├── EntityHierarchyTree │ │ │ │ └── index.ts │ │ │ ├── form │ │ │ │ ├── controls │ │ │ │ │ ├── RichTextArea.less │ │ │ │ │ ├── SourceCodeField.module.less │ │ │ │ │ ├── Button.tsx │ │ │ │ │ └── base │ │ │ │ │ │ └── JmixFormFieldProps.ts │ │ │ │ ├── CharInput.module.less │ │ │ │ ├── InputNumber.module.less │ │ │ │ ├── validation │ │ │ │ │ └── passthroughRule.ts │ │ │ │ ├── CompositionFields.module.less │ │ │ │ └── CharInput.tsx │ │ │ ├── menu │ │ │ │ ├── addons-menu │ │ │ │ │ └── index.ts │ │ │ │ ├── vertical-menu │ │ │ │ │ ├── index.ts │ │ │ │ │ └── VerticalMenu.tsx │ │ │ │ ├── horizontal-menu │ │ │ │ │ ├── index.ts │ │ │ │ │ └── HorizontalMenu.tsx │ │ │ │ ├── menu-item │ │ │ │ │ └── index.ts │ │ │ │ ├── sub-menu-item │ │ │ │ │ └── index.ts │ │ │ │ └── index.ts │ │ │ ├── modals │ │ │ │ └── index.ts │ │ │ ├── Spinner.module.less │ │ │ ├── notifications │ │ │ │ └── index.ts │ │ │ ├── Grid │ │ │ │ ├── index.ts │ │ │ │ ├── Col │ │ │ │ │ └── Col.tsx │ │ │ │ └── Row │ │ │ │ │ └── Row.tsx │ │ │ ├── retry-dialog │ │ │ │ └── RetryDialog.module.less │ │ │ ├── layouts │ │ │ │ ├── index.ts │ │ │ │ ├── AppLayout.tsx │ │ │ │ ├── Footer.tsx │ │ │ │ ├── Header.tsx │ │ │ │ ├── Sidebar.tsx │ │ │ │ └── Content.tsx │ │ │ ├── progress-bar │ │ │ │ └── ProgressBar.tsx │ │ │ ├── Spinner.tsx │ │ │ ├── ImagePreview.module.less │ │ │ ├── Card │ │ │ │ └── Card.tsx │ │ │ ├── hotkeys │ │ │ │ └── HotkeyInfoModalButton.module.less │ │ │ ├── MasterDetail │ │ │ │ └── useChangeConfirm.ts │ │ │ ├── DatePicker.tsx │ │ │ ├── tooltip │ │ │ │ └── Tooltip.tsx │ │ │ ├── table │ │ │ │ └── DataTableIntervalEditor.module.less │ │ │ ├── MultiSelectionTable │ │ │ │ └── MultiSelectionTableStore.ts │ │ │ └── TimePicker.tsx │ │ ├── custom.d.ts │ │ ├── crud │ │ │ └── editor │ │ │ │ ├── form │ │ │ │ ├── useCreateAntdResetForm.ts │ │ │ │ └── createUseAntdForm.ts │ │ │ │ ├── validation │ │ │ │ └── createUseAntdFormValidation.ts │ │ │ │ └── ui-callbacks │ │ │ │ └── useSubmitFailedCallback.ts │ │ └── util │ │ │ ├── history.test.ts │ │ │ └── history.ts │ ├── .eslintrc.json │ ├── .gitignore │ ├── .editorconfig │ ├── babel.config.js │ └── .eslintignore ├── jmix-react-core │ ├── src │ │ ├── test │ │ │ └── polyfills.js │ │ ├── conditional-rendering │ │ │ └── index.ts │ │ ├── timer │ │ │ └── index.ts │ │ ├── util │ │ │ ├── uncapitalize-first.ts │ │ │ ├── misc.ts │ │ │ ├── isNull.ts │ │ │ ├── base64.test.ts │ │ │ ├── file.ts │ │ │ ├── graphql.test.ts │ │ │ ├── temp-id.ts │ │ │ ├── devMode.ts │ │ │ ├── dollars-to-underscores.test.ts │ │ │ ├── base64.ts │ │ │ ├── dollars-to-underscores.ts │ │ │ ├── errorHandling.ts │ │ │ └── data.ts │ │ ├── crud │ │ │ ├── sort.ts │ │ │ └── JmixConstraintViolation.ts │ │ ├── common │ │ │ └── ReactComponent.ts │ │ ├── data │ │ │ ├── aliases.ts │ │ │ └── PropertyType.ts │ │ ├── app │ │ │ ├── MenuConfig.ts │ │ │ └── JmixServerError.ts │ │ └── test-doubles │ │ │ └── WebStorageStub.ts │ ├── .eslintrc.json │ ├── .gitignore │ ├── .editorconfig │ ├── babel.config.js │ ├── .eslintignore │ ├── .snyk │ └── README.md ├── jmix-server-mock │ ├── .editorconfig │ ├── .gitignore │ ├── tsconfig.json │ └── .eslintrc.json └── jmix-addon-charts │ ├── .gitignore │ └── src │ ├── custom-typings │ └── react-pivottable.ts │ └── component │ ├── default-chart-options.ts │ ├── ChordChart.tsx │ ├── RadarChart.tsx │ ├── HeatMapChart.tsx │ ├── NetworkChart.tsx │ ├── TreeMapChart.tsx │ ├── ChoroplethChart.tsx │ ├── BarChart.tsx │ ├── ClusteredBarChart.tsx │ └── CirclePackingChart.tsx ├── docs-src ├── doc-component-repo │ ├── modules │ │ ├── typescript-sdk │ │ │ ├── pages │ │ │ │ ├── enums.adoc │ │ │ │ └── entities.adoc │ │ │ └── nav.adoc │ │ ├── jmix-rest-js │ │ │ ├── nav.adoc │ │ │ └── pages │ │ │ │ └── index.adoc │ │ ├── generator │ │ │ ├── nav.adoc │ │ │ ├── partials │ │ │ │ └── feat-available-in-studio.adoc │ │ │ └── images │ │ │ │ ├── browser-cards.png │ │ │ │ ├── browser-list.png │ │ │ │ ├── studio-integration.png │ │ │ │ └── interactive-projects.png │ │ ├── getting-started │ │ │ └── nav.adoc │ │ ├── client-react │ │ │ ├── images │ │ │ │ ├── home-screen.png │ │ │ │ ├── login-screen.png │ │ │ │ ├── data-table-demo.gif │ │ │ │ ├── pet-clinic-editor.png │ │ │ │ ├── pet-clinic-browser.png │ │ │ │ ├── studio-create-front-module.gif │ │ │ │ └── studio-adding-frontend-component.gif │ │ │ └── pages │ │ │ │ ├── config.adoc │ │ │ │ ├── supported-browsers.adoc │ │ │ │ ├── sync-project-model.adoc │ │ │ │ └── build.adoc │ │ ├── client-react-native │ │ │ ├── images │ │ │ │ └── RNDemo.gif │ │ │ ├── nav.adoc │ │ │ └── pages │ │ │ │ ├── learning-path.adoc │ │ │ │ └── technologies.adoc │ │ ├── overview │ │ │ └── partials │ │ │ │ └── getting-started-note.adoc │ │ ├── jmix-react-ui │ │ │ ├── images │ │ │ │ └── FileUploadAndImagePreviewDemo.gif │ │ │ ├── pages │ │ │ │ ├── image-preview.adoc │ │ │ │ └── index.adoc │ │ │ └── nav.adoc │ │ ├── libs │ │ │ └── nav.adoc │ │ └── jmix-react-core │ │ │ ├── pages │ │ │ └── index.adoc │ │ │ └── nav.adoc │ └── antora.yml ├── api-reference │ ├── jmix-rest │ │ └── assets │ │ │ └── images │ │ │ ├── icons.png │ │ │ ├── icons@2x.png │ │ │ ├── widgets.png │ │ │ └── widgets@2x.png │ ├── jmix-react-ui │ │ └── assets │ │ │ └── images │ │ │ ├── icons.png │ │ │ ├── widgets.png │ │ │ ├── icons@2x.png │ │ │ └── widgets@2x.png │ ├── jmix-react-core │ │ └── assets │ │ │ └── images │ │ │ ├── icons.png │ │ │ ├── icons@2x.png │ │ │ ├── widgets.png │ │ │ └── widgets@2x.png │ └── react-ide-toolbox │ │ └── assets │ │ └── images │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── widgets.png │ │ └── widgets@2x.png ├── supplemental-ui │ ├── css │ │ └── overrides.css │ └── partials │ │ ├── head-meta.hbs │ │ └── head-styles.hbs └── redirect-page-template.html ├── docs-src-cn ├── doc-component-repo │ ├── modules │ │ ├── typescript-sdk │ │ │ ├── pages │ │ │ │ ├── entities.adoc │ │ │ │ └── enums.adoc │ │ │ └── nav.adoc │ │ ├── cuba-rest-js │ │ │ ├── nav.adoc │ │ │ └── pages │ │ │ │ └── index.adoc │ │ ├── generator │ │ │ ├── nav.adoc │ │ │ ├── partials │ │ │ │ └── feat-available-in-studio.adoc │ │ │ └── images │ │ │ │ ├── browser-list.png │ │ │ │ ├── browser-cards.png │ │ │ │ ├── interactive-projects.png │ │ │ │ └── studio-integration.png │ │ ├── overview │ │ │ └── partials │ │ │ │ └── getting-started-note.adoc │ │ ├── getting-started │ │ │ ├── nav.adoc │ │ │ └── pages │ │ │ │ ├── learning-path.adoc │ │ │ │ └── index.adoc │ │ ├── client-react │ │ │ ├── pages │ │ │ │ ├── sync-project-model.adoc │ │ │ │ ├── supported-browsers.adoc │ │ │ │ ├── build.adoc │ │ │ │ └── config.adoc │ │ │ ├── images │ │ │ │ ├── home-screen.png │ │ │ │ ├── login-screen.png │ │ │ │ ├── data-table-demo.gif │ │ │ │ ├── pet-clinic-editor.png │ │ │ │ ├── pet-clinic-browser.png │ │ │ │ ├── studio-create-front-module.gif │ │ │ │ └── studio-adding-frontend-component.gif │ │ │ └── nav.adoc │ │ ├── client-react-native │ │ │ ├── images │ │ │ │ └── RNDemo.gif │ │ │ ├── nav.adoc │ │ │ └── pages │ │ │ │ ├── learning-path.adoc │ │ │ │ └── technologies.adoc │ │ ├── cuba-react-ui │ │ │ ├── images │ │ │ │ └── FileUploadAndImagePreviewDemo.gif │ │ │ ├── pages │ │ │ │ ├── index.adoc │ │ │ │ ├── image-preview.adoc │ │ │ │ ├── nested-entity-field.adoc │ │ │ │ └── entity-property.adoc │ │ │ └── nav.adoc │ │ ├── libs │ │ │ └── nav.adoc │ │ └── cuba-react-core │ │ │ └── pages │ │ │ └── index.adoc │ └── antora.yml ├── api-reference │ ├── cuba-rest-js │ │ └── assets │ │ │ └── images │ │ │ ├── icons.png │ │ │ ├── icons@2x.png │ │ │ ├── widgets.png │ │ │ └── widgets@2x.png │ ├── cuba-react-core │ │ └── assets │ │ │ └── images │ │ │ ├── icons.png │ │ │ ├── widgets.png │ │ │ ├── icons@2x.png │ │ │ └── widgets@2x.png │ └── cuba-react-ui │ │ └── assets │ │ └── images │ │ ├── icons.png │ │ ├── widgets.png │ │ ├── icons@2x.png │ │ └── widgets@2x.png ├── supplemental-ui │ └── partials │ │ └── head-styles.hbs └── redirect-page-template.html ├── test-pup ├── jmix_logo.png ├── babel.config.js ├── jest.config.js ├── package.json ├── example-react-app │ └── data-table │ │ └── data-table-custom-filter │ │ └── data-table-no-filters.test.js └── common │ ├── custom-form-controls.js │ └── paging.js ├── lerna.json ├── scripts ├── jmix │ ├── start-jmix-app.js │ ├── update-jmix-app.js │ └── bootstrap-jmix-app.js ├── model │ └── graphql │ │ ├── intIdEntity.js │ │ ├── associationM2M.js │ │ ├── associationM2O.js │ │ ├── associationO2M.js │ │ ├── associationO2O.js │ │ ├── trickyIdEntity.js │ │ ├── deeplyNestedTestEntity.js │ │ ├── boringStringIdEntity.js │ │ ├── deeplyNestedO2MTestEntity.js │ │ ├── formWizardCompositionO2O.js │ │ ├── datatypesTestEntity3.js │ │ ├── weirdStringIdEntity.js │ │ ├── datatypesTestEntity2.js │ │ ├── compositionO2M.js │ │ ├── compositionO2O.js │ │ ├── favoriteCarsCards.js │ │ ├── formWizardTestEntity.js │ │ ├── intIdentityIdEntity.js │ │ ├── stringIdEntity.js │ │ └── carEntity.js ├── pack-given-client-libs.js ├── update-react-native-client-libs.js ├── generator-customization │ ├── generators │ │ └── src │ │ │ └── custom-screen │ │ │ ├── options.ts │ │ │ ├── blank.svg │ │ │ ├── template-model.ts │ │ │ └── template │ │ │ └── Component.tsx │ └── templates │ │ ├── README.md │ │ └── blank-screen │ │ └── Component.tsx ├── update-given-client-libs.js ├── screens │ ├── int-id-editor.js │ ├── tricky-id-editor.js │ ├── int-identity-id-editor.js │ ├── form-wizard-editor.js │ ├── string-id-cards.js │ ├── string-id-editor.js │ ├── deeply-nested-editor.js │ ├── form-wizard-browser.js │ ├── int-id-browser-list.js │ ├── deeply-nested-o2m-editor.js │ ├── form-wizard-composition-o2o.js │ ├── int-id-browser-cards.js │ ├── int-id-browser-table.js │ ├── weird-string-id-editor.js │ ├── int-identity-id-cards.js │ ├── boring-string-id-editor.js │ ├── car-cards-with-details.js │ ├── tricky-id-browser-table.js │ ├── car-table-with-filters.js │ ├── int-identity-id-browser-cards.js │ ├── int-identity-id-browser-list.js │ ├── int-identity-id-browser-table.js │ ├── deeply-nested-o2m-browser-table.js │ ├── string-id-browser-cards.js │ ├── string-id-browser-list.js │ ├── string-id-browser-table.js │ ├── datatypes-calendar.js │ ├── weird-string-id-browser-list.js │ ├── weird-string-id-browser-cards.js │ ├── weird-string-id-browser-table.js │ └── boring-string-id-browser-table.js ├── custom-screens │ ├── CustomAppLayouts.module.css │ └── CustomDataDisplayComponents.module.css ├── generate-react-native-client-scr.js ├── pack-react-native-client-libs.js ├── update-react-client-libs.js ├── run-gradle.js ├── pack-react-client-libs.js └── ci-bootstrap-backend.js ├── .snyk ├── .gitattributes ├── .gitignore ├── README.md └── commitlint.config.js /.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example-react-app/src/addons.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/generator.test.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/typescript-sdk/pages/enums.adoc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/typescript-sdk/pages/entities.adoc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/typescript-sdk/pages/enums.adoc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/typescript-sdk/pages/entities.adoc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example-react-app/tsconfig.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json" 3 | } -------------------------------------------------------------------------------- /packages/jmix-front-generator/.npmignore: -------------------------------------------------------------------------------- 1 | /* 2 | !package.json 3 | !bin 4 | !lib -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | /metadata 3 | node_modules 4 | -------------------------------------------------------------------------------- /packages/jmix-react-web/.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | rollup.config.js 3 | jest.config.js -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/cuba-rest-js/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[REST API] -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/jmix-rest-js/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[REST API] -------------------------------------------------------------------------------- /example-react-app/src/app/CenteredLoader.module.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-size: 24px; 3 | } -------------------------------------------------------------------------------- /example-react-app/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example-react-app/src/themes/antd-themes/light.less: -------------------------------------------------------------------------------- 1 | @import 'antd/dist/antd.less'; 2 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/templates/EntityManagementEditor.tsx: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/typescript-sdk/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[TypeScript SDK] -------------------------------------------------------------------------------- /packages/jmix-rest/examples/node/README.md: -------------------------------------------------------------------------------- 1 | ```bash 2 | npm install 3 | node index.js 4 | ``` -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/typescript-sdk/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[TypeScript SDK] -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/test/polyfills.js: -------------------------------------------------------------------------------- 1 | Object.fromEntries = require('object.fromentries'); -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/EntityHierarchyTree/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./EntityHierachyTree"; -------------------------------------------------------------------------------- /packages/jmix-react-core/src/test/polyfills.js: -------------------------------------------------------------------------------- 1 | Object.fromEntries = require('object.fromentries'); -------------------------------------------------------------------------------- /example-react-app/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 -------------------------------------------------------------------------------- /packages/jmix-front-generator/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.{js,ts,tsx,ejs}] 4 | indent_size = 2 -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/addons.ts: -------------------------------------------------------------------------------- 1 | export {} 2 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/form/controls/RichTextArea.less: -------------------------------------------------------------------------------- 1 | .ql-editor { 2 | height: 200px; 3 | } -------------------------------------------------------------------------------- /test-pup/jmix_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/test-pup/jmix_logo.png -------------------------------------------------------------------------------- /packages/jmix-react-core/src/conditional-rendering/index.ts: -------------------------------------------------------------------------------- 1 | import {IF} from './IF'; 2 | export {IF}; 3 | -------------------------------------------------------------------------------- /packages/jmix-server-mock/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 -------------------------------------------------------------------------------- /example-react-app/images.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.svg"; 2 | declare module "*.png"; 3 | declare module "*.jpg"; 4 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/stages/writing/pieces/entity-management/entity-management.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../eslint-config-jmix-react/.eslintrc.json" 3 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/form/CharInput.module.less: -------------------------------------------------------------------------------- 1 | .charInputField { 2 | max-width: 55px; 3 | } 4 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/form/InputNumber.module.less: -------------------------------------------------------------------------------- 1 | .inputNumberField { 2 | width: 100%; 3 | } 4 | -------------------------------------------------------------------------------- /packages/jmix-react-core/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../eslint-config-jmix-react/.eslintrc.json" 3 | } -------------------------------------------------------------------------------- /packages/jmix-react-web/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist 4 | dist-transpiled 5 | *.tgz 6 | coverage 7 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*", "test-pup" 4 | ], 5 | "version": "independent" 6 | } 7 | -------------------------------------------------------------------------------- /packages/jmix-addon-charts/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | /metadata 3 | node_modules 4 | haulmont-jmix-addon-charts-*.tgz 5 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/test/mocha.opts: -------------------------------------------------------------------------------- 1 | --require ts-node/register 2 | src/test/**/*.test.ts 3 | --timeout 0 4 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist 4 | dist-transpiled 5 | *.tgz 6 | coverage 7 | -------------------------------------------------------------------------------- /packages/jmix-react-core/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist 4 | dist-transpiled 5 | *.tgz 6 | coverage 7 | -------------------------------------------------------------------------------- /packages/jmix-react-web/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../eslint-config-jmix-react/.eslintrc.json" 3 | } 4 | -------------------------------------------------------------------------------- /packages/jmix-server-mock/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | node_modules 3 | dist 4 | dist-transpiled 5 | *.tgz 6 | coverage 7 | -------------------------------------------------------------------------------- /scripts/jmix/start-jmix-app.js: -------------------------------------------------------------------------------- 1 | const startJmixApp = require("./_start-jmix-app"); 2 | 3 | startJmixApp(false); 4 | -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/screens/Screens.less: -------------------------------------------------------------------------------- 1 | .screen-disabled { 2 | display: none; 3 | } 4 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/stages/answers/pieces/EmptyAnswers.ts: -------------------------------------------------------------------------------- 1 | export interface EmptyAnswers {} -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/routing.ts: -------------------------------------------------------------------------------- 1 | import './app/home/HomePage'; 2 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/timer/index.ts: -------------------------------------------------------------------------------- 1 | import {useTimer} from "./timer"; 2 | 3 | export { 4 | useTimer 5 | } 6 | -------------------------------------------------------------------------------- /test-pup/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | '@babel/plugin-proposal-class-properties' 4 | ] 5 | } -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/sdk/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "clientBaseTech": "Typescript", 3 | "bower": false 4 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_size = 2 6 | indent_style = space -------------------------------------------------------------------------------- /packages/jmix-react-antd/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@babel/preset-env', '@babel/preset-react'], 3 | }; -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/menu/addons-menu/index.ts: -------------------------------------------------------------------------------- 1 | import {AddonsMenu} from "./AddonsMenu"; 2 | export {AddonsMenu}; 3 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/modals/index.ts: -------------------------------------------------------------------------------- 1 | import { Modals, modals } from "./Modals"; 2 | export { Modals, modals }; 3 | -------------------------------------------------------------------------------- /packages/jmix-react-core/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_size = 2 6 | indent_style = space -------------------------------------------------------------------------------- /packages/jmix-react-core/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['@babel/preset-env', '@babel/preset-react'], 3 | }; -------------------------------------------------------------------------------- /packages/jmix-react-web/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_size = 2 6 | indent_style = space -------------------------------------------------------------------------------- /packages/jmix-react-web/src/ui/entity-property/EntityPropery.module.less: -------------------------------------------------------------------------------- 1 | .propertyContainer { 2 | display: flex; 3 | } 4 | -------------------------------------------------------------------------------- /packages/jmix-rest/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | indent_style = space 6 | indent_size = 2 7 | -------------------------------------------------------------------------------- /example-react-app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/example-react-app/public/favicon.ico -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/screens/index.ts: -------------------------------------------------------------------------------- 1 | import {Screens} from "./Screens"; 2 | export {Screens}; 3 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "clientBaseTech": "React", 3 | "bower": false 4 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/form/controls/SourceCodeField.module.less: -------------------------------------------------------------------------------- 1 | .sourceCodeField { 2 | border: 1px solid #d9d9d9; 3 | } -------------------------------------------------------------------------------- /test-pup/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | verbose: true, 3 | preset: "jest-puppeteer", 4 | testTimeout: 10000 5 | }; 6 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/stages/template-model/pieces/EmptyTemplateModel.ts: -------------------------------------------------------------------------------- 1 | export interface EmptyTemplateModel {} -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/tsconfig.prod.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json" 3 | } -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.13.5 3 | ignore: {} 4 | patch: {} 5 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/generator/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Frontend Generator 参考] 2 | ** xref:commands-reference.adoc[命令参考] -------------------------------------------------------------------------------- /example-react-app/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs" 5 | } 6 | } -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-editor/EntityDataEditor.less: -------------------------------------------------------------------------------- 1 | .form-item { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/info.json: -------------------------------------------------------------------------------- 1 | { 2 | "clientBaseTech": "React Native", 3 | "bower": false 4 | } 5 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/themes/antd-themes/light.less: -------------------------------------------------------------------------------- 1 | @import 'antd/dist/antd.less'; 2 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/menu/vertical-menu/index.ts: -------------------------------------------------------------------------------- 1 | import {VerticalMenu} from "./VerticalMenu"; 2 | export default VerticalMenu; 3 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/util/useNoop.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A hook that does nothing. 3 | */ 4 | export function useNoop() { 5 | // Noop 6 | } -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/breadcrumbs/index.ts: -------------------------------------------------------------------------------- 1 | import {Breadcrumbs} from "./Breadcrumbs"; 2 | export {Breadcrumbs}; 3 | -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-editor/fields/index.ts: -------------------------------------------------------------------------------- 1 | import {Fields} from "./Fields"; 2 | export {Fields}; 3 | -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-select/index.ts: -------------------------------------------------------------------------------- 1 | import {EntitySelect} from "./EntitySelect"; 2 | export {EntitySelect}; -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/stages/options/pieces/dir-shift.ts: -------------------------------------------------------------------------------- 1 | export interface DirShiftOption { 2 | dirShift: string; 3 | } -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/app/CenteredLoader.module.css: -------------------------------------------------------------------------------- 1 | .icon { 2 | font-size: 24px; 3 | } -------------------------------------------------------------------------------- /packages/jmix-react-core/.eslintignore: -------------------------------------------------------------------------------- 1 | dist-transpiled 2 | dist 3 | rollup.config.js 4 | babel.config.js 5 | jest.config.js 6 | src/test/polyfills.js -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/uncapitalize-first.ts: -------------------------------------------------------------------------------- 1 | export const unCapitalizeFirst = (part: string) => part[0].toLowerCase() + part.slice(1); -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/overview/partials/getting-started-note.adoc: -------------------------------------------------------------------------------- 1 | NOTE: 如果您还没有阅读 xref:getting-started:index.adoc[开始使用] 部分,我们建议您先阅读那部分内容。 -------------------------------------------------------------------------------- /example-react-app/src/styles.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.module.css" { 2 | const classes: { [key: string]: string }; 3 | export default classes; 4 | } 5 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/menu/horizontal-menu/index.ts: -------------------------------------------------------------------------------- 1 | import {HorizontalMenu} from "./HorizontalMenu"; 2 | export default HorizontalMenu; 3 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/custom.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.less' { 2 | const classes: { [key: string]: string }; 3 | export default classes; 4 | } 5 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/generator/partials/feat-available-in-studio.adoc: -------------------------------------------------------------------------------- 1 | TIP: 该功能也能在 Studio 中使用,参阅 {manual_studio_frontendUi}[Studio 使用手册]。 2 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/_editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/custom.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.less' { 2 | const classes: { [key: string]: string }; 3 | export default classes; 4 | } 5 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/test/styleMock.ts: -------------------------------------------------------------------------------- 1 | const styleMock = new Proxy({}, { 2 | get: (_target, key) => key, 3 | }); 4 | export default styleMock; 5 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/test/styleMock.ts: -------------------------------------------------------------------------------- 1 | const styleMock = new Proxy({}, { 2 | get: (_target, key) => key, 3 | }); 4 | export default styleMock; 5 | -------------------------------------------------------------------------------- /packages/jmix-rest/.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.13.5 3 | ignore: {} 4 | patch: {} 5 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/generator/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Frontend Generator Reference] 2 | ** xref:commands-reference.adoc[Commands Description] -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/getting-started/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:learning-path.adoc[Getting Started] 2 | ** xref:migration-cuba-to-jmix.adoc[Migration from CUBA] 3 | -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-editor/index.ts: -------------------------------------------------------------------------------- 1 | import {EntityDataEditor} from "./EntityDataEditor"; 2 | export {EntityDataEditor}; 3 | -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-viewer/index.ts: -------------------------------------------------------------------------------- 1 | import {EntityDataViewer} from "./EntityDataViewer"; 2 | export {EntityDataViewer}; 3 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/images.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.svg' 2 | declare module '*.png' 3 | declare module '*.jpg' 4 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | babel.config.js 3 | rollup.config.js 4 | jest.config.js 5 | src/test/polyfills.js 6 | resolve-node-imports-in-less.js -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/Spinner.module.less: -------------------------------------------------------------------------------- 1 | .spinner { 2 | position: absolute; 3 | left: 50%; 4 | top: 50%; 5 | transform: translate(-50%, -50%); 6 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/notifications/index.ts: -------------------------------------------------------------------------------- 1 | import {notifications, NotificationType} from "./Notifications" 2 | export {notifications, NotificationType}; 3 | -------------------------------------------------------------------------------- /packages/jmix-react-core/.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.13.5 3 | ignore: {} 4 | patch: {} 5 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/misc.ts: -------------------------------------------------------------------------------- 1 | export function sleep(ms = 0) { 2 | return new Promise((resolve) => { 3 | setTimeout(resolve, ms); 4 | }); 5 | } 6 | -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-rest/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-rest/assets/images/icons.png -------------------------------------------------------------------------------- /docs-src/supplemental-ui/css/overrides.css: -------------------------------------------------------------------------------- 1 | /* This file contains CSS rules that override the rules defined by Antora Default UI */ 2 | .doc { 3 | hyphens: none; 4 | } -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-editor/association-2o/index.ts: -------------------------------------------------------------------------------- 1 | import {Association2O} from "./Association2O"; 2 | export {Association2O}; 3 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/menu/menu-item/index.ts: -------------------------------------------------------------------------------- 1 | import {MenuItem, Props} from "./MenuItem"; 2 | export {Props as MenuItemProps}; 3 | export default MenuItem; 4 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/isNull.ts: -------------------------------------------------------------------------------- 1 | export function isNull(value: any) { 2 | return value === null || typeof value === 'undefined' || value === ''; 3 | } 4 | -------------------------------------------------------------------------------- /scripts/model/graphql/intIdEntity.js: -------------------------------------------------------------------------------- 1 | const intIdEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | description 6 | } 7 | `; 8 | 9 | module.exports = intIdEntityQuery; -------------------------------------------------------------------------------- /scripts/pack-given-client-libs.js: -------------------------------------------------------------------------------- 1 | const packClientLibs = require('./pack-client-libs'); 2 | 3 | const libs = process.argv.slice(2); 4 | 5 | packClientLibs(libs, libs); 6 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/getting-started/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[开始使用] 2 | ** xref:cli-specific-instructions.adoc[CLI 特性介绍] 3 | ** xref:learning-path.adoc[选择学习路径] -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-react-ui/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-react-ui/assets/images/icons.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-rest/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-rest/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-rest/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-rest/assets/images/widgets.png -------------------------------------------------------------------------------- /scripts/model/graphql/associationM2M.js: -------------------------------------------------------------------------------- 1 | const associationM2MQuery = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | } 7 | `; 8 | 9 | module.exports = associationM2MQuery; -------------------------------------------------------------------------------- /scripts/model/graphql/associationM2O.js: -------------------------------------------------------------------------------- 1 | const associationM2OQuery = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | } 7 | `; 8 | 9 | module.exports = associationM2OQuery; -------------------------------------------------------------------------------- /scripts/model/graphql/associationO2M.js: -------------------------------------------------------------------------------- 1 | const associationO2MQuery = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | } 7 | `; 8 | 9 | module.exports = associationO2MQuery; -------------------------------------------------------------------------------- /scripts/model/graphql/associationO2O.js: -------------------------------------------------------------------------------- 1 | const associationO2Oquery = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | } 7 | `; 8 | 9 | module.exports = associationO2Oquery; -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-rest-js/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-rest-js/assets/images/icons.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-react-core/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-react-core/assets/images/icons.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-react-ui/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-react-ui/assets/images/widgets.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-rest/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-rest/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/generator/partials/feat-available-in-studio.adoc: -------------------------------------------------------------------------------- 1 | TIP: This feature is also available in Jmix Studio. 2 | // TODO: Add link to Studio manual 3 | -------------------------------------------------------------------------------- /example-react-app/src/index.css: -------------------------------------------------------------------------------- 1 | html, body, #root { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | padding: 0; 8 | font-family: sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/custom-typings/react-pivottable.ts: -------------------------------------------------------------------------------- 1 | declare module 'react-pivottable/PivotTableUI' { 2 | const PivotTableUI: any; 3 | export = PivotTableUI; 4 | } -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-inspector-main/index.ts: -------------------------------------------------------------------------------- 1 | import {EntityInspectorMain} from "./EntityInscpectorMain"; 2 | export {EntityInspectorMain}; 3 | -------------------------------------------------------------------------------- /scripts/model/graphql/trickyIdEntity.js: -------------------------------------------------------------------------------- 1 | const trickyIdEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | otherAttr 6 | } 7 | `; 8 | 9 | module.exports = trickyIdEntityQuery; -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Exclude docs folder from GitHub language statistics 2 | docs/** linguist-documentation 3 | docs-src/** linguist-documentation 4 | docs-src-cn/** linguist-documentation 5 | -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-react-core/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-react-core/assets/images/icons.png -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-react-ui/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-react-ui/assets/images/icons.png -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-react-ui/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-react-ui/assets/images/widgets.png -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-rest-js/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-rest-js/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-rest-js/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-rest-js/assets/images/widgets.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-react-core/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-react-core/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-react-core/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-react-core/assets/images/widgets.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-react-ui/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-react-ui/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-react-ui/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-react-ui/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs-src/api-reference/react-ide-toolbox/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/react-ide-toolbox/assets/images/icons.png -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-editor/composition-field/index.ts: -------------------------------------------------------------------------------- 1 | import {CompositionField} from "./CompositionField"; 2 | export {CompositionField}; 3 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/.gitignore: -------------------------------------------------------------------------------- 1 | .tmp 2 | .idea 3 | test/integration/generated 4 | src/test/generated 5 | lib 6 | node_modules 7 | coverage 8 | .nyc_output 9 | *.tgz 10 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/Grid/index.ts: -------------------------------------------------------------------------------- 1 | import { Col, ColProps } from './Col/Col'; 2 | import { Row, RowProps } from './Row/Row'; 3 | 4 | export { Col, ColProps, Row, RowProps }; -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/menu/sub-menu-item/index.ts: -------------------------------------------------------------------------------- 1 | import {SubMenuItem, Props} from "./SubMenuItem"; 2 | export {Props as SubMenuItemProps}; 3 | export default SubMenuItem; 4 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/retry-dialog/RetryDialog.module.less: -------------------------------------------------------------------------------- 1 | @import 'antd/es/style/themes/default'; 2 | 3 | .retryBtn { 4 | display: block; 5 | margin-top: @margin-sm; 6 | } -------------------------------------------------------------------------------- /packages/jmix-rest/.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .local-storage 3 | node_modules 4 | npm-debug.log 5 | .nyc_output 6 | coverage 7 | .gradle 8 | *.tgz 9 | dist-browser 10 | dist-node 11 | -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-react-core/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-react-core/assets/images/widgets.png -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-react-ui/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-react-ui/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-rest-js/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-rest-js/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs-src/api-reference/jmix-react-core/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/jmix-react-core/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs-src/api-reference/react-ide-toolbox/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/react-ide-toolbox/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs-src/api-reference/react-ide-toolbox/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/react-ide-toolbox/assets/images/widgets.png -------------------------------------------------------------------------------- /example-react-app/src/app/common/Centered.module.css: -------------------------------------------------------------------------------- 1 | .centered { 2 | width: 100vw; 3 | height: 100vh; 4 | display: flex; 5 | align-items: center; 6 | justify-content: center; 7 | } -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-react-core/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-react-core/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-react-core/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-react-core/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs-src-cn/api-reference/cuba-react-ui/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/api-reference/cuba-react-ui/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs-src/api-reference/react-ide-toolbox/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/api-reference/react-ide-toolbox/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/generator/images/browser-cards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/generator/images/browser-cards.png -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/generator/images/browser-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/generator/images/browser-list.png -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-editor/composition-field/composition-o2m/index.ts: -------------------------------------------------------------------------------- 1 | import {CompositionO2M} from "./CompositionO2M"; 2 | export {CompositionO2M}; 3 | -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-editor/composition-field/composition-o2o/index.ts: -------------------------------------------------------------------------------- 1 | import {CompositionO2O} from "./CompositionO2O"; 2 | export {CompositionO2O}; 3 | -------------------------------------------------------------------------------- /scripts/model/graphql/deeplyNestedTestEntity.js: -------------------------------------------------------------------------------- 1 | const deeplyNestedTestEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | } 7 | `; 8 | 9 | module.exports = deeplyNestedTestEntityQuery; -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/pages/sync-project-model.adoc: -------------------------------------------------------------------------------- 1 | = 项目模型同步 2 | 3 | 如需同步后端改动的模型,可以通过下面命令重新生成项目模型: 4 | 5 | [source,bash] 6 | ---- 7 | $ npm run `update-model` 8 | ---- 9 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/generator/images/browser-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/generator/images/browser-list.png -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/images/home-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/client-react/images/home-screen.png -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/images/login-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/client-react/images/login-screen.png -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "module": "commonjs" 5 | } 6 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/layouts/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./AppLayout"; 2 | export * from "./Header"; 3 | export * from "./Sidebar"; 4 | export * from "./Footer"; 5 | export * from "./Content"; 6 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/crud/sort.ts: -------------------------------------------------------------------------------- 1 | export type JmixSortOrder = {[key: string]: 'ASC' | 'DESC' | JmixSortOrder}; 2 | 3 | export type SortOrderChangeCallback = (sortOrder?: JmixSortOrder) => void -------------------------------------------------------------------------------- /scripts/model/graphql/boringStringIdEntity.js: -------------------------------------------------------------------------------- 1 | const boringStringIdEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | description 6 | } 7 | `; 8 | 9 | module.exports = boringStringIdEntityQuery; -------------------------------------------------------------------------------- /scripts/update-react-native-client-libs.js: -------------------------------------------------------------------------------- 1 | const updateClientLibs = require('./update-client-libs'); 2 | 3 | updateClientLibs( 4 | 'react-native-client-scr', 5 | ['rest', 'react-core'] 6 | ); -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/images/home-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/client-react/images/home-screen.png -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/images/login-screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/client-react/images/login-screen.png -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/generator/images/browser-cards.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/generator/images/browser-cards.png -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react-native/images/RNDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/client-react-native/images/RNDemo.gif -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/images/data-table-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/client-react/images/data-table-demo.gif -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/generator/images/studio-integration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/generator/images/studio-integration.png -------------------------------------------------------------------------------- /packages/jmix-react-core/src/crud/JmixConstraintViolation.ts: -------------------------------------------------------------------------------- 1 | export interface JmixConstraintViolation { 2 | invalidValue: any; 3 | message: string; 4 | messageTemplate: string; 5 | path: string; 6 | } -------------------------------------------------------------------------------- /scripts/model/graphql/deeplyNestedO2MTestEntity.js: -------------------------------------------------------------------------------- 1 | const deeplyNestedO2MTestEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | } 7 | `; 8 | 9 | module.exports = deeplyNestedO2MTestEntityQuery; -------------------------------------------------------------------------------- /scripts/model/graphql/formWizardCompositionO2O.js: -------------------------------------------------------------------------------- 1 | const formWizardCompositionO2OQuery = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | } 7 | `; 8 | 9 | module.exports = formWizardCompositionO2OQuery; -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react-native/images/RNDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/client-react-native/images/RNDemo.gif -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/images/pet-clinic-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/client-react/images/pet-clinic-editor.png -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/generator/images/interactive-projects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/generator/images/interactive-projects.png -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/overview/partials/getting-started-note.adoc: -------------------------------------------------------------------------------- 1 | NOTE: If you haven't read our introductory xref:getting-started:index.adoc[Getting Started] section, we encourage you to do so now. -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/styles.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.module.css" { 2 | const classes: { [key: string]: string }; 3 | export default classes; 4 | } 5 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/images/data-table-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/client-react/images/data-table-demo.gif -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/images/pet-clinic-editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/client-react/images/pet-clinic-editor.png -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/generator/images/interactive-projects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/generator/images/interactive-projects.png -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/generator/images/studio-integration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/generator/images/studio-integration.png -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/images/pet-clinic-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/client-react/images/pet-clinic-browser.png -------------------------------------------------------------------------------- /scripts/model/graphql/datatypesTestEntity3.js: -------------------------------------------------------------------------------- 1 | const query = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | } 7 | `; 8 | 9 | module.exports = { 10 | listQuery: query, 11 | editQuery: query, 12 | }; -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react-native/nav.adoc: -------------------------------------------------------------------------------- 1 | * React Native Client 2 | ** xref:starter-guide.adoc[开始使用 React Native Client] 3 | ** xref:technologies.adoc[技术概览] 4 | ** xref:learning-path.adoc[然后怎么办?] -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/images/pet-clinic-browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/client-react/images/pet-clinic-browser.png -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/pages/supported-browsers.adoc: -------------------------------------------------------------------------------- 1 | = 支持的浏览器 2 | 3 | 该客户端支持所有现代浏览器。如果要支持 IE 9/10/11,需要 https://facebook.github.io/create-react-app/docs/supported-browsers-features[额外配置]。 4 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/hotkeys/hotkeyConfig.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @param description is unique 3 | */ 4 | export interface HotkeyConfig { 5 | hotkey: string; 6 | description: string; 7 | categoryName: string; 8 | } 9 | -------------------------------------------------------------------------------- /scripts/model/graphql/weirdStringIdEntity.js: -------------------------------------------------------------------------------- 1 | const weirdStringIdEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | identifier 6 | description 7 | } 8 | `; 9 | 10 | module.exports = weirdStringIdEntityQuery; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .idea 3 | .vscode 4 | .npmrc 5 | node_modules 6 | example-react-app/generator-customization/generators/build 7 | react-native-client-scr/** 8 | docs-build*/** 9 | _testgen/** 10 | scr-jmix/ 11 | -------------------------------------------------------------------------------- /example-react-app/.env.development.local: -------------------------------------------------------------------------------- 1 | REACT_APP_JMIX_REST_URL=/rest/ 2 | REACT_APP_REST_CLIENT_ID=client 3 | REACT_APP_REST_CLIENT_SECRET=secret 4 | REACT_APP_GRAPHQL_URI=/graphql 5 | REACT_APP_ENABLE_UI_PERMISSIONS=false 6 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-cards/options.ts: -------------------------------------------------------------------------------- 1 | import {ComponentOptions} from "../../../building-blocks/stages/options/pieces/component"; 2 | 3 | export type Options = ComponentOptions; -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/layouts/AppLayout.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Layout, LayoutProps} from "antd"; 3 | 4 | export const AppLayout = (props: LayoutProps) => { 5 | return ; 6 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/layouts/Footer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Layout, LayoutProps} from "antd"; 3 | 4 | export const Footer = (props: LayoutProps) => { 5 | return 6 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/layouts/Header.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Layout, LayoutProps} from "antd"; 3 | 4 | export const Header = (props: LayoutProps) => { 5 | return 6 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/layouts/Sidebar.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Layout, LayoutProps} from "antd"; 3 | 4 | export const Sidebar = (props: LayoutProps) => { 5 | return 6 | } -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/images/studio-create-front-module.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/client-react/images/studio-create-front-module.gif -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/packages/jmix-front-generator/src/generators/react-native/app/template/assets/icon.png -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/form/validation/passthroughRule.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * An Ant Design `
` validation rule that always passes. 3 | */ 4 | export const passthroughRule = { 5 | validator: () => Promise.resolve() 6 | }; 7 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/layouts/Content.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Layout, LayoutProps} from "antd"; 3 | 4 | export const Content = (props: LayoutProps) => { 5 | return 6 | } -------------------------------------------------------------------------------- /scripts/model/graphql/datatypesTestEntity2.js: -------------------------------------------------------------------------------- 1 | const datatypes2Query = ` 2 | { 3 | id 4 | _instanceName 5 | } 6 | `; 7 | 8 | module.exports = { 9 | listQuery: datatypes2Query, 10 | editQuery: datatypes2Query, 11 | }; -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/images/studio-create-front-module.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/client-react/images/studio-create-front-module.gif -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/jmix-react-ui/images/FileUploadAndImagePreviewDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/jmix-react-ui/images/FileUploadAndImagePreviewDemo.gif -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/packages/jmix-front-generator/src/generators/react-native/app/template/assets/splash.png -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/index.css: -------------------------------------------------------------------------------- 1 | html, body, #root { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | margin: 0; 7 | padding: 0; 8 | font-family: sans-serif; 9 | } 10 | -------------------------------------------------------------------------------- /scripts/generator-customization/generators/src/custom-screen/options.ts: -------------------------------------------------------------------------------- 1 | import { CommonGenerationOptions, DirShiftOption } from "@haulmont/jmix-front-generator"; 2 | 3 | export type Options = CommonGenerationOptions & DirShiftOption; 4 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/pages/build.adoc: -------------------------------------------------------------------------------- 1 | = 构建客户端 2 | 3 | `npm run build` 命令可以构建生产环境版本。构建结果在 `build` 文件夹。 4 | 5 | 参阅 React 文档了解更多支持的 https://facebook.github.io/create-react-app/docs/available-scripts[可用脚本]。 6 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/images/studio-adding-frontend-component.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src/doc-component-repo/modules/client-react/images/studio-adding-frontend-component.gif -------------------------------------------------------------------------------- /example-react-app/src/jmix/entities/scr_Order_1.ts: -------------------------------------------------------------------------------- 1 | export class Order { 2 | static NAME = "scr_Order_1"; 3 | id?: string; 4 | } 5 | export type OrderViewName = "_base" | "_instance_name" | "_local"; 6 | export type OrderView = never; 7 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/images/studio-adding-frontend-component.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/client-react/images/studio-adding-frontend-component.gif -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/cuba-react-ui/images/FileUploadAndImagePreviewDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/docs-src-cn/doc-component-repo/modules/cuba-react-ui/images/FileUploadAndImagePreviewDemo.gif -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo', 'module:react-native-dotenv'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Haulmont/jmix-frontend/HEAD/packages/jmix-front-generator/src/generators/react-typescript/app/template/public/favicon.ico -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/app/common/Centered.module.css: -------------------------------------------------------------------------------- 1 | .centered { 2 | width: 100vw; 3 | height: 100vh; 4 | display: flex; 5 | align-items: center; 6 | justify-content: center; 7 | } -------------------------------------------------------------------------------- /packages/jmix-react-core/README.md: -------------------------------------------------------------------------------- 1 | # Jmix React Core 2 | 3 | Contains core components and utilities for Jmix frontend clients based on React and React Native. 4 | 5 | Documentation and API reference can be found [here](https://docs.jmix.io/). 6 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/common/ReactComponent.ts: -------------------------------------------------------------------------------- 1 | import {IReactComponent} from "mobx-react/dist/types/IReactComponent"; 2 | 3 | /** 4 | * React component of any kind. 5 | */ 6 | export type ReactComponent = IReactComponent; 7 | -------------------------------------------------------------------------------- /packages/jmix-rest/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "coverageThreshold": { 3 | "global": { 4 | "statements": 80, 5 | "branches": 75, 6 | "functions": 60, 7 | "lines": 80 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/cuba-rest-js/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = REST API 2 | 3 | 生成的客户端代码使用 {manual_restApi}[通用 REST API]。详细的 API endpoint 文档在 {restApiSwagger}[这里] 发布。 4 | 5 | 使用 CUBA REST JS 与通用 REST API 通信。文档和 API 参考可以在 {api_rest}[这里]。 6 | -------------------------------------------------------------------------------- /example-react-app/.env.production.local: -------------------------------------------------------------------------------- 1 | PUBLIC_URL=/front/ 2 | REACT_APP_JMIX_REST_URL=/rest/ 3 | REACT_APP_REST_CLIENT_ID=client 4 | REACT_APP_REST_CLIENT_SECRET=secret 5 | REACT_APP_GRAPHQL_URI=/graphql 6 | REACT_APP_ENABLE_UI_PERMISSIONS=false 7 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/includes/FieldImports.ejs: -------------------------------------------------------------------------------- 1 | <%# In future we might want to generate dedicated components (e.g. TextField, etc.) instead of generic Field -%> 2 | <% if (attributes.length > 0) { %> 3 | Field, 4 | <% } -%> -------------------------------------------------------------------------------- /scripts/update-given-client-libs.js: -------------------------------------------------------------------------------- 1 | const updateClientLibs = require('./update-client-libs'); 2 | 3 | const args = process.argv.slice(2); 4 | const clientDir = args[0]; 5 | const libs = args.slice(1); 6 | 7 | updateClientLibs(clientDir, libs); 8 | -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-select/EntitySelect.less: -------------------------------------------------------------------------------- 1 | .select-container { 2 | padding: 0 0 15px 0; 3 | } 4 | 5 | .select-title { 6 | padding: 0 0 5px 0; 7 | } 8 | 9 | .select { 10 | width: 340px; 11 | } 12 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react-native/pages/learning-path.adoc: -------------------------------------------------------------------------------- 1 | = 然后怎么办? 2 | 3 | 查阅 xref:cuba-react-core:index.adoc[CUBA React Core] 章节了解可用的组件以及如何使用。 4 | 5 | 查阅 {api_rest}[CUBA REST JS] 了解您的组件如何与 {manual_restApi}[Generic REST API] 通信。 6 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react-native/nav.adoc: -------------------------------------------------------------------------------- 1 | * React Native Client 2 | ** xref:starter-guide.adoc[Getting Started with React Native Client] 3 | ** xref:technologies.adoc[Technologies Overview] 4 | ** xref:learning-path.adoc[Where Do I Go From Here?] -------------------------------------------------------------------------------- /packages/jmix-react-web/src/util/files.ts: -------------------------------------------------------------------------------- 1 | export function saveFile(objectUrl: string, fileName: string) { 2 | const anchor: HTMLAnchorElement = document.createElement('a'); 3 | anchor.href = objectUrl; 4 | anchor.download = fileName; 5 | anchor.click(); 6 | } -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/default-chart-options.ts: -------------------------------------------------------------------------------- 1 | 2 | export const defaultChartOptions = { 3 | height: 360, 4 | width: 600, 5 | margin: {top:25, left: 25, right: 25, bottom: 25}, 6 | theme: { 7 | background: '#FFF' 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/scripts/copy-templates.js: -------------------------------------------------------------------------------- 1 | const vfs = require('vinyl-fs'); 2 | 3 | vfs.src([ 4 | 'src/**/includes/**', 5 | 'src/**/template/**', 6 | 'src/**/template/.**', 7 | 'src/**/info.json', 8 | 'src/**/*.svg', 9 | ]).pipe(vfs.dest('lib')); -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/react-client/.env.development.local: -------------------------------------------------------------------------------- 1 | REACT_APP_JMIX_REST_URL=/rest/ 2 | REACT_APP_REST_CLIENT_ID=client 3 | REACT_APP_REST_CLIENT_SECRET=secret 4 | REACT_APP_GRAPHQL_URI=/graphql 5 | REACT_APP_ENABLE_UI_PERMISSIONS=false 6 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/base64.test.ts: -------------------------------------------------------------------------------- 1 | import {base64encode} from "./base64"; 2 | 3 | describe('base64encode()', () => { 4 | it('encodes correctly using btoa', () => { 5 | expect(base64encode('lorem ipsum')).toEqual('bG9yZW0gaXBzdW0='); 6 | }); 7 | }); -------------------------------------------------------------------------------- /scripts/screens/int-id-editor.js: -------------------------------------------------------------------------------- 1 | const intIdEntityQuery = require('../model/graphql/intIdEntity'); 2 | 3 | module.exports = { 4 | "query": intIdEntityQuery, 5 | "componentName": "IntIdEditor", 6 | "entity": { 7 | "name": "scr_IntegerIdTestEntity" 8 | } 9 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jmix Frontend Tools and Libraries 2 | 3 | CAUTION: This branch contains experimental code that will be removed soon. 4 | 5 | If you need to migrate a CUBA frontend to Jmix, switch to [release_0_9](https://github.com/Haulmont/jmix-frontend/tree/release_0_9) branch. 6 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/libs/nav.adoc: -------------------------------------------------------------------------------- 1 | .Libraries API Reference 2 | * link:../api-reference/jmix-rest/index.html[Jmix REST^] 3 | * link:../api-reference/jmix-react-core/index.html[Jmix React Core^] 4 | * link:../api-reference/jmix-react-ui/index.html[Jmix React UI^] 5 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/file.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Extracts file name from FileRef string 3 | * 4 | * @param fileRef 5 | */ 6 | export function extractName(fileRef: string): string { 7 | return decodeURIComponent( 8 | fileRef.split('?name=')[1] 9 | ); 10 | } -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/libs/nav.adoc: -------------------------------------------------------------------------------- 1 | .Libraries API Reference 2 | * link:../api-reference/cuba-rest-js/index.html[CUBA REST JS^] 3 | * link:../api-reference/cuba-react-core/index.html[CUBA React Core^] 4 | * link:../api-reference/cuba-react-ui/index.html[CUBA React UI^] -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/custom.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.css' { 2 | const classes: { [key: string]: string }; 3 | export default classes; 4 | } 5 | 6 | declare module '*.less' { 7 | const classes: { [key: string]: string }; 8 | export default classes; 9 | } 10 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/test/integration/expect/enums/enums.ts: -------------------------------------------------------------------------------- 1 | export enum CarType { 2 | SEDAN = "SEDAN", 3 | HATCHBACK = "HATCHBACK" 4 | } 5 | 6 | export enum EcoRank { 7 | EURO1 = "EURO1", 8 | EURO2 = "EURO2", 9 | EURO3 = "EURO3" 10 | } 11 | 12 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/test/integration/fixtures/sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "module": "commonjs", 5 | "outDir": "./lib", 6 | "sourceMap": true, 7 | "strict": true, 8 | "types": [] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /scripts/model/graphql/compositionO2M.js: -------------------------------------------------------------------------------- 1 | const compositionO2MQuery = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | quantity 7 | deeplyNestedO2Mattr { 8 | id 9 | _instanceName 10 | name 11 | } 12 | } 13 | `; 14 | 15 | module.exports = compositionO2MQuery; -------------------------------------------------------------------------------- /scripts/model/graphql/compositionO2O.js: -------------------------------------------------------------------------------- 1 | const compositionO2OQuery = ` 2 | { 3 | id 4 | _instanceName 5 | name 6 | quantity 7 | nestedComposition { 8 | id 9 | _instanceName 10 | name 11 | } 12 | } 13 | `; 14 | 15 | module.exports = compositionO2OQuery; -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/util/attribute-types.ts: -------------------------------------------------------------------------------- 1 | import {EntityAttribute} from "../../common/model/cuba-model"; 2 | 3 | export function isStringAttribute(attr: EntityAttribute) { 4 | return attr.mappingType === 'DATATYPE' && attr.type.label === 'String'; 5 | } 6 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/react-client/.env.production.local: -------------------------------------------------------------------------------- 1 | PUBLIC_URL=/front/ 2 | REACT_APP_JMIX_REST_URL=/rest/ 3 | REACT_APP_REST_CLIENT_ID=client 4 | REACT_APP_REST_CLIENT_SECRET=secret 5 | REACT_APP_GRAPHQL_URI=/graphql 6 | REACT_APP_ENABLE_UI_PERMISSIONS=false 7 | -------------------------------------------------------------------------------- /example-react-app/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # testing 5 | /coverage 6 | 7 | # production 8 | /build 9 | /build-gradle 10 | 11 | # misc 12 | .DS_Store 13 | 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | .idea 19 | .vscode 20 | .gradle -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/stages/options/pieces/component.ts: -------------------------------------------------------------------------------- 1 | import {CommonGenerationOptions} from "../../../../common/cli-options"; 2 | import {DirShiftOption} from "./dir-shift"; 3 | 4 | export interface ComponentOptions extends CommonGenerationOptions, DirShiftOption {} -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | .idea/* 4 | npm-debug.* 5 | *.jks 6 | *.p8 7 | *.p12 8 | *.key 9 | *.mobileprovision 10 | *.orig.* 11 | web-build/ 12 | web-report/ 13 | 14 | # macOS 15 | .DS_Store 16 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/common/base-entity-screen-generator/template-model.ts: -------------------------------------------------------------------------------- 1 | import {CommonTemplateModel} from '../template-model'; 2 | 3 | export interface BaseEntityScreenTemplateModel extends CommonTemplateModel { 4 | stringIdName?: string; 5 | } 6 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/view-properties--association-o2o.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "name", 4 | "lazy": false 5 | }, 6 | { 7 | "name": "datatypesTestEntity", 8 | "entity": "scr_DatatypesTestEntity", 9 | "lazy": false 10 | } 11 | ] 12 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/crud/editor/form/useCreateAntdResetForm.ts: -------------------------------------------------------------------------------- 1 | import { FormInstance } from "antd"; 2 | import { useCallback } from "react"; 3 | 4 | export function useCreateAntdResetForm(form: FormInstance): () => void { 5 | return useCallback(() => form.resetFields(), [form]); 6 | } 7 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/progress-bar/ProgressBar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Progress } from "antd"; 3 | import { ProgressProps } from "antd/es/progress"; 4 | 5 | export function ProgressBar({ ...props }: ProgressProps) { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /scripts/custom-screens/CustomAppLayouts.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | background: #bbdefb; 3 | } 4 | .content { 5 | background: #42a5f5; 6 | line-height: 100px; 7 | } 8 | .sider { 9 | background: #90caf9; 10 | line-height: 100px; 11 | } 12 | .footer { 13 | background: #bbdefb; 14 | } -------------------------------------------------------------------------------- /scripts/screens/tricky-id-editor.js: -------------------------------------------------------------------------------- 1 | const trickyIdEntityQuery = require('../model/graphql/trickyIdEntity'); 2 | 3 | module.exports = { 4 | "query": trickyIdEntityQuery, 5 | "componentName": "TrickyIdEditor", 6 | "entity": { 7 | "name": "scr_TrickyIdTestEntity" 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /scripts/screens/int-identity-id-editor.js: -------------------------------------------------------------------------------- 1 | const intIdentityIdQuery = require('../model/graphql/intIdentityIdEntity'); 2 | 3 | module.exports = { 4 | "query": intIdentityIdQuery, 5 | "componentName": "IntIdentityIdEditor", 6 | "entity": { 7 | "name": "scr_IntIdentityIdTestEntity" 8 | } 9 | }; -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/pages/config.adoc: -------------------------------------------------------------------------------- 1 | = Configuration 2 | 3 | See the https://facebook.github.io/create-react-app/docs/advanced-configuration[list of all available environment variables]. 4 | 5 | See `src/config.ts` for full list of common application settings used in runtime. 6 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/pages/supported-browsers.adoc: -------------------------------------------------------------------------------- 1 | = Supported Browsers 2 | 3 | The client supports all modern (evergreen) browsers. In order to support IE 9,10,11 https://facebook.github.io/create-react-app/docs/supported-browsers-features[additional configuration] is required. 4 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/pages/sync-project-model.adoc: -------------------------------------------------------------------------------- 1 | = Synchronizing the Project Model 2 | 3 | In order to sync up with the changes on the backend, you can re-generate the project model using the following command: 4 | 5 | [source,bash] 6 | ---- 7 | $ npm run update-model 8 | ---- 9 | -------------------------------------------------------------------------------- /scripts/generate-react-native-client-scr.js: -------------------------------------------------------------------------------- 1 | const gen = require('./generate-client-scr'); 2 | 3 | gen( 4 | 'React Native client SCR', 5 | 'react-native-client-scr', 6 | 'scripts/model/projectModel-scr-jmix.json', 7 | [ 8 | { command: 'react-native:app' } 9 | ] 10 | ); 11 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react/pages/build.adoc: -------------------------------------------------------------------------------- 1 | = Building the Client 2 | 3 | `npm run build` command builds your app for production use. See `build` folder. 4 | 5 | See https://facebook.github.io/create-react-app/docs/available-scripts[available scripts] in Create React App documentation. 6 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/.env: -------------------------------------------------------------------------------- 1 | REACT_NATIVE_APP_CUBA_URL="<% if (project.modulePrefix) { %>/<%=project.modulePrefix%><%}%>/rest/" 2 | REACT_NATIVE_APP_REST_CLIENT_ID=<%= project.restClientId %> 3 | REACT_NATIVE_APP_REST_CLIENT_SECRET=<%= project.restClientSecret %> 4 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/styles/palette.ts: -------------------------------------------------------------------------------- 1 | export const colors = { 2 | primary: '#3D88EC', 3 | 4 | error: "#bb0000", 5 | 6 | borders: '#EAEAEA', 7 | placeholders: '#C7C7C7', 8 | 9 | textPrimary: '#3D3D3D', 10 | textInverted: '#FFFFFF', 11 | }; 12 | -------------------------------------------------------------------------------- /scripts/screens/form-wizard-editor.js: -------------------------------------------------------------------------------- 1 | const query = require('../model/graphql/formWizardTestEntity'); 2 | 3 | module.exports = { 4 | 'menuItem': 'ROOT', 5 | "componentName": "FormWizardEditor", 6 | "entity": { 7 | "name": "scr_FormWizardTestEntity" 8 | }, 9 | query, 10 | "steps": '3' 11 | }; -------------------------------------------------------------------------------- /example-react-app/src/app/custom-app-layouts/CustomAppLayouts.module.css: -------------------------------------------------------------------------------- 1 | .header { 2 | background: #bbdefb; 3 | } 4 | .content { 5 | background: #42a5f5; 6 | line-height: 100px; 7 | } 8 | .sider { 9 | background: #90caf9; 10 | line-height: 100px; 11 | } 12 | .footer { 13 | background: #bbdefb; 14 | } -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/structure/options.ts: -------------------------------------------------------------------------------- 1 | import {CommonGenerationOptions} from "../../../common/cli-options"; 2 | import {DirShiftOption} from "../../../building-blocks/stages/options/pieces/dir-shift"; 3 | 4 | export type Options = CommonGenerationOptions & DirShiftOption; 5 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/tsconfig.declarations.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "emitDeclarationOnly": true, 6 | "outDir": "./lib" 7 | }, 8 | "include": [ 9 | "custom_types/**/*.ts", 10 | "src/index.ts" 11 | ] 12 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/form/CompositionFields.module.less: -------------------------------------------------------------------------------- 1 | @import 'antd/es/style/themes/default'; 2 | 3 | .upsertBtn { 4 | padding-right: 0; 5 | padding-left: 0; 6 | } 7 | 8 | :global(.ant-form-item-has-error) { 9 | .compositionField { 10 | border: solid 1px @error-color; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /scripts/model/graphql/favoriteCarsCards.js: -------------------------------------------------------------------------------- 1 | const favoriteCarsCardsQuery = ` 2 | { 3 | id 4 | _instanceName 5 | notes 6 | 7 | user { 8 | id 9 | _instanceName 10 | } 11 | car { 12 | id 13 | _instanceName 14 | } 15 | } 16 | `; 17 | 18 | module.exports = favoriteCarsCardsQuery; 19 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/blank-screen/options.ts: -------------------------------------------------------------------------------- 1 | import {CommonGenerationOptions} from "../../../common/cli-options"; 2 | import {DirShiftOption} from "../../../building-blocks/stages/options/pieces/dir-shift"; 3 | 4 | export type Options = CommonGenerationOptions & DirShiftOption; 5 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-calendar/options.ts: -------------------------------------------------------------------------------- 1 | import {CommonGenerationOptions} from "../../../common/cli-options"; 2 | import {DirShiftOption} from "../../../building-blocks/stages/options/pieces/dir-shift"; 3 | 4 | export type Options = CommonGenerationOptions & DirShiftOption; 5 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/crud/editor/validation/createUseAntdFormValidation.ts: -------------------------------------------------------------------------------- 1 | import { FormInstance } from "antd"; 2 | import {useAntdFormValidation} from "./useAntdFormValidation"; 3 | 4 | export function createUseAntdFormValidation(form: FormInstance) { 5 | return useAntdFormValidation.bind(null, form); 6 | } 7 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/Spinner.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {Spin} from "antd"; 3 | import styles from './Spinner.module.less'; 4 | 5 | export function Spinner() { 6 | 7 | return ( 8 |
9 | 10 |
11 | ); 12 | 13 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/form/controls/Button.tsx: -------------------------------------------------------------------------------- 1 | import { Button as AntdButton } from "antd"; 2 | import * as React from "react"; 3 | import { ButtonProps } from "antd/es/button"; 4 | 5 | export function Button({ children, ...rest }: ButtonProps) { 6 | return {children}; 7 | } 8 | -------------------------------------------------------------------------------- /scripts/screens/string-id-cards.js: -------------------------------------------------------------------------------- 1 | const stringIdEntityQuery = require('../model/graphql/stringIdEntity'); 2 | 3 | module.exports = { 4 | "query": stringIdEntityQuery, 5 | "entity": { 6 | "name": "scr_StringIdTestEntity" 7 | }, 8 | "componentName": "StringIdCards", 9 | 'menuItem': 'ROOT' 10 | } 11 | -------------------------------------------------------------------------------- /scripts/screens/string-id-editor.js: -------------------------------------------------------------------------------- 1 | const stringIdEntityQuery = require('../model/graphql/stringIdEntity'); 2 | 3 | module.exports = { 4 | "query": stringIdEntityQuery, 5 | "componentName": "StringIdMgtCardsEdit", 6 | "entity": { 7 | "name": "scr_StringIdTestEntity" 8 | }, 9 | "editIdAttrPos": 1 10 | }; -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-cards-grid/options.ts: -------------------------------------------------------------------------------- 1 | import {CommonGenerationOptions} from "../../../common/cli-options"; 2 | import {DirShiftOption} from "../../../building-blocks/stages/options/pieces/dir-shift"; 3 | 4 | export type Options = CommonGenerationOptions & DirShiftOption; 5 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-form-wizard/options.ts: -------------------------------------------------------------------------------- 1 | import {CommonGenerationOptions} from "../../../common/cli-options"; 2 | import {DirShiftOption} from "../../../building-blocks/stages/options/pieces/dir-shift"; 3 | 4 | export type Options = CommonGenerationOptions & DirShiftOption; 5 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/Grid/Col/Col.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Col as AntdCol, ColProps as AntdColProps } from 'antd'; 3 | 4 | type ColProps = AntdColProps; 5 | 6 | function Col(props: ColProps) { 7 | return ( 8 | 9 | ); 10 | } 11 | 12 | export { Col, ColProps }; -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/Grid/Row/Row.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Row as AntdRow, RowProps as AntdRowProps } from 'antd'; 3 | 4 | type RowProps = AntdRowProps; 5 | 6 | function Row(props: RowProps) { 7 | return ( 8 | 9 | ); 10 | } 11 | 12 | export { Row, RowProps }; -------------------------------------------------------------------------------- /scripts/screens/deeply-nested-editor.js: -------------------------------------------------------------------------------- 1 | const deeplyNestedTestEntityQuery = require('../model/graphql/deeplyNestedTestEntity'); 2 | 3 | module.exports = { 4 | "query": deeplyNestedTestEntityQuery, 5 | "componentName": "DeeplyNestedTestEntityEditor", 6 | "entity": { 7 | "name": "scr_DeeplyNestedTestEntity" 8 | } 9 | }; -------------------------------------------------------------------------------- /docs-src/supplemental-ui/partials/head-meta.hbs: -------------------------------------------------------------------------------- 1 | {{! This Source Code Form is subject to the terms of the Mozilla Public }} 2 | {{! License, v. 2.0. If a copy of the MPL was not distributed with this }} 3 | {{! file, You can obtain one at http://mozilla.org/MPL/2.0/. }} 4 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/ImagePreview.module.less: -------------------------------------------------------------------------------- 1 | .imagePreview { 2 | & > .title { 3 | margin-bottom: 8px; 4 | } 5 | 6 | & > .image { 7 | display: block; 8 | margin: 0 auto; 9 | max-height: 60vh; 10 | max-width: 100%; 11 | } 12 | } 13 | 14 | .spinner { 15 | margin: 64px 0 64px 0; 16 | } -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/graphql.test.ts: -------------------------------------------------------------------------------- 1 | import {extractEntityName} from "./graphql"; 2 | 3 | describe('extractEntityName()', () => { 4 | it('extracts entity name from List query name', () => { 5 | const queryName = 'scr_CarList'; 6 | expect(extractEntityName(queryName, 'List')).toEqual('scr_Car'); 7 | }); 8 | }); -------------------------------------------------------------------------------- /example-react-app/src/jmix/entities/scr_CarDto.ts: -------------------------------------------------------------------------------- 1 | export class CarDto { 2 | static NAME = "scr_CarDto"; 3 | id?: string; 4 | manufacturer?: string | null; 5 | price?: any | null; 6 | model?: string | null; 7 | } 8 | export type CarDtoViewName = "_base" | "_instance_name" | "_local"; 9 | export type CarDtoView = never; 10 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/Card/Card.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Card as AntdCard, CardProps as AntdCardProps } from 'antd'; 3 | 4 | type CardProps = AntdCardProps; 5 | 6 | function Card(props: CardProps) { 7 | return ( 8 | 9 | ); 10 | } 11 | 12 | export { Card, CardProps }; -------------------------------------------------------------------------------- /scripts/screens/form-wizard-browser.js: -------------------------------------------------------------------------------- 1 | const query = require('../model/graphql/formWizardTestEntity'); 2 | 3 | module.exports = { 4 | "componentName": "FormWizardBrowserTable", 5 | "browserType": "table", 6 | "entity": { 7 | "name": "scr_FormWizardTestEntity" 8 | }, 9 | query, 10 | 'menuItem': 'ROOT', 11 | }; 12 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/dev/previews.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Previews, ComponentPreview} from "@haulmont/react-ide-toolbox"; 3 | 4 | export const ComponentPreviews = () => { 5 | return ( 6 | 7 | 8 | ); 9 | }; 10 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/temp-id.ts: -------------------------------------------------------------------------------- 1 | import { v4 as uuidv4 } from 'uuid'; 2 | 3 | export const TEMP_ID_PREFIX = 'TEMP_ID_'; 4 | 5 | export function generateTempId(): string { 6 | return TEMP_ID_PREFIX + uuidv4(); 7 | } 8 | 9 | export function isTempId(id: string): boolean { 10 | return id.startsWith(TEMP_ID_PREFIX); 11 | } -------------------------------------------------------------------------------- /scripts/screens/int-id-browser-list.js: -------------------------------------------------------------------------------- 1 | const intIdEntityQuery = require('../model/graphql/intIdEntity'); 2 | 3 | module.exports = { 4 | "query": intIdEntityQuery, 5 | "componentName": "IntIdBrowserList", 6 | "browserType": "list", 7 | "entity": { 8 | "name": "scr_IntegerIdTestEntity" 9 | }, 10 | 'menuItem': 'ROOT' 11 | }; -------------------------------------------------------------------------------- /packages/jmix-front-generator/custom_types/inquirer.d.ts: -------------------------------------------------------------------------------- 1 | import * as inquirer from 'inquirer'; 2 | import {AutocompleteQuestionOptions} from 'inquirer-autocomplete-prompt'; 3 | 4 | declare module 'inquirer' { 5 | interface QuestionMap { 6 | autocomplete: AutocompleteQuestionOptions; 7 | } 8 | } -------------------------------------------------------------------------------- /packages/jmix-react-web/src/crud/editor/EntityEditorProps.ts: -------------------------------------------------------------------------------- 1 | import {EntityInstance} from "@haulmont/jmix-react-core"; 2 | 3 | export interface EntityEditorProps { 4 | onCommit?: (value: this['entityInstance']) => void; 5 | entityInstance?: EntityInstance; 6 | submitBtnCaption?: string; 7 | disabled?: boolean; 8 | } -------------------------------------------------------------------------------- /scripts/screens/deeply-nested-o2m-editor.js: -------------------------------------------------------------------------------- 1 | const deeplyNestedO2MTestEntityQuery = require('../model/graphql/deeplyNestedO2MTestEntity'); 2 | 3 | module.exports = { 4 | "query": deeplyNestedO2MTestEntityQuery, 5 | "componentName": "DeeplyNestedO2MTestEntityEditor", 6 | "entity": { 7 | "name": "scr_DeeplyNestedO2MTestEntity" 8 | } 9 | }; -------------------------------------------------------------------------------- /scripts/screens/form-wizard-composition-o2o.js: -------------------------------------------------------------------------------- 1 | const formWizardCompositionO2OQuery = require('../model/graphql/formWizardCompositionO2O'); 2 | 3 | module.exports = { 4 | "query": formWizardCompositionO2OQuery, 5 | "componentName": "FormWizardCompositionO2O", 6 | "entity": { 7 | "name": "scr_FormWizardCompositionO2OTestEntity" 8 | } 9 | }; -------------------------------------------------------------------------------- /scripts/screens/int-id-browser-cards.js: -------------------------------------------------------------------------------- 1 | const intIdEntityQuery = require('../model/graphql/intIdEntity'); 2 | 3 | module.exports = { 4 | "query": intIdEntityQuery, 5 | "componentName": "IntIdBrowserCards", 6 | "browserType": "cards", 7 | "entity": { 8 | "name": "scr_IntegerIdTestEntity" 9 | }, 10 | 'menuItem': 'ROOT' 11 | }; -------------------------------------------------------------------------------- /scripts/screens/int-id-browser-table.js: -------------------------------------------------------------------------------- 1 | const intIdEntityQuery = require('../model/graphql/intIdEntity'); 2 | 3 | module.exports = { 4 | "query": intIdEntityQuery, 5 | "componentName": "IntIdBrowserTable", 6 | "browserType": "table", 7 | "entity": { 8 | "name": "scr_IntegerIdTestEntity" 9 | }, 10 | 'menuItem': 'ROOT' 11 | }; -------------------------------------------------------------------------------- /scripts/screens/weird-string-id-editor.js: -------------------------------------------------------------------------------- 1 | const weirdStringIdEntityQuery = require('../model/graphql/weirdStringIdEntity'); 2 | 3 | module.exports = { 4 | "query": weirdStringIdEntityQuery, 5 | "componentName": "WeirdStringIdEditor", 6 | "entity": { 7 | "name": "scr_WeirdStringIdTestEntity" 8 | }, 9 | "editIdAttrPos": 1, 10 | }; -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/breadcrumbs/Breadcrumbs.less: -------------------------------------------------------------------------------- 1 | .breadcrumb { 2 | cursor: pointer; 3 | color: #197de1; 4 | 5 | &:hover { 6 | text-decoration: underline; 7 | } 8 | } 9 | 10 | .breadcrumb-active{ 11 | color: inherit; 12 | } 13 | 14 | .breadcrumbs-container { 15 | padding-bottom: 20px; 16 | } 17 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/bin/gen-jmix-front.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict'; 4 | 5 | process.title = 'gen-jmix-front'; 6 | 7 | process.on('unhandledRejection', (reason, p) => { 8 | console.log('Unhandled Rejection ', p, ' reason: ', reason); 9 | process.exit(1); 10 | }); 11 | 12 | require('../lib/cli').createAndLaunchCli(); -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/_gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules 3 | 4 | # testing 5 | /coverage 6 | 7 | # production 8 | /build 9 | /build-gradle 10 | 11 | # misc 12 | .DS_Store 13 | 14 | npm-debug.log* 15 | yarn-debug.log* 16 | yarn-error.log* 17 | 18 | .idea 19 | .vscode 20 | .gradle -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/util/history.test.ts: -------------------------------------------------------------------------------- 1 | import { saveHistory } from "./history" 2 | 3 | it('should save history', () => { 4 | const historySpy = jest.spyOn(window.history, 'pushState'); 5 | 6 | saveHistory('car', { current: 2, pageSize: 50 }) 7 | 8 | expect(historySpy).toHaveBeenCalledWith({}, '', 'car?page=2&pageSize=50'); 9 | }) -------------------------------------------------------------------------------- /scripts/screens/int-identity-id-cards.js: -------------------------------------------------------------------------------- 1 | const intIdentityIdEntityQuery = require('../model/graphql/intIdentityIdEntity'); 2 | 3 | module.exports = { 4 | "query": intIdentityIdEntityQuery, 5 | "componentName": "IntIdentityIdCards", 6 | "entity": { 7 | "name": "scr_IntIdentityIdTestEntity" 8 | }, 9 | 'menuItem': 'ROOT' 10 | } 11 | -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/ChordChart.tsx: -------------------------------------------------------------------------------- 1 | import {Chord, ChordProps} from "@nivo/chord"; 2 | import { defaultChartOptions } from "./default-chart-options"; 3 | import React from "react"; 4 | 5 | export const ChordChart = (props: Omit) => { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/README.md: -------------------------------------------------------------------------------- 1 | # Frontend Generator 2 | 3 | The Frontend Generator is a scaffolding tool that can be used to speed up the process of developing a frontend client. 4 | It can be used from Jmix Studio or as a standalone CLI tool. 5 | It can generate a starter app and add the pieces you need such as entity browser and editor screens. 6 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/ui/MultilineText.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | 3 | export type MultilineTextProps = { 4 | lines: string[] 5 | } 6 | 7 | export function MultilineText({lines}: MultilineTextProps) { 8 | return ( 9 | <> 10 | { lines.map((line, index) =>
{line}
) } 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /scripts/screens/boring-string-id-editor.js: -------------------------------------------------------------------------------- 1 | const boringStringIdEntityQuery = require('../model/graphql/boringStringIdEntity'); 2 | 3 | module.exports = { 4 | "query": boringStringIdEntityQuery, 5 | "componentName": "BoringStringIdEditor", 6 | "entity": { 7 | "name": "scr_BoringStringIdTestEntity" 8 | }, 9 | "editIdAttrPos": 1, 10 | }; 11 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react-native/pages/learning-path.adoc: -------------------------------------------------------------------------------- 1 | = Where Do I Go From Here? 2 | 3 | Check xref:jmix-react-core:index.adoc[Jmix React Core] section to see what components are available to you and how to use them. 4 | 5 | Check {api_rest}[Jmix REST] to see how your components can communicate with the {manual_restApi}[Generic REST API]. 6 | -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/RadarChart.tsx: -------------------------------------------------------------------------------- 1 | import {Radar, RadarSvgProps} from "@nivo/radar"; 2 | import { defaultChartOptions } from "./default-chart-options"; 3 | import React from "react"; 4 | 5 | export const RadarChart = (props: Omit, 'height' | 'width'>) => { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /scripts/screens/car-cards-with-details.js: -------------------------------------------------------------------------------- 1 | const query = require('../model/graphql/carEntity'); 2 | 3 | module.exports = { 4 | 'menuItem': 'ROOT', 5 | "componentName": "CarCardsWithDetails", 6 | "entity": { 7 | "name": "scr_Car" 8 | }, 9 | query, 10 | "mainFields": [ 11 | 'model', 12 | "manufacturer", 13 | "carType", 14 | ], 15 | }; -------------------------------------------------------------------------------- /scripts/screens/tricky-id-browser-table.js: -------------------------------------------------------------------------------- 1 | const trickyIdEntityQuery = require('../model/graphql/trickyIdEntity'); 2 | 3 | module.exports = { 4 | "query": trickyIdEntityQuery, 5 | "browserType": "table", 6 | "componentName": "TrickyIdBrowserTable", 7 | "entity": { 8 | "name": "scr_TrickyIdTestEntity" 9 | }, 10 | 'menuItem': 'ROOT' 11 | }; 12 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/jmix-rest-js/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = REST API 2 | 3 | Generated frontend clients use {manual_restApi}[Generic REST API]. The detailed documentation on the API endpoints is published {restApiSwagger}[here]. 4 | 5 | Jmix REST library is used to communicate with Generic REST API. Documentation and API reference can be found {api_rest}[here]. 6 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/hotkeys/HotkeyInfoModalButton.module.less: -------------------------------------------------------------------------------- 1 | .hotkeyInfoButton:global(.ant-btn.ant-btn-text.ant-btn-icon-only) { 2 | color: #CCCCCC; 3 | } 4 | 5 | .hotkeyInfoButton:global(.ant-btn.ant-btn-text.ant-btn-icon-only):hover { 6 | color: #FFF; 7 | } 8 | 9 | .scrollContainerStyle { 10 | max-height: 400px; 11 | overflow-y: auto; 12 | } -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/devMode.ts: -------------------------------------------------------------------------------- 1 | // It's more correct to retrieve dev mode status from @haulmont/react-ide-devtools 2 | // but this will be unnecessary once https://github.com/Haulmont/jmix-frontend/issues/385 is resolved. 3 | const DEV_MODE = process.env.REACT_APP_IDE_DEVMODE === "true"; 4 | 5 | export const isDevModeEnabled = () => { 6 | return DEV_MODE; 7 | } -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/dollars-to-underscores.test.ts: -------------------------------------------------------------------------------- 1 | import {dollarsToUnderscores} from "./dollars-to-underscores"; 2 | 3 | describe('dollarsToUnderscores()', () => { 4 | it('replaces $ with _', () => { 5 | expect(dollarsToUnderscores('scr$Car')).toEqual('scr_Car'); 6 | expect(dollarsToUnderscores('$abc$def$')).toEqual('_abc_def_'); 7 | }); 8 | }); -------------------------------------------------------------------------------- /scripts/generator-customization/templates/README.md: -------------------------------------------------------------------------------- 1 | This folder contains custom templates used with stock generators. Templates should be put into separate folders, folder name should correspond to generator name, e.g.: 2 | 3 | ``` 4 | templates 5 | ├── app 6 | │ ├── index.tsx.ejs 7 | │ └── package.json 8 | └── entity-management 9 | └── Table.tsx.ejs 10 | ``` -------------------------------------------------------------------------------- /scripts/screens/car-table-with-filters.js: -------------------------------------------------------------------------------- 1 | const query = require('../model/graphql/carEntity'); 2 | 3 | module.exports = { 4 | 'menuItem': 'ROOT', 5 | "componentName": "carTableWithFilters", 6 | "entity": { 7 | "name": "scr_Car" 8 | }, 9 | query, 10 | "filterableFields": [ 11 | 'model', 12 | "manufacturer", 13 | "carType", 14 | ], 15 | }; -------------------------------------------------------------------------------- /example-react-app/src/jmix/enums/enums.ts: -------------------------------------------------------------------------------- 1 | export enum CarType { 2 | SEDAN = "SEDAN", 3 | HATCHBACK = "HATCHBACK" 4 | } 5 | 6 | export enum EcoRank { 7 | EURO1 = "EURO1", 8 | EURO2 = "EURO2", 9 | EURO3 = "EURO3" 10 | } 11 | 12 | export enum TestEnum { 13 | NEW_VALUE = "NEW_VALUE", 14 | NEW_VALUE1 = "NEW_VALUE1", 15 | NEW_VALUE2 = "NEW_VALUE2" 16 | } 17 | -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/HeatMapChart.tsx: -------------------------------------------------------------------------------- 1 | import {HeatMap, HeatMapSvgProps} from "@nivo/heatmap"; 2 | import { defaultChartOptions } from "./default-chart-options"; 3 | import React from "react"; 4 | 5 | export const HeatMapChart = (props: Omit) => { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/NetworkChart.tsx: -------------------------------------------------------------------------------- 1 | import {Network, NetworkSvgProps} from "@nivo/network"; 2 | import { defaultChartOptions } from "./default-chart-options"; 3 | import React from "react"; 4 | 5 | export const NetworkChart = (props: Omit) => { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/TreeMapChart.tsx: -------------------------------------------------------------------------------- 1 | import {TreeMap, TreeMapSvgProps} from "@nivo/treemap"; 2 | import { defaultChartOptions } from "./default-chart-options"; 3 | import React from "react"; 4 | 5 | export const TreeMapChart = (props: Omit) => { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/rest/errorCodes.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Error code indicating that authorization grant is not valid (for example, login credentials are incorrect). 3 | * Refer to OAuth 2.0 specification at https://tools.ietf.org/html/rfc6749#section-5.2 for more details 4 | */ 5 | export const OAUTH2_INVALID_GRANT = 'invalid_grant'; -------------------------------------------------------------------------------- /example-react-app/src/app/car-cards-with-details/CarCardsWithDetails.module.css: -------------------------------------------------------------------------------- 1 | .collapse :global(.ant-collapse-header) { 2 | transition: none; 3 | } 4 | 5 | .collapse :global(.ant-collapse-header):focus-visible { 6 | outline: 2px solid rgb(9, 109, 217) !important; 7 | outline-offset: -2px; 8 | border-radius: 2px !important; 9 | transition: none; 10 | } -------------------------------------------------------------------------------- /example-react-app/src/app/common/Centered.tsx: -------------------------------------------------------------------------------- 1 | import React, { ReactNode } from "react"; 2 | import styles from "./Centered.module.css"; 3 | 4 | interface CenteredProps { 5 | children?: ReactNode; 6 | } 7 | 8 | const Centered = ({ children }: CenteredProps) => { 9 | return
{children}
; 10 | }; 11 | 12 | export default Centered; 13 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/util/base64.ts: -------------------------------------------------------------------------------- 1 | import base64 from 'base-64'; 2 | 3 | declare const global; 4 | export function registerBase64() { 5 | if (!global.btoa) { 6 | global.btoa = base64.encode; 7 | } 8 | 9 | if (!global.atob) { 10 | global.atob = base64.decode; 11 | } 12 | } 13 | 14 | registerBase64(); 15 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/MasterDetail/useChangeConfirm.ts: -------------------------------------------------------------------------------- 1 | import {useMasterDetailStore} from "./MasterDetailContext"; 2 | 3 | export function useChangeConfirm() { 4 | const masterDetailStore = useMasterDetailStore(); 5 | 6 | return { 7 | setDirty: () => masterDetailStore.setDirty(true), 8 | setPristine: () => masterDetailStore.setDirty(false) 9 | } 10 | } -------------------------------------------------------------------------------- /scripts/pack-react-native-client-libs.js: -------------------------------------------------------------------------------- 1 | const packClientLibs = require('./pack-client-libs'); 2 | 3 | packClientLibs( 4 | [ 5 | '@haulmont/jmix-front-generator', 6 | '@haulmont/jmix-rest', 7 | '@haulmont/jmix-react-core' 8 | ], 9 | [ 10 | '@haulmont/jmix-rest', 11 | '@haulmont/jmix-react-core' 12 | ] 13 | ); 14 | 15 | -------------------------------------------------------------------------------- /scripts/screens/int-identity-id-browser-cards.js: -------------------------------------------------------------------------------- 1 | const intIdentityIdQuery = require('../model/graphql/intIdentityIdEntity'); 2 | 3 | module.exports = { 4 | "query": intIdentityIdQuery, 5 | "componentName": "IntIdentityIdBrowserCards", 6 | "browserType": "cards", 7 | "entity": { 8 | "name": "scr_IntIdentityIdTestEntity" 9 | }, 10 | 'menuItem': 'ROOT' 11 | }; -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/ChoroplethChart.tsx: -------------------------------------------------------------------------------- 1 | import {Choropleth, ChoroplethProps} from "@nivo/geo"; 2 | import { defaultChartOptions } from "./default-chart-options"; 3 | import React from "react"; 4 | 5 | export const ChoroplethChart = (props: Omit) => { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/.nycrc.yaml: -------------------------------------------------------------------------------- 1 | # coverage check config 2 | 3 | extends: "@istanbuljs/nyc-config-typescript" 4 | check-coverage: true 5 | skip-full: true 6 | 7 | # do not check coverage in this folders 8 | exclude: [ 9 | "src/test/**", 10 | "src/generators/*/*/template/**", 11 | ] 12 | 13 | statements: 78 14 | branches: 62 15 | functions: 69 16 | lines: 78 17 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/test/integration/fixtures/projectModel-empty.json: -------------------------------------------------------------------------------- 1 | { 2 | "project": { 3 | "name": "empty-prj", 4 | "namespace": "emptyprj", 5 | "modulePrefix": "app", 6 | "modelPrefix": "app" 7 | }, 8 | "entities": [], 9 | "enums": [], 10 | "baseProjectEntities": [], 11 | "views": [], 12 | "restQueries": [], 13 | "restServices": [] 14 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/util/history.ts: -------------------------------------------------------------------------------- 1 | import {addPagingParams} from "@haulmont/jmix-react-web"; 2 | import {JmixPagination, redirect} from "@haulmont/jmix-react-core"; 3 | 4 | export function saveHistory(routingPath: string, pagination?: JmixPagination) { 5 | const {current, pageSize} = pagination ?? {}; 6 | redirect(addPagingParams(routingPath, current, pageSize)) 7 | } 8 | -------------------------------------------------------------------------------- /scripts/screens/int-identity-id-browser-list.js: -------------------------------------------------------------------------------- 1 | const intIdentityIdEntityQuery = require('../model/graphql/intIdentityIdEntity'); 2 | 3 | module.exports = { 4 | "query": intIdentityIdEntityQuery, 5 | "componentName": "IntIdentityIdBrowserList", 6 | "browserType": "list", 7 | "entity": { 8 | "name": "scr_IntIdentityIdTestEntity" 9 | }, 10 | 'menuItem': 'ROOT' 11 | }; -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/cuba-react-ui/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = CUBA React UI 组件 2 | 3 | *CUBA React UI* 包含 UI 组件。使用 {antDesign_base}/docs/react/introduce[Ant Design] UI 开发,在 xref:client-react:starter-guide.adoc[React] 客户端使用。可以通过 npm 安装:{npm_cubaReactUi}[@cuba-platform/react-ui]。 4 | 5 | API 参考文档在 link:../api-reference/cuba-react-ui/index.html[这里]。 6 | 7 | 阅读本章节剩下的部分了解如何使用该库提供的组件。 8 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/.env.development.local: -------------------------------------------------------------------------------- 1 | REACT_APP_JMIX_REST_URL=<% if (project.modulePrefix) { %>/<%=project.modulePrefix%><%}%>/rest/ 2 | REACT_APP_REST_CLIENT_ID=<%= project.restClientId %> 3 | REACT_APP_REST_CLIENT_SECRET=<%= project.restClientSecret %> 4 | REACT_APP_GRAPHQL_URI=/graphql 5 | REACT_APP_ENABLE_UI_PERMISSIONS=false 6 | -------------------------------------------------------------------------------- /scripts/screens/int-identity-id-browser-table.js: -------------------------------------------------------------------------------- 1 | const intIdentityIdEntityQuery = require('../model/graphql/intIdentityIdEntity'); 2 | 3 | module.exports = { 4 | "query": intIdentityIdEntityQuery, 5 | "componentName": "IntIdentityIdBrowserTable", 6 | "browserType": "table", 7 | "entity": { 8 | "name": "scr_IntIdentityIdTestEntity" 9 | }, 10 | 'menuItem': 'ROOT' 11 | }; -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/crud/editor/form/createUseAntdForm.ts: -------------------------------------------------------------------------------- 1 | import { EntityInstance } from "@haulmont/jmix-react-core"; 2 | import { FormInstance } from "antd"; 3 | import { useAntdForm } from "./useAntdForm"; 4 | 5 | export function createUseAntdForm(form: FormInstance): (item: EntityInstance, entityName: string) => void { 6 | return useAntdForm.bind(null, form); 7 | } -------------------------------------------------------------------------------- /example-react-app/src/jmix/entities/ScrUserInfo.ts: -------------------------------------------------------------------------------- 1 | import { Car } from "./scr_Car"; 2 | export class ScrUserInfo { 3 | static NAME = "ScrUserInfo"; 4 | id?: string; 5 | firstName?: string | null; 6 | lastName?: string | null; 7 | favouriteCars?: Car[] | null; 8 | } 9 | export type ScrUserInfoViewName = "_base" | "_instance_name" | "_local"; 10 | export type ScrUserInfoView = never; 11 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/data/aliases.ts: -------------------------------------------------------------------------------- 1 | import {FetchResult, MutationFunctionOptions, QueryLazyOptions} from "@apollo/client"; 2 | 3 | // Aliases of Apollo types 4 | export type GraphQLQueryFn = (options?: QueryLazyOptions) => void; 5 | export type GraphQLMutationFn = (options?: MutationFunctionOptions) => Promise>; 6 | -------------------------------------------------------------------------------- /scripts/update-react-client-libs.js: -------------------------------------------------------------------------------- 1 | const updateClientLibs = require('./update-client-libs'); 2 | const rimraf = require("rimraf"); 3 | const path = require("path"); 4 | 5 | const clientDir = 'example-react-app'; 6 | rimraf.sync(path.join(clientDir,'package-lock.json')); 7 | updateClientLibs( 8 | clientDir, 9 | ['rest', 'react-core', 'react-web', 'react-antd', 'front-generator'] 10 | ); -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/cuba-react-ui/pages/image-preview.adoc: -------------------------------------------------------------------------------- 1 | = ImagePreview 2 | :api_ui_ImagePreviewProps: link:../api-reference/cuba-react-ui/interfaces/_ui_imagepreview_.imagepreviewprops.html 3 | 4 | `ImagePreview` 可以预览并下载图片。需要使用 link:https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL[对象 URL]。 5 | 6 | ''' 7 | 8 | API: {api_ui_ImagePreviewProps}[ImagePreviewProps]. 9 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/crud/list/EntityListProps.ts: -------------------------------------------------------------------------------- 1 | import { EntityInstance } from "@haulmont/jmix-react-core"; 2 | 3 | export interface EntityListProps { 4 | onEntityListChange?: (entityList?: this['entityList']) => void; 5 | entityList?: Array>; 6 | onSelectEntity?: (entityInstance?: EntityInstance) => void; 7 | disabled?: boolean; 8 | } 9 | -------------------------------------------------------------------------------- /example-react-app/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "scr-jmix", 3 | "name": "scr-jmix", 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 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/util/dollars-to-underscores.test.ts: -------------------------------------------------------------------------------- 1 | import {expect} from "chai"; 2 | import {dollarsToUnderscores} from "./dollars-to-underscores"; 3 | 4 | describe('dollarsToUnderscores()', () => { 5 | it('replaces $ with _', () => { 6 | expect(dollarsToUnderscores('scr$Car')).eq('scr_Car'); 7 | expect(dollarsToUnderscores('$abc$def$')).eq('_abc_def_'); 8 | }); 9 | }); -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/DatePicker.tsx: -------------------------------------------------------------------------------- 1 | import { Dayjs } from 'dayjs'; 2 | import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs'; 3 | import generatePicker, {PickerProps} from 'antd/es/date-picker/generatePicker'; 4 | import 'antd/es/date-picker/style/index'; 5 | 6 | export type DatePickerProps = PickerProps 7 | 8 | export const DatePicker = generatePicker(dayjsGenerateConfig); 9 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/form/controls/base/JmixFormFieldProps.ts: -------------------------------------------------------------------------------- 1 | import {FormItemProps} from "antd"; 2 | 3 | export interface JmixFormFieldProps< 4 | ValueType = any, OnChangeType = (value: any) => void 5 | > { 6 | value?: ValueType; 7 | onChange?: OnChangeType; 8 | entityName?: string; 9 | propertyName: string; 10 | formItemProps?: FormItemProps; 11 | disabled?: boolean; 12 | } -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "experimentalDecorators": true, 5 | "jsx": "react-native", 6 | "lib": ["dom", "esnext"], 7 | "moduleResolution": "node", 8 | "noEmit": true, 9 | "skipLibCheck": true, 10 | "resolveJsonModule": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /scripts/custom-screens/CustomDataDisplayComponents.module.css: -------------------------------------------------------------------------------- 1 | .rowItem { 2 | margin-bottom: 1em; 3 | } 4 | 5 | .rowItem > div { 6 | color: #ffffff; 7 | text-align: center; 8 | padding: 1em 0; 9 | } 10 | 11 | .rowItem > div:nth-child(even) { 12 | background-color: rgb(0, 146, 255); 13 | } 14 | 15 | .rowItem > div:nth-child(odd) { 16 | background-color: rgba(0, 146, 255, .75); 17 | } -------------------------------------------------------------------------------- /scripts/screens/deeply-nested-o2m-browser-table.js: -------------------------------------------------------------------------------- 1 | const deeplyNestedO2MTestEntityQuery = require('../model/graphql/deeplyNestedO2MTestEntity'); 2 | 3 | module.exports = { 4 | "query": deeplyNestedO2MTestEntityQuery, 5 | "componentName": "DeeplyNestedO2MTestEntityTable", 6 | "browserType": "table", 7 | "entity": { 8 | "name": "scr_DeeplyNestedO2MTestEntity" 9 | }, 10 | 'menuItem': 'ROOT' 11 | }; -------------------------------------------------------------------------------- /scripts/screens/string-id-browser-cards.js: -------------------------------------------------------------------------------- 1 | const stringIdEntityQuery = require('../model/graphql/stringIdEntity'); 2 | 3 | module.exports = { 4 | "query": stringIdEntityQuery, 5 | "componentName": "StringIdBrowserCards", 6 | "browserType": "cards", 7 | "entity": { 8 | "name": "scr_StringIdTestEntity" 9 | }, 10 | "listShowIdAttr": true, 11 | "listIdAttrPos": 2, 12 | 'menuItem': 'ROOT' 13 | }; -------------------------------------------------------------------------------- /scripts/screens/string-id-browser-list.js: -------------------------------------------------------------------------------- 1 | const stringIdEntityQuery = require('../model/graphql/stringIdEntity'); 2 | 3 | module.exports = { 4 | "query": stringIdEntityQuery, 5 | "componentName": "StringIdBrowserList", 6 | "browserType": "list", 7 | "entity": { 8 | "name": "scr_StringIdTestEntity" 9 | }, 10 | "listShowIdAttr": true, 11 | "listIdAttrPos": 2, 12 | 'menuItem': 'ROOT' 13 | }; -------------------------------------------------------------------------------- /scripts/screens/string-id-browser-table.js: -------------------------------------------------------------------------------- 1 | const stringIdEntityQuery = require('../model/graphql/stringIdEntity'); 2 | 3 | module.exports = { 4 | "query": stringIdEntityQuery, 5 | "componentName": "StringIdBrowserTable", 6 | "browserType": "table", 7 | "entity": { 8 | "name": "scr_StringIdTestEntity" 9 | }, 10 | "listShowIdAttr": true, 11 | "listIdAttrPos": 2, 12 | 'menuItem': 'ROOT' 13 | }; -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/BarChart.tsx: -------------------------------------------------------------------------------- 1 | import { Bar, BarDatum } from "@nivo/bar"; 2 | import { defaultChartOptions } from "./default-chart-options"; 3 | import React from "react"; 4 | import { BarSvgProps } from "@nivo/bar/dist/types/types"; 5 | 6 | export const BarChart = (props: Omit, 'height' | 'width'>) => { 7 | return ; 8 | } 9 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/.env.production.local: -------------------------------------------------------------------------------- 1 | PUBLIC_URL=/<%= basePath %>/ 2 | REACT_APP_JMIX_REST_URL=<% if (project.modulePrefix) { %>/<%=project.modulePrefix%><%}%>/rest/ 3 | REACT_APP_REST_CLIENT_ID=<%= project.restClientId %> 4 | REACT_APP_REST_CLIENT_SECRET=<%= project.restClientSecret %> 5 | REACT_APP_GRAPHQL_URI=/graphql 6 | REACT_APP_ENABLE_UI_PERMISSIONS=false 7 | -------------------------------------------------------------------------------- /packages/jmix-rest/test/listeners.spec.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | global.fetch = require('node-fetch'); 4 | const {initApp} = require('./common'); 5 | 6 | describe('.onLocaleChange()', () => { 7 | const app = initApp(); 8 | 9 | it('invokes a callback on locale change', done => { 10 | const callback = () => done(); 11 | app.onLocaleChange(callback); 12 | app.locale = 'en'; 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/jmix-server-mock/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["es2020"], 6 | "esModuleInterop": true, 7 | "outDir": "dist", 8 | "rootDir": "src", 9 | "skipLibCheck": true, 10 | "declaration": true, 11 | "sourceMap": true 12 | }, 13 | "exclude": [ "node_modules" ], 14 | "include": [ "src/**/*.ts" ] 15 | } -------------------------------------------------------------------------------- /example-react-app/src/app/CenteredLoader.tsx: -------------------------------------------------------------------------------- 1 | import { LoadingOutlined } from "@ant-design/icons"; 2 | import Centered from "./common/Centered"; 3 | import React from "react"; 4 | import styles from "./CenteredLoader.module.css"; 5 | 6 | const CenteredLoader = () => ( 7 | 8 | 9 | 10 | ); 11 | 12 | export default CenteredLoader; 13 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/common/base-entity-screen-generator/params.ts: -------------------------------------------------------------------------------- 1 | import {Entity} from '../../../../common/model/cuba-model'; 2 | 3 | export interface BaseEntityScreenAnswers { 4 | entity: Entity; 5 | listShowIdAttr?: boolean; 6 | listIdAttrPos?: number; 7 | editIdAttrPos?: number; 8 | idAttrName?: string; // Will be asked for if not found in project model 9 | } 10 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-cards-with-details/template/CardsWithDetails.module.css: -------------------------------------------------------------------------------- 1 | .collapse :global(.ant-collapse-header) { 2 | transition: none; 3 | } 4 | 5 | .collapse :global(.ant-collapse-header):focus-visible { 6 | outline: 2px solid rgb(9, 109, 217) !important; 7 | outline-offset: -2px; 8 | border-radius: 2px !important; 9 | transition: none; 10 | } -------------------------------------------------------------------------------- /scripts/model/graphql/formWizardTestEntity.js: -------------------------------------------------------------------------------- 1 | const formWizardTestEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | notNull 6 | date 7 | time 8 | integer 9 | associationO2O { 10 | id 11 | _instanceName 12 | } 13 | compositionO2O { 14 | id 15 | _instanceName 16 | name 17 | } 18 | } 19 | `; 20 | 21 | module.exports = formWizardTestEntityQuery; -------------------------------------------------------------------------------- /scripts/screens/datatypes-calendar.js: -------------------------------------------------------------------------------- 1 | const query = require('../model/graphql/datatypesTestEntity'); 2 | 3 | module.exports = { 4 | menuItem: 'ROOT', 5 | componentName: "DatatypesCalendar", 6 | entity: { 7 | name: "scr_DatatypesTestEntity" 8 | }, 9 | query, 10 | eventStartAttr: 'dateAttr', 11 | eventEndAttr: "dateTimeAttr", 12 | titleAttr: "stringAttr", 13 | descriptionAttr: "stringAttr", 14 | }; -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/tooltip/Tooltip.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { Tooltip as TooltipAntd } from "antd"; 3 | import { TooltipProps as Props } from "antd/es/tooltip"; 4 | 5 | export type TooltipProps = Props & { 6 | children: React.ReactNode; 7 | }; 8 | 9 | export function Tooltip({ children, ...rest }: TooltipProps) { 10 | return {children}; 11 | } 12 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/base64.ts: -------------------------------------------------------------------------------- 1 | export function base64encode(str: string): string { 2 | /* istanbul ignore else */ 3 | if (typeof btoa === 'function') { 4 | return btoa(str); 5 | } else if (global['Buffer']) { // prevent Buffer from being injected by browserify 6 | return new global['Buffer'](str).toString('base64'); 7 | } else { 8 | throw new Error('Unable to encode to base64'); 9 | } 10 | } -------------------------------------------------------------------------------- /docs-src/supplemental-ui/partials/head-styles.hbs: -------------------------------------------------------------------------------- 1 | {{! This Source Code Form is subject to the terms of the Mozilla Public }} 2 | {{! License, v. 2.0. If a copy of the MPL was not distributed with this }} 3 | {{! file, You can obtain one at http://mozilla.org/MPL/2.0/. }} 4 | 5 | -------------------------------------------------------------------------------- /packages/jmix-rest/src/error.ts: -------------------------------------------------------------------------------- 1 | export class JmixRestError extends Error { 2 | public response?: Response; 3 | public name = 'JmixRestError' as const; 4 | 5 | constructor({message, response}: { 6 | message: string, 7 | response?: Response 8 | }) { 9 | super(message); 10 | if (response !== undefined) { 11 | this.response = response; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/cuba-react-core/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = CUBA React Core 组件库 2 | 3 | *CUBA React Core* 组件库是由一系列组件和工具类组成,负责一些核心功能,比如操作 CUBA 实体。xref:client-react:starter-guide.adoc[React] 和 xref:client-react-native:starter-guide.adoc[React Native] 客户端都用到了这个库。该库可以通过 npm 安装: {npm_cubaReactCore}[@cuba-platform/react-core] 4 | 5 | API 参考在 link:../api-reference/cuba-react-core/index.html[这里]。 6 | 7 | 查阅本章其他内容了解如何使用该库提供的组件和工具。 8 | -------------------------------------------------------------------------------- /docs-src-cn/supplemental-ui/partials/head-styles.hbs: -------------------------------------------------------------------------------- 1 | {{! This Source Code Form is subject to the terms of the Mozilla Public }} 2 | {{! License, v. 2.0. If a copy of the MPL was not distributed with this }} 3 | {{! file, You can obtain one at http://mozilla.org/MPL/2.0/. }} 4 | 5 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/data/PropertyType.ts: -------------------------------------------------------------------------------- 1 | export declare type TemporalPropertyType = 'Date' | 'Time' | 'DateTime' | 'LocalDate' | 'LocalTime' | 'LocalDateTime' | 'OffsetDateTime' | 'OffsetTime'; 2 | export declare type NumericPropertyType = 'Integer' | 'Long' | 'Double' | 'BigDecimal'; 3 | export declare type PropertyType = TemporalPropertyType | 'String' | 'UUID' | 'Character' | 'ByteArray' | NumericPropertyType | 'Boolean' | 'fileRef'; -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/jmix-react-ui/pages/image-preview.adoc: -------------------------------------------------------------------------------- 1 | = ImagePreview 2 | :api_ui_ImagePreviewProps: link:../api-reference/jmix-react-ui/interfaces/ui_imagepreview.imagepreviewprops.html 3 | 4 | `ImagePreview` allows to preview or download an image. It works with an link:https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL[object URL]. 5 | 6 | ''' 7 | 8 | API: {api_ui_ImagePreviewProps}[ImagePreviewProps]. 9 | -------------------------------------------------------------------------------- /example-react-app/src/app/custom-data-display-components/CustomDataDisplayComponents.module.css: -------------------------------------------------------------------------------- 1 | .rowItem { 2 | margin-bottom: 1em; 3 | } 4 | 5 | .rowItem > div { 6 | color: #ffffff; 7 | text-align: center; 8 | padding: 1em 0; 9 | } 10 | 11 | .rowItem > div:nth-child(even) { 12 | background-color: rgb(0, 146, 255); 13 | } 14 | 15 | .rowItem > div:nth-child(odd) { 16 | background-color: rgba(0, 146, 255, .75); 17 | } -------------------------------------------------------------------------------- /packages/jmix-react-web/src/screen-registration/registry.ts: -------------------------------------------------------------------------------- 1 | import {RegisteredScreen} from "./screen-registration"; 2 | 3 | /** 4 | * @internal 5 | */ 6 | export const screenRegistry = new Map(); 7 | 8 | /** 9 | * @internal 10 | */ 11 | export const entityEditorRegistry = new Map(); 12 | 13 | /** 14 | * @internal 15 | */ 16 | export const entityListRegistry = new Map(); 17 | -------------------------------------------------------------------------------- /packages/jmix-rest/examples/node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cuba-rest-js-node-example", 3 | "version": "1.0.0", 4 | "description": "Example of cuba-rest-js in node js app", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "license": "Apache-2.0", 10 | "dependencies": { 11 | "node-fetch": "^1.7.1", 12 | "node-localstorage": "^1.3.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /scripts/jmix/update-jmix-app.js: -------------------------------------------------------------------------------- 1 | const {runCmdSync, log} = require("../common"); 2 | const fs = require('fs'); 3 | const {isEmptyDir} = require("../common"); 4 | 5 | function updateJmixApp() { 6 | if (!fs.existsSync('scr-jmix') && isEmptyDir('scr-jmix')) { 7 | log.error('repo not found'); 8 | return; 9 | } 10 | runCmdSync('git -C scr-jmix pull'); 11 | log.success('repo has been updated'); 12 | } 13 | 14 | updateJmixApp(); -------------------------------------------------------------------------------- /scripts/screens/weird-string-id-browser-list.js: -------------------------------------------------------------------------------- 1 | const weirdStringIdEntityQuery = require('../model/graphql/weirdStringIdEntity'); 2 | 3 | module.exports = { 4 | "query": weirdStringIdEntityQuery, 5 | "componentName": "WeirdStringIdBrowserList", 6 | "browserType": "list", 7 | "entity": { 8 | "name": "scr_WeirdStringIdTestEntity" 9 | }, 10 | "listShowIdAttr": true, 11 | "listIdAttrPos": 2, 12 | 'menuItem': 'ROOT' 13 | }; -------------------------------------------------------------------------------- /test-pup/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-puppeteer", 3 | "private": true, 4 | "scripts": { 5 | "test": "jest" 6 | }, 7 | "devDependencies": { 8 | "@babel/plugin-proposal-class-properties": "^7.8.3", 9 | "@types/jest": "^26.0.0", 10 | "dayjs": "^1.10.7", 11 | "jest": "^26.0.0", 12 | "jest-puppeteer": "^4.3.0", 13 | "pptr-testing-library": "^0.6.5", 14 | "puppeteer": "^2.0.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/util/to-fat-snake-case.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Transforms camelCase and PascalCase to FAT_SNAKE_CASE. 3 | * 4 | * @param str 5 | */ 6 | export function toFatSnakeCase(str: string): string { 7 | return str 8 | .replace(/[A-Z]/g, char => `_${char}`) // precede each uppercase letter with an underscore 9 | .replace(/^_/, '') // if first char is underscore - remove it 10 | .toUpperCase(); 11 | } -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/dollars-to-underscores.ts: -------------------------------------------------------------------------------- 1 | // TODO Currently duplicated between jmix-front-generator and jmix-react-core. Probably we should extract utils into a separate lightweight package. 2 | /** 3 | * Replaces all occurrences of a dollar sign ($) inside a string with underscores (_). 4 | * 5 | * @param input 6 | */ 7 | export const dollarsToUnderscores = (input: string): string => { 8 | return input.replace(/\$/g, '_'); 9 | }; -------------------------------------------------------------------------------- /scripts/screens/weird-string-id-browser-cards.js: -------------------------------------------------------------------------------- 1 | const weirdStringIdEntityQuery = require('../model/graphql/weirdStringIdEntity'); 2 | 3 | module.exports = { 4 | "query": weirdStringIdEntityQuery, 5 | "componentName": "WeirdStringIdBrowserCards", 6 | "browserType": "cards", 7 | "entity": { 8 | "name": "scr_WeirdStringIdTestEntity" 9 | }, 10 | "listShowIdAttr": true, 11 | "listIdAttrPos": 2, 12 | 'menuItem': 'ROOT' 13 | }; -------------------------------------------------------------------------------- /scripts/screens/weird-string-id-browser-table.js: -------------------------------------------------------------------------------- 1 | const weirdStringIdEntityQuery = require('../model/graphql/weirdStringIdEntity'); 2 | 3 | module.exports = { 4 | "query": weirdStringIdEntityQuery, 5 | "componentName": "WeirdStringIdBrowserTable", 6 | "browserType": "table", 7 | "entity": { 8 | "name": "scr_WeirdStringIdTestEntity" 9 | }, 10 | "listShowIdAttr": true, 11 | "listIdAttrPos": 2, 12 | 'menuItem': 'ROOT' 13 | }; -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/templates/i18nMappings.ts: -------------------------------------------------------------------------------- 1 | import en from "./en.json"; 2 | import enUs from "antd/es/locale/en_US"; 3 | import ru from "./ru.json"; 4 | import ruRu from "antd/es/locale/ru_RU"; 5 | import "dayjs/locale/en"; 6 | import "dayjs/locale/ru"; 7 | 8 | export const antdLocaleMapping = { 9 | en: enUs, 10 | ru: ruRu 11 | }; 12 | 13 | export const messagesMapping = { 14 | en: en, 15 | ru: ru 16 | }; 17 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/app/MenuConfig.ts: -------------------------------------------------------------------------------- 1 | export interface RouteItem { 2 | pathPattern: string 3 | menuLink: string 4 | caption: string 5 | screenId: string; 6 | } 7 | 8 | export interface SubMenu { 9 | items: Array 10 | caption: string 11 | } 12 | 13 | const menuItems: Array = []; 14 | 15 | export function getMenuItems() : Array { 16 | return menuItems; 17 | } 18 | -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/ClusteredBarChart.tsx: -------------------------------------------------------------------------------- 1 | import { BarDatum } from "@nivo/bar"; 2 | import React from "react"; 3 | import { BarSvgProps } from "@nivo/bar/dist/types/types"; 4 | import {BarChart} from "./BarChart"; 5 | 6 | export const ClusteredBarChart = (props: Omit, 'height' | 'width'>) => { 7 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /scripts/run-gradle.js: -------------------------------------------------------------------------------- 1 | const { runCmdSync, isWindows } = require("./common") 2 | const path = require('path'); 3 | 4 | let [, , ...scriptArg] = process.argv; 5 | scriptArg = scriptArg.join(" "); 6 | 7 | const basePath = process.cwd(); 8 | const scriptName = isWindows() ? 'gradlew.bat' : 'gradlew'; 9 | const pathToScript = path.join(basePath, 'scr-jmix', scriptName); 10 | 11 | const cmd = `${pathToScript} ${scriptArg}`; 12 | runCmdSync(`${cmd}`); 13 | -------------------------------------------------------------------------------- /scripts/screens/boring-string-id-browser-table.js: -------------------------------------------------------------------------------- 1 | const boringStringIdEntityQuery = require('../model/graphql/boringStringIdEntity'); 2 | 3 | module.exports = { 4 | "query": boringStringIdEntityQuery, 5 | "componentName": "BoringStringIdBrowserTable", 6 | "browserType": "table", 7 | "entity": { 8 | "name": "scr_BoringStringIdTestEntity" 9 | }, 10 | "listShowIdAttr": true, 11 | "listIdAttrPos": 2, 12 | 'menuItem': 'ROOT' 13 | }; 14 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/pages/config.adoc: -------------------------------------------------------------------------------- 1 | = 配置 2 | 3 | 默认情况下,客户端使用生产版本部署至 Tomcat,用 `app-front` 作为路径上下文。修改 `PUBLIC_URL` 环境变量可以配置这个上下文路径(在 `.env.production.local` 内定义)。 4 | 5 | 开发阶段 serve 的话,客户端使用 REST API 的绝对路径,通过 `REACT_APP_JMIX_REST_URL` 设置(在 `.env.development.local` 内定义)。 6 | 7 | 参阅 React 文档了解 https://facebook.github.io/create-react-app/docs/advanced-configuration[所有可用的环境变量]。 8 | 9 | 查看 `src/config.ts` 文件,了解运行时通用的应用程序配置。 10 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/structure/structure.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /example-react-app/src/config.ts: -------------------------------------------------------------------------------- 1 | export const JMIX_REST_URL = process.env.REACT_APP_JMIX_REST_URL ?? "/rest/"; 2 | export const REST_CLIENT_ID = process.env.REACT_APP_REST_CLIENT_ID ?? "client"; 3 | export const REST_CLIENT_SECRET = 4 | process.env.REACT_APP_REST_CLIENT_SECRET ?? "secret"; 5 | export const GRAPHQL_URI = process.env.REACT_APP_GRAPHQL_URI ?? "/graphql"; 6 | 7 | export const DEFAULT_COUNT = 10; // Typical amount of entities to be loaded on browse screens 8 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/common/test-utils.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "chai"; 2 | 3 | export async function expectRejectedPromise(promiseCallback: () => Promise, errorMessage?: string) { 4 | try { 5 | await promiseCallback(); 6 | expect.fail('The promise is fulfilled'); 7 | } catch (err: any) { 8 | if (errorMessage != null) { 9 | expect(err.message).to.equal(errorMessage); 10 | } 11 | return; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scripts/model/graphql/intIdentityIdEntity.js: -------------------------------------------------------------------------------- 1 | const intIdentityIdEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | description 6 | 7 | updateTs 8 | updatedBy 9 | deleteTs 10 | deletedBy 11 | createTs 12 | createdBy 13 | version 14 | 15 | datatypesTestEntity { 16 | id 17 | _instanceName 18 | } 19 | datatypesTestEntity3 { 20 | id 21 | _instanceName 22 | } 23 | } 24 | `; 25 | 26 | module.exports = intIdentityIdEntityQuery; -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/app/common/Centered.tsx: -------------------------------------------------------------------------------- 1 | import React, {ReactNode} from "react"; 2 | import styles from './Centered.module.css'; 3 | 4 | interface CenteredProps { 5 | children?: ReactNode; 6 | } 7 | 8 | const Centered = ({children}: CenteredProps) => { 9 | return ( 10 |
11 | {children} 12 |
13 | ) 14 | }; 15 | 16 | export default Centered 17 | -------------------------------------------------------------------------------- /packages/jmix-rest/examples/node/index.js: -------------------------------------------------------------------------------- 1 | global.fetch = require('node-fetch'); 2 | global.localStorage = new require('node-localstorage').LocalStorage('./.local-storage'); 3 | 4 | const cuba = require('../../dist-node/cuba.js'); 5 | 6 | const app = cuba.initializeApp({apiUrl: 'http://localhost:8080/app/rest/'}); 7 | 8 | app.getUserInfo().then((d) => { 9 | console.log(d); 10 | }); 11 | 12 | app.login('admin', 'admin').then((d) => { 13 | console.log(d); 14 | }); -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/common/cli/cli.ts: -------------------------------------------------------------------------------- 1 | import {OptionsConfig} from "../cli-options"; 2 | import {StudioTemplateProperty} from "../studio/studio-model"; 3 | import {YeomanGenerator} from "../../building-blocks/YeomanGenerator"; 4 | 5 | export interface GeneratorExports { 6 | generator: typeof YeomanGenerator, 7 | options?: OptionsConfig, 8 | params?: StudioTemplateProperty[], 9 | description?: string; 10 | icon?: string; 11 | index?: number; 12 | } -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "<%= project.name %>", 3 | "name": "<%= title %>", 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 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/app/CenteredLoader.tsx: -------------------------------------------------------------------------------- 1 | import { LoadingOutlined } from '@ant-design/icons'; 2 | import Centered from './common/Centered'; 3 | import React from 'react'; 4 | import styles from './CenteredLoader.module.css'; 5 | 6 | const CenteredLoader = () => ( 7 | 8 | 9 | 10 | ); 11 | 12 | export default CenteredLoader; 13 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/common/JmixServerValidationErrors.ts: -------------------------------------------------------------------------------- 1 | export interface JmixServerValidationErrors { 2 | /** 3 | * Errors that are related to a single field. 4 | * Map between field `path` and arrays of error messages. 5 | */ 6 | fieldErrors?: Map; 7 | /** 8 | * Errors that are related to more than one field (e.g. cross-validation errors) 9 | * or not related to field values. 10 | */ 11 | globalErrors?: string[]; 12 | } -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/cuba-react-ui/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[CUBA React UI] 2 | ** xref:data-table.adoc[DataTable] 3 | ** xref:entity-editor.adoc[EntityEditor] 4 | ** xref:entity-property.adoc[EntityProperty] 5 | ** xref:file-upload.adoc[FileUpload] 6 | ** xref:form-field.adoc[FormField] 7 | ** xref:image-preview.adoc[ImagePreview] 8 | ** xref:nested-entities-table-field.adoc[NestedEntitiesTableField] 9 | ** xref:nested-entity-field.adoc[NestedEntityField] 10 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/jmix-react-ui/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Jmix React UI] 2 | ** xref:data-table.adoc[DataTable] 3 | ** xref:entity-editor.adoc[EntityEditor] 4 | ** xref:entity-property.adoc[EntityProperty] 5 | ** xref:file-upload.adoc[FileUpload] 6 | ** xref:form-field.adoc[FormField] 7 | ** xref:image-preview.adoc[ImagePreview] 8 | ** xref:nested-entities-table-field.adoc[NestedEntitiesTableField] 9 | ** xref:nested-entity-field.adoc[NestedEntityField] 10 | -------------------------------------------------------------------------------- /packages/jmix-addon-charts/src/component/CirclePackingChart.tsx: -------------------------------------------------------------------------------- 1 | import {CirclePacking, CirclePackingSvgProps} from "@nivo/circle-packing"; 2 | import { defaultChartOptions } from "./default-chart-options"; 3 | import React from "react"; 4 | 5 | export const CirclePackingChart = (props: Partial, "height" | "width" | "data">> & Pick, "data">) => { 6 | return ; 7 | } 8 | -------------------------------------------------------------------------------- /scripts/model/graphql/stringIdEntity.js: -------------------------------------------------------------------------------- 1 | const stringIdEntityQuery = ` 2 | { 3 | identifier 4 | _instanceName 5 | description 6 | productCode 7 | 8 | createTs 9 | createdBy 10 | updateTs 11 | updatedBy 12 | deleteTs 13 | deletedBy 14 | version 15 | 16 | datatypesTestEntity { 17 | id 18 | _instanceName 19 | } 20 | datatypesTestEntity3 { 21 | id 22 | _instanceName 23 | } 24 | } 25 | `; 26 | 27 | module.exports = stringIdEntityQuery; -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/menu/index.ts: -------------------------------------------------------------------------------- 1 | import VerticalMenu from "./vertical-menu"; 2 | import HorizontalMenu from './horizontal-menu'; 3 | import MenuItem, {MenuItemProps} from "./menu-item"; 4 | import SubMenuItem, {SubMenuItemProps} from "./sub-menu-item"; 5 | import {AddonsMenu} from "./addons-menu"; 6 | 7 | export { 8 | VerticalMenu, 9 | MenuItem, 10 | SubMenuItem, 11 | HorizontalMenu, 12 | AddonsMenu, 13 | MenuItemProps, 14 | SubMenuItemProps 15 | }; 16 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/YeomanGenerator.ts: -------------------------------------------------------------------------------- 1 | import { CommonGenerationOptions } from "../common/cli-options"; 2 | import Base from "yeoman-generator"; 3 | 4 | // Do not put anything in this class. It only exists to simplify the IDE-assisted imports and fix the typings. 5 | export abstract class YeomanGenerator extends Base { 6 | protected constructor(args: string | string[], options: CommonGenerationOptions) { 7 | super(args, options, {customInstallTask: true}); 8 | } 9 | } -------------------------------------------------------------------------------- /example-react-app/src/app/login/Login.module.css: -------------------------------------------------------------------------------- 1 | .loginForm { 2 | border-radius: 4px; 3 | padding: 32px 32px 0; 4 | min-width: 300px; 5 | box-shadow: 0 0 50px 0 rgba(0,0,0,0.2); 6 | } 7 | 8 | .loginForm .title { 9 | text-align: center; 10 | margin-bottom: 24px; 11 | font-size: 20px; 12 | } 13 | 14 | .loginForm .logo { 15 | display: block; 16 | margin: 0 auto 12px; 17 | width: 64px; 18 | height: 64px; 19 | } 20 | 21 | .languageSwitcherContainer { 22 | float: right; 23 | } 24 | -------------------------------------------------------------------------------- /example-react-app/src/hotkeyConfigs.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defaultBrowserTableHotkeyConfigs, 3 | defaultEditorHotkeyConfigs, 4 | defaultTabHotkeyConfigs, 5 | HotkeyConfig 6 | } from "@haulmont/jmix-react-web"; 7 | import { hotkeyInfoHotkeyConfigs } from "./app/header/AppHeader"; 8 | 9 | export const defaultHotkeyConfigs: HotkeyConfig[] = [ 10 | ...hotkeyInfoHotkeyConfigs, 11 | ...defaultTabHotkeyConfigs, 12 | ...defaultEditorHotkeyConfigs, 13 | ...defaultBrowserTableHotkeyConfigs 14 | ]; 15 | -------------------------------------------------------------------------------- /packages/jmix-rest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES5", 4 | "noEmitOnError": true, 5 | "removeComments": false, 6 | "declaration": true, 7 | "sourceMap": true, 8 | "outDir": "dist-node", 9 | "lib": [ 10 | "DOM", 11 | "ES5", 12 | "ES2015.Promise", 13 | "ES2015.Symbol", 14 | "ES2015.Iterable" 15 | ] 16 | }, 17 | "include": [ 18 | "src/**/*" 19 | ], 20 | "exclude": [ 21 | "node_modules" 22 | ] 23 | } -------------------------------------------------------------------------------- /docs-src/doc-component-repo/antora.yml: -------------------------------------------------------------------------------- 1 | name: jmix-frontend-docs 2 | title: Jmix Frontend UI Manual 3 | version: "1.0" 4 | nav: 5 | - modules/overview/nav.adoc 6 | - modules/getting-started/nav.adoc 7 | - modules/client-react/nav.adoc 8 | # - modules/client-react-native/nav.adoc 9 | - modules/jmix-react-core/nav.adoc 10 | - modules/jmix-react-ui/nav.adoc 11 | - modules/typescript-sdk/nav.adoc 12 | # - modules/generator/nav.adoc 13 | - modules/jmix-rest-js/nav.adoc 14 | - modules/libs/nav.adoc 15 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/config.ts: -------------------------------------------------------------------------------- 1 | export const JMIX_REST_URL = process.env.REACT_APP_JMIX_REST_URL ?? '/rest/'; 2 | export const REST_CLIENT_ID = process.env.REACT_APP_REST_CLIENT_ID ?? "client"; 3 | export const REST_CLIENT_SECRET = process.env.REACT_APP_REST_CLIENT_SECRET ?? "secret"; 4 | export const GRAPHQL_URI = process.env.REACT_APP_GRAPHQL_URI ?? "/graphql"; 5 | 6 | export const DEFAULT_COUNT = 10; // Typical amount of entities to be loaded on browse screens -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/hotkeyConfigs.ts: -------------------------------------------------------------------------------- 1 | import { defaultBrowserTableHotkeyConfigs, defaultEditorHotkeyConfigs, defaultTabHotkeyConfigs, HotkeyConfig } from "@haulmont/jmix-react-web"; 2 | import { hotkeyInfoHotkeyConfigs } from "./app/header/AppHeader"; 3 | 4 | export const defaultHotkeyConfigs: HotkeyConfig[] = [ 5 | ...hotkeyInfoHotkeyConfigs, 6 | ...defaultTabHotkeyConfigs, 7 | ...defaultEditorHotkeyConfigs, 8 | ...defaultBrowserTableHotkeyConfigs 9 | ]; -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-browser/entity-browser.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/graphql/stringIdEntity.js: -------------------------------------------------------------------------------- 1 | const stringIdEntityQuery = ` 2 | { 3 | identifier 4 | _instanceName 5 | description 6 | productCode 7 | 8 | createTs 9 | createdBy 10 | updateTs 11 | updatedBy 12 | deleteTs 13 | deletedBy 14 | version 15 | 16 | datatypesTestEntity { 17 | id 18 | _instanceName 19 | } 20 | datatypesTestEntity3 { 21 | id 22 | _instanceName 23 | } 24 | } 25 | `; 26 | 27 | module.exports = stringIdEntityQuery; -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react-native/pages/technologies.adoc: -------------------------------------------------------------------------------- 1 | = 技术概览 2 | 3 | React Native client 基于下面的框架和库开发: 4 | 5 | * https://facebook.github.io/react-native/[React Native] - UI 渲染 6 | * https://mobx.js.org/[MobX] - 响应式状态管理 7 | * xref:cuba-react-core:index.adoc[CUBA React Core] - CUBA React core 组件和工具 8 | * {api_rest}[CUBA REST JS] - 与 СUBA 通用 REST API 交互 9 | * https://expo.io/[Expo] - React Native 的开发工具 10 | 11 | React Native client 使用 link:https://www.typescriptlang.org/[TypeScript] 开发。 12 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/answers/string-id-management-table.js: -------------------------------------------------------------------------------- 1 | const stringIdEntityQuery = require("../graphql/stringIdEntity"); 2 | 3 | module.exports = { 4 | "entity": { 5 | "name": "scr_StringIdTestEntity" 6 | }, 7 | 8 | "editorComponentName": "StringIdMgtTableEdit", 9 | "editorQuery": stringIdEntityQuery, 10 | 11 | "browserComponentName": "StringIdMgtTableBrowse", 12 | "browserType": "table", 13 | "browserQuery": stringIdEntityQuery, 14 | 15 | 'menuItem': 'ROOT' 16 | } -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/table/DataTableIntervalEditor.module.less: -------------------------------------------------------------------------------- 1 | @import "antd/es/style/themes/default"; 2 | 3 | .intervalModeSelect { 4 | display: flex; 5 | flex-direction: column; 6 | 7 | padding: 6px; 8 | margin-top: 0; 9 | margin-right: 16px; 10 | border: dotted @border-width-base @normal-color; 11 | border-radius: @border-radius-base; 12 | } 13 | 14 | .intervalPredefinedSelect { 15 | min-width: 100px; 16 | } 17 | 18 | .intervalIncludeCurrent { 19 | white-space: nowrap; 20 | } 21 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/errorHandling.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * To be used in (supposedly) unreachable code after exhaustive check of `argument`. 3 | * 4 | * @remarks 5 | * Will cause a compile-time error if `argument` was not exhaustively checked. 6 | * Will cause a runtime error if reached. 7 | * 8 | * @param argumentName 9 | * @param argument 10 | */ 11 | export function assertNever(argumentName: string, argument: never): never { 12 | throw new Error(`Unexpected ${argumentName}: ${argument}`); 13 | } 14 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/ui/Label.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {Msg} from "./Msg"; 3 | 4 | export interface LabelProps extends React.DetailedHTMLProps, HTMLLabelElement> { 5 | entityName: string; 6 | propertyName: string; 7 | } 8 | 9 | export const Label = ({entityName, propertyName, ...rest}: LabelProps) => { 10 | return ( 11 | 14 | ) 15 | } -------------------------------------------------------------------------------- /scripts/generator-customization/generators/src/custom-screen/blank.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/test/integration/expect/entities/ScrUserInfo.ts: -------------------------------------------------------------------------------- 1 | import { BaseUuidEntity } from "./base/sys$BaseUuidEntity"; 2 | import { Car } from "./scr$Car"; 3 | export class ScrUserInfo extends BaseUuidEntity { 4 | static NAME = "ScrUserInfo"; 5 | firstName?: string | null; 6 | lastName?: string | null; 7 | favouriteCars?: Car | null; 8 | } 9 | export type ScrUserInfoViewName = "_minimal" | "_local" | "_base"; 10 | export type ScrUserInfoView = never; 11 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/antora.yml: -------------------------------------------------------------------------------- 1 | name: cuba-frontend-docs 2 | title: CUBA 前端 UI 开发手册 3 | version: 1.x 4 | nav: 5 | - modules/overview/nav.adoc 6 | - modules/getting-started/nav.adoc 7 | - modules/client-react/nav.adoc 8 | - modules/client-react-native/nav.adoc 9 | - modules/cuba-react-core/nav.adoc 10 | - modules/cuba-react-ui/nav.adoc 11 | - modules/typescript-sdk/nav.adoc 12 | - modules/generator/nav.adoc 13 | - modules/cuba-rest-js/nav.adoc 14 | - modules/libs/nav.adoc 15 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/blank-screen/blank.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: ['@commitlint/config-conventional'], 3 | rules: { 4 | 'scope-enum': [2, 'always', [ 5 | 'React', 'React Native', 'SDK', 6 | 'DataTable', 'Front Generator', 7 | 'deps', 'deps-dev' 8 | ]], 9 | 'scope-case': [0], 10 | 'type-enum': [2, 'always', [ 11 | 'feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'chore', 'revert', 'WIP' 12 | ]], 13 | 'type-case': [0], 14 | 'header-max-length': [2, 'always', 100] 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-multi-selection-table/entity-multi-selection-table.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-table-with-filters/entity-multi-selection-table.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /example-react-app/src/jmix/entities/scr_TrickyIdTestEntity.ts: -------------------------------------------------------------------------------- 1 | export class TrickyIdTestEntity { 2 | static NAME = "scr_TrickyIdTestEntity"; 3 | id?: string; 4 | otherAttr?: string | null; 5 | } 6 | export type TrickyIdTestEntityViewName = "_base" | "_instance_name" | "_local"; 7 | export type TrickyIdTestEntityView< 8 | V extends TrickyIdTestEntityViewName 9 | > = V extends "_base" 10 | ? Pick 11 | : V extends "_local" 12 | ? Pick 13 | : never; 14 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/app/JmixServerError.ts: -------------------------------------------------------------------------------- 1 | // Designed as replacement for JmixRestError 2 | export interface JmixServerError extends Error { 3 | response?: Response 4 | } 5 | 6 | export function createJmixServerError(response: Response): JmixServerError { 7 | return new JmixServerErrorImpl(response); 8 | } 9 | 10 | class JmixServerErrorImpl extends Error implements JmixServerError { 11 | constructor(public response: Response) { 12 | super(response.statusText); 13 | this.name = 'JmixServerError'; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test-pup/example-react-app/data-table/data-table-custom-filter/data-table-no-filters.test.js: -------------------------------------------------------------------------------- 1 | const FilterActions = require('./FilterActions'); 2 | 3 | // TODO https://github.com/cuba-platform/frontend/issues/284 4 | xdescribe('DataTable - no filters', () => { 5 | let fa = new FilterActions(); 6 | beforeAll(fa.beforeAll); 7 | beforeEach(fa.beforeEach); 8 | afterAll(fa.afterAll); 9 | 10 | it('No filters applied', async () => { 11 | await fa.expectResults(0, ['0', '-8273729824.34', '9131354156.12', '']); 12 | }); 13 | 14 | }); -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/jmix-react-core/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = Jmix React Core Components 2 | 3 | *Jmix React Core* library is a collection of components and utilities responsible for core functionalities such as working with Jmix entities. This library is available as an npm package {npm_cubaReactCore}[@haulmont/jmix-react-core]. 4 | 5 | API reference can be found link:../api-reference/jmix-react-core/index.html[here]. 6 | 7 | See the rest of this section for information on how to use the components and utilities provided by this library. 8 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/jmix-react-ui/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = Jmix React UI Components 2 | 3 | *Jmix React UI* contains the UI components. It uses {antDesign_base}/docs/react/introduce[Ant Design] UI kit and is used by the xref:client-react:starter-guide.adoc[React] client. It is available as an npm package {npm_cubaReactUi}[@haulmont/jmix-react-ui]. 4 | 5 | API reference can be found link:../api-reference/jmix-react-ui/index.html[here]. 6 | 7 | See the rest of this section for information on how to use the components provided by this library. 8 | -------------------------------------------------------------------------------- /example-react-app/src/jmix/entities/scr_Product.ts: -------------------------------------------------------------------------------- 1 | import { Car } from "./scr_Car"; 2 | export class Product { 3 | static NAME = "scr_Product"; 4 | id?: string; 5 | car?: Car | null; 6 | price?: any | null; 7 | special?: boolean | null; 8 | } 9 | export type ProductViewName = "_base" | "_instance_name" | "_local"; 10 | export type ProductView = V extends "_base" 11 | ? Pick 12 | : V extends "_local" 13 | ? Pick 14 | : never; 15 | -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-editor/fields/Fields.less: -------------------------------------------------------------------------------- 1 | .association-field-wrapper { 2 | width: 100%; 3 | } 4 | 5 | .entity-picker-icon { 6 | justify-content: center; 7 | align-items: flex-end; 8 | align-self: center; 9 | width: 30px; 10 | height: 32px; 11 | border-style: solid; 12 | border-width: 1px; 13 | margin-top: 5px; 14 | opacity: 0.4; 15 | } 16 | 17 | .association-field-container { 18 | display: flex; 19 | 20 | .entity-picker-icon { 21 | display: flex; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/crud/list/ui-callbacks/useSelectionChangeCallback.ts: -------------------------------------------------------------------------------- 1 | import {useCallback} from "react"; 2 | import {action} from "mobx"; 3 | import { EntityListState } from "../useEntityList"; 4 | 5 | export function useSelectionChangeCallback( 6 | entityListState: EntityListState 7 | ) { 8 | return useCallback( 9 | action((selectedRowKeys: string[]) => { 10 | entityListState.selectedEntityId = selectedRowKeys[0]; 11 | }), 12 | [entityListState.selectedEntityId] 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/crud/list/util/getEntityInstanceById.ts: -------------------------------------------------------------------------------- 1 | import { EntityInstance, toIdString } from "@haulmont/jmix-react-core"; 2 | 3 | export function getEntityInstanceById(id: string, items: Array>): EntityInstance { 4 | const record: EntityInstance | undefined = (items ?? []).find((item: EntityInstance) => toIdString(item.id!) === id); 5 | 6 | if (!record) { 7 | throw new Error("Cannot find entity with id " + id); 8 | } 9 | 10 | return record; 11 | } -------------------------------------------------------------------------------- /example-react-app/src/app/blank-screen/TestBlankScreen.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { registerScreen } from "@haulmont/jmix-react-web"; 3 | 4 | const ROUTING_PATH = "/testBlankScreen"; 5 | 6 | const TestBlankScreen = () =>
TestBlankScreen
; 7 | 8 | registerScreen({ 9 | component: TestBlankScreen, 10 | caption: "screen.TestBlankScreen", 11 | screenId: "TestBlankScreen", 12 | menuOptions: { 13 | pathPattern: ROUTING_PATH, 14 | menuLink: ROUTING_PATH 15 | } 16 | }); 17 | 18 | export default TestBlankScreen; 19 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/util/dollars-to-underscores.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Replaces all occurrences of a dollar sign ($) inside a string with underscores (_). 3 | * 4 | * Useful when generating GraphQL templates for an entity that has a dollar sign in its name 5 | * (e.g. scr$Car), since corresponding GraphQL types will have underscore in its place 6 | * (e.g. inp_scr_CarOrderBy). 7 | * 8 | * @param input 9 | */ 10 | export const dollarsToUnderscores = (input: string): string => { 11 | return input.replace(/\$/g, '_'); 12 | }; -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/answers/int-id-management-table.json: -------------------------------------------------------------------------------- 1 | { 2 | "editView": { 3 | "name": "_local", 4 | "entityName": "scr_IntegerIdTestEntity" 5 | }, 6 | "editComponentName": "IntIdMgtTableEdit", 7 | "listView": { 8 | "name": "_local", 9 | "entityName": "scr_IntegerIdTestEntity" 10 | }, 11 | "listComponentName": "IntIdMgtTableBrowse", 12 | "listType": "table", 13 | "entity": { 14 | "name": "scr_IntegerIdTestEntity" 15 | }, 16 | "managementComponentName": "int-id-management-table" 17 | } -------------------------------------------------------------------------------- /packages/jmix-front-generator/tsconfig_strict.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "module": "commonjs", 5 | "outDir": "./lib", 6 | "resolveJsonModule": true, 7 | "sourceMap": true, 8 | "strict": true, 9 | "noUnusedLocals": true, 10 | "noUnusedParameters": true, 11 | "noImplicitReturns": true, 12 | "noFallthroughCasesInSwitch": true, 13 | "baseUrl": "." 14 | }, 15 | "include": [ 16 | "src/**/*.ts", 17 | "clients/**/*.ts", 18 | "custom_types/**/*.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/app/login/Login.module.css: -------------------------------------------------------------------------------- 1 | .loginForm { 2 | border-radius: 4px; 3 | padding: 32px 32px 0; 4 | min-width: 300px; 5 | box-shadow: 0 0 50px 0 rgba(0,0,0,0.2); 6 | } 7 | 8 | .loginForm .title { 9 | text-align: center; 10 | margin-bottom: 24px; 11 | font-size: 20px; 12 | } 13 | 14 | .loginForm .logo { 15 | display: block; 16 | margin: 0 auto 12px; 17 | width: 64px; 18 | height: 64px; 19 | } 20 | 21 | .languageSwitcherContainer { 22 | float: right; 23 | } 24 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/util/data.ts: -------------------------------------------------------------------------------- 1 | import { EntityId } from "./metadata"; 2 | import { base64encode } from "./base64"; 3 | 4 | export const TEMPORARY_ENTITY_ID_PREFIX = '_CUBA_TEMPORARY_ENTITY_ID_'; 5 | 6 | export const generateTemporaryEntityId = () => TEMPORARY_ENTITY_ID_PREFIX + Math.random().toString().slice(2); 7 | 8 | export function toIdString(id: EntityId) : string { 9 | switch (typeof id) { 10 | case "object": return base64encode(JSON.stringify(id)) 11 | case "number": return String(id) 12 | default: return id 13 | } 14 | } -------------------------------------------------------------------------------- /packages/jmix-react-web/src/ui/single-content-area/SingleContentArea.tsx: -------------------------------------------------------------------------------- 1 | import { Screens, ScreensContext } from "@haulmont/jmix-react-core"; 2 | import { observer } from "mobx-react"; 3 | import React, {useState} from "react"; 4 | import {singleContentArea} from "./SingleContentAreaState"; 5 | 6 | export const SingleContentArea = observer(() => { 7 | const [screens] = useState(new Screens()); 8 | 9 | return ( 10 | 11 | {singleContentArea.content} 12 | 13 | ); 14 | }); -------------------------------------------------------------------------------- /test-pup/common/custom-form-controls.js: -------------------------------------------------------------------------------- 1 | const {getDocument, queries} = require("pptr-testing-library"); 2 | const {findByRole} = queries; 3 | 4 | exports.getSubmitResult = async (page) => { 5 | const $document = await getDocument(page); 6 | 7 | const $submit = await findByRole($document, 'button', {name: /submit/i}); 8 | $submit.click(); 9 | 10 | const $result = await findByRole($document, 'log'); 11 | 12 | const displayedSubmitResult = await page.evaluate(el => el.innerHTML, $result); 13 | return JSON.parse(displayedSubmitResult); 14 | }; -------------------------------------------------------------------------------- /example-react-app/src/jmix/entities/scr_Customer.ts: -------------------------------------------------------------------------------- 1 | export class Customer { 2 | static NAME = "scr_Customer"; 3 | id?: string; 4 | name?: string | null; 5 | email?: string | null; 6 | } 7 | export type CustomerViewName = "_base" | "_instance_name" | "_local"; 8 | export type CustomerView = V extends "_base" 9 | ? Pick 10 | : V extends "_instance_name" 11 | ? Pick 12 | : V extends "_local" 13 | ? Pick 14 | : never; 15 | -------------------------------------------------------------------------------- /packages/jmix-addon-data-tools/src/entity-inspector/entity-data-editor/association-2o/Association2O.less: -------------------------------------------------------------------------------- 1 | .association-field-wrapper { 2 | width: 100%; 3 | } 4 | 5 | .entity-picker-icon { 6 | justify-content: center; 7 | align-items: flex-end; 8 | align-self: center; 9 | width: 30px; 10 | height: 32px; 11 | border-style: solid; 12 | border-width: 1px; 13 | margin-top: 5px; 14 | opacity: 0.4; 15 | } 16 | 17 | .association-field-container { 18 | display: flex; 19 | 20 | .entity-picker-icon { 21 | display: flex; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/common/questions.ts: -------------------------------------------------------------------------------- 1 | import {StudioTemplateProperty, StudioTemplatePropertyType} from '../../../common/studio/studio-model'; 2 | 3 | export const idAttrNameQuestions: StudioTemplateProperty[] = [ 4 | { 5 | code: 'idAttrName', 6 | caption: 'You have chosen a String ID entity, but we could not find the ID attribute name in the project model. \n' + 7 | 'What is the ID attribute name?', 8 | propertyType: StudioTemplatePropertyType.STRING, 9 | required: true 10 | } 11 | ]; 12 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/generator-customization/generator-customization.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/crud/list/ui-callbacks/useFilterChangeCallback.ts: -------------------------------------------------------------------------------- 1 | import {useCallback} from "react"; 2 | import {action} from "mobx"; 3 | import {JmixEntityFilter} from "@haulmont/jmix-react-core"; 4 | import {EntityListState} from "../useEntityList"; 5 | 6 | export function useFilterChangeCallback( 7 | entityListState: EntityListState 8 | ) { 9 | return useCallback( 10 | action((filter?: JmixEntityFilter[]) => { 11 | entityListState.filter = filter; 12 | }), 13 | [entityListState.filter] 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/crud/list/util/getSubmitBtnCaption.ts: -------------------------------------------------------------------------------- 1 | import { EntityInstance } from "@haulmont/jmix-react-core"; 2 | 3 | export function getSubmitBtnCaption( 4 | entityList?: Array>, 5 | onEntityListChange?: (entityList: Array>) => void, 6 | ): string | undefined { 7 | let submitBtnCaption: string | undefined; 8 | 9 | if (entityList != null && onEntityListChange != null) { 10 | submitBtnCaption = 'common.ok'; 11 | } 12 | 13 | return submitBtnCaption; 14 | } 15 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/cuba-react-ui/pages/nested-entity-field.adoc: -------------------------------------------------------------------------------- 1 | = NestedEntityField 2 | :api_ui_NestedEntityFieldProps: link:../api-reference/cuba-react-ui/interfaces/_ui_form_form_.nestedentityfieldprops.html 3 | 4 | `NestedEntityField` 是一个字段组件,用在一对一组合的上下文环境中,用来表示嵌套的实体。可以用来新建、编辑或删除嵌套实体。新建、编辑时,会为嵌套实体打开 xref:entity-editor.adoc[EntityEditor]。对于一对一组合的实体属性,xref:form-field.adoc[FormField] 可以自动渲染为 `NestedEntityField`。 5 | 6 | CAUTION: 多层级联组合(比如嵌套实体也带有嵌套实体),目前不支持。 7 | 8 | ''' 9 | 10 | API: {api_ui_NestedEntityFieldProps}[NestedEntityFieldProps]. 11 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/getting-started/pages/learning-path.adoc: -------------------------------------------------------------------------------- 1 | = 选择学习路径 2 | 3 | 如果您想创建一个基于 React 的前端 UI,参阅 xref:client-react:starter-guide.adoc[React Client] 向导。 4 | 5 | 如果选择 React Native, 参阅 xref:client-react-native:starter-guide.adoc[该向导]。 6 | 7 | 8 | 如果想使用其他的前端框架,可以参阅 xref:typescript-sdk:index.adoc[TypeScript SDK] 和 {api_rest}[CUBA REST JS] 文档。 9 | 10 | 如果您希望构建一个前端客户端,既可以用于桌面电脑也可以用于手机端,但是您不知道用什么框架比较好,我们推荐您使用 xref:client-react:starter-guide.adoc[React Client],这是目前能得到最优支持的选择。 11 | 12 | 如果您还是犹豫不决,或者我们的文档并没有覆盖您特殊的使用场景,请在 {forum}[论坛] 与我们联系。 13 | -------------------------------------------------------------------------------- /example-react-app/README.md: -------------------------------------------------------------------------------- 1 | # React Front-end Client for Jmix 2 | 3 | This project was generated with [@haulmont/jmix-front-generator](https://docs.jmix.io/jmix/0.x/frontend-ui/index.html). 4 | 5 | Install dependencies: 6 | 7 | ```bash 8 | npm install 9 | ``` 10 | 11 | Run project: 12 | 13 | ```bash 14 | npm run start 15 | ``` 16 | 17 | This will launch a dev server and allow you to access your app at `localhost:3000`. 18 | 19 | ### Learn More 20 | 21 | React client documentation is available [here](https://docs.jmix.io/jmix/0.x/frontend-ui/index.html). 22 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/query-model-car.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "ecoCars", 4 | "jpql": "select c from mpg$Car c where c.ecoRank = 3", 5 | "entity": "mpg$Car", 6 | "view": "_local", 7 | "params": [] 8 | }, 9 | { 10 | "name": "carsByType", 11 | "jpql": "select c from mpg$Car c where c.carType = :carType", 12 | "entity": "mpg$Car", 13 | "view": "_local", 14 | "params": [ 15 | { 16 | "name": "carType", 17 | "type": "java.lang.String" 18 | } 19 | ] 20 | } 21 | ] 22 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/cuba-react-ui/pages/entity-property.adoc: -------------------------------------------------------------------------------- 1 | = EntityProperty 2 | :api_ui_EntityPropertyProps: link:../api-reference/cuba-react-ui/interfaces/_ui_entityproperty_.entitypropertyprops.html 3 | 4 | `EntityProperty` 组件用来展示实体属性的值。可以根据属性的类型自动应用展示格式,并能从全局消息包(在后台定义)获取文本为属性添加相应的标签。 5 | 6 | [source,typescript] 7 | ---- 8 | 11 | ---- 12 | 13 | ''' 14 | 15 | API: {api_ui_EntityPropertyProps}[EntityPropertyProps]. 16 | -------------------------------------------------------------------------------- /scripts/model/graphql/carEntity.js: -------------------------------------------------------------------------------- 1 | const carEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | manufacturer 6 | model 7 | regNumber 8 | purchaseDate 9 | manufactureDate 10 | wheelOnRight 11 | carType 12 | ecoRank 13 | maxPassengers 14 | price 15 | mileage 16 | garage { 17 | id 18 | _instanceName 19 | } 20 | technicalCertificate { 21 | id 22 | _instanceName 23 | } 24 | 25 | version 26 | createdBy 27 | createdDate 28 | lastModifiedBy 29 | lastModifiedDate 30 | } 31 | `; 32 | 33 | module.exports = carEntityQuery; -------------------------------------------------------------------------------- /example-react-app/src/app/AppErrorBoundary.tsx: -------------------------------------------------------------------------------- 1 | import { useIntl } from "react-intl"; 2 | import { ErrorBoundary } from "@haulmont/jmix-react-core"; 3 | import { Result } from "antd"; 4 | import React from "react"; 5 | 6 | export const AppErrorBoundary = function(props) { 7 | const intl = useIntl(); 8 | 9 | return ( 10 | } 13 | > 14 | {props.children} 15 | 16 | ); 17 | }; 18 | -------------------------------------------------------------------------------- /example-react-app/src/app/home/HomePage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { FormattedMessage } from "react-intl"; 3 | import { registerScreen } from "@haulmont/jmix-react-web"; 4 | 5 | const ROUTING_PATH = "/"; 6 | 7 | export const HomePage = () => ( 8 |
9 | scr-jmix! 10 |
11 | ); 12 | 13 | registerScreen({ 14 | component: HomePage, 15 | caption: "screen.home", 16 | screenId: "HomePage", 17 | menuOptions: { 18 | pathPattern: ROUTING_PATH, 19 | menuLink: ROUTING_PATH 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/crud/list/ui-callbacks/useSortOrderChangeCallback.ts: -------------------------------------------------------------------------------- 1 | import {useCallback} from "react"; 2 | import {action} from "mobx"; 3 | import {EntityListState} from "../useEntityList"; 4 | import { JmixSortOrder } from "@haulmont/jmix-react-core"; 5 | 6 | export function useSortOrderChangeCallback( 7 | entityListState: EntityListState 8 | ) { 9 | return useCallback( 10 | action((sortOrder?: JmixSortOrder) => { 11 | entityListState.sortOrder = sortOrder; 12 | }), 13 | [entityListState.sortOrder] 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/jmix-server-mock/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es2021": true, 4 | "node": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "plugin:@typescript-eslint/recommended" 9 | ], 10 | "parser": "@typescript-eslint/parser", 11 | "parserOptions": { 12 | "ecmaVersion": 12, 13 | "sourceType": "module" 14 | }, 15 | "plugins": [ 16 | "@typescript-eslint" 17 | ], 18 | "rules": { 19 | "@typescript-eslint/explicit-module-boundary-types": "off" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /scripts/jmix/bootstrap-jmix-app.js: -------------------------------------------------------------------------------- 1 | const {runCmdSync, isEmptyDir, log} = require("../common"); 2 | const fs = require('fs'); 3 | 4 | function bootstrapJmixApp() { 5 | log.info('bootstrapping Jmix app'); 6 | checkoutJmixScrRepo(); 7 | } 8 | 9 | function checkoutJmixScrRepo() { 10 | if (fs.existsSync('scr-jmix') && !isEmptyDir('scr-jmix')) { 11 | runCmdSync('npm run update-jmix-app'); 12 | } else { 13 | runCmdSync('git clone https://github.com/jmix-projects/scr-jmix.git'); 14 | log.info('repo has been cloned'); 15 | } 16 | } 17 | 18 | bootstrapJmixApp(); -------------------------------------------------------------------------------- /packages/jmix-react-web/src/ui/Menu/MenuPermContainer.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { MenuAccessControl } from "@haulmont/jmix-react-core"; 3 | 4 | type Props = { 5 | children: JSX.Element; 6 | accessKey: string 7 | } 8 | 9 | export const MenuPermissionContainer = (props: Props) => { 10 | const {accessKey, children} = props; 11 | 12 | return process.env.REACT_APP_ENABLE_UI_PERMISSIONS === "true" 13 | ? ( 14 | 18 | ) 19 | : children 20 | } 21 | -------------------------------------------------------------------------------- /scripts/generator-customization/templates/blank-screen/Component.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {registerScreen} from "@haulmont/jmix-react-ui"; 3 | 4 | const ROUTING_PATH = '/<%= nameLiteral %>'; 5 | 6 | export const <%= className %> = () => ( 7 |
8 | CUSTOM TEMPLATE <%= className %> 9 |
10 | ); 11 | 12 | registerScreen({ 13 | component: <%= className %>, 14 | caption: 'screen.<%= className %>', 15 | screenId: '<%= className %>', 16 | menuOptions: { 17 | pathPattern: ROUTING_PATH, 18 | menuLink: ROUTING_PATH, 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /scripts/pack-react-client-libs.js: -------------------------------------------------------------------------------- 1 | const packClientLibs = require('./pack-client-libs'); 2 | 3 | packClientLibs( 4 | [ 5 | '@haulmont/jmix-front-generator', 6 | '@haulmont/jmix-rest', 7 | '@haulmont/jmix-react-core', 8 | '@haulmont/jmix-react-antd', 9 | '@haulmont/jmix-react-web', 10 | ], 11 | [ 12 | '@haulmont/jmix-front-generator', 13 | '@haulmont/jmix-rest', 14 | '@haulmont/jmix-react-core', 15 | '@haulmont/jmix-react-antd', 16 | '@haulmont/jmix-react-web', 17 | ] 18 | ); 19 | 20 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/components/Example.tsx: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {StyleSheet, Text} from "react-native"; 3 | import {observer} from "mobx-react"; 4 | 5 | const styles = StyleSheet.create({ 6 | title: { 7 | fontSize: 18, 8 | fontWeight: 'bold', 9 | marginTop: 16, 10 | } 11 | }); 12 | 13 | @observer 14 | export class Example extends Component { 15 | 16 | render() { 17 | return ( 18 | Welcome to <%=project.name%>! 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/react-client/src/app/component/BlankComponent.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { registerScreen } from "@haulmont/jmix-react-web"; 3 | 4 | const ROUTING_PATH = "/blankComponent"; 5 | 6 | const BlankComponent = () =>
BlankComponent
; 7 | 8 | registerScreen({ 9 | component: BlankComponent, 10 | caption: "screen.BlankComponent", 11 | screenId: "BlankComponent", 12 | menuOptions: { 13 | pathPattern: ROUTING_PATH, 14 | menuLink: ROUTING_PATH 15 | } 16 | }); 17 | 18 | export default BlankComponent; 19 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/MultiSelectionTable/MultiSelectionTableStore.ts: -------------------------------------------------------------------------------- 1 | import {action, makeObservable, observable} from 'mobx'; 2 | 3 | export class MultiSelectionTableStore { 4 | selectedEntityIds: string[] | undefined = undefined; 5 | 6 | constructor() { 7 | makeObservable(this, { 8 | selectedEntityIds: observable, 9 | setSelectedEntityIds: action, 10 | }); 11 | } 12 | 13 | setSelectedEntityIds(selectedEntityIds: string[] | undefined) { 14 | this.selectedEntityIds = selectedEntityIds; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/rest/rest.ts: -------------------------------------------------------------------------------- 1 | import { initializeApp } from "@haulmont/jmix-rest"; 2 | import { REACT_NATIVE_APP_CUBA_URL, REACT_NATIVE_APP_REST_CLIENT_ID, REACT_NATIVE_APP_REST_CLIENT_SECRET } from "react-native-dotenv"; 3 | 4 | export const jmixREST = initializeApp({ 5 | name: '<%=project.namespace%>', 6 | apiUrl: REACT_NATIVE_APP_CUBA_URL, 7 | restClientId: REACT_NATIVE_APP_REST_CLIENT_ID, 8 | restClientSecret: REACT_NATIVE_APP_REST_CLIENT_SECRET, 9 | }); 10 | 11 | export const REST_TOKEN_STORAGE_KEY = "cubaAccessToken"; 12 | -------------------------------------------------------------------------------- /scripts/generator-customization/generators/src/custom-screen/template-model.ts: -------------------------------------------------------------------------------- 1 | import {Answers} from "./answers"; 2 | import {Options} from "./options"; 3 | import {CommonTemplateModel, deriveEntityCommon, ProjectModel, YeomanGenerator} from "@haulmont/jmix-front-generator"; 4 | 5 | export interface TemplateModel extends CommonTemplateModel {} 6 | 7 | export async function deriveTemplateModel( 8 | answers: Answers, projectModel: ProjectModel, gen: YeomanGenerator, options: Options 9 | ): Promise { 10 | return {...deriveEntityCommon(options, answers)} 11 | } 12 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/TimePicker.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Dayjs } from 'dayjs'; 3 | import {PickerTimeProps} from 'antd/es/date-picker/generatePicker'; 4 | import 'antd/es/date-picker/style/index'; 5 | import {DatePicker} from './DatePicker'; 6 | 7 | export interface TimePickerProps extends Omit, 'picker'> {} 8 | 9 | export const TimePicker = React.forwardRef((props, ref) => { 10 | return ; 11 | }); 12 | 13 | TimePicker.displayName = 'TimePicker'; 14 | -------------------------------------------------------------------------------- /packages/jmix-react-web/src/util/regex.ts: -------------------------------------------------------------------------------- 1 | // More strict validation would be: 2 | // export const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; 3 | // However, we are using relaxed validation rules as Backoffice UI allows to create UUIDs with invalid 4 | // versions and variants (https://github.com/cuba-platform/cuba/issues/2867) 5 | // TODO Once https://github.com/cuba-platform/cuba/issues/2867 is fixed, choose the regex dynamically based on Platform version. 6 | export const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; 7 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/jmix-react-core/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Jmix React Core] 2 | ** xref:access-control.adoc[AccessControl] 3 | ** xref:attr-perm-access-control.adoc[AttrPermAccessControl] 4 | ** xref:client-side-data-collection-store.adoc[ClientSideDataCollectionStore] 5 | ** xref:cuba-app-provider.adoc[JmixAppProvider] 6 | ** xref:data-collection-store.adoc[DataCollectionStore] 7 | ** xref:data-instance-store.adoc[DataInstanceStore] 8 | ** xref:entity-perm-access-control.adoc[EntityPermAccessControl] 9 | ** xref:main-store.adoc[MainStore] 10 | ** xref:security.adoc[Security] 11 | -------------------------------------------------------------------------------- /scripts/generator-customization/generators/src/custom-screen/template/Component.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {registerScreen} from "@haulmont/jmix-react-ui"; 3 | 4 | const ROUTING_PATH = '/<%= nameLiteral %>'; 5 | 6 | export const <%= className %> = () => ( 7 |
8 | CUSTOM GENERATOR <%= className %> 9 |
10 | ); 11 | 12 | registerScreen({ 13 | component: <%= className %>, 14 | caption: 'screen.<%= className %>', 15 | screenId: '<%= className %>', 16 | menuOptions: { 17 | pathPattern: ROUTING_PATH, 18 | menuLink: ROUTING_PATH, 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /docs-src-cn/redirect-page-template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 正在跳转... 13 | 14 | 15 | 16 | 如果没有为您自动跳转,请点击链接。 17 | 18 | 19 | -------------------------------------------------------------------------------- /example-react-app/src/jmix/entities/scr_OrderLine.ts: -------------------------------------------------------------------------------- 1 | import { Product } from "./scr_Product"; 2 | import { Order } from "./scr_Order"; 3 | export class OrderLine { 4 | static NAME = "scr_OrderLine"; 5 | id?: string; 6 | product?: Product | null; 7 | quantity?: number | null; 8 | order?: Order | null; 9 | } 10 | export type OrderLineViewName = "_base" | "_instance_name" | "_local"; 11 | export type OrderLineView = V extends "_base" 12 | ? Pick 13 | : V extends "_local" 14 | ? Pick 15 | : never; 16 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/graphql/carEntity.js: -------------------------------------------------------------------------------- 1 | const carEntityQuery = ` 2 | { 3 | id 4 | _instanceName 5 | manufacturer 6 | model 7 | regNumber 8 | purchaseDate 9 | manufactureDate 10 | wheelOnRight 11 | carType 12 | ecoRank 13 | maxPassengers 14 | price 15 | mileage 16 | garage { 17 | id 18 | _instanceName 19 | } 20 | technicalCertificate { 21 | id 22 | _instanceName 23 | } 24 | 25 | version 26 | createdBy 27 | createdDate 28 | lastModifiedBy 29 | lastModifiedDate 30 | } 31 | `; 32 | 33 | module.exports = carEntityQuery; -------------------------------------------------------------------------------- /example-react-app/src/themes/themes.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "pathToThemesDir": "/static/css", 3 | "idThemePresetLink": "jmix-antd-theme-link", 4 | "storageThemeAttr": "jmixAntdActiveTheme", 5 | "defaultThemePreset": { 6 | "themeName": "light", 7 | "sizeName": null 8 | }, 9 | "themes": [ 10 | { 11 | "name": "light", 12 | "caption": "themes.light" 13 | }, 14 | { 15 | "name": "dark", 16 | "caption": "themes.dark" 17 | }, 18 | { 19 | "name": "high-contrast", 20 | "caption": "themes.highСontrast" 21 | } 22 | ], 23 | "sizes": [] 24 | } 25 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/common/constants.ts: -------------------------------------------------------------------------------- 1 | export const ENTITIES_DIR = 'entities'; 2 | export const BASE_ENTITIES_DIR = 'base'; 3 | export const ENUMS_DIR = 'enums'; 4 | export const ENUMS_FILE = 'enums'; 5 | 6 | export const CUBA_APP_NAME = 'cubaApp'; 7 | export const CUBA_APP_TYPE = 'JmixRestConnection'; 8 | export const FETCH_OPTIONS_TYPE = 'FetchOptions'; 9 | export const SERIALIZED_ENTITY_TYPE = 'SerializedEntity'; 10 | export const ENTITIES_WITH_COUNT_TYPE = 'EntitiesWithCount'; 11 | export const FETCH_OPTIONS_NAME = 'fetchOpts'; 12 | export const CUBA_APP_MODULE_SPEC = '@haulmont/jmix-rest'; 13 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/getting-started/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = 开始使用 2 | 3 | 首先,请安装 {manual_studio}/#installation[CUBA Studio]。 4 | 5 | 您的学习路径一般会根据您准备构建什么样的前端(React,React Native,等等)而有所不同。但是,通常从 *Frontend Generator* 开始,两种使用的途径: 6 | 7 | - 从 Studio UI 使用 8 | - 在命令行窗口使用,这里要用到通过 Studio 生成的项目模型文件 9 | 10 | CAUTION: CLI 支持的大部分功能 Studio 都能支持,但是有一些不是。查看 xref:generator:commands-reference.adoc[Frontend Generator 参考] 了解具体支持哪些功能。另外,如果您希望您的前端项目独立于 CUBA 项目(比如前后端由不同团队开发),那么也需要在前端项目使用 CLI。 11 | 12 | 如果您需要在 CLI 使用 Frontend Generator,请参阅 xref:cli-specific-instructions.adoc[CLI 特性介绍]。否则,继续阅读 xref:learning-path.adoc[这章]。 13 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/README.md: -------------------------------------------------------------------------------- 1 | # React Front-end Client for Jmix 2 | 3 | This project was generated with [@haulmont/jmix-front-generator](https://docs.jmix.io/jmix/0.x/frontend-ui/index.html). 4 | 5 | Install dependencies: 6 | 7 | ```bash 8 | npm install 9 | ``` 10 | 11 | Run project: 12 | 13 | ```bash 14 | npm run start 15 | ``` 16 | 17 | This will launch a dev server and allow you to access your app at `localhost:3000`. 18 | 19 | ### Learn More 20 | 21 | React client documentation is available [here](https://docs.jmix.io/jmix/0.x/frontend-ui/index.html). 22 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/app/AppErrorBoundary.tsx: -------------------------------------------------------------------------------- 1 | import {useIntl} from "react-intl"; 2 | import {ErrorBoundary} from "@haulmont/jmix-react-core"; 3 | import {Result} from "antd"; 4 | import React from "react"; 5 | 6 | export const AppErrorBoundary = function(props) { 7 | const intl = useIntl(); 8 | 9 | return ( 10 | } 13 | > 14 | {props.children} 15 | 16 | ); 17 | }; -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-editor/entity-editor.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/sdk/all/write.ts: -------------------------------------------------------------------------------- 1 | import {WriteStage} from "../../../building-blocks/pipelines/defaultPipeline"; 2 | import {TemplateModel} from "./template-model"; 3 | import {writeSdkAll} from "../../../building-blocks/stages/writing/pieces/sdk/sdk" 4 | import { CommonGenerationOptions } from "../../../common/cli-options"; 5 | 6 | export const write: WriteStage = async ( 7 | projectModel, templateModel, gen, _options 8 | ) => { 9 | gen.log(`Generating sdk:Model to ${gen.destinationPath()}`); 10 | writeSdkAll(gen, templateModel); 11 | }; 12 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/crud/editor/ui-callbacks/useSubmitFailedCallback.ts: -------------------------------------------------------------------------------- 1 | import {NotificationType, notifications} from "../../../ui/notifications"; 2 | import { useIntl } from "react-intl"; 3 | import { useCallback } from 'react'; 4 | 5 | export function useSubmitFailedCallback(): () => void { 6 | const intl = useIntl(); 7 | const onSubmitFailed = useCallback(() => { 8 | notifications.show({ 9 | type: NotificationType.ERROR, 10 | description: intl.formatMessage({ id: "management.editor.validationError" }) 11 | }); 12 | }, [intl, notifications]); 13 | return onSubmitFailed; 14 | } 15 | -------------------------------------------------------------------------------- /docs-src/redirect-page-template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | Redirecting... 12 | 13 | 14 | If you are not automatically redirected, please follow this link. 15 | 16 | 17 | -------------------------------------------------------------------------------- /example-react-app/src/jmix/entities/scr_Order.ts: -------------------------------------------------------------------------------- 1 | import { OrderLine } from "./scr_OrderLine"; 2 | import { Customer } from "./scr_Customer"; 3 | export class Order { 4 | static NAME = "scr_Order"; 5 | id?: string; 6 | date?: any | null; 7 | lines?: OrderLine[] | null; 8 | amount?: any | null; 9 | customer?: Customer | null; 10 | } 11 | export type OrderViewName = "_base" | "_instance_name" | "_local"; 12 | export type OrderView = V extends "_base" 13 | ? Pick 14 | : V extends "_local" 15 | ? Pick 16 | : never; 17 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/template/src/app/home/HomePage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {FormattedMessage} from 'react-intl'; 3 | import {registerScreen} from '@haulmont/jmix-react-web'; 4 | 5 | const ROUTING_PATH = "/"; 6 | 7 | export const HomePage = () => ( 8 |
9 | <%=title%>! 10 |
11 | ); 12 | 13 | registerScreen({ 14 | component: HomePage, 15 | caption: "screen.home", 16 | screenId: "HomePage", 17 | menuOptions: { 18 | pathPattern: ROUTING_PATH, 19 | menuLink: ROUTING_PATH 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/remove-addon/write.ts: -------------------------------------------------------------------------------- 1 | import {WriteStage} from "../../../building-blocks/pipelines/defaultPipeline"; 2 | import {removeAddonsPalette, removeAddonImport} from "../../../building-blocks/stages/writing/pieces/addons"; 3 | import {Options} from "./options"; 4 | 5 | export const write: WriteStage = async ( 6 | projectModel, templateModel, gen, options 7 | ) => { 8 | const {dirShift, addonPackageName} = options; 9 | removeAddonImport(gen, dirShift, addonPackageName); 10 | removeAddonsPalette(gen, dirShift, addonPackageName); 11 | } 12 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/sdk/model/write.ts: -------------------------------------------------------------------------------- 1 | import {WriteStage} from "../../../building-blocks/pipelines/defaultPipeline"; 2 | import {CommonGenerationOptions} from "../../../common/cli-options"; 3 | import {TemplateModel} from "./template-model"; 4 | import {writeSdkModel} from "../../../building-blocks/stages/writing/pieces/sdk/sdk" 5 | 6 | export const write: WriteStage = async ( 7 | projectModel, templateModel, gen, _options 8 | ) => { 9 | gen.log(`Generating sdk:Model to ${gen.destinationPath()}`); 10 | writeSdkModel(gen, templateModel); 11 | }; 12 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/menu/vertical-menu/VerticalMenu.tsx: -------------------------------------------------------------------------------- 1 | import React, {CSSProperties} from "react"; 2 | import {Menu, MenuProps} from "antd"; 3 | 4 | interface Props { 5 | children: (JSX.Element | JSX.Element[]); 6 | style?: CSSProperties; 7 | } 8 | 9 | export function VerticalMenu({children, style, ...restProps}: Props & T) { 10 | return ( 11 | 20 | {children} 21 | 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /docs-src-cn/doc-component-repo/modules/client-react/nav.adoc: -------------------------------------------------------------------------------- 1 | * React Client 2 | ** xref:starter-guide.adoc[开始使用 React Client] 3 | ** xref:learning-path.adoc[然后怎么办?] 4 | ** xref:technologies.adoc[技术概览] 5 | ** xref:supported-browsers.adoc[支持的浏览器] 6 | ** xref:creating-react-components.adoc[创建 React 组件] 7 | ** xref:mobx.adoc[MobX 处理 Observable State] 8 | ** xref:routing.adoc[路由和目录] 9 | ** xref:forms.adoc[表单] 10 | ** xref:i18n.adoc[国际化] 11 | ** xref:theme.adoc[自定义主题] 12 | ** xref:backend-model.adoc[后端模型] 13 | ** xref:sync-project-model.adoc[项目模型同步] 14 | ** xref:security.adoc[安全] 15 | ** xref:build.adoc[构建客户端] 16 | ** xref:config.adoc[配置] -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/entity-form-wizard/entity-form-wizard.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/menu/horizontal-menu/HorizontalMenu.tsx: -------------------------------------------------------------------------------- 1 | import React, {CSSProperties} from "react"; 2 | import {Menu, MenuProps} from "antd"; 3 | 4 | type Props = { 5 | children: JSX.Element | JSX.Element[]; 6 | style?: CSSProperties; 7 | } 8 | 9 | export function HorizontalMenu({children, style, ...restProps}: Props & T) { 10 | return ( 11 | 20 | {children} 21 | 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /test-pup/common/paging.js: -------------------------------------------------------------------------------- 1 | 2 | exports.checkPaging = (rowSelector) => async (page, url, [cardsCount, buttonTitles]) => { 3 | await page.goto(`http://localhost:3000/${url}`); 4 | await page.reload(); 5 | await page.waitFor(rowSelector); 6 | await page.waitFor('ul.ant-pagination li'); 7 | 8 | const carCards = await page.$$(rowSelector); 9 | if (cardsCount != null) expect(carCards.length).toEqual(cardsCount); 10 | 11 | const pagingButtonCaptions = await page 12 | .$$eval('ul.ant-pagination li', els => els.map(el => el.getAttribute('title'))); 13 | expect(pagingButtonCaptions).toEqual(buttonTitles); 14 | }; 15 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/building-blocks/stages/options/defaultGetOptions.ts: -------------------------------------------------------------------------------- 1 | import {OptionsConfig} from "../../../common/cli-options"; 2 | import {YeomanGenerator} from "../../YeomanGenerator"; 3 | 4 | export const defaultGetOptions = (optionsConfig: OptionsConfig, gen: YeomanGenerator): O => { 5 | // We are telling Yeoman to expect the options contained in optionsConfig 6 | Object.keys(optionsConfig).forEach(optionName => { 7 | gen.option(optionName, optionsConfig[optionName]); 8 | }); 9 | 10 | // Now we can gen the values of these options from Yeoman 11 | return gen.options as O; 12 | }; -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/blank-screen/template/Component.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import {registerScreen} from "@haulmont/jmix-react-web"; 3 | 4 | const ROUTING_PATH = '/<%= nameLiteral %>'; 5 | 6 | const <%= className %> = () => ( 7 |
8 | <%= className %> 9 |
10 | ); 11 | 12 | registerScreen({ 13 | component: <%= className %>, 14 | caption: 'screen.<%= className %>', 15 | screenId: '<%= className %>', 16 | menuOptions: { 17 | pathPattern: ROUTING_PATH, 18 | menuLink: ROUTING_PATH, 19 | } 20 | }); 21 | 22 | export default <%= className %>; 23 | -------------------------------------------------------------------------------- /packages/jmix-react-antd/src/ui/form/CharInput.tsx: -------------------------------------------------------------------------------- 1 | import {Input} from "antd"; 2 | import {InputProps} from "antd/lib/input"; 3 | import React, {forwardRef, Ref} from "react"; 4 | import styles from "./CharInput.module.less"; 5 | import classNames from "classnames"; 6 | 7 | export const CharInput = forwardRef((props: InputProps, ref: Ref) => { 8 | const {className = '', ...rest} = props; 9 | return ( 10 | 19 | ); 20 | }); 21 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/app/options.ts: -------------------------------------------------------------------------------- 1 | import {CommonGenerationOptions, commonGenerationOptionsConfig, OptionsConfig} from "../../../common/cli-options"; 2 | import {DirShiftOption} from "../../../building-blocks/stages/options/pieces/dir-shift"; 3 | 4 | export type Options = CommonGenerationOptions & DirShiftOption; 5 | 6 | export const appOptionsConfig: OptionsConfig = { 7 | ...commonGenerationOptionsConfig, 8 | answers: { 9 | alias: 'a', 10 | description: 'fulfilled params for generator to avoid interactive input in serialized JSON string', 11 | type: String 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scripts/ci-bootstrap-backend.js: -------------------------------------------------------------------------------- 1 | const startJmixApp = require("./jmix/_start-jmix-app"); 2 | const {runCmdSync} = require('./common'); 3 | 4 | const ciBootstrapBackend = () => { 5 | 6 | require("./jmix/bootstrap-jmix-app"); 7 | 8 | runCmdSync(`psql -c "create user cuba with encrypted password 'cuba';" -U postgres`); 9 | runCmdSync(`psql -c "alter user cuba createdb;" -U postgres`); 10 | runCmdSync(`psql -c "create database "'"scr-jmix"'";" -U postgres`); 11 | runCmdSync(`psql -c "grant all privileges on database "'"scr-jmix"'" to cuba;" -U postgres`); 12 | 13 | startJmixApp(true) 14 | }; 15 | 16 | ciBootstrapBackend(); 17 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-native/app/template/App.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {AsyncStorage} from 'react-native'; 3 | import {registerBase64} from "./util/base64"; 4 | import {JmixAppProvider} from "@haulmont/jmix-react-core"; 5 | import {Root} from "./components/Root"; 6 | import {jmixREST, REST_TOKEN_STORAGE_KEY} from './rest/rest'; 7 | 8 | registerBase64(); 9 | 10 | export default function App() { 11 | return ( 12 | AsyncStorage.getItem(REST_TOKEN_STORAGE_KEY)}> 13 | 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/generators/react-typescript/blank-screen/answers.ts: -------------------------------------------------------------------------------- 1 | import {StudioTemplateProperty} from "../../../common/studio/studio-model"; 2 | import { 3 | createComponentNameQuestion, 4 | ComponentNameAnswer, 5 | menuItemQuestion, 6 | MenuItemAnswer, 7 | } from "../../../building-blocks/stages/answers/pieces/defaultAnswers"; 8 | 9 | export interface Answers extends 10 | ComponentNameAnswer, 11 | MenuItemAnswer {} 12 | 13 | export const blankComponentQuestions: StudioTemplateProperty[] = [ 14 | createComponentNameQuestion({ 15 | defaultValue: 'BlankComponent', 16 | }), 17 | menuItemQuestion, 18 | ]; 19 | -------------------------------------------------------------------------------- /docs-src/doc-component-repo/modules/client-react-native/pages/technologies.adoc: -------------------------------------------------------------------------------- 1 | = Technologies Overview 2 | 3 | The client is based on the following frameworks and libraries: 4 | 5 | * https://facebook.github.io/react-native/[React Native] - UI rendering; 6 | * https://mobx.js.org/[MobX] - reactive state management; 7 | * xref:jmix-react-core:index.adoc[Jmix React Core] - Jmix React core components and utilities; 8 | * {api_rest}[Jmix REST] - interaction with СUBA generic REST API; 9 | * https://expo.io/[Expo] - development tools for React Native; 10 | 11 | React Native client is written in link:https://www.typescriptlang.org/[TypeScript]. 12 | -------------------------------------------------------------------------------- /packages/jmix-react-core/src/test-doubles/WebStorageStub.ts: -------------------------------------------------------------------------------- 1 | export class WebStorageStub implements Storage { 2 | storage: Record = {}; 3 | length: number = 0; 4 | 5 | clear(): void { 6 | this.storage = {}; 7 | this.length = 0; 8 | } 9 | 10 | getItem(key: string): string | null { 11 | return this.storage[key] ?? null; 12 | } 13 | 14 | key(_index: number): string | null { 15 | throw Error("not implemented"); 16 | } 17 | 18 | removeItem(key: string): void { 19 | delete this.storage[key]; 20 | } 21 | 22 | setItem(key: string, value: string): void { 23 | this.storage[key] = value; 24 | } 25 | } -------------------------------------------------------------------------------- /packages/jmix-react-web/src/util/copyToClipboard.ts: -------------------------------------------------------------------------------- 1 | export function copyToClipboard ( 2 | text: string, 3 | onSuccess?: () => void, 4 | onError?: () => void 5 | ) { 6 | try { 7 | const el = document.createElement('textarea'); 8 | el.value = text; 9 | el.setAttribute('readonly', ''); 10 | el.style.position = 'absolute'; 11 | el.style.left = '-9999px'; 12 | document.body.appendChild(el); 13 | el.select(); 14 | document.execCommand('copy'); 15 | document.body.removeChild(el); 16 | 17 | onSuccess?.() 18 | } catch (e) { 19 | onError?.() 20 | } 21 | } -------------------------------------------------------------------------------- /packages/jmix-front-generator/src/test/fixtures/answers/string-id-management-table-no-id-name.json: -------------------------------------------------------------------------------- 1 | { 2 | "editView": { 3 | "name": "_local", 4 | "entityName": "scr_StringIdTestEntity" 5 | }, 6 | "editComponentName": "StringIdMgtTableEdit", 7 | "editIdAttrPos": 1, 8 | "listView": { 9 | "name": "_local", 10 | "entityName": "scr_StringIdTestEntity" 11 | }, 12 | "listComponentName": "StringIdMgtTableBrowse", 13 | "listType": "table", 14 | "listShowIdAttr": true, 15 | "listIdAttrPos": 2, 16 | "entity": { 17 | "name": "scr_StringIdTestEntity" 18 | }, 19 | "managementComponentName": "string-id-mgt-table-management" 20 | } -------------------------------------------------------------------------------- /packages/jmix-rest/src/filter.ts: -------------------------------------------------------------------------------- 1 | export type OperatorType = '=' | '>' | '>=' | '<' | '<=' | '<>' | 'startsWith' | 'endsWith' | 'contains' 2 | | 'doesNotContain' | 'in' | 'notIn' | 'notEmpty'; 3 | 4 | export type GroupType = 'AND' | 'OR'; 5 | 6 | export interface EntityFilter { 7 | conditions: Array; 8 | } 9 | 10 | export interface ConditionsGroup { 11 | group: GroupType; 12 | conditions: Condition[]; 13 | } 14 | 15 | export type FilterValue = string | number | string[] | number[] | null; 16 | 17 | export interface Condition { 18 | property: string; 19 | operator: OperatorType; 20 | value: FilterValue; 21 | } 22 | --------------------------------------------------------------------------------