Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
web-et-numerique
web-et-numerique-internet
data.grandlyon.com
web-portal
components
custom-apps
web-app
Commits
58f0230d
Commit
58f0230d
authored
Jan 11, 2021
by
Jean-François LOTHEAL
Browse files
Merge branch 'D81919' into 'master'
D81919 See merge request
!115
parents
adb619af
356b7acf
Pipeline
#10112
passed with stage
in 8 minutes and 39 seconds
Changes
15
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
package-lock.json
View file @
58f0230d
{
"name": "webapp",
"version": "2.6.
6
",
"version": "2.6.
11
",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
...
...
package.json
View file @
58f0230d
{
"name"
:
"webapp"
,
"version"
:
"2.6.1
5
"
,
"version"
:
"2.6.1
6
"
,
"license"
:
"GNU Affero General Public License v3.0"
,
"scripts"
:
{
"ng"
:
"ng"
,
...
...
src/app/core/services/index.ts
View file @
58f0230d
...
...
@@ -7,6 +7,7 @@ import { MatomoService } from './matomo.service';
import
{
NavigationHistoryService
}
from
'
./navigation-history.service
'
;
import
{
NotificationService
}
from
'
./notification.service
'
;
import
{
StorageService
}
from
'
./storage.service
'
;
import
{
ToolsService
}
from
'
./tools.service
'
;
// tslint:disable-next-line: max-line-length
export
{
ErrorService
,
NotificationService
,
MatomoService
,
NavigationHistoryService
,
EmailService
,
FileService
,
AppConfigService
,
AppStateService
,
};
...
...
@@ -22,4 +23,5 @@ export const CoreServices = [
FileService
,
AppConfigService
,
AppStateService
,
ToolsService
,
];
src/app/core/services/tools.service.ts
0 → 100644
View file @
58f0230d
import
{
Injectable
}
from
'
@angular/core
'
;
@
Injectable
()
export
class
ToolsService
{
constructor
(
)
{
}
/**
* Détermine si une url est externe
* @param url
* @return boolean
*/
isExternalURL
(
url
:
string
)
{
return
new
URL
(
url
).
host
!==
(
location
.
host
);
}
/**
* Ajoute de nouveaux attributs html aux urls externes
* @param html
*/
decorateRichText
(
html
)
{
const
domParser
=
new
DOMParser
()
const
document
=
domParser
.
parseFromString
(
html
,
`text/html`
)
const
serializer
=
new
XMLSerializer
()
// Handles external links
const
links
=
document
.
querySelectorAll
(
`a`
);
links
.
forEach
((
link
)
=>
{
if
(
link
.
href
)
{
if
(
this
.
isExternalURL
(
link
.
href
))
{
link
.
target
=
`_blank`
link
.
rel
=
`noopener noreferrer`
}
}
})
return
serializer
.
serializeToString
(
document
)
}
}
\ No newline at end of file
src/app/dataset-detail/components/dataset-detail/dataset-detail.component.ts
View file @
58f0230d
...
...
@@ -226,11 +226,11 @@ export class DatasetDetailComponent implements OnInit, OnDestroy {
this
.
_router
.
navigate
([
`/
${
AppRoutes
.
datasets
.
uri
}
/
${
this
.
_datasetDetailService
.
dataset
.
slug
}
/
${
AppRoutes
.
data
.
uri
}
`
,
// tslint:disable-next-line: align
],
{
queryParamsHandling
:
'
preserve
'
});
],
{
queryParamsHandling
:
'
preserve
'
,
replaceUrl
:
true
});
}
else
{
this
.
_router
.
navigate
([
`/
${
AppRoutes
.
datasets
.
uri
}
/
${
this
.
_datasetDetailService
.
dataset
.
slug
}
/
${
AppRoutes
.
info
.
uri
}
`
,
]);
]
,
{
replaceUrl
:
true
}
);
}
}
else
{
// Making that the url contains the slug and not the uuid of the dataset
...
...
@@ -239,7 +239,7 @@ export class DatasetDetailComponent implements OnInit, OnDestroy {
`/
${
AppRoutes
.
datasets
.
uri
}
/
${
this
.
_datasetDetailService
.
dataset
.
slug
}
/
${
this
.
_route
.
snapshot
.
firstChild
.
url
[
0
]}
`
,
],
// tslint:disable-next-line: align
{
queryParamsHandling
:
'
preserve
'
});
{
queryParamsHandling
:
'
preserve
'
,
replaceUrl
:
true
});
}
// Emit event to indicate to child component that the dataset has changed
...
...
src/app/datasets/components/filter-list/filter-list.component.ts
View file @
58f0230d
...
...
@@ -2,6 +2,7 @@ import { Location } from '@angular/common';
import
{
Component
,
OnDestroy
,
OnInit
}
from
'
@angular/core
'
;
import
{
Subscription
}
from
'
rxjs
'
;
import
{
geosource
}
from
'
../../../../i18n/traductions
'
;
import
{
NavigationHistoryService
}
from
'
../../../core/services
'
;
import
{
Aggregation
,
Filter
,
IActiveFiltersTemplate
}
from
'
../../../elasticsearch/models
'
;
import
{
AppRoutes
}
from
'
../../../routes
'
;
import
{
scopesResearch
}
from
'
../../../shared/variables
'
;
...
...
@@ -24,9 +25,11 @@ export class FilterListComponent implements OnInit, OnDestroy {
constructor
(
private
_datasetResearchService
:
DatasetResearchService
,
private
_location
:
Location
,
private
_navigationHistoryService
:
NavigationHistoryService
,
)
{
}
ngOnInit
()
{
const
filters
=
this
.
_datasetResearchService
.
filters
;
if
(
filters
)
{
this
.
initFilters
();
...
...
@@ -103,6 +106,7 @@ export class FilterListComponent implements OnInit, OnDestroy {
this
.
_datasetResearchService
.
resetActiveAggregations
();
this
.
_datasetResearchService
.
triggerSearchChange
();
this
.
_location
.
go
(
AppRoutes
.
research
.
uri
,
''
);
this
.
_navigationHistoryService
.
add
(
this
.
_location
.
path
());
}
ngOnDestroy
()
{
...
...
src/app/datasets/components/results/results.component.ts
View file @
58f0230d
...
...
@@ -87,11 +87,14 @@ export class ResultsComponent implements OnInit, OnDestroy {
// If there are parameters, we extract them to set the ESoptions for a news search.
private
manageUrlParameters
(
params
)
{
this
.
_datasetResearchService
.
resetActiveAggregations
();
if
(
params
&&
Object
.
keys
(
params
).
length
>
0
)
{
this
.
hasParams
=
true
;
// We need to make an initial request to get the aggregations and subaggregations
this
.
_datasetResearchService
.
getResults
().
subscribe
(()
=>
{
// Create the ESOptions
const
options
=
this
.
_researchUrlService
.
getOptionsFromParameters
(
params
);
this
.
_datasetResearchService
.
elasticSearchOptions
.
setElasticsearchOptions
(
options
);
// Force to recalculate the aggregate counts
...
...
@@ -112,7 +115,6 @@ export class ResultsComponent implements OnInit, OnDestroy {
let
parentAgg
=
''
;
filters
.
forEach
((
filter
)
=>
{
if
(
filter
.
field
===
aggField
)
{
// No need this rule. In this case we control the parameters, and we want a loose
// comparison to handle the filter with a 'Date' type (where the key aggregation is a number).
...
...
@@ -139,13 +141,17 @@ export class ResultsComponent implements OnInit, OnDestroy {
});
}
});
this
.
_datasetResearchService
.
updateAggregation
(
newAggField
,
aggKey
,
true
,
parentAgg
,
false
);
});
});
this
.
_datasetResearchService
.
triggerSearchChange
();
});
}
else
{
//reset filters recorded when there are not get parameters
this
.
_datasetResearchService
.
triggerSearchChange
();
this
.
_researchUrlService
.
reset
();
}
}
ngOnDestroy
()
{
...
...
@@ -260,6 +266,6 @@ export class ResultsComponent implements OnInit, OnDestroy {
}
get
toResultNumber
()
{
return
Math
.
min
((
(
this
.
paginator
.
pageIndex
-
1
)
*
this
.
paginator
.
pageSize
)
+
10
,
this
.
paginator
.
length
);
return
Math
.
min
((
this
.
paginator
.
pageIndex
*
this
.
paginator
.
pageSize
),
this
.
paginator
.
length
);
}
}
src/app/datasets/services/dataset-research.service.ts
View file @
58f0230d
...
...
@@ -37,7 +37,7 @@ export class DatasetResearchService {
this
.
_searchChangeSubject
=
new
Subject
<
any
>
();
this
.
_datasetsReloadedSubject
=
new
Subject
<
any
>
();
this
.
_scopeChangedSubject
=
new
Subject
<
any
>
();
this
.
_elasticsearchOptions
=
new
ElasticsearchOptions
({
pageSize
:
10
});
this
.
_elasticsearchOptions
=
new
ElasticsearchOptions
({
pageSize
:
5
});
this
.
_resultsCount
=
[];
}
...
...
src/app/datasets/services/research-url.service.ts
View file @
58f0230d
import
{
Location
}
from
'
@angular/common
'
;
import
{
Injectable
}
from
'
@angular/core
'
;
import
{
NavigationHistoryService
}
from
'
../../core/services
'
;
import
{
Aggregation
,
IElasticsearchOptions
,
ISortOption
}
from
'
../../elasticsearch/models
'
;
import
{
AppRoutes
}
from
'
../../routes
'
;
import
{
scopesResearch
}
from
'
../../shared/variables
'
;
...
...
@@ -12,6 +13,7 @@ export class ResearchUrlService {
constructor
(
private
_location
:
Location
,
private
_navigationHistoryService
:
NavigationHistoryService
)
{
}
// Get the ES options from parameters
...
...
@@ -78,6 +80,7 @@ export class ResearchUrlService {
this
.
_parameters
[
key
]
=
searchValue
;
const
params
=
this
.
generateUrlParams
();
this
.
_location
.
go
(
AppRoutes
.
research
.
uri
,
params
);
this
.
_navigationHistoryService
.
add
(
this
.
_location
.
path
());
}
// Set an aggregation parameter in the _aggParameters variable, and change the url
...
...
@@ -132,6 +135,7 @@ export class ResearchUrlService {
}
const
params
=
this
.
generateUrlParams
();
this
.
_location
.
go
(
AppRoutes
.
research
.
uri
,
params
);
this
.
_navigationHistoryService
.
add
(
this
.
_location
.
path
());
}
private
addAggregation
(
fieldKey
:
string
,
aggregationKey
:
string
)
{
...
...
@@ -168,6 +172,7 @@ export class ResearchUrlService {
this
.
_parameters
[
'
sort
'
]
=
value
;
const
params
=
this
.
generateUrlParams
();
this
.
_location
.
go
(
AppRoutes
.
research
.
uri
,
params
);
this
.
_navigationHistoryService
.
add
(
this
.
_location
.
path
());
}
// Generate the parameters to set into the url from the _parameters and _aggParametersa arrays
...
...
src/app/editorialisation/components/cms-page/cms-page.component.ts
View file @
58f0230d
...
...
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
import
{
DomSanitizer
,
Meta
,
SafeHtml
}
from
'
@angular/platform-browser
'
;
import
{
ActivatedRoute
,
Router
}
from
'
@angular/router
'
;
import
{
environment
}
from
'
../../../../environments/environment
'
;
import
{
ToolsService
}
from
'
../../../core/services/tools.service
'
;
import
{
AppRoutes
}
from
'
../../../routes
'
;
import
{
IPageHeaderInfo
}
from
'
../../../shared/models
'
;
import
{
CMSContent
}
from
'
../../models
'
;
...
...
@@ -23,6 +24,7 @@ export class CMSPageComponent implements OnInit {
private
_route
:
ActivatedRoute
,
private
_editorialisationService
:
EditorialisationService
,
private
sanitizer
:
DomSanitizer
,
private
_toolsService
:
ToolsService
,
private
_router
:
Router
,
private
_meta
:
Meta
,
)
{
...
...
@@ -46,7 +48,7 @@ export class CMSPageComponent implements OnInit {
if
(
!
(
this
.
page
instanceof
CMSContent
))
{
this
.
_router
.
navigate
([
'
/
'
,
AppRoutes
.
page404
.
uri
]);
}
else
{
this
.
safePageContent
=
this
.
sanitizer
.
bypassSecurityTrustHtml
(
this
.
page
.
content
.
html
);
this
.
safePageContent
=
this
.
sanitizer
.
bypassSecurityTrustHtml
(
this
.
_toolsService
.
decorateRichText
(
this
.
page
.
content
.
html
)
)
;
this
.
pageHeaderInfo
.
title
=
this
.
page
.
content
.
title
;
}
});
...
...
src/app/editorialisation/components/cms-post-detail/cms-post-detail.component.ts
View file @
58f0230d
...
...
@@ -2,7 +2,8 @@ import { DatePipe } from '@angular/common';
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
DomSanitizer
,
Meta
,
SafeHtml
}
from
'
@angular/platform-browser
'
;
import
{
ActivatedRoute
,
Router
}
from
'
@angular/router
'
;
import
{
notificationMessages
}
from
'
../../../../i18n/traductions
'
;
import
{
datasetStatistics
,
notificationMessages
}
from
'
../../../../i18n/traductions
'
;
import
{
ToolsService
}
from
'
../../../core/services/tools.service
'
;
import
{
ElasticsearchService
}
from
'
../../../elasticsearch/services/elasticsearch.service
'
;
import
{
AppRoutes
}
from
'
../../../routes
'
;
import
{
IPageHeaderInfo
,
Metadata
,
typesMetadata
}
from
'
../../../shared/models
'
;
...
...
@@ -35,6 +36,7 @@ export class CMSPostDetailComponent implements OnInit {
private
_datePipe
:
DatePipe
,
private
_sanitizer
:
DomSanitizer
,
private
_elasticSearchService
:
ElasticsearchService
,
private
_toolsService
:
ToolsService
,
private
_meta
:
Meta
,
)
{
}
...
...
@@ -47,7 +49,7 @@ export class CMSPostDetailComponent implements OnInit {
// Set the title and description for a CMS post
this
.
_meta
.
updateTag
({
name
:
'
description
'
,
content
:
this
.
post
.
content
.
excerpt
});
this
.
safePostContent
=
this
.
_sanitizer
.
bypassSecurityTrustHtml
(
this
.
post
.
content
.
html
);
this
.
safePostContent
=
this
.
_sanitizer
.
bypassSecurityTrustHtml
(
this
.
_toolsService
.
decorateRichText
(
this
.
post
.
content
.
html
)
)
;
// Construct header informations: (Date + tags) and title
this
.
pageHeaderInfo
.
title
=
this
.
post
.
content
.
title
;
...
...
@@ -78,6 +80,8 @@ export class CMSPostDetailComponent implements OnInit {
}
}
setBackupImage
(
metadata
:
Metadata
)
{
// Init the image property to make sure that 'url' is accessible in the following lines
metadata
.
image
=
{
...
...
src/app/editorialisation/components/organizations/organizations.component.ts
View file @
58f0230d
import
{
Component
,
OnInit
}
from
'
@angular/core
'
;
import
{
Location
}
from
'
@angular/common
'
;
import
{
Router
}
from
'
@angular/router
'
;
import
{
map
,
mergeMap
,
tap
}
from
'
rxjs/operators
'
;
import
{
notificationMessages
,
pageTitles
}
from
'
../../../../i18n/traductions
'
;
...
...
@@ -30,6 +31,7 @@ export class OrganizationsComponent implements OnInit {
private
_datasetResearchService
:
DatasetResearchService
,
private
_notificationService
:
NotificationService
,
private
_router
:
Router
,
private
_location
:
Location
)
{
}
ngOnInit
()
{
...
...
@@ -79,7 +81,7 @@ export class OrganizationsComponent implements OnInit {
this
.
_datasetResearchService
.
getResults
().
subscribe
(()
=>
{
this
.
_datasetResearchService
.
updateAggregation
(
'
metadata-fr.responsibleParty.organisationName
'
,
name
,
true
);
this
.
_datasetResearchService
.
scopeReasearch
=
scopesResearch
.
datasets
;
this
.
_router
.
navigate
([
'
/
'
,
AppRoutes
.
research
.
uri
]
);
this
.
_router
.
navigate
ByUrl
(
this
.
_location
.
path
()
);
});
}
...
...
@@ -89,7 +91,7 @@ export class OrganizationsComponent implements OnInit {
this
.
_datasetResearchService
.
getResults
().
subscribe
(()
=>
{
this
.
_datasetResearchService
.
updateAggregation
(
'
metadata-fr.responsibleParty.organisationName
'
,
name
,
true
);
this
.
_datasetResearchService
.
scopeReasearch
=
scopesResearch
.
services
;
this
.
_router
.
navigate
([
'
/
'
,
AppRoutes
.
research
.
uri
]
);
this
.
_router
.
navigate
ByUrl
(
this
.
_location
.
path
()
);
});
}
...
...
src/app/user/components/auth/login/login.component.ts
View file @
58f0230d
...
...
@@ -6,6 +6,7 @@ import { UserService } from '../../../services';
import
{
AppRoutes
}
from
'
../../../../routes
'
;
import
{
IPageHeaderInfo
}
from
'
../../../../shared/models
'
;
import
{
pageTitles
}
from
'
../../../../../i18n/traductions
'
;
import
{
NavigationHistoryService
}
from
'
../../../../core/services
'
;
@
Component
({
selector
:
'
app-login
'
,
...
...
@@ -22,6 +23,7 @@ export class LoginComponent implements OnInit {
};
showPassword
:
boolean
;
returnUrl
:
string
;
// Account validation
token
:
string
;
// uuid4 allowing to identify the account that needs to be validated
...
...
@@ -33,12 +35,18 @@ export class LoginComponent implements OnInit {
private
_userService
:
UserService
,
private
_router
:
Router
,
private
_activatedRoute
:
ActivatedRoute
,
private
_navigationHistoryService
:
NavigationHistoryService
,
)
{
this
.
form
=
this
.
_fb
.
group
({
username
:
[
''
,
[
Validators
.
required
,
Validators
.
email
]],
password
:
[
''
,
Validators
.
required
],
});
this
.
returnUrl
=
this
.
_navigationHistoryService
.
getFromLast
(
0
);
if
(
null
==
this
.
returnUrl
||
this
.
_router
.
url
==
this
.
returnUrl
){
this
.
returnUrl
=
'
/
'
+
AppRoutes
.
home
.
uri
;
}
}
ngOnInit
()
{
...
...
@@ -73,7 +81,7 @@ export class LoginComponent implements OnInit {
(
res
)
=>
{
this
.
form
.
enable
();
this
.
errorStatus
=
null
;
this
.
_router
.
navigate
([
'
/
'
,
AppRoutes
.
home
.
uri
]);
this
.
_router
.
navigate
([
this
.
returnUrl
]);
},
(
err
)
=>
{
if
(
err
instanceof
HttpErrorResponse
)
{
...
...
src/i18n/messages.en.xlf
View file @
58f0230d
...
...
@@ -796,8 +796,8 @@ Here is the list of the last evolutions of the portal. If you wish to contribute
<target>
Your credentials are not correct.
</target>
</trans-unit>
<trans-unit
id=
"login.internalError"
datatype=
"html"
>
<source>
Something went wrong, please try again later
.
</source>
<target>
Something went wrong, please try again later
.
</target>
<source>
Please enter a valid email and password
.
</source>
<target>
Please enter a valid email and password
.
</target>
</trans-unit>
<trans-unit
id=
"login.emailRequired"
datatype=
"html"
>
<source>
Email is required.
</source>
...
...
src/i18n/messages.fr.xlf
View file @
58f0230d
...
...
@@ -805,8 +805,8 @@ Voici la liste des dernières évolutions du portail. Si vous souhaitez contribu
<target>
Vos identifiants ne sont pas corrects.
</target>
</trans-unit>
<trans-unit
id=
"login.internalError"
datatype=
"html"
>
<source>
Something went wrong, please try again later
.
</source>
<target>
Une erreur est survenue, veuillez réessayer ultérieurement
.
</target>
<source>
Please enter a valid email and password
.
</source>
<target>
Merci de saisir un email et un mot de passe valides
.
</target>
</trans-unit>
<trans-unit
id=
"login.emailRequired"
datatype=
"html"
>
<source>
Email is required.
</source>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment