= oVirt Dashboard

== Introduction

This project contains http://www.ovirt.org/[oVirt]
http://www.ovirt.org/develop/release-management/features/ux/uiplugins/[UI plugin]
that gives overview of the virtualized environment and its specific objects.

This plugin is installed during oVirt Engine installation and upgraded via `engine-setup`.
This means no manual steps are required in order to install this plugin in production env.

== Setting up development environment

=== Prerequisites

Install https://nodejs.org/[Node.js] (LTS) based on the version specified in
`automation/build.packages` (used when building the project in oVirt CI system).

https://github.com/creationix/nvm[nvm] can be used to manage multiple Node.js versions.

Run `node -v` to check the current Node.js version.

Build and configure oVirt Engine according to its
https://gerrit.ovirt.org/gitweb?p=ovirt-engine.git;a=blob_plain;f=README.adoc;hb=master[developer instructions].

=== Dashboard setup

* `yarn install` to install dependencies
* `yarn test` to run tests (single run)
* `yarn run test:watch` for continuous testing (watch & rerun tests on change)
* `yarn run dev` for development build and watch & recompile files on change
* `yarn run build` for production build

=== Engine setup

Symlink plugin resources to `ui-plugins` directory as following:

  cd ${PREFIX}/share/ovirt-engine/ui-plugins/
  ln -s ${PLUGIN_HOME}/dist/dashboard.json dashboard.json
  ln -s ${PLUGIN_HOME}/dist/dashboard-resources dashboard-resources

=== Accessing plugin

Open WebAdmin in your browser, you should land on *Dashboard* main tab automatically:

  https://engine.example:8443/ovirt-engine/webadmin/WebAdmin.html

== Internationalization and Localization

=== Introduction

The oVirt Dashboard project has the ability to render in different languages.  Internally, the
`msg` object in `intl-messages.js` holds all of the localizable keys and exposes them as
functions.  The `msg` object also wraps all of the localized translations loaded from
`intl/translations.json` and uses a localized version of each key as required.

The current locale used by the `intl.js` formatting functions is provided to the application
via the `app-init.js` service and the oVirt UI plugin API.

We use the https://translate.zanata.org/[Zanata] tool to manage translations.

=== Translation Workflow

Generally, the project is made localizable and is translated in the following workflow:

* Developers import from `intl-messages.js`, create their code and use the `msg` object to both access and format text messages
* As needed, keys are added to `intl-messages.js` and accessed as a function of the `msg` object
* When the strings are stable, the messages are converted to a GNU gettext .pot file
* The .pot file is pushed to Zanata
* Translators do their work for each supported language within the
  https://translate.zanata.org/project/view/ovirt-engine-dashboard[dashboard's Zanata project]
* When translations are complete, the localized strings are pulled from Zanata as a set of GNU gettext .po files
* The .po files are converted to a JSON file, specifically `intl/translations.json`
* The JSON file is referenced in `intl.js`, providing localized messages to the `msg` object in `intl-messages.js`
* Rebuilding the project will make the updated translations available for use

=== Zanata Setup

Setup your Zanata configurations in the usual way.  See
http://docs.zanata.org/en/release/client/[Zanata's client setup documentation] for specific details.

=== Commands

==== Push current English source strings to Zanata

Pushing the current English sources will update the project on Zanata.  Any strings that have been
added, changed or deleted will be shown as such in the Zanata UI.  Here is the set of commands to
push the changes:

 % yarn run intl:extract
 % yarn run intl:push-all

Alternatively, use the explicit `zanata-cli` command to control which locale you want to push:

 % yarn run intl:extract
 % cd intl
 % zanata-cli push --push-type source --locales de,es,fr,it,ja,ko,pt-BR,zh-CN


==== Pull updated translations from Zanata

To properly pull and update from Zanata, the source JSON and POT files must exist.  This is done by
running the `intl:extract` script.  Standard zanata CLI pulls the data down as PO files.  The PO
files get converted into a single JSON file containing translations for all locales.  This JSON
file needs to be normalized for git diff sanity.

 % yarn run intl:extract
 % yarn run intl:pull-all
 % yarn run intl:apply
 % yarn run intl:normalize

Alternatively, use the explicit `zanata-cli` command to control which locales you want to pull:

 % yarn run intl:extract
 % cd intl
 % zanata-cli pull --pull-type trans --locales de,es,fr,it,ja,ko,pt-BR,zh-CN
 % cd ..
 % yarn run intl:apply
 % yarn run intl:normalize

== Instructions for maintainers

=== Managing dependencies

Dependencies not related to production build (not needed for `yarn run build`)
should go into `devDependencies`. Try to keep as few `dependencies` as possible.

Whenever `dependencies` are changed:

* submit patch for https://gerrit.ovirt.org/#/q/project:ovirt-engine-nodejs-modules[ovirt-engine-nodejs-modules]:
** bump the `Release` number
** merge the patch, this triggers `ovirt-engine-nodejs-modules` RPM build
* update `automation/build.packages` according to the new RPM version

=== Package versioning

* alpha and beta builds (pre-releases): `x.y.z-0.N` where version stays the same
* RC and GA builds (releases): `x.y.z-N` where version grows between releases

`version` in `package.json` is reflected into the RPM `x.y.z` version.

=== Release process

Only covers release builds (RC and GA).

==== Stable branches

To create new stable branch:

. create new branch via https://gerrit.ovirt.org/#/admin/projects/ovirt-engine-dashboard,branches[Gerrit]
. rebase on top of the newly created branch
. ensure that `automation/build.repos` contains proper repos (avoid `master` repos)

Then, update the master branch:

* submit patch with following changes:
** `package.json` - bump `version`
** `packaging/spec.in` - reset `Release` number to `0.1` and update `%changelog`

Finally, update CI job config:

* submit patch for https://gerrit.ovirt.org/#/q/project:jenkins[jenkins]:
** in `jobs/confs/projects/ovirt-engine-dashboard/ovirt-engine-dashboard_standard.yaml`,
   ensure that `version` contains proper Engine version to corresponding Dashboard stable
   branch mapping

==== Releases

To perform new release:

. switch to appropriate stable branch
. submit patch that prepares the branch for release:
.. `package.json` - ensure proper `version` (e.g. bump `.z` component)
.. `packaging/spec.in` - ensure proper `Release` number and update `%changelog`
. pull changes from remote
. tag release-prep patch and push the tag to remote:
.. `git tag -a <tag-name>`
.. `git push origin <tag-name>`
. trigger CI build on release-prep patch
. update oVirt release config in `releng-tools` repo

Tag name example: `ovirt-engine-dashboard-1.0.0-1`

=== Building RPM

To build RPM from an open patch, just post `ci please build` comment on Gerrit. See
https://www.ovirt.org/blog/2016/12/ci-please-build/[this blog post] for details on this CI feature.

Alternatively, RPM can be built locally using
http://ovirt-infra-docs.readthedocs.io/en/latest/CI/Build_and_test_standards.html#testing-the-scripts-locally[mock_runner].
