Skip to content
GitLab
Menu
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
aa1fb918
Commit
aa1fb918
authored
Aug 14, 2019
by
ncastejon
Browse files
Refactor the table data. Use of css grid instead of Bulma Flexbox. WIP.
parent
4188bd51
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/app/geosource/components/dataset-detail/dataset-data/dataset-data.component.ts
View file @
aa1fb918
...
...
@@ -30,9 +30,6 @@ export class DatasetDataComponent implements OnInit, OnDestroy {
message
:
string
=
null
;
maximumNumberOfData
=
10000
;
// Opened data
openedData
:
number
[]
=
[];
// search
searchInput
=
new
FormControl
(
''
);
...
...
@@ -113,18 +110,6 @@ export class DatasetDataComponent implements OnInit, OnDestroy {
return
this
.
_datasetDetailService
.
datasetDataNumber
;
}
// Add or Remove the id (given in the code) of the data
// from the array of openned data (details displayed)
toogleData
(
num
:
number
)
{
// If id found remove it from array alse add it to array
const
index
=
this
.
openedData
.
findIndex
(
e
=>
e
===
num
);
if
(
index
!==
-
1
)
{
this
.
openedData
.
splice
(
index
,
1
);
}
else
{
this
.
openedData
.
push
(
num
);
}
}
toogleColumsMenu
()
{
this
.
displayColumnsMenu
=
!
this
.
displayColumnsMenu
;
}
...
...
@@ -135,14 +120,7 @@ export class DatasetDataComponent implements OnInit, OnDestroy {
}
}
// If id of the data is in array return true (details should be displayed)
isDataOpened
(
index
:
number
):
boolean
{
return
this
.
openedData
.
findIndex
(
e
=>
e
===
index
)
!==
-
1
;
}
sortBy
(
key
:
string
)
{
// Set the new sort value in the service
this
.
openedData
=
[];
this
.
_datasetDetailService
.
sortBy
(
key
);
this
.
newAsyncRequest
();
// Retrieve date sorted with the new value
...
...
@@ -160,7 +138,6 @@ export class DatasetDataComponent implements OnInit, OnDestroy {
// Get the new data
this
.
_datasetDetailService
.
retrieveDatasetData
().
subscribe
((
data
)
=>
{
this
.
asyncRequestDone
();
this
.
openedData
=
[];
this
.
data
=
data
;
});
}
...
...
src/app/geosource/components/dataset-detail/dataset-table/dataset-table.component.html
0 → 100644
View file @
aa1fb918
<div
class=
"columns is-multiline page-header"
>
<div
class=
"restricted-access-container"
*ngIf=
"isSample"
>
<app-restricted-access-banner></app-restricted-access-banner>
</div>
<div
class=
"column is-paddingless"
>
<div
class=
"documents-number"
>
<span
class=
"documents-number"
>
<span
class=
"research-documents-number"
>
{{ researchMaxResult }}
</span>
<span>
/ {{ datasetDataNumber }}
</span>
<span
i18n=
"@@dataset.data.recordsFound"
>
records found
</span>
</span>
</div>
<div
class=
"search-container"
>
<div
class=
"control has-icons-left search-control"
[ngClass]=
"{'is-loading': isLoading}"
>
<span
class=
"icon is-medium is-left"
>
<svg
xmlns=
"http://www.w3.org/2000/svg"
id=
"loupe"
viewBox=
"0 0 17 16"
>
<path
d=
"M9 3zM3.5 4.5zM15.8 14.4h-.1l-3.1-3.1v-.1h-.8v.9l3.1 3.1.8-.8zM3.7 12.1zM9.9 1.5C9 1 8.1.8 7 .8c-1.1 0-2 .2-2.9.7C3.2 2 2.5 2.7 2 3.6c-.5.9-.8 1.8-.8 2.9 0 1.1.3 2 .8 2.9.5.9 1.2 1.6 2.1 2.1.9.5 1.8.7 2.9.7 1.3 0 2.5-.4 3.5-1.2l.6-.4.4-.6c.8-1 1.2-2.2 1.2-3.5 0-1.1-.3-2-.8-2.9-.4-.9-1.1-1.6-2-2.1m-7 2.6c.4-.7 1-1.3 1.7-1.7.7-.4 1.5-.6 2.4-.6.9 0 1.6.2 2.4.6.7.4 1.3 1 1.7 1.7.4.7.6 1.5.6 2.4 0 .9-.2 1.7-.6 2.4-.4.7-1 1.3-1.7 1.7-.8.4-1.5.6-2.4.6-.9 0-1.7-.2-2.4-.6-.7-.4-1.3-1-1.7-1.7-.4-.7-.7-1.5-.7-2.4 0-.9.3-1.6.7-2.4z"
class=
"st0"
/>
</svg>
</span>
<input
type=
"text"
[formControl]=
"searchInput"
class=
"input"
placeholder=
"Filter records"
i18n-placeholder=
"@@dataset.data.filterReccordPlaceholder"
>
</div>
</div>
</div>
<div
class=
"column is-paddingless"
>
<div
class=
"properties-number"
>
<span><span
class=
"selected-properties-number"
>
{{ selectedProperties.length }}
</span><span>
/{{ properties.length }}
</span>
<span
i18n=
"@@dataset.data.displayedProperties"
>
displayed properties
</span></span>
</div>
<div
class=
"dropdown properties-dropdown"
[ngClass]=
"{'is-active': displayColumnsMenu}"
(clickOutside)=
"closeColumsMenu()"
>
<div
class=
"dropdown-trigger"
>
<button
class=
"button button-gl is-outlined"
aria-haspopup=
"true"
aria-controls=
"dropdown-menu"
(click)=
"toogleColumsMenu()"
i18n=
"@@dataset.data.customizeButton"
>
Customize
</button>
</div>
<div
class=
"dropdown-menu"
id=
"dropdown-menu"
role=
"menu"
>
<div
class=
"dropdown-content has-text-left"
>
<div
class=
"field dropdown-item"
*ngFor=
"let prop of properties"
>
<input
class=
"is-checkradio has-error is-small"
[id]=
"prop"
type=
"checkbox"
name=
"selectedColumns"
[checked]=
"columnIsSelected(prop) !== -1"
(click)=
"toogleColumn(prop)"
>
<label
[for]=
"prop"
>
{{ prop }}
</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"data-table"
infinite-scroll
[infiniteScrollDistance]=
"scrollDistance"
[infiniteScrollUpDistance]=
"scrollUpDistance"
[infiniteScrollThrottle]=
"throttle"
[scrollWindow]=
"false"
(scrolled)=
"onScrollDown()"
[ngStyle]=
"getStyle()"
>
<div
class=
" item-grid column-header"
*ngFor=
"let key of selectedProperties"
(click)=
"sortBy(key)"
>
<span
class=
"sort-icons"
>
<span
class=
"icon"
>
<i
class=
"fas fa-sort-up"
[ngClass]=
"{'icon-red': sortValue === key && sortOrder === 'desc'}"
></i>
</span>
<span
class=
"icon"
>
<i
class=
"fas fa-sort-down"
[ngClass]=
"{'icon-red': sortValue === key && sortOrder === 'asc'}"
></i>
</span>
</span>
<span
class=
"column-title"
[ngClass]=
"{'active': sortValue === key}"
>
{{ key }}
</span>
</div>
<ng-container
*ngFor=
"let element of data; let i=index; let even=even;"
>
<div
class=
"item-grid"
[ngClass]=
"'item-grid-' + i"
*ngFor=
"let key of selectedProperties"
(click)=
"setStyleForAllRow(i)"
>
<span
*ngIf=
"!isPropertyComplex(element,key)"
class=
"data-property-value"
>
{{ element.properties[key] }}
</span>
<span
*ngIf=
"isPropertyComplex(element,key)"
>
<span
class=
"tooltip-right"
i18n-data-tooltip=
"@@dataset.data.tooltip"
data-tooltip=
"Complex property, please unfold the line"
>
<svg
xmlns=
"http://www.w3.org/2000/svg"
width=
"16"
height=
"14"
fill=
"none"
viewBox=
"0 0 16 14"
>
<path
fill=
"#fff"
d=
"M15.581 12.031c.146.292.191.584.137.875-.055.31-.2.565-.438.766-.237.219-.52.328-.848.328H1.308c-.329 0-.611-.11-.848-.328a1.26 1.26 0 0 1-.438-.766 1.356 1.356 0 0 1 .137-.875L6.722.656c.164-.291.392-.483.683-.574.31-.11.61-.11.903 0 .31.091.546.283.71.574l6.563 11.375zM7.87 9.68c-.346 0-.647.127-.902.383a1.19 1.19 0 0 0-.356.874c0 .347.119.648.356.903.255.237.556.355.902.355s.638-.118.875-.355c.255-.255.383-.556.383-.902 0-.347-.128-.639-.383-.876a1.147 1.147 0 0 0-.875-.382zM6.667 5.168l.219 3.719c0 .073.027.146.082.218a.4.4 0 0 0 .246.082h1.312a.296.296 0 0 0 .219-.082c.073-.072.11-.145.11-.218l.218-3.719c0-.11-.036-.191-.11-.246a.26.26 0 0 0-.218-.11h-1.75a.34.34 0 0 0-.246.11c-.055.055-.082.137-.082.246z"
/>
</svg>
<span
class=
"warning-complexity"
i18n=
"@@dataset.data.complexProperty"
>
Complex property
</span>
</span>
</span>
</div>
</ng-container>
</div>
\ No newline at end of file
src/app/geosource/components/dataset-detail/dataset-table/dataset-table.component.scss
0 → 100644
View file @
aa1fb918
@import
"../../../../../scss/variables"
;
@import
"../../../../../../node_modules/bulma/sass/utilities/_all"
;
:root
{
--colNum
:
1
;
}
.data-table
{
display
:
grid
;
max-height
:
80vh
;
overflow
:
auto
;
grid-template-rows
:
44px
repeat
(
auto-fill
,
35px
);
grid-auto-rows
:
35px
;
// grid-template-columns: repeat(var(--colNum), 1fr);
}
.item-grid
{
display
:
flex
;
align-items
:
center
;
padding-right
:
1rem
;
cursor
:
pointer
;
}
.selected
{
background-color
:
#f1f3f8
;
span
{
color
:
$tomato-color
;
}
}
.column-header
{
position
:
sticky
;
top
:
0
;
background-color
:
$grey-background-color
;
display
:
flex
;
justify-content
:
flex-start
;
border-bottom
:
1px
solid
$grey-super-light-color
;
span
{
cursor
:
pointer
;
}
.sort-icons
{
display
:
flex
;
flex-direction
:
column
;
align-self
:
center
;
.icon
{
height
:
0
.2rem
;
width
:
unset
;
justify-content
:
center
;
}
.icon-red
{
color
:
$tomato-color
;
}
}
.column-title
{
margin-left
:
0
.3rem
;
}
}
.arrows
{
svg
{
/* stylelint-disable-line */
margin-right
:
1rem
;
width
:
16px
;
fill
:
$grey-dark-color
;
transform
:
rotate
(
-90deg
);
}
}
src/app/geosource/components/dataset-detail/dataset-table/dataset-table.component.ts
0 → 100644
View file @
aa1fb918
import
{
Component
,
OnInit
,
ElementRef
,
QueryList
,
ViewChildren
,
OnDestroy
}
from
'
@angular/core
'
;
import
{
DatasetDetailService
}
from
'
../../../services
'
;
import
{
Data
}
from
'
../../../models
'
;
import
{
Subscription
}
from
'
../../../../../../node_modules/rxjs
'
;
import
{
debounceTime
}
from
'
../../../../../../node_modules/rxjs/operators
'
;
import
{
geosource
}
from
'
../../../../../i18n/traductions
'
;
import
{
FormControl
}
from
'
@angular/forms
'
;
import
{
AppRoutes
}
from
'
../../../../routes
'
;
@
Component
({
selector
:
'
app-dataset-table
'
,
templateUrl
:
'
./dataset-table.component.html
'
,
styleUrls
:
[
'
./dataset-table.component.scss
'
],
})
export
class
DatasetTableComponent
implements
OnInit
,
OnDestroy
{
@
ViewChildren
(
'
itemsToCollapse
'
,
{
read
:
ElementRef
})
itemsToCollapseList
:
QueryList
<
ElementRef
>
;
AppRoutes
=
AppRoutes
;
data
:
Data
[];
subscriptions
:
Subscription
[]
=
[];
// Count the number of currently running queries in order do display or not a loading icon
private
_pendingRequests
:
number
=
0
;
isSample
=
false
;
// Infinite scroll
throttle
=
300
;
scrollDistance
=
1
;
scrollUpDistance
=
2
;
message
:
string
=
null
;
maximumNumberOfData
=
10000
;
// Opened data
openedData
:
number
[]
=
[];
// search
searchInput
=
new
FormControl
(
''
);
previousSelectedRow
:
string
;
// columns options
displayColumnsMenu
=
false
;
selectedProperties
:
string
[]
=
[];
// Array of columns to be displayed
properties
:
string
[];
// maxDisplayedColumns = 5; // Set the max number of columns to be displayed in the table
constructor
(
private
_datasetDetailService
:
DatasetDetailService
,
)
{
}
ngOnInit
()
{
this
.
initializeComponent
();
// Intialize the search value with the value from the service in order to keep it when navigating in tabs
this
.
searchInput
.
setValue
(
this
.
_datasetDetailService
.
searchString
);
this
.
subscriptions
.
push
(
// Subscribe to input changes
this
.
searchInput
.
valueChanges
.
pipe
(
debounceTime
(
500
)).
subscribe
(()
=>
{
this
.
searchChanged
();
}),
// Subscribe to dataset changes
this
.
_datasetDetailService
.
dataset$
.
subscribe
(()
=>
{
this
.
initializeComponent
();
}),
);
}
ngOnDestroy
()
{
this
.
subscriptions
.
forEach
((
sub
)
=>
{
sub
.
unsubscribe
();
});
}
initializeComponent
()
{
this
.
isSample
=
this
.
_datasetDetailService
.
dataset
.
editorialMetadata
.
isSample
;
this
.
data
=
this
.
_datasetDetailService
.
datasetData
;
this
.
properties
=
[];
if
(
this
.
data
&&
this
.
data
.
length
>
0
)
{
// If dataset has data, initialize an array with the
// the key of each property
this
.
properties
=
this
.
_datasetDetailService
.
dataset
.
fields
.
list
;
// Initialize an array with max 'maxDisplayedColumns' properties
this
.
selectedProperties
=
Array
.
from
(
this
.
properties
);
}
}
getStyle
()
{
return
{
// 'grid-template-columns': `repeat(${this.selectedProperties.length}, minmax(50px, 1fr)`,
'
grid-template-columns
'
:
`repeat(
${
this
.
selectedProperties
.
length
}
, max-content`
,
};
}
setStyleForAllRow
(
index
)
{
// Remove the style form previous selected row
Array
.
from
(
document
.
getElementsByClassName
(
this
.
previousSelectedRow
)).
forEach
((
el
)
=>
{
el
.
className
=
el
.
className
.
replace
(
/
\b
selected
\b
/g
,
''
);
});
const
className
=
`item-grid-
${
index
}
`
;
Array
.
from
(
document
.
getElementsByClassName
(
className
)).
forEach
((
el
)
=>
{
el
.
className
+=
'
selected
'
;
});
this
.
previousSelectedRow
=
className
;
}
// Method called when the scrolled down
onScrollDown
()
{
// Only call the service if the actual number of data is smaller than the
// total number of data found for this reseach
if
(
this
.
data
.
length
<
this
.
researchMaxResult
)
{
// Increase the from value to get more data
this
.
_datasetDetailService
.
nextPage
();
// Make sure from + size (in the service) dont exceed maximumNumberOfData, limit set by elasticsearch
// if a request is made with a size and from and the sum of those is over maximumNumberOfData it will
// cause an internal error in elaticsearch and the request will fail
if
(
this
.
_datasetDetailService
.
scrollOptionsSum
<=
this
.
maximumNumberOfData
)
{
// Update the array of data with the newly retrieved data (size shoul have increased by 'size' value)
this
.
_datasetDetailService
.
retrieveMoreDatasetData
().
subscribe
((
data
)
=>
{
this
.
data
=
data
;
});
}
else
{
this
.
message
=
`
${
geosource
.
datasetData
.
maxDataDisplayedMessage
}${
this
.
maximumNumberOfData
}
.`
;
}
}
else
{
// console.log('Already retrieved all occurences');
}
}
// Get the number of documents in this dataset
get
datasetDataNumber
()
{
return
this
.
_datasetDetailService
.
datasetDataNumber
;
}
// Add or Remove the id (given in the code) of the data
// from the array of openned data (details displayed)
toogleData
(
num
:
number
)
{
// If id found remove it from array alse add it to array
const
index
=
this
.
openedData
.
findIndex
(
e
=>
e
===
num
);
if
(
index
!==
-
1
)
{
this
.
openedData
.
splice
(
index
,
1
);
}
else
{
this
.
openedData
.
push
(
num
);
}
}
toogleColumsMenu
()
{
this
.
displayColumnsMenu
=
!
this
.
displayColumnsMenu
;
}
closeColumsMenu
()
{
if
(
this
.
displayColumnsMenu
)
{
this
.
displayColumnsMenu
=
false
;
}
}
sortBy
(
key
:
string
)
{
// Set the new sort value in the service
this
.
openedData
=
[];
this
.
_datasetDetailService
.
sortBy
(
key
);
this
.
newAsyncRequest
();
// Retrieve date sorted with the new value
this
.
_datasetDetailService
.
retrieveDatasetData
().
subscribe
((
data
)
=>
{
this
.
asyncRequestDone
();
this
.
data
=
data
;
});
}
searchChanged
()
{
this
.
_datasetDetailService
.
searchChanged
(
this
.
searchInput
.
value
);
this
.
newAsyncRequest
();
// Get the new data
this
.
_datasetDetailService
.
retrieveDatasetData
().
subscribe
((
data
)
=>
{
this
.
asyncRequestDone
();
this
.
openedData
=
[];
this
.
data
=
data
;
});
}
get
sortValue
()
{
return
this
.
_datasetDetailService
.
sortValue
;
}
get
sortOrder
()
{
return
this
.
_datasetDetailService
.
sortOrder
;
}
get
researchMaxResult
()
{
return
this
.
_datasetDetailService
.
researchMaxResult
;
}
// Returns the index if found in the array, -1 if not found
columnIsSelected
(
name
:
string
)
{
return
this
.
selectedProperties
.
findIndex
(
e
=>
e
===
name
);
}
// Return the type of the 'key' property of the input object
isPropertyComplex
(
element
,
key
:
string
)
{
const
type
=
typeof
element
.
properties
[
key
];
return
type
===
'
object
'
||
Array
.
isArray
(
element
.
properties
[
key
]);
}
toogleColumn
(
name
:
string
)
{
const
index
=
this
.
selectedProperties
.
findIndex
(
e
=>
e
===
name
);
// If value found remove it from the array
if
(
index
!==
-
1
)
{
this
.
selectedProperties
.
splice
(
index
,
1
);
}
else
{
// If not found add the value to the array
this
.
selectedProperties
.
push
(
name
);
}
}
// Increments the number of curretly running async request by one
newAsyncRequest
()
{
this
.
_pendingRequests
+=
1
;
}
// Decrement the number of async requests by one
asyncRequestDone
()
{
this
.
_pendingRequests
-=
1
;
}
// Return true if http queries are being made
get
isLoading
()
{
return
this
.
_pendingRequests
>
0
?
true
:
false
;
}
}
src/app/geosource/components/index.ts
View file @
aa1fb918
...
...
@@ -11,6 +11,7 @@ import { ResourceDownloadableComponent } from './dataset-detail/dataset-resource
import
{
DatasetMapComponent
}
from
'
./dataset-detail/dataset-map/dataset-map.component
'
;
import
{
DatasetInfoComponent
}
from
'
./dataset-detail/dataset-info/dataset-info.component
'
;
import
{
DatasetDataComponent
}
from
'
./dataset-detail/dataset-data/dataset-data.component
'
;
import
{
DatasetTableComponent
}
from
'
./dataset-detail/dataset-table/dataset-table.component
'
;
import
{
DataPropertiesComponent
}
from
'
./dataset-detail/dataset-data/data-properties/data-properties.component
'
;
import
{
IconFormatComponent
}
from
'
./dataset-detail/dataset-resources/icon-format/icon-format.component
'
;
import
{
SearchBarComponent
}
from
'
./search-bar/search-bar.component
'
;
...
...
@@ -30,6 +31,7 @@ export {
DatasetMapComponent
,
DatasetInfoComponent
,
DatasetDataComponent
,
DatasetTableComponent
,
ResultsComponent
,
SearchBarComponent
,
ResearchComponent
,
...
...
@@ -53,6 +55,7 @@ export const GeosourceComponents = [
DatasetMapComponent
,
DatasetInfoComponent
,
DatasetDataComponent
,
DatasetTableComponent
,
ResultsComponent
,
SearchBarComponent
,
ResearchComponent
,
...
...
src/app/geosource/geosource-routing.module.ts
View file @
aa1fb918
import
{
NgModule
}
from
'
@angular/core
'
;
import
{
Routes
,
RouterModule
}
from
'
@angular/router
'
;
import
{
ResultsComponent
,
DatasetDetailComponent
,
ResearchComponent
,
DatasetInfoComponent
,
DatasetMapComponent
,
DatasetResourcesComponent
,
Dataset
Data
Component
}
from
'
./components
'
;
DatasetMapComponent
,
DatasetResourcesComponent
,
Dataset
Table
Component
}
from
'
./components
'
;
import
{
AppRoutes
}
from
'
../routes
'
;
export
const
routes
:
Routes
=
[
...
...
@@ -40,7 +40,7 @@ export const routes: Routes = [
},
{
path
:
AppRoutes
.
data
.
uri
,
component
:
Dataset
Data
Component
,
component
:
Dataset
Table
Component
,
data
:
{
title
:
AppRoutes
.
data
.
title
,
},
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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