{"id":41698217,"url":"https://github.com/grip-on-software/visualization-site","last_synced_at":"2026-01-24T20:55:07.179Z","repository":{"id":171609889,"uuid":"648159568","full_name":"grip-on-software/visualization-site","owner":"grip-on-software","description":"Configuration for GROS servers, templates for integrated visualization hub, tests, analytics, schema documentation and prediction API routes","archived":false,"fork":false,"pushed_at":"2024-08-05T09:06:39.000Z","size":2838,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-01T02:01:57.261Z","etag":null,"topics":["server-configuration","visualization-dashboard"],"latest_commit_sha":null,"homepage":"https://gros.liacs.nl/visualization/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grip-on-software.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-01T10:41:24.000Z","updated_at":"2024-08-05T10:03:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"f657155a-c068-4fcd-bcfc-9efd88b5369c","html_url":"https://github.com/grip-on-software/visualization-site","commit_stats":null,"previous_names":["grip-on-software/visualization-site"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/grip-on-software/visualization-site","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fvisualization-site","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fvisualization-site/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fvisualization-site/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fvisualization-site/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grip-on-software","download_url":"https://codeload.github.com/grip-on-software/visualization-site/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fvisualization-site/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28736791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T19:23:36.361Z","status":"ssl_error","status_checked_at":"2026-01-24T19:23:28.966Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["server-configuration","visualization-dashboard"],"created_at":"2026-01-24T20:55:06.272Z","updated_at":"2026-01-24T20:55:07.159Z","avatar_url":"https://github.com/grip-on-software.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GROS visualization proxy and site\n\nThis repository contains configuration files and static web files for the \nvisualization hub of the GROS project. The proxy is intended to provide access \nto a Ghost blog and Discourse forum if they are deployed within the \nenvironment, as well as to the visualization reports for the organization, \nwhich were generated using branch-based builds on a Jenkins instance.\n\nThe repository needs to be configured to work within a specific environment. \nTwo stages of reverse proxies are used to safely provide access to the GROS \nwebservers (separate Docker instances, a Jenkins setup and/or direct access). \nThe reverse proxies are as follows:\n\n- [Caddy](https://caddyserver.com/) for transparent proxy access from a BigBoat \n  dashboard. Several subinstances handle specific domain names. This is only \n  used in an environment where access has to be routed through several VLANs.\n- [NGINX](https://www.nginx.com/) for proxy access and/or static file hosting \n  from a central server listening on specific ports. It can also use Host-based \n  proxying. Complete, direct hosting is possible but may require additional, \n  separate server configuration.\n- [Apache](https://httpd.apache.org/) as an alternative to NGINX, for proxy \n  access and/or static file hosting from a central server listening on specific \n  ports. It can also use Host-based proxying. Complete, direct hosting is \n  possible but may require additional, separate server configuration.\n\nMany of the configuration files and web files use \n[Mustache](https://www.npmjs.com/package/mustache) in order to use \nconfiguration items and functions to adjust to other environments. \n\nAdditionally, this repository contains a Shell script `goaccess-report.sh` that \ncan be run periodically to generate a server statistics report. It requires \ninstallation of [GoAccess](https://goaccess.io/) which analyzes logs and \ncreates an analytics dashboard.\n\nSeparate documentation exists for more details on how the second proxy layer \nworks.\n\n## Dependencies\n\nWhile the build of the visualization site may work with simply having Docker \ninstalled, the test and production environments will need a more full-fledged \ninstallation of other dependencies.\n\nFor the tests, a Jenkins installation is assumed with proper OpenJDK Java 8+ \nand Python 3.6+ (including `distutils` and `virtualenv`). The agent that \nperforms the tests must have Docker Compose V2. In addition, tools such as \nBash, Git, `jq`, `awk`, `sed`, `grep` and `xargs` must be available and \nGNU-like (POSIX-compliant may not be enough). A SonarQube Scanner must be \nregistered in Jenkins. The server agent that performs the publishing must have \nDocker Compose V2, Node.js, `curl` and `rsync` as well. Details for configuring \nJenkins servers and agents are outside the scope of this documentation, \nalthough some details may be available in other GROS documentation. The \nintegration tests may be able to be run outside a Jenkins job, but support for \nthis is limited and it requires passing additional environment variables.\n\nThe deployment assumes an NGINX or Apache service and potentially a Docker \nCompose installation some which can be set up using (some of) the configuration \nfiles that we build from the templates in this repository.\n\n## Tests\n\nThis repository contains integration tests for the visualizations. The entire \nvisualization proxy layer setup is emulated within a `docker-compose` network, \nwith each deployed visualization within its own Docker instance running its \nNode.js development web service. A Caddy proxy pretends to be the Jenkins \nserver with access to the HTML reports and artifacts.\n\nThe tests themselves are run with a Selenium instance using a Chromium browser, \nwhich is being controlled by a Python runner. The tests are in the form of \nPython unit tests which instruct the Selenium instance to navigate to pages and \nperform actions such as clicking. The unit tests then check if certain elements \nare visible, contain certain text, or have other properties, and the test \npasses if this is the case.\n\nThe visualizations use their test builds which contain coverage tracking, which \nis extracted and combined after the test completes. In addition to coverage, \nSonar scans check for code smells, and a dependency check searches for \nvulnerabilities.\n\nAt the end of each test, more actions take place. Logs are stored and \na screenshot is made of the page, so that there is a visual reference of the \nstate of the page in case a test fails. Finally, an accessibility testing \nengine is used to verify if the contents of the page conform to various WCAG \nrules. All of these results are combined as well into a report.\n\n## Configuration\n\nThe visualization dashboard, connections to other servers as well as common \nelements such as a navigation bar, are all configured in this repository. The \nmain configuration point is usually the `config.json` file, which can be copied \nfrom `lib/config.json` to the root of the repository in order to make local \nadjustments. The following configuration items (all strings, unless noted \notherwise) are known:\n\n- `visualization_url`: The URL to the visualizations. This may include \n  a protocol and domain name, but does not need to in case all the resources \n  are hosted on the same domain. The remainder is a path to the root of the \n  visualizations, where the dashboard is found and every visualization (except \n  predictions) has sub-paths below it.\n- `prediction_url`: The URL to the prediction site. This may include \n  a protocol and domain name, but does not need to in case all the resources \n  are hosted on the same domain. The remainder is a path to the root of the \n  predictions (without any specific paths below it).\n- `base_url`: The absolute URL to the base website where other static resources \n  are located. This is used to link to the base website in the navigation bar \n  and to make certain URLs absolute like schema identifiers and canonical URLs. \n  If it is left empty, then some of those URLs will not have a protocol and \n  domain name or use the current location as base.\n- `blog_url`: The URL to the blog. This may include a protocol and domain name, \n  but does not need to in case all the resources are hosted on the same domain. \n  The remainder is a path to the root of the blog. If this is empty, then no \n  blog is available.\n- `discussion_url`: The URL to the discussion forum. This may include \n  a protocol and domain name, but does not need to in case all the resources \n  are hosted on the same domain. The remainder is a path to the root of the \n  forum. If this is empty, then no forum is available.\n- `download_url`: The URL to default download links on the dashboard. This can \n  be overwritten by specific download URLs by the visualizations and an altered \n  value may work with the redirections provided by the NGINX or Apache proxy, \n  so care should be taken when adjusting this. This may be helpful when direct \n  access to downloads are available. If this is empty, then no download links \n  are shown on the dashboard.\n- `jira_url`: URL that is used in some navigation bars to link to a Jira \n  instance.\n- `blog_host`: Domain name of an internal server where the blog is hosted.\n- `blog_server`: Domain name of an external server that provides access to the \n  blog. This name should point (possibly via a Caddy proxy) toward the NGINX or \n  Apache proxy that makes the server available.\n- `discussion_host`: Domain name of an internal server where the discussion \n  forum is hosted.\n- `discussion_server`: Domain name of an external server that provides access \n  to the discussion forum. This name should point (possibly via a Caddy proxy) \n  toward the NGINX or Apache proxy that makes the server available.\n- `visualization_server`: Domain name of an external server that provides \n  access to the visualization dashboard and every visualization (except \n  predictions). This name should point (possibly via a Caddy proxy) toward the \n  NGINX or Apache proxy that makes the server available.\n- `www_server`: Domain name of an external server that listens on a \"www\" \n  address. This server redirects to the visualization server. This name should \n  point (possibly via a Caddy proxy) toward the NGINX or Apache proxy that \n  makes the redirection service available.\n- `prediction_server`: Domain name of an external server that provides access \n  to the predictions. This name should point (possibly via a Caddy proxy) \n  toward the NGINX or Apache proxy that makes the server available.\n- `hub_organizations` (array): When multiple organizations are hosted in the \n  same environment, an array of objects containing organizations, navigation \n  data and branch names can be added to make them available cross-builds. For \n  tests, they provide a build and serve dummy data for visualizations on \n  multiple branches. The test routes only consider the `visualization-site` and \n  `prediction-site` as keys in each object, and their values should provide \n  a branch name that the `visualization_branch` and `prediction_branch` may \n  respectively point to for NGINX testing, or the branch names generated using \n  `hub_mapping` for Apache testing. The organizations objects in this array \n  also define how items in a navigation bar dropdown should appear, with \n  titles, content/alternative text locales, images (plus width/height/style \n  attributes) and external URLs. Finally, a key `visualizations` may have an \n  array value with the visualizations that the organization's hub hosts.\n- `hub_regex`: When multiple organizations are hosted in the same environment, \n  a regular expression can be used to match the organization name which must \n  occur at the start of the path, and place the matched parts into variables \n  for later use in rewrite rules of NGINX or Apache. Use `(?\u003cgroupname\u003e...)` \n  for capturing matches for compatibility across proxy servers. To avoid \n  renumbering issues, this regular expression should not contain unnamed match \n  captures `(...)`.\n- `hub_mapping` (object): Groups of environment variable names to replace the \n  matched substrings from the regular expression from `hub_regex` in. Only used \n  for Apache, when hosting multiple organizations in the same environment. \n  Group keys can be \"hub\", \"visualization\" and \"prediction\", corresponding to \n  the visualization-site itself, the visualizations and the prediction-site, \n  respectively. Each variable within the group has an object with \"input\", \n  \"default\", and \"output\" keys, which are used to build a `RewriteMap`. The \n  input and default can refer to other variables with dollar signs. The output \n  mapping cannot contain spaces or empty strings in both the keys and values. \n  In addition to the `hub_regex` variables, the \"prediction\" group may also \n  transform a `branch_organization` variable to map paths to organizations in \n  (combined) prediction setups. The mapping is also used for determining the \n  available prediction path setups on the server for the OpenAPI specification, \n  and for copying the published visualizations on master branches to the proper \n  default organizations. In NGINX, one can instead alter variables captured \n  from regular expressions using `hub_branch`, `visualization_branch` and \n  `prediction_branch`.\n- `branch_maps_path`: Filesystem path where the rewrite maps for the Apache \n  configuration are expected to reside. The map files are written to \n  `httpd/maps` in this repository, but may be mapped to another absolute path. \n  This affects the path within the Docker instance during the `docker-compose` \n  paths, but can also be helpful when using (portions of) the configuration on \n  an Apache server.\n- `hub_redirect`: When multiple organizations are hosted in the same \n  environment, variables from a matched organization at the start of the path \n  using `hub_regex` can be used in a rewrite that redirects to another URL. It \n  is assumed that this configuration value produces an absolute URL. For NGINX, \n  use dollar-sign variables; for Apache, use environment variables named with \n  `hub_mapping` with `%{...}` syntax.\n- `hub_branch`: Inject some processing steps in the NGINX configuration for the \n  visualizations hub. This should at least determine the branch of a Jenkins \n  build to use for the visualization site. When multiple organizations are \n  hosted in the same environment, variables from a matched organization at the \n  start of the path using `hub_regex` can be used in further processing.\n- `visualization_branch`: Inject some processing steps in the NGINX \n  configuration for a visualization. This should at least determine the branch \n  of a Jenkins build to use for a visualization. When multiple organizations \n  are hosted in the same environment, variables from a matched organization at \n  the start of the path using `hub_regex` can be used in further processing.\n- `prediction_branch`: Inject some processing steps in the NGINX configuration \n  for the prediction site. This should at least determine the branch of \n  a Jenkins build to use for the visualization or prediction site. When \n  multiple organizations are hosted in the same environment, variables from \n  a matched organization at the start of the path using `hub_regex` can be used \n  in further processing.\n- `jenkins_host`: Domain name of an internal server where the Jenkins build \n  system is hosted.\n- `jenkins_path`: Path that the Jenkins build system is hosted below. This is \n  useful in situations where Jenkins is hosted on the same domain as other \n  resources and is therefore within a path rather than directly at the root of \n  a domain.\n- `jenkins_direct`: Filesystem path of a location where a copy of the \n  visualizations and predictions are available. If this is not empty, the \n  structure within the path must follow that which the `copy.sh` script makes \n  and supported requests are internally rewritten to this path. If this is \n  empty, then requests for visualizations and predictions are proxied to the \n  Jenkins server.\n- `jenkins_direct_url`: URL through which the Jenkins server is available from \n  the location of the build (a Jenkins node with the 'publish' tag, most likely \n  the server itself), when the visualizations and predictions are copied.\n- `jenkins_direct_cert`: Filesystem path to a certificate used for validating \n  a HTTPS connection to the Jenkins server, when the visualizations and \n  predictions are copied (for branch information).\n- `jenkins_api_token`: Encrypted token that can be used for basic authorization \n  against the Jenkins API for at least branch details of builds.\n- `files_host`: Domain name of an internal server where an ownCloud instance is \n  hosted.\n- `files_share_id`: Identifier of a published share on an ownCloud instance \n  with files that are made available in addition to the prediction resources. \n  If this is an empty string, then the paths to the files list and specific \n  files are not passed through to ownCloud from the NGINX or Apache proxy.\n- `control_host`: Domain name of an internal server where secure resources are \n  hosted, including encryption services and access control checks. This domain \n  must be accessible through HTTPS from the NGINX or Apache proxy. This can be \n  set to an empty string to disable proxy connections to endpoints for \n  encrypting names of developers and checking project group access, as used in \n  some visualizations. An empty string also makes the Caddy proxy configuration \n  unusable, so only leave this empty if a portion of the configuration is used.\n- `websocket_server`: Domain name of an external server where a WebSocket for \n  real-time updates of access log analytics is hosted. This name should point \n  (possibly via a Caddy proxy) toward the NGINX or Apache proxy that makes the \n  WebSocket service available (via the GoAccess script).\n- `proxy_nginx` (boolean): Whether to use NGINX to provide access to the other \n  servers or host the direct files. If set to false, use Apache HTTP Server \n  instead. Affects the test as well as which configuration is generated.\n- `proxy_range`: CIDR range of trusted IP addresses that may host the first \n  layer of proxies in front of the NGINX or Apache proxy, for example the Caddy \n  proxies. Requests from these addresses may provide headers with the real IP \n  address of the original request, which are used instead of the proxy's IP \n  address.\n- `proxy_port_in_redirect` (boolean): Whether to make the NGINX or Apache proxy \n  specify the port number when a redirect is generated. If a Caddy proxy is in \n  front of it, then this is most likely not wanted. Similarly, if only portions \n  of the configuration files are used, then this is also not useful to enable.\n- `auth_cert`: Filesystem path to a certificate used for validating the HTTPS \n  connection to the `control_host`. If a `$SERVER_CERTIFICATE` environment is \n  not set, then this is also used as the path on the Docker host machine during \n  the `docker-compose` tests to provide this path within the Docker instance.\n- `allow_range` (array): CIDR ranges of IP addresses that are allowed to access \n  the access log analytics.\n- `goaccess_path`: Filesystem path to the location where the GoAccess interface \n  is hosted. The directory should contain an `analytics` subpath which holds \n  the actual web interface. This can be set to an empty string to disable the \n  GoAccess endpoint.\n- `goaccess_log_path`: Filesystem path to log file location. Access logs stored \n  in this path (including rotated and possibly GZip-encoded logs) are followed.\n- `swagger_openapi_url`: URL prefix to use for the OpenAPI specification files \n  that are made available in the Swagger UI. The default value of `./` works \n  well for the Docker instance, but if the OpenAPI files are meant to be stored \n  elsewhere then another path is possible. For production builds of a static \n  file hosting setup with `jenkins_direct`, this value is set to the absolute \n  path of the direct hosting root, and additional OpenAPI files rather than \n  just the prediction API are made available.\n- `swagger_validator_url`: URL to use to connect to the validator. The default \n  value of `/validator` works well for the Docker compose network. If it is set \n  to an empty string, then the online validator is used. Can be set to `none` \n  to disable the validator. For production builds of a static file hosting \n  setup with `jenkins_direct`, we use the online validator.\n\nConfiguration items that have keys ending in `_url` may be processed to direct \ntoward an organization-specific path, in case multiple organizations are hosted \nin the same environment. The value is searched for the substring \n`$organization`, possibly after slashes. These can be replaced with the actual \norganization that the build is for. In some cases, it is removed only to allow \nNGINX or Apache rules to add a supported variant of it in front of the path \nusing `hub_regex`, and in other cases, it may be preserved to be adjusted at \na later moment within the visualization or hub. Specific [environment \nvariables](#environment-variables) determine how the substring `$organization` \nis replaced.\n\nNote that configuration items that have keys ending in `_host` or `_server` may \nbe set to \"fake\" values when only a portion of the final NGINX or Apache \nconfiguration is actually used, for example when some resources are not made \navailable. The configuration values should still be set to valid domain names \nso that they can be used within the `docker-compose` network during the tests.\n\n### Environment variables\n\nSeveral environment variables may be used when calling `npm run` or the Shell \nscripts, and may affect various contexts, such as resource paths in the HTML \npages, the JavaScript-based navigation bar, the proxy server configuration and \nthe test environment. Boolean environment variables must be set to `true` in \norder to take effect.\n\n- `$VISUALIZATION_ORGANIZATION`: Determines the organization to use within the \n  URLs defined in the configuration.\n- `$VISUALIZATION_COMBINED` (boolean): Determines whether to replace the \n  organization within the URL with `/combined`.\n- `$NAVBAR_SCOPE`: Determines the navigation bar override file to use. If the \n  file `navbar.$NAVBAR_SCOPE.js` exists, then it is loaded in place of the \n  generated `navbar.json` file. See [files](#files) for more details.\n- `$VISUALIZATION_ANONYMIZED` (boolean): Determines whether to show \n  a notification on the HTML page indicating that the visualizations contain \n  anonymized data and that some functionality is limited or missing.\n- `$VISUALIZATION_SITE_CONFIGURATION`: Path to the main configuration file, \n  defaulting to `config.json`. If this file does not exist, then \n  `lib/config.json` is used.\n- `$PREDICTION_CONFIGURATION`: Path to the configuration file of the \n  `prediction-site` visualization, which is then used during tests. By default, \n  the prediction's default configuration is used, which may be incompatible in \n  some complex combined/organization setups. Other visualizations are tested \n  with default configuration.\n- `$VISUALIZATION_NAMES`: Optional space-separated list of repository names of \n  visualizations (excluding `visualization-site` itself) that should be \n  included in the navigation bar, proxy configuration, test environment setup, \n  and publishing phase. By default, all visualizations listed in the file \n  `visualizations.json` are considered.\n- `$VISUALIZATION_MAX_SECONDS` (integer): Number of seconds to wait before are \n  visualizations are compiled and made available during the test setup. By \n  default, 60 seconds is allocated, which may be too short for some nodes.\n- `$REPO_ROOT`: Directory to store the Git repositories of the visualizations \n  during the test setup. Relative to the current directory. By default, `repos` \n  is created as a subdirectory. If another directory is used, then existing \n  clones are left as-is with no up-to-dateness checks and dependencies are \n  backed up so that they do not interfere with the test setup.\n- `$SERVER_CERTIFICATE`: Path to the HTTPS certificate to use in the test setup \n  when requesting upstream resources for encryption and access checks. By \n  default, this is the `auth_cert` from the configuration, but this can be set \n  to use a different path at the host device than in the Docker test setup.\n- `$PUBLISH_PRODUCTION`: A boolean variable which indicates whether to perform \n  a copy for potential publication from the current feature branch instead of \n  only doing so when on a main branch. Note that main branches are skipped in \n  this case, so the publication may not have organization-specific paths.\n- `$JENKINS_HOME`: Provided by \n  [Jenkins](https://www.jenkins.io/doc/book/managing/system-properties/#jenkins_home) \n  and used by the `copy.sh` script as the root from which to collect artifacts \n  and visualization HTML reports for publishing.\n- `$BRANCH_NAME`: Provided by [Jenkins Multibranch \n  Pipeline](https://www.jenkins.io/doc/book/pipeline/multibranch/#additional-environment-variables) \n  and used by the test environment in order to separate Docker resources when \n  building dependencies for visualizations under test.\n- `$BUILD_NUMBER`, `$BUILD_TAG`, `$BUILD_URL`, `$NODE_NAME`: Provided by \n  [Jenkins](https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables) \n  and used by the test environment in order to track build context for \n  reporting and naming purposes.\n\n### Files\n\nWhereas the configuration file, usually located at `config.json`, is likely \nnecessary to be copied (from `lib/config.json`) and changed, there are other \nfiles within the repository that can be modified to adjust what is available on \nthe visualization site. We will briefly introduce these files, as adjustments \nshould be considered more like code changes.\n\nThe navigation bar is configured in `navbar.json.mustache`, with optional \ncontextual overrides in `navbar.$NAVBAR_SCOPE.js`. The format is defined in the \n`@gros/visualization-ui` package for the `Navbar` class, with the addition that \nURLs can have `$organization` substrings replaced, and various Mustache \noperations can take place to fill the navigation bar with menus/links defined \nelsewhere, such as visualizations and organizations. `navbar.$NAVBAR_SCOPE.js` \nshould, if used, refer to `navbar.json` and use simple JavaScript operations to \naugment it, though the use of this file may not be necessary when specifics for \nan organization can be set by changing other files, such as `config.json` and \n`visualizations.json`.\n\nThe available visualizations are configured in `visualizations.json`. The \nstructure is based on the layout of the dashboard, but the items defined in it \nalso determine which visualizations are actually made available in the \nnavigation bar, proxy server configuration as well as within the tests. The \nJSON object is used as a Mustache structure within the index template and the \nnavigation bar, and so they may contain Mustache items to refer to certain\nconfiguration items, such as URLs.\n\nLocalization of the visualization site is in `lib/locales.json`. The messages \nin it are used when referred from JavaScript code using the `Locales` class \nfrom the `@gros/visualization-ui` package, or when using the `data-message` \nattribute within the HTML templates.\n\n## Running\n\nThe visualization can be built using Node.js and `npm` by running `npm install` \nand then either `npm run watch` to start a development server that also \nrefreshes browsers upon code changes, or `npm run production` to create \na minimized bundle. The resulting HTML, CSS and JavaScript is made available in \nthe `www` directory.\n\nAs mentioned in the [dependencies](#dependencies), this repository also \ncontains a `Dockerfile` specification for a Docker image that can perform the \ninstallation of the app and dependencies, which allows building the \nvisualization site within there, removing the need for a global Node.js \ninstallation. The `Jenkinsfile` contains appropriate steps for a Jenkins CI \ndeployment, including the tests, visualization building and publishing.\n\nDuring the build, JavaScript in order to construct a common navigation bar is \nseparated from the main JavaScript bundle in `vendor.js`. The visualizations \nand prediction site also refer to this file to display the navigation bar.\n\nA non-static production environment can make use of the generated proxy server \nconfiguration in order to deploy the reverse proxy layer(s) that allow access \nto all the visualizations and other resources. Optionally, the `caddy` docker \ncompose file can be set up. Next, either the main `nginx.conf` plus the files \ngenerated in the `nginx` directory can be supplied to the NGINX service, or \nlikewise with `httpd.confg` and the generated files in the `httpd` directory \nfor the Apache service. Alternatively, a subset of these files may be used, for \nexample to host all under one domain, with additional local configuration.\n\nDocumentation based on JSON schema specification files from various GROS \nrepositories can be built with the `doc` directory. This requires installing \nthe some Python dependencies, preferably first setting up a `virtualenv`, then \nrunning `pip install -r doc/requirements.txt`. The file `doc/source/conf.py` \ncontains configuration for the documentation, including paths or URLs to the \nschema files, which can be altered to use local paths. When run on the Jenkins \nserver to create static documentation, these paths may be defined through the \n`doc.sh` script which locates the JSON schemas as part of archives and modules \navailable in the current workspace and beyond.\n\nA static production environment can make use of the result of the Bash script \n`copy.sh` when run on the Jenkins server in order to create a document root \ndirectory with the organizational hubs, all the visualizations, JSON schemas, \nOpenAPI specifications and Swagger UI available for publishing on a static file \nhosting server. This server may make use of the NGINX or Apache configurations, \nwhich in their compiled form properly route the prediction site and error \npages, among others. Like other parts, the `copy.sh` script requires specific \n[configuration](#configuration) for mapping hub paths, selecting organizations, \nproducing paths and URLs and accessing Jenkins for the publishable \nvisualizations, archived files and prediction branches.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrip-on-software%2Fvisualization-site","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrip-on-software%2Fvisualization-site","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrip-on-software%2Fvisualization-site/lists"}