Giter Site home page Giter Site logo

cuba-platform / documentation Goto Github PK

View Code? Open in Web Editor NEW
25.0 6.0 45.0 63.76 MB

CUBA Platform Documentation

Home Page: https://www.cuba-platform.com

License: Creative Commons Attribution 4.0 International

Groovy 8.01% Java 54.58% JavaScript 3.82% Shell 0.37% CSS 8.72% HTML 13.74% Batchfile 0.11% Ruby 0.31% Makefile 0.06% SCSS 10.28%
cuba-platform documentation manual

documentation's Introduction

CUBA Platform Documentation

Overview

The documentation is written in AsciiDoc format. Source files, images and includes are located in the content directory in the following subdirectories:

  • manual - Developer's Manual
  • polymer - Polymer UI Tutorial
  • release_notes - latest release notes
  • other subdirectories contain documentation on platform addons.

Most of the documents have English and Russian versions in the corresponding subdirectories (en and ru).

Released documentation is available at CUBA website.

Building from Source

Prerequisites

In order to produce HTML from AsciiDoc, we use Asciidoctor. It can be installed as follows:

  1. Install Ruby (tested on version 2.1).

  2. Install Asciidoctor:

     gem install asciidoctor -v 1.5.2
    
  3. Install coderay for code highlighting:

     gem install coderay
    
  4. If you want to generate PDF, install Asciidoctor PDF:

     gem install asciidoctor-pdf -v 1.5.2
    

This is enough to build the documentation with the existing visual theme. If you want to change the theme, see the Building Theme section below.

Build Tasks

Gradle is used as a build tool. Build task names have the following structure: {purpose}{doc}{lang}.

{purpose} can be one of the following:

  • build - build single-HTML document.
  • chop - build multi-page document.
  • war - build a WAR file. The resulting WAR file will have a name corresponding to the document name and a version which is set by the ext.docVersion property defined in build.gradle, for example manual-7.0.war.
  • deploy - deploy WAR to Tomcat (installed by the setupTomcat task, see below).
  • pdf - generate PDF.

{doc} is the document name (Manual, Bpm, etc.)

{lang} can be either En or Ru.

For example, to build and deploy the English manual, use the following command:

./gradlew deployManualEn

Before running the deploy task, install the local Tomcat server by executing the following task:

./gradlew setupTomcat

By default, Tomcat is installed into ./deploy/tomcat and configured to listen on port 6080.

Building Theme

The CSS file containing the theme is located in the styles directory. Don't change this file - it must be built by the AsciiDoc theme builder. The theme builder is located in the tools/asciidoctor-stylesheet-factory directory (it is a copy of the asciidoctor-stylesheet-factory project).

The theme source code is contained in two files: sass/cuba.scss and sass/settings/_cuba.scss. After making changes in these files, execute the buildCubaTheme Gradle task. As a result, a new cuba.css will be written to the styles directory.

The buildCubaTheme task requires the following Ruby gems:

gem install --no-rdoc --no-ri sass -v 3.4.22
gem install --no-rdoc --no-ri compass
gem install zurb-foundation

If you get an error like

C:/Program Files/Ruby21-x64/lib/ruby/gems/2.1.0/gems/compass-core-1.0.3/lib/compass/core/sass_extensions/functions/urls.rb:5:in `has?': undefined method `has?' for Sass::Util:Module (NoMethodError)
        from C:/Program Files/Ruby21-x64/lib/ruby/gems/2.1.0/gems/compass-core-1.0.3/lib/compass/core/sass_extensions/functions/urls.rb:9:in `included'
        from C:/Program Files/Ruby21-x64/lib/ruby/gems/2.1.0/gems/sass-3.5.0.pre.rc.1/lib/sass/script/functions.rb:632:in `include'

then try to uninstall gem sass-3.5.0.pre.rc.1 and install 3.4.22. Perhaps you should also reinstall all the other gems.

Notes on PDF Generation

The PDF generation is based on the Asciidoctor PDF.

Due to the issue asciidoctor/asciidoctor-pdf#830 images in table cells should have pdfwidth=xxin attribute.

Viewing Documentation Locally

After installing Tomcat and deploying a document as described above, start the server:

./deploy/tomcat/bin/startup.sh 

If you build, for example, manual for version 7.1, it will be available at http://localhost:6080/manual-7.1.

documentation's People

Contributors

aleksey-stukalov avatar alexbudarov avatar andrew-archer avatar andreyvb avatar belyaev-andrey avatar crontabpy avatar dartverder avatar dependabot[bot] avatar euonymos avatar flaurite avatar gasloff avatar glebfox avatar gorbunkov avatar ikuchmin avatar jreznot avatar knstvk avatar mariodavid avatar natfirst avatar nikolasmelui avatar oshiryaeva avatar romancooler avatar skatova avatar stansurovhaulmont avatar sukhova avatar tinhol avatar torquemada163 avatar vyacheslav-pushkin avatar web-devel avatar xiety avatar xinatcg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

documentation's Issues

How to customize validation notification in Window

Relates to
At the moment, it is implemented in com.haulmont.cuba.web.gui.WebWindow#showValidationErrors and cannot be changed.

See: https://www.cuba-platform.com/support/topic/how-to-change-the-position-of-error-alert

New configuration property: cuba.gui.validationNotificationType
Default value: TRAY

Valid value: one of com.haulmont.cuba.gui.components.Frame.NotificationType (TRAY, TRAY_HTML, HUMANIZED, HUMANIZED_HTML, WARNING, WARNING_HTML, ERROR, ERROR_HTML)

You can override default behaviour for concrete Window/Frame in showValidationErrors() method:

    @Override
    public void showValidationErrors(ValidationErrors errors) {
        super.showValidationErrors(errors);
    }

Time Frame description for cron scheduling type

Time frame – if Start date is specified, Time frame defines the time window in seconds, during which the task will be launched after startDate + period * N time expires. If Time frame is not specified explicitly, it is equal to period / 2.
If Start date is not specified, Time frame is ignored, i.e. the task will be launched at any time after Period since the previous execution of the task expires.

Describe also cron scheduling with time frame

Hot deploy settings

Document how HD works:

  • Help -> Hot Deploy settings in Studio
  • Help -> Instant Hot deploy setting in Studio
  • Run ->Hot deploy conf

If Instant Hot deploy is deactivated, one can run Run ->Hot deploy conf:

If Instant Hot deploy is active:

  • Help->Instant Hot deploy settings are applied
  • files in global module are not hot deployed at all (waiting for the fix)
  • changes in services are hot deployed only from implementations, interface changes (in global) cannot be hot deployed
  • Groovy beans cannot be hot deployed (ticket)

Help -> Settings, ->Context help

The 'Instant hot deploy' checkbox allows you to turn off hot deploy.
If hot deployment is enabled, Studio dynamically updates the UI of your deployed web application as you apply or save changes to views, screens, messages or the main menu. На самом деле Instant hot deploy работает не только для UI (see above)

Run ->Hot deploy conf

Hot deploy conf runs the deployConf Gradle task which by default copies all sources of the web module into the application server's configuration directory.
The task can be configured in build.gradle if necessary. This command is usually excessive because Studio can instantly deploy changed source files of the web module if the Instant hot deploy for Web Client checkbox in the Screens section is set.

In fact: not only Web module and not all sources.

Instant hot deploy for Web Client checkbox in the Screens section - should be clarified.

UPDATE:

  1. What works:
    XML descriptors and screen controllers (including static methods), located in web and gui modules
    Middleware service implementations, located in core module

  2. What doesn't work:
    Any classes of the global module, including middleware service interfaces

  3. Other UI and middleware classes and beans, including their static methods, hot deployed ONLY IF some class from item 1 has also been changed. The reason for this is that class reloading is started by some signal: for screen controllers it is the screen reopening, for services - Studio generates special trigger file that is recognized by server and used to reload particular service class and all its dependencies.

See also https://www.cuba-platform.com/support/topic/hot-deploy-issue#comment-6654

JS Slider does not set values to state on `valueChanged` from Client

https://doc.cuba-platform.com/manual-6.6/js_library_sample.html

SliderServerComponent should have the following constructor:

    public SliderServerComponent() {
        addFunction("valueChanged", arguments -> {
            JsonArray array = arguments.getArray(0);
            double[] values = new double[2];
            values[0] = array.getNumber(0);
            values[1] = array.getNumber(1);

            getState(false).values = values;

            listener.valueChanged(values);
        });
    }

Also we have to override the following method:

    @Override
    protected SliderState getState(boolean markAsDirty) {
        return (SliderState) super.getState(markAsDirty);
    }

Multi-threading considerations for BackgroundTask#run() implementation

Add examples of safe multi-threading.

Problem:
The run() method runs in a separate thread, not in the UI thread. It must be considered in case:

  • you need to pass parameters to the task,
  • call UI components from the task,
  • use changeable variables, also used from UI thread, from the task.

Main rules:

  • Changing UI components and datasources state from run() is a bad practice that can result in mystic Vaadin and Swing errors.
  • Read and update operations for any changeable state from run() (including datasources, components, and added fields of screen controllers) must be synchronized,
  • The best practice for background tasks would be to avoid synchronization at all with the help of Platform means.

These means are:

The task is coded in functional style divided into 3 parts:

  1. Prepare task parameters - in UI thread before running the task,
  2. run() performing a continuous action in a separate thread. It uses only prepared parameters and prepares some result which serves as a class-task parameter. Multiple results can be wrapped in POJO.
  3. The task result is applied to the interface and saved in some cache-fields, performed in done(), handleException(), handleTimeout().

Passing parameters via the task constructor seems to be more type-safe than by getParams().

Example №2:

// Here:
// parameter - String searchString
// result - List<AddressSuggestion>
// state - addresses and components

@Named("searchString")
protected TextField searchStringField;
@Named("addressDs")
private CustomDatasource<GuiSuggestion> addressDs;
@Named("searchProgressBar")
private Label searchProgressBar;

protected List<AddressSuggestion> addresses;
protected BackgroundTaskWrapper<Void, List<AddressSuggestion>> backgroundTaskWrapper = new BackgroundTaskWrapper<>();

protected class AddressSearchTask extends BackgroundTask<Void, List<AddressSuggestion>> {
    private String searchString;

    public AddressSearchTask(String searchString) {
        super(30);
        this.searchString = searchString;
    }

    @Override
    public List<AddressSuggestion> run(TaskLifeCycle<Void> taskLifeCycle) {
        List<AddressSuggestion> matches = addressSearchService.search(searchString);
        return matches;
    }

    @Override
    public void canceled() {
        addresses = Collections.emptyList();
        addressDs.refresh();
        setInSearch(false);
    }

    @Override
    public void done(List<AddressSuggestion> result) {
        addresses = result;
        addressDs.refresh();
        setInSearch(false);
    }
}

protected void setInSearch(boolean inSearch) {
    searchProgressBar.setVisible(inSearch);
}

...
// call
String searchString = searchStringField.getValue();
setInSearch(true);
backgroundTaskWrapper.restart(new AddressSearchTask(searchString));

Example №2

// Пример №2
// Расчёт цены заказа в фоновом потоке
// для сложного объекта-заказа, который редактируется на форме

// Т.к. во время выполнения задачи заказ может изменяться через компоненты редактирования
//  - то нельзя передавать в задачу объект, хранящийся в датасорсе.
//  Перед запуском задачи нужно создать объект-копию заказа, для которого и будет идти расчет

    @Inject
    protected Datasource<Order> orderDs;
    @Inject
    protected ProgressBar progressBar;
    @Inject
    protected Label priceLabel;

    private class PriceCalcTask extends BackgroundTask<Void, Price> {
        private Order orderCopy;

        public PriceCalcTask(Order orderCopy) {
            super(60, frame);
            this.orderCopy = orderCopy;
        }

        @Override
        public Price run(TaskLifeCycle<Void> taskLifeCycle) {
            return priceService.calculatePrice(orderCopy);
        }

        @Override
        public void done(Price result) {
            assignPriceToOrder(orderCopy, result);
            priceLabel.setValue(result.getTotal());
            progressBar.setVisible(false);
        }

        @Override
        public boolean handleException(Exception ex) {
            showNotification("Failed to calculate price", NotificationType.WARNING);
            progressBar.setVisible(false);
            return true;
        }
    }

// вызов
progressBar.setVisible(true);
Order orderClone = deepClone(orderDs.getItem());
priceTaskWrapper.restart(new PriceCalcTask(orderClone));

Thread safety of Configuration Interfaces

Configuration interfaces may be used as middleware beans' attributes, for example:

class MyBean {

    protected  MyConfiguration myConfig;

    @PostConstruct
    public void init() {
        myConfig = configuration.getConfig(MyConfiguration.class);
    }

    public void doSomething() {
        if (myConfig.isSomePropertyEnabled()) {
            ....
        }
    }
}

Thus,

  • ConfigPersisterImpl is thead-safe,
  • Server implementation does not cache values, so it always read the newest values from ConfigStorage.

Fix integration test examples

https://doc.cuba-platform.com/manual-6.6/integration_tests_mw.html

  1. Get rid of:
  • new Customer() - creation of entities with new is dangerous and we show warning inspection in Idea
  • new ArrayList<>(Arrays.asList( - verbose, use simple Arrays.asList(
  1. There is no example of test-app.properties file, usually it contains important options:
cuba.confDir=${user.dir}/test-home/cuba/conf
cuba.logDir=${user.dir}/test-home/cuba/logs
cuba.tempDir=${user.dir}/test-home/cuba/temp
cuba.dataDir=${user.dir}/test-home/cuba/work
  1. Specify full package name for sales-app.properties, test-app.properties, since new projects always have app.properties files inside of root package

Entity states and em.merge

All newbie developers and many experienced ones don't understand the meaning of managed entity state and purpose of em.merge. For them em.merge call is "save entity changes to DB", like em.save().
Existing documentation pages (1, 2) are not enough. Too brief, people just don't get the sense without real code.

TODO: add examples, recommended scenarios, explanations of side effects.

What can be added:

  • explanation of what exactly em.merge is doing under the hood. Side effects: optimistic lock checking. When we need to use em.merge and when we don't need it. Code example of justified em.merge usage.
  • code example of em.reload usage.
  • code example for this sentence:

Any changes of the instance in Managed state will be saved to the database when the transaction that the EntityManager belongs to is committed.

Production settings

Relates to
See also

Document the recommended production settings:

  • Tomcat (local.app.properties etc),
  • production mode ON for vaadin in web.xml
  • production mode ON for REST API
  • unset auto-filled default login and password
  • (optional) if app is running under nginx, the correct version of proxy http and certain headers should be set, otherwise, websockets will not start up, and vaadin will fall into long polling (this can be detected in JS console)

The real question from a client: We want to deploy the portal app on a separate tomcat instance on a different physical server. What config needs to be set for it to know the location of the core app?

How to replace Service implementation completely

Without inheritance from base service from app component

At the moment, we have to annotate new service implementation with @service annotation and exclude this class from component-scan:

<context:component-scan base-package="com.haulmont.cuba">
    <context:exclude-filter type="regex" expression="com\.haulmont\.cuba\.web\.sys\.CustomMyServiceBean"/>
</context:component-scan>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.