Commit aab9b002 authored by ext.sopra.ncastejon's avatar ext.sopra.ncastejon
Browse files

Merge branch 'development' into ign-raster

parents 47bc2078 d0321325
stages:
# - test
- sonar-analysis
- build
- deploy
- post-deploy
variables:
SONAR_URL: https://sonarqube.forge.grandlyon.com
......@@ -14,6 +13,24 @@ variables:
# script:
# - docker-compose -f docker-compose-development.tests.yml build
code_analysis:
stage: sonar-analysis
only:
- master
before_script:
- export PATH=$PATH:/usr/local/bin/sonar-scanner-3.2.0.1227-linux/bin/
- export NODE_PATH=$NODE_PATH:`npm root -g`
script:
- >
sonar-scanner
-Dsonar.projectName=${SONAR_PROJECT_KEY}
-Dsonar.projectVersion=1.0
-Dsonar.sourceEncoding=UTF-8
-Dsonar.projectBaseDir=.
-Dsonar.host.url=${SONAR_URL}
-Dsonar.projectKey=${SONAR_PROJECT_KEY}
-Dsonar.login=${SONAR_TOKEN}
build_development:
stage: build
tags:
......@@ -22,12 +39,13 @@ build_development:
- development
- refacto
script:
- export TAG=dev
- export NGINX_PORT=8081
- export CONFIG_FILE_PATH=./config/config.json
- docker-compose build --build-arg conf=dev nginx-app
- export TAG=$CI_COMMIT_SHORT_SHA
- echo ${TAG}
- export WEB_APP_BIND_PORT=8081
- docker-compose build --build-arg conf=dev web-app
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker-compose push
- "curl -X POST -F token=$CI_JOB_TOKEN -F ref=master -F variables[TAG]=${TAG} https://forge.grandlyon.com/api/v4/projects/310/trigger/pipeline"
build_release:
stage: build
......@@ -35,69 +53,10 @@ build_release:
- build
only:
- tags
# except:
# - /^(?!master).+@/
script:
- export TAG=$(echo $CI_COMMIT_TAG | sed 's/v//g')
- export NGINX_PORT=8081
- export CONFIG_FILE_PATH=./config/config.json
- docker-compose build --build-arg conf=prod nginx-app
- echo ${TAG}
- export WEB_APP_BIND_PORT=8081
- docker-compose build --build-arg conf=prod web-app
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker-compose push
deploy_development:
stage: deploy
only:
- development
- refacto
script:
- export TAG=dev
- export NGINX_PORT=8081
- export MATOMO_SITE_ID=1
- export MATOMO_SERVER_URL=https://matomo-intothesky.alpha.grandlyon.com
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- docker-compose pull
- export CONFIG_FILE_PATH=./config/config-dev.json
- docker-compose --project-name portail-data-${TAG} up -d --force-recreate
environment:
name: development
url: https://data-reloaded-dev.alpha.grandlyon.com
deploy_staging:
stage: deploy
only:
- development
when: manual
script:
- export TAG=staging
- export NGINX_PORT=8080
- export MATOMO_SITE_ID=3
- export MATOMO_SERVER_URL=https://matomo-intothesky.alpha.grandlyon.com
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
- TAG=dev docker-compose pull
- docker tag $CI_REGISTRY/web-et-numerique/web-et-numerique-internet/data.grandlyon.com/web-portal/components/custom-apps/web-app:dev $CI_REGISTRY/web-et-numerique/web-et-numerique-internet/data.grandlyon.com/web-portal/components/custom-apps/web-app:${TAG}
- docker push $CI_REGISTRY/web-et-numerique/web-et-numerique-internet/data.grandlyon.com/web-portal/components/custom-apps/web-app:${TAG}
- export CONFIG_FILE_PATH=./config/config-rec.json
- docker-compose --project-name portail-data-${TAG} up -d --force-recreate
environment:
name: staging
url: https://data-reloaded-rec.alpha.grandlyon.com
code_analysis:
stage: post-deploy
only:
- development
before_script:
- export PATH=$PATH:/usr/local/bin/sonar-scanner-3.2.0.1227-linux/bin/
- export NODE_PATH=$NODE_PATH:`npm root -g`
script:
- >
sonar-scanner
-Dsonar.projectName=${SONAR_PROJECT_KEY}
-Dsonar.projectVersion=1.0
-Dsonar.sourceEncoding=UTF-8
-Dsonar.projectBaseDir=.
-Dsonar.host.url=${SONAR_URL}
-Dsonar.projectKey=${SONAR_PROJECT_KEY}
-Dsonar.login=${SONAR_TOKEN}
# Stage 0, based on Node.js, to build and compile Angular
FROM node:8.10.0 as builder
FROM node:12.13.0 as builder
WORKDIR /app
......
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
# You can see what browsers were selected by your queries by running:
# npx browserslist
> 0.5%
last 2 versions
Firefox ESR
not dead
not IE 9-11 # For IE 9-11 support, remove 'not'.
\ No newline at end of file
{
"backendUrls": {
"organizations": "/api/organizations",
"resources": "/api/resources",
"changelog": "/api/changelog",
"credits": "/api/credits/credits",
"auth": "/api/authentication/",
"middlewareLegacyAuth": "/api/middleware-legacy/",
"email": "/api/email",
"matomo": "/api/analytics/pageStats",
"elasticsearch": "/api/es-consumer-aware",
"catalogue": "/api/catalogue",
"reuses": "/api/reuses/reuses",
"wms": "https://data-reloaded-dev.alpha.grandlyon.com/api/services/wms",
"mvt": "https://data-reloaded-dev.alpha.grandlyon.com/api/services/mvt",
"geocoder": "https://download.data.grandlyon.com/geocoding/photon",
"seo": "/share"
},
"theFunctionalitiesInterruptor": {
"credits": true,
"reuses": true,
"partners": true
}
}
\ No newline at end of file
{
"backendUrls": {
"organizations": "/api/organizations",
"resources": "/api/resources",
"changelog": "/api/changelog",
"credits": "/api/credits/credits",
"auth": "/api/authentication/",
"middlewareLegacyAuth": "/api/middleware-legacy/",
"email": "/api/email",
"matomo": "/api/analytics/pageStats",
"elasticsearch": "/api/es-consumer-aware",
"catalogue": "/api/catalogue",
"reuses": "/api/reuses/reuses",
"wms": "https://data-reloaded-rec.alpha.grandlyon.com/api/services/wms",
"mvt": "https://data-reloaded-rec.alpha.grandlyon.com/api/services/mvt",
"geocoder": "https://download.data.grandlyon.com/geocoding/photon",
"seo": "/share"
},
"theFunctionalitiesInterruptor": {
"credits": true,
"reuses": true,
"partners": true
}
}
\ No newline at end of file
version: "3"
services:
nginx-app:
web-app:
restart: unless-stopped
build: .
image: registry.forge.grandlyon.com/web-et-numerique/web-et-numerique-internet/data.grandlyon.com/web-portal/components/custom-apps/web-app:${TAG}
volumes:
- ./nginx.conf.template:/etc/nginx/nginx.conf.template
- ${CONFIG_FILE_PATH}:/usr/share/nginx/html/assets/config/config.json
- ${CONFIG_FILE_PATH}:/usr/share/nginx/html/en/assets/config/config.json
ports:
- ${NGINX_PORT}:8080
- ${WEB_APP_BIND_PORT}:8080
command: >
/bin/sh -c
'sed "s#<MATOMO_SITE_ID>#$MATOMO_SITE_ID#g; s#<MATOMO_SERVER_URL>#$MATOMO_SERVER_URL#g" /etc/nginx/nginx.conf.template
......
This diff is collapsed.
{
"name": "webapp",
"version": "2.4.0",
"version": "2.5.0",
"license": "MIT",
"scripts": {
"ng": "ng",
......@@ -21,16 +21,15 @@
},
"private": true,
"dependencies": {
"@angular/animations": "7.2.4",
"@angular/animations": "8.2.14",
"@angular/cdk": "^7.3.1",
"@angular/common": "7.2.4",
"@angular/compiler": "7.2.4",
"@angular/core": "7.2.4",
"@angular/forms": "7.2.4",
"@angular/http": "7.2.4",
"@angular/platform-browser": "7.2.4",
"@angular/platform-browser-dynamic": "7.2.4",
"@angular/router": "7.2.4",
"@angular/common": "8.2.14",
"@angular/compiler": "8.2.14",
"@angular/core": "8.2.14",
"@angular/forms": "8.2.14",
"@angular/platform-browser": "8.2.14",
"@angular/platform-browser-dynamic": "8.2.14",
"@angular/router": "8.2.14",
"@turf/centroid": "^5.1.5",
"@turf/helpers": "^6.1.4",
"angulartics2": "^7.5.2",
......@@ -50,22 +49,22 @@
"ngx-cookie-service": "^2.2.0",
"ngx-infinite-scroll": "^6.0.1",
"node-rsa": "^1.0.3",
"rxjs": "^6.4.0",
"rxjs": "^6.5.4",
"xml2js": "^0.4.19",
"zone.js": "^0.8.29"
"zone.js": "~0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "^0.13.1",
"@angular/cli": "^7.3.1",
"@angular/compiler-cli": "7.2.4",
"@angular/language-service": "7.2.4",
"@angular-devkit/build-angular": "~0.803.23",
"@angular/cli": "^8.3.23",
"@angular/compiler-cli": "8.2.14",
"@angular/language-service": "8.2.14",
"@types/file-saver": "^2.0.1",
"@types/jasmine": "^2.8.12",
"@types/jasminewd2": "^2.0.6",
"@types/jwt-decode": "^2.2.1",
"@types/mapbox-gl": "^1.6.0",
"@types/node": "^6.14.2",
"codelyzer": "^4.5.0",
"codelyzer": "^5.0.1",
"jasmine-core": "~2.8.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "^4.0.0",
......@@ -83,7 +82,7 @@
"ts-node": "~4.1.0",
"tslint": "^5.12.1",
"tslint-config-airbnb": "^5.11.1",
"typescript": "3.2.4",
"typescript": "3.5.3",
"webpack-bundle-analyzer": "^3.1.0"
}
}
[![pipeline status](https://forge.grandlyon.com/web-et-numerique/web-et-numerique-internet/data.grandlyon.com/web-portal/components/custom-apps/web-app/badges/development/pipeline.svg)](https://forge.grandlyon.com/web-et-numerique/web-et-numerique-internet/data.grandlyon.com/web-portal/components/custom-apps/web-app/commits/development)
# Web app
[![Quality Gate Status](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=data.grandlyon.com_custom-apps_web-app&metric=alert_status)](https://sonarqube.forge.grandlyon.com/dashboard?id=data.grandlyon.com_custom-apps_web-app)
## Installation and usage
[![Maintainability Rating](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=data.grandlyon.com_custom-apps_web-app&metric=sqale_rating)](https://sonarqube.forge.grandlyon.com/dashboard?id=data.grandlyon.com_custom-apps_web-app)
The interface has been developed with the Angular framework, so you need to have Node.js installed on your machine in order to run the web application.
Once you have Node.js installed you need to install the Angular CLI. Open a command line and run:
[![Security Rating](https://sonarqube.forge.grandlyon.com/api/project_badges/measure?project=data.grandlyon.com_custom-apps_web-app&metric=security_rating)](https://sonarqube.forge.grandlyon.com/dashboard?id=data.grandlyon.com_custom-apps_web-app)
\ No newline at end of file
```bash
npm install -g @angular/cli
```
### Configuration
Open the /src/assets/config/config.json file and update the configuration in order to match yours.
### Run the web application
Using the Angular CLI:
```bash
ng serve
```
Using the npm script (which use the Angular CLI):
```bash
npm run start
```
### Build the application
We defined in the package.json two scripts that can build the application. One that generates an optimized build and the other an unoptimized build. The optimized build takes longer than the normal one.
Those two scripts contain an option --max_old_space_size=\<nb of max RAM octets the node process can take\>. Make sure the number does not exceed your RAM capacity (you can simply remove the option, it will use the default value: 512mb on 32-bit systems and 1gb on 64-bit systems). By incrising the node process memory limit we decrease the build time.
For development environment (not optimized)
```bash
npm run build-i18n:dev
```
For production environment (optimized)
```bash
npm run build-i18n:prod
```
### Build and deploy with Docker
The related files are:
* docker-compose.yml which indicates what Dockerfile should be used, what image is going to be build, volumes, exposed port...
* Dockerfile which describe the steps to build the docker image.
Some environment variables need to be set before building or running the image. Use the appropriate command to set those variables: SET on Windows, export on Linux.
```bash
export TAG=<version>
export WEB_APP_BIND_PORT=<port the application should be running on>
export MATOMO_SITE_ID=<the id of your site in matomo>
export MATOMO_SERVER_URL=<the of your matomo running instance>
```
Then to build the image run:
```bash
docker-compose build --build-arg conf=prod web-app #you can change prod to dev if you don't want an optimized build
```
Once the image is built on your machine, run the following command to start a container:
```bash
docker-compose --project-name web-app up
```
......@@ -211,11 +211,8 @@
<input id="consent" class="is-checkradio" type="checkbox" formControlName="consent">
<label for="consent" class="label consent-label checkbox-label">
<p>
<span i18n="@@consent.partOne">By checking this box, I accept the</span><a i18n="@@consent.partTwo"
[routerLink]="['/', AppRoutes.cgu.uri]"> general terms of use </a>
<span i18n="@@consent.partThree">and the processing of the information entered in this form to respond
to
my request.</span><span class="required-field">*</span>
<span i18n="@@consent.withoutCGU">By checking this box, I accept the processing of the information
entered in this form to respond to my request.</span><span class="required-field">*</span>
</p>
</label>
<p class="consent-text" i18n="@@consent.text">
......
import { Component, OnInit } from '@angular/core';
import { AppRoutes } from '../../../routes';
import { CookieService } from 'ngx-cookie-service';
import { AppRoutes } from '../../../routes';
@Component({
selector: 'app-cookie-banner',
......@@ -21,6 +21,7 @@ export class CookieBannerComponent implements OnInit {
this.cookiesAcceptedKey, // Key
'true', // Value
new Date(new Date().setFullYear(new Date().getFullYear() + 1)), // Expiration date now + 1 year
'/',
);
}
......
<div class="feedback-component-container" [ngClass]="{'on-home-page': isHomePage}"
(clickOutside)="closeFeedbackFromClickOutside()">
<button tabindex="0" class="feedback-button" (click)="toogle()" aria-label="Your feedback..."
i18n-aria-label="@@feedback.giveYourFeedback"
[ngClass]="{'expended': isExpended, 'closed': shouldAnimateClosing}">
i18n-aria-label="@@feedback.giveYourFeedback" [ngClass]="{'expended': isExpended, 'closed': shouldAnimateClosing}">
<svg xmlns="http://www.w3.org/2000/svg" id="feedback_x5F_icon" viewBox="0 0 37.2 34">
<path
d="M11 26c-.7 2.3-2.3 4.9-5.5 7.2 5.7 0 10.1-2.9 12.9-5.8h.3c9.7 0 17.5-5.9 17.5-13.2C36.2 6.8 28.4 1 18.7 1S1.2 6.8 1.2 14.1c0 5.2 4 9.7 9.8 11.9z"
......@@ -97,11 +96,8 @@
[tabindex]="isExpended ? 0 : -1">
<label for="consent-feedback" class="label checkbox-label feedback-consent">
<p>
<span i18n="@@consent.partOne">By checking this box, I accept the</span><a i18n="@@consent.partTwo"
[routerLink]="['/', AppRoutes.cgu.uri]" [tabindex]="isExpended ? 0 : -1"> general terms of use </a>
<span i18n="@@consent.partThree">and the processing of the information entered in this form to respond
to
my request.</span><span class="required-field">*</span>
<span i18n="@@consent.withoutCGU">By checking this box, I accept the processing of the information
entered in this form to respond to my request.</span><span class="required-field">*</span>
</p>
</label>
</div>
......
......@@ -5,6 +5,7 @@ footer.footer {
padding-top: 1em;
padding-bottom: 1em;
background-color: $brand-color;
height: $footer-height;
a {
color: white;
......@@ -16,6 +17,8 @@ footer.footer {
}
@media screen and (max-width: $desktop) {
height: unset;
div.column {
text-align: center;
}
......
......@@ -4,7 +4,7 @@ import { ErrorHandler, Injectable } from '@angular/core';
export class ErrorsHandler implements ErrorHandler {
handleError(error: Error) {
// console.log(error);
console.log(error);
return;
}
......
<div *ngIf="metadata" class="resource-container">
<div [ngClass]="{'blury': cguModalIsOpened}">
<div class="restricted-access-container" *ngIf="isSample">
<app-restricted-access-banner></app-restricted-access-banner>
</div>
<div class="resource-queryable" *ngIf="hasQueryableResources">
<div class="resource-item" *ngFor="let resource of queryableResources | keyvalue;let i = index">
<div class="resource-description">
<span>{{resource.key}}</span>
</div>
<app-resources-queryable [resources]="resource.value" [openFirst]="i === 0" [metadata]="metadata">
</app-resources-queryable>
</div>
</div>
</div>
<app-cgu-modal (cguAccepted)="cguAccepted()"></app-cgu-modal>
</div>
\ No newline at end of file
@import "../../../../scss/variables";
@import "../../../../../node_modules/bulma/sass/utilities/_all";
@import "../../../../scss/variables.scss";
@import "../../../../../node_modules/bulma/sass/utilities/_all.sass";
.resource-container {
padding: 2rem 1.25rem 1.25rem 1.25rem;
background-color: $grey-background-color;
position: relative;
@media screen and (min-width: $tablet) {
padding: 2rem 1.25rem 1.25rem 1.25rem;
}
}
.blury {
filter: blur(4px);
max-height: 100vh;
overflow: hidden;
}
.restricted-access-container {
......@@ -12,6 +23,10 @@
margin-bottom: 1rem;
}
.card-header-title {
justify-content: center;
}
.unlock-icon {
margin-bottom: 0.5rem;
......@@ -44,46 +59,41 @@ h4 {
.resource-queryable {
padding-bottom: 3rem;
border-bottom: 2px solid $grey-background-color;
.resource-item {
background-color: white;
padding: 0.5rem;
padding-left: 0;
padding-bottom: 0;
border-radius: 8px;
@media screen and (min-width: $tablet) {
margin-bottom: 1rem;
padding: 1.5rem;
box-shadow: 0 6px 12px 0 rgba(129, 128, 128, 0.1);
}
}
.resource-description {
border-bottom: 2px solid $grey-background-color;
padding-bottom: 1.5rem;
padding-bottom: 0.5rem;
padding-left: 0.5rem;
padding-top: 1rem;
span {
font-weight: 600;
line-height: 1;
font-size: 1rem;
}
}
}
.resources-downloadable {
margin-top: 2rem;
border-bottom: 2px solid $grey-background-color;
}
.resource-downloadable {
margin-top: 1rem;
padding-bottom: 1rem;
&:not(:last-of-type) {
border-bottom: 1px solid $grey-background-color;
}
}
.resources-other {
margin-top: 2rem;
}
@media screen and (min-width: $tablet) {
font-size: 1.25rem;
padding-bottom: 1.5rem;
padding-left: 1.5rem;
padding-top: 1.5rem;
.resource-other-title {
margin-top: 1rem;
margin-bottom: 1rem;
span {
/* stylelint-disable-line */
font-size: 1.1rem;
font-weight: 600;
}
}
}
}
......
import { Component, OnDestroy, OnInit } from '@angular/core';
import { CookieService } from 'ngx-cookie-service';
import { Subscription } from 'rxjs';
import { environment } from '../../../../environments/environment';
import { notificationMessages } from '../../../../i18n/traductions';
import { Notification } from '../../../core/models';
import { NotificationService } from '../../../core/services';
import { IMetadataLink, Metadata } from '../../../shared/models';
import { Metadata } from '../../../shared/models';
import { UserService } from '../../../user/services';
import { Resource } from '../../models';
import { DatasetDetailService, ResourcesService } from '../../services';
@Component({
selector: 'app-dataset-resources',
templateUrl: './dataset-resources.component.html',
styleUrls: ['./dataset-resources.component.scss'],