Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • web-et-numerique/web-et-numerique-internet/data.grandlyon.com/web-portal/components/custom-apps/admin-gui
1 result
Show changes
Commits on Source (4)
Showing
with 475 additions and 259 deletions
{ {
"name": "admin-gui", "name": "admin-gui",
"version": "1.0.0", "version": "1.1.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
...@@ -2306,9 +2306,9 @@ ...@@ -2306,9 +2306,9 @@
"dev": true "dev": true
}, },
"bulma": { "bulma": {
"version": "0.7.4", "version": "0.7.5",
"resolved": "https://registry.npmjs.org/bulma/-/bulma-0.7.4.tgz", "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.7.5.tgz",
"integrity": "sha512-krG2rP6eAX1WE0sf6O0SC/FUVSOBX4m1PBC2+GKLpb2pX0qanaDqcv9U2nu75egFrsHkI0zdWYuk/oGwoszVWg==" "integrity": "sha512-cX98TIn0I6sKba/DhW0FBjtaDpxTelU166pf7ICXpCCuplHWyu6C9LYZmL5PEsnePIeJaiorsTEzzNk3Tsm1hw=="
}, },
"bytes": { "bytes": {
"version": "3.0.0", "version": "3.0.0",
......
...@@ -5,10 +5,71 @@ ...@@ -5,10 +5,71 @@
</div> </div>
<h4>Plateforme Data Admin</h4> <h4>Plateforme Data Admin</h4>
<div class="logo"> <div class="navbar-header-item navbar-right-side">
<img src="assets/img/logo.svg" alt="Le Grand Lyon, la métropole"> <div class="connect-me">
<a routerLink="/login" *ngIf="!loggedInUserFullname; else userSignedInTemplate">
<button class="button connect-button">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23">
<g id="btn_x5F_connect">
<path
d="M11.5 11.7c-3.1 0-5.6-2.6-5.6-5.6C5.9 3 8.5.5 11.5.5c3.1 0 5.6 2.6 5.6 5.6 0 3-2.6 5.6-5.6 5.6zM17.2 14.6c1.3.6 2.3 1.5 3 2.6 1.2 1.9 1.2 3.8 1.2 3.9 0 .8-.6 1.4-1.2 1.4H2.6c-.6 0-1.2-.6-1.2-1.4 0-.1 0-2 1.2-3.9.7-1.1 1.8-2 3-2.6 1.6-.8 3.5-1.2 5.8-1.2s4.2.4 5.8 1.2z"
class="stroke_white" />
</g>
</svg>
<span>Me connecter</span>
</button>
</a>
</div>
<ng-template #userSignedInTemplate>
<div class="put-menu-to-right" [ngClass]="{'is-active': userDropdownIsOpened}">
<button class="button connect-button" (click)="toggleUserDropdown()"
(clickOutside)="closeUserDropdown()">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23" class="is-connected">
<g id="btn_x5F_connect">
<path
d="M11.5 11.7c-3.1 0-5.6-2.6-5.6-5.6C5.9 3 8.5.5 11.5.5c3.1 0 5.6 2.6 5.6 5.6 0 3-2.6 5.6-5.6 5.6zM17.2 14.6c1.3.6 2.3 1.5 3 2.6 1.2 1.9 1.2 3.8 1.2 3.9 0 .8-.6 1.4-1.2 1.4H2.6c-.6 0-1.2-.6-1.2-1.4 0-.1 0-2 1.2-3.9.7-1.1 1.8-2 3-2.6 1.6-.8 3.5-1.2 5.8-1.2s4.2.4 5.8 1.2z"
class="stroke_white" />
</g>
</svg>
<span class="text-overflow">{{ loggedInUserFullname }}</span>
</button>
<div class="dropdown-content user-information">
<a href preventDefault (click)="loggout()" class="dropdown-item with-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23">
<g id="picto_x5F_deconnect">
<g class="fill_black">
<g class="fill_black">
<path
d="M11 18H8c-1.7 0-3-1.3-3-3V9c0-1.7 1.3-3 3-3h3c.6 0 1 .4 1 1s-.4 1-1 1H8c-.6 0-1 .4-1 1v6c0 .6.4 1 1 1h3c.6 0 1 .4 1 1s-.4 1-1 1z"
class="fill_black" />
</g>
<g class="fill_black">
<path
d="M11 18H8c-1.7 0-3-1.3-3-3V9c0-1.7 1.3-3 3-3h3c.6 0 1 .4 1 1s-.4 1-1 1H8c-.6 0-1 .4-1 1v6c0 .6.4 1 1 1h3c.6 0 1 .4 1 1s-.4 1-1 1z"
class="fill_black" />
</g>
</g>
<path
d="M19.4 11.3L14.1 6v4H10c-.6 0-1 .4-1 1v2c0 .6.4 1 1 1h4.1v4l5.3-5.3c.4-.4.4-1 0-1.4z"
class="fill_black" />
</g>
</svg>
<span i18n="@@header.signOut">Sign Out</span>
</a>
</div>
</div>
<div class="modal" [ngClass]="{'is-active': userDropdownIsOpened}"></div>
</ng-template>
<div class="logo">
<img src="assets/img/logo.svg" alt="Le Grand Lyon, la métropole">
</div>
</div> </div>
</header> </header>
<nav class="main-nav" [ngClass]="{'is-active': sidebarOpened}"> <nav class="main-nav" [ngClass]="{'is-active': sidebarOpened}">
<app-menu [expanded]="sidebarOpened"></app-menu> <app-menu [expanded]="sidebarOpened"></app-menu>
......
@import '../scss/variables.scss';
@import '../../node_modules/bulma/sass/utilities/_all.sass';
.grid{ .grid {
display: grid; display: grid;
grid-template-columns: 50px auto; grid-template-columns: 50px auto;
grid-template-rows: 60px minmax(calc(100vh - 60px), auto); grid-template-rows: 60px minmax(calc(100vh - 60px), auto);
overflow: hidden; // overflow: hidden;
} }
.main-header{ .main-header {
grid-row: 1; grid-row: 1;
grid-column: 1 / -1; grid-column: 1 / span 2;
display: flex; display: flex;
flex-flow: row; flex-flow: row;
align-items: center; align-items: center;
background-color: white;; background-color: white;
border-bottom: 1px solid lightgray; border-bottom: 1px solid lightgray;
h4 { h4 {
...@@ -22,9 +24,9 @@ ...@@ -22,9 +24,9 @@
} }
.logo { .logo {
margin-left: auto;
padding-right: 20px; padding-right: 20px;
} }
.hamburger { .hamburger {
width: 50px; width: 50px;
height: 30px; height: 30px;
...@@ -36,29 +38,32 @@ ...@@ -36,29 +38,32 @@
} }
.hamburger.expanded { .hamburger.expanded {
background-image: url("../assets/img/hamburger_bitten.png"); background-image: url("../assets/img/hamburger_bitten.png");
} }
} }
.main-nav{ .main-nav {
grid-row: 2; grid-row: 2;
grid-column: 1 / span 1; grid-column: 1;
width: 50px; width: 50px;
z-index: 200; height: 100vh;
z-index: 200;
transition: all .2s linear; transition: all .2s linear;
background-color: #333745; background-color: #333745;
position: sticky;
top: 0px;
&.is-active { &.is-active {
width: 200px; width: 200px;
} }
} }
.main-content{ .main-content {
grid-row: 2; grid-row: 2;
grid-column: 2 / -1; grid-column: 2;
margin-left: 150px; margin-left: 150px;
background-color: #f2f2f2; background-color: $grey-background-color;
transition: all 200ms cubic-bezier(0.7, 0, 0.3, 1); transition: all 200ms cubic-bezier(0.7, 0, 0.3, 1);
&.wide { &.wide {
...@@ -66,3 +71,155 @@ ...@@ -66,3 +71,155 @@
} }
} }
// Connexion button
.text-overflow {
overflow: hidden;
text-overflow: ellipsis;
}
svg {
height: 21px;
stroke: $brand-color;
stroke-width: 1px;
flex-shrink: 0;
.stroke_white {
fill: transparent;
}
}
.connect-button {
border-color: $grey-dark-color;
width: 100%;
background: transparent;
padding: 0.5em 1.2em;
height: 2.5rem;
font-weight: 600;
line-height: 1;
span {
color: $grey-dark-color;
}
&:hover {
color: $grey-super-light-color;
}
svg {
margin-right: 0.6rem;
}
@media screen and (max-width: $tablet) {
height: 2.5rem;
width: 2.5rem;
padding: 7px;
justify-content: center;
svg {
margin-right: 0;
}
span {
display: none;
}
}
}
svg.is-connected {
.stroke_white {
fill: $grey-dark-color;
}
}
.navbar-right-side {
display: flex;
align-items: center;
z-index: 5;
margin-left: auto;
}
.dropdown-item.with-icon {
display: flex;
align-items: center;
span {
margin-left: 0.5rem;
}
svg {
fill: $brand-color;
}
&:hover {
background-color: transparent;
span {
font-weight: 600;
}
}
}
.put-menu-to-right {
position: relative;
z-index: 15;
.user-information {
width: 223px;
border-radius: 5px;
display: none;
position: absolute;
background-color: white;
top: 3.6em;
left: -151px;
padding: 0;
@media screen and (min-width: $tablet) {
left: -28px;
}
}
.user-information::before {
content: "";
position: absolute;
width: 12px;
height: 12px;
top: -6px;
left: 50%;
background: inherit;
border: inherit;
border-right: 0;
border-bottom: 0;
transform: rotate(45deg);
// When tablet, change the position to not be cut
@media screen and (max-width: $desktop) {
& {
left: 73%;
}
}
}
&.is-active {
.user-information {
display: block;
}
}
}
.connect-me {
margin-right: 1rem;
}
.connect-me a:hover {
text-decoration: none;
}
.modal.is-active {
position: fixed;
z-index: 10;
bottom: 0;
left: 0;
right: 0;
top: $header-bar-height;
background-color: rgba(10, 10, 10, 0.86);
}
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { UserService } from './user/services';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';
import { NavigationHistoryService } from './services';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
...@@ -9,11 +13,41 @@ export class AppComponent implements OnInit { ...@@ -9,11 +13,41 @@ export class AppComponent implements OnInit {
title: string; title: string;
sidebarOpened: boolean; sidebarOpened: boolean;
userDropdownIsOpened = false;
constructor( constructor(
) {} private _userService: UserService,
private _router: Router,
private _navigationHistoryService: NavigationHistoryService,
) { }
ngOnInit(): void { ngOnInit(): void {
this.sidebarOpened = false; this.sidebarOpened = true;
// Activate navigation history
this._router.events.pipe(
filter(e => e instanceof NavigationEnd),
).subscribe((e) => {
this._navigationHistoryService.add(e['urlAfterRedirects']);
});
}
get loggedInUserFullname() {
return this._userService.user ? `${this._userService.user.firstName} ${this._userService.user.lastName}` : null;
}
loggout() {
console.log('blabla')
this._userService.resetAuth();
this.closeUserDropdown();
this._router.navigate(['/login']);
}
toggleUserDropdown() {
this.userDropdownIsOpened = !this.userDropdownIsOpened;
}
closeUserDropdown() {
this.userDropdownIsOpened = false;
} }
} }
...@@ -10,6 +10,7 @@ import { AppServices, AppConfigService } from './services'; ...@@ -10,6 +10,7 @@ import { AppServices, AppConfigService } from './services';
import { AppComponents } from './components'; import { AppComponents } from './components';
import { UserModule } from './user/user.module'; import { UserModule } from './user/user.module';
import { UserService } from './user/services'; import { UserService } from './user/services';
import { AppDirectives } from './directives';
// Function used by APP_INITIALIZER before the app start: init user info / statut (expect a promise) // Function used by APP_INITIALIZER before the app start: init user info / statut (expect a promise)
export function initUserService(authService: UserService) { export function initUserService(authService: UserService) {
...@@ -34,6 +35,7 @@ export function initAppConfig(appConfigService: AppConfigService) { ...@@ -34,6 +35,7 @@ export function initAppConfig(appConfigService: AppConfigService) {
declarations: [ declarations: [
AppComponent, AppComponent,
...AppComponents, ...AppComponents,
...AppDirectives,
], ],
imports: [ imports: [
AppRoutingModule, AppRoutingModule,
......
import { WelcomeComponent } from './components/welcome/welcome.component';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { OrganizationsComponent } from './components/organizations/list/organizations.component'; import { OrganizationsComponent } from './components/organizations/list/organizations.component';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
...@@ -13,42 +12,39 @@ import { AuthenticatedGuard } from './user/guards/authenticated.guard'; ...@@ -13,42 +12,39 @@ import { AuthenticatedGuard } from './user/guards/authenticated.guard';
const appRoutes: Routes = [ const appRoutes: Routes = [
{ {
path: '', path: '',
component: WelcomeComponent, pathMatch: 'full',
canActivate: [AuthenticatedGuard], redirectTo: 'producteur-de-donnees',
data: {
title: 'Bienvenue',
},
}, },
{ {
path: 'organizations', path: 'producteur-de-donnees',
component: OrganizationsComponent, component: OrganizationsComponent,
canActivate: [AuthenticatedGuard], canActivate: [AuthenticatedGuard],
data: { data: {
title: 'Organisations', title: 'Producteur de donnees',
}, },
}, },
{ {
path: 'organizations/new', path: 'producteur-de-donnees/new',
component: OrganizationFormComponent, component: OrganizationFormComponent,
canActivate: [AuthenticatedGuard], canActivate: [AuthenticatedGuard],
data: { data: {
title: 'Nouvelle organisation', title: 'Nouveau producteur de données',
}, },
}, },
{ {
path: 'organizations/:id/edit', path: 'producteur-de-donnees/:id/edit',
component: OrganizationFormComponent, component: OrganizationFormComponent,
canActivate: [AuthenticatedGuard], canActivate: [AuthenticatedGuard],
data: { data: {
title: 'Modifier l\'organisation', title: 'Modifier le producteur de données',
}, },
}, },
{ {
path: 'organizations/:id', path: 'producteur-de-donnees/:id',
component: OrganizationDetailComponent, component: OrganizationDetailComponent,
canActivate: [AuthenticatedGuard], canActivate: [AuthenticatedGuard],
data: { data: {
title: 'Organisation', title: 'Detail du producteur de données',
}, },
}, },
{ {
...@@ -80,7 +76,7 @@ const appRoutes: Routes = [ ...@@ -80,7 +76,7 @@ const appRoutes: Routes = [
component: ResourceDetailComponent, component: ResourceDetailComponent,
canActivate: [AuthenticatedGuard], canActivate: [AuthenticatedGuard],
data: { data: {
title: 'Ressource', title: 'Detail de la ressource',
}, },
}, },
{ {
...@@ -112,7 +108,7 @@ const appRoutes: Routes = [ ...@@ -112,7 +108,7 @@ const appRoutes: Routes = [
component: FormatDetailComponent, component: FormatDetailComponent,
canActivate: [AuthenticatedGuard], canActivate: [AuthenticatedGuard],
data: { data: {
title: 'Format', title: 'Detail du format',
}, },
}, },
]; ];
......
<ng-container *ngIf="format"> <section class="section page-container" *ngIf="format">
<app-page-header [pageInfo]="{title: title}"></app-page-header>
<app-back-button [route]="'/formats'" [title]="'Retourner à la liste des formats'"></app-back-button> <div class="columns is-centered">
<div class="column is-8">
<section class="section"> <div class="card">
<div class="columns is-centered"> <header class="card-header">
<div class="column is-8"> <p class="card-header-title has-text-centered">
<div class="card"> {{format.name}}
<header class="card-header"> </p>
<p class="card-header-title has-text-centered"> </header>
{{format.name}} <div class="card-content">
<div class="content">
<p>
<span class="has-text-weight-bold">Id: </span>
<span>{{format.id}}</span>
</p>
<p>
<span class="has-text-weight-bold">Type MapServer: </span>
<span>{{format.mapServerType}}</span>
</p> </p>
</header>
<div class="card-content">
<div class="content">
<p>
<span class="has-text-weight-bold">Id: </span>
<span>{{format.id}}</span>
</p>
<p>
<span class="has-text-weight-bold">Type MapServer: </span>
<span>{{format.mapServerType}}</span>
</p>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </div>
</ng-container> </section>
\ No newline at end of file \ No newline at end of file
...@@ -13,6 +13,7 @@ import { Format } from 'src/app/models/format.model'; ...@@ -13,6 +13,7 @@ import { Format } from 'src/app/models/format.model';
export class FormatDetailComponent implements OnInit { export class FormatDetailComponent implements OnInit {
format: Format; format: Format;
title: string;
constructor( constructor(
private _route: ActivatedRoute, private _route: ActivatedRoute,
...@@ -21,6 +22,7 @@ export class FormatDetailComponent implements OnInit { ...@@ -21,6 +22,7 @@ export class FormatDetailComponent implements OnInit {
} }
ngOnInit(): void { ngOnInit(): void {
this.title = this._route.snapshot.data.title;
this._route.paramMap.pipe( this._route.paramMap.pipe(
switchMap((params: ParamMap) => this._formatService.findById(params.get('id')))) switchMap((params: ParamMap) => this._formatService.findById(params.get('id'))))
.subscribe((format: Format) => this.format = format); .subscribe((format: Format) => this.format = format);
......
<ng-container *ngIf="format"> <section class="section page-container" *ngIf="format">
<app-page-header [pageInfo]="{title: title}"></app-page-header>
<app-back-button [route]="'/formats'" [title]="'Retourner à la liste des formats'"></app-back-button>
<h1>{{ title }}</h1>
<form [formGroup]="form" (ngSubmit)="onSubmit()" class="columns is-centered is-marginless"> <form [formGroup]="form" (ngSubmit)="onSubmit()" class="columns is-centered is-marginless">
<div class="column is-7"> <div class="column is-7">
...@@ -38,4 +35,4 @@ ...@@ -38,4 +35,4 @@
</div> </div>
</div> </div>
</form> </form>
</ng-container> </section>
\ No newline at end of file \ No newline at end of file
<ng-container *ngIf="formats"> <section class="section page-container" *ngIf="formats">
<div> <app-page-header [pageInfo]="pageHeaderInfo" [hideBackButton]="true"></app-page-header>
<div class="section"> <div class="add-item-link has-text-right">
<div class="columns is-centered is-marginless"> <a class="button button-gl" [routerLink]="['new']">
<div class="column has-text-centered"> Ajouter
<h2>{{ totalElement }} formats trouvés</h2> </a>
</div> </div>
</div> <div class="table entity-list-table">
<div class="add-item has-text-right"> <div class="header columns is-marginless">
<a class="button button-gl" [routerLink]="['new']"> <div class="column is-2">
Ajouter <span (click)="sortBy('name')" class="is-sortable">
</a> <span class="sort-icons">
<span class="icon">
<i class="fas fa-sort-up"
[ngClass]="{'icon-red': sortOptions.value === 'name' && sortOptions.order === 'desc'}"></i>
</span>
<span class="icon">
<i class="fas fa-sort-down"
[ngClass]="{'icon-red': sortOptions.value === 'name' && sortOptions.order === 'asc'}"></i>
</span>
</span>
<span class="column-title" [ngClass]="{'active': sortOptions.value === name}">Nom</span>
</span>
</div> </div>
<div class="table"> <div class="column is-2">
<div class="header columns is-marginless"> <span (click)="sortBy('mapServerType')" class="is-sortable">
<div class="column is-2 has-text-centered"> <span class="sort-icons">
<span (click)="sortBy('name')" class="is-sortable"> <span class="icon">
<span class="column-title" [ngClass]="{'active': sortOptions.value === name}">Name</span> <i class="fas fa-sort-up"
<span *ngIf="sortOptions.value === 'name'" class="has-text-danger"> [ngClass]="{'icon-red': sortOptions.value === 'mapServerType' && sortOptions.order === 'desc'}"></i>
<i class="fas sort-order-icon" </span>
[ngClass]="{'fa-arrow-up': sortOptions.order === 'asc', 'fa-arrow-down': sortOptions.order === 'desc'}"></i> <span class="icon">
</span> <i class="fas fa-sort-down"
[ngClass]="{'icon-red': sortOptions.value === 'mapServerType' && sortOptions.order === 'asc'}"></i>
</span> </span>
</div> </span>
<div class="column is-2 has-text-centered"> <span class="column-title" [ngClass]="{'active': sortOptions.value === mapServerType}">Type
<span class="column-title">Type MapServer</span> MapServer</span>
</div> </span>
<div class="column is-offset-7 is-1 has-text-centered"> </div>
<span class="column-title">Actions</span> <div class="column is-offset-7 is-1 has-text-centered">
</div> <span class="column-title">Actions</span>
</div>
</div>
<div class="data-list">
<div class="data columns is-multiline is-vcentered is-marginless"
*ngFor="let format of formats; let i=index; let odd=odd; let even=even;" [ngClass]="{ odd: odd, even: even }">
<div class="column is-2">
<span>{{ format.name}}</span>
</div> </div>
<div class="data-list"> <div class="column is-2">
<div class="data columns is-multiline is-vcentered is-marginless" <span>{{ format.mapServerType}}</span>
*ngFor="let format of formats; let i=index; let odd=odd; let even=even;"
[ngClass]="{ odd: odd, even: even }">
<div class="column is-2 has-text-centered">
{{ format.name}}
</div>
<div class="column is-2 has-text-centered">
{{ format.mapServerType}}
</div>
<div class="column is-offset-7 is-1 has-text-centered actions">
<app-crud-buttons [id]="format.id" (delete)="displayDeletePopup($event)"></app-crud-buttons>
</div>
</div>
</div> </div>
<div class="columns is-marginless"> <div class="column is-offset-7 is-1 has-text-centered actions">
<div class="column"> <app-crud-buttons [id]="format.id" (delete)="displayDeletePopup($event)"></app-crud-buttons>
<app-paginator *ngIf="paginator.length > 0" [length]="paginator.length" [pageSize]="paginator.limit"
[pageSizeOptions]="paginator.pageSizeOptions" [pageIndex]="paginator.pageIndex" [pagesToShow]="5"
[showFirstLastButtons]="true" (page)="changePagination($event)"
(pageSizeChanged)="changePageSize($event)">
</app-paginator>
</div>
</div> </div>
</div> </div>
</div> </div>
<div class="columns is-marginless paginator">
<div class="column">
<app-paginator *ngIf="paginator.length > 0" [length]="paginator.length" [pageSize]="paginator.limit"
[pageSizeOptions]="paginator.pageSizeOptions" [pageIndex]="paginator.pageIndex" [pagesToShow]="5"
[showFirstLastButtons]="true" (page)="changePagination($event)" (pageSizeChanged)="changePageSize($event)">
</app-paginator>
</div>
</div>
</div> </div>
</ng-container> </section>
\ No newline at end of file
section {
padding: 20px;
}
.section {
padding-top: 0;
}
.table {
background-color: white;
border: 1px solid lightgray;
}
.center {
text-align: center;
}
img {
max-width: 100px;
}
.header {
border-bottom: 1px solid lightgray;
background-color: #fafafa;
span {
color: #999;
}
}
.is-sortable .column-title {
cursor: pointer;
}
.table .columns {
border-bottom: 1px solid lightgray
}
i {
&.title-icon {
margin-right: 0.75rem;
}
&.sort-order-icon {
padding-left: 0.75rem;
cursor: pointer;
}
}
.add-item {
margin-bottom: 20px;
}
...@@ -3,6 +3,7 @@ import { FormatService } from 'src/app/services/format.service'; ...@@ -3,6 +3,7 @@ import { FormatService } from 'src/app/services/format.service';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { PaginatorOptions } from 'src/app/models/paginator-options.model'; import { PaginatorOptions } from 'src/app/models/paginator-options.model';
import { Format, FormatRO } from 'src/app/models/format.model'; import { Format, FormatRO } from 'src/app/models/format.model';
import { IPageHeaderInfo } from '../../../models/page.model';
@Component({ @Component({
selector: 'app-formats', selector: 'app-formats',
...@@ -11,6 +12,9 @@ import { Format, FormatRO } from 'src/app/models/format.model'; ...@@ -11,6 +12,9 @@ import { Format, FormatRO } from 'src/app/models/format.model';
}) })
export class FormatsComponent implements OnInit { export class FormatsComponent implements OnInit {
pageHeaderInfo: IPageHeaderInfo = {
title: '',
};
formats: Format[]; formats: Format[];
searchChangeSub: Subscription; searchChangeSub: Subscription;
...@@ -58,6 +62,8 @@ export class FormatsComponent implements OnInit { ...@@ -58,6 +62,8 @@ export class FormatsComponent implements OnInit {
this.formats = items.formats; this.formats = items.formats;
this.totalElement = items.totalCount; this.totalElement = items.totalCount;
this.pageHeaderInfo.title = `${this.totalElement} formats trouvés`;
this.paginator.limit = this.formatsService.limit; this.paginator.limit = this.formatsService.limit;
this.paginator.pageIndex = this.formatsService.pageNumber; this.paginator.pageIndex = this.formatsService.pageNumber;
this.paginator.length = items.totalCount; this.paginator.length = items.totalCount;
......
<div class="field"> <div class="field">
<label class="label" [for]="fieldParams.inputName">{{ fieldParams.label }}</label> <label class="label" [ngClass]="{'required': fieldParams.isRequired}"
[for]="fieldParams.inputName">{{ fieldParams.label }}</label>
<div class="image-preview-container" *ngIf="fieldParams.existingImageUrl && !removeImageBtnClicked"> <div class="image-preview-container" *ngIf="fieldParams.existingImageUrl && !removeImageBtnClicked">
<button class="button" (click)="removeImage()"><i class="far fa-times-circle"></i></button> <button class="button" (click)="removeImage()"><i class="far fa-times-circle"></i></button>
<img [src]="fieldParams.existingImageUrl" alt="" class="image-preview"> <img [src]="fieldParams.existingImageUrl" alt="" class="image-preview">
......
...@@ -6,7 +6,6 @@ import { PaginatorComponent } from './paginator/paginator.component'; ...@@ -6,7 +6,6 @@ import { PaginatorComponent } from './paginator/paginator.component';
import { ResourceDetailComponent } from './resources/detail/resource-detail.component'; import { ResourceDetailComponent } from './resources/detail/resource-detail.component';
import { ResourceFormComponent } from './resources/edit/resource-form.component'; import { ResourceFormComponent } from './resources/edit/resource-form.component';
import { ResourcesComponent } from './resources/list/resources.component'; import { ResourcesComponent } from './resources/list/resources.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { BackButtonComponent } from './back-button/back-button.component'; import { BackButtonComponent } from './back-button/back-button.component';
import { CrudButtonsComponent } from './crud-buttons/crud-buttons.component'; import { CrudButtonsComponent } from './crud-buttons/crud-buttons.component';
import { FormatsComponent } from './formats/list/formats.component'; import { FormatsComponent } from './formats/list/formats.component';
...@@ -14,6 +13,7 @@ import { FormatDetailComponent } from './formats/detail/format-detail.component' ...@@ -14,6 +13,7 @@ import { FormatDetailComponent } from './formats/detail/format-detail.component'
import { FormatFormComponent } from './formats/edit/format-form.component'; import { FormatFormComponent } from './formats/edit/format-form.component';
import { ImageUploadComponent } from './image-upload/image-upload.component'; import { ImageUploadComponent } from './image-upload/image-upload.component';
import { NotificationsComponent } from './notifications/notifications.component'; import { NotificationsComponent } from './notifications/notifications.component';
import { PageHeaderComponent } from './page-header/page-header.component';
export { export {
MenuComponent, MenuComponent,
...@@ -24,7 +24,6 @@ export { ...@@ -24,7 +24,6 @@ export {
ResourceDetailComponent, ResourceDetailComponent,
ResourceFormComponent, ResourceFormComponent,
ResourcesComponent, ResourcesComponent,
WelcomeComponent,
BackButtonComponent, BackButtonComponent,
CrudButtonsComponent, CrudButtonsComponent,
FormatsComponent, FormatsComponent,
...@@ -32,6 +31,7 @@ export { ...@@ -32,6 +31,7 @@ export {
FormatFormComponent, FormatFormComponent,
ImageUploadComponent, ImageUploadComponent,
NotificationsComponent, NotificationsComponent,
PageHeaderComponent,
}; };
// tslint:disable-next-line:variable-name // tslint:disable-next-line:variable-name
...@@ -44,7 +44,6 @@ export const AppComponents = [ ...@@ -44,7 +44,6 @@ export const AppComponents = [
ResourceDetailComponent, ResourceDetailComponent,
ResourceFormComponent, ResourceFormComponent,
ResourcesComponent, ResourcesComponent,
WelcomeComponent,
BackButtonComponent, BackButtonComponent,
CrudButtonsComponent, CrudButtonsComponent,
FormatsComponent, FormatsComponent,
...@@ -52,4 +51,5 @@ export const AppComponents = [ ...@@ -52,4 +51,5 @@ export const AppComponents = [
FormatFormComponent, FormatFormComponent,
ImageUploadComponent, ImageUploadComponent,
NotificationsComponent, NotificationsComponent,
PageHeaderComponent,
]; ];
<aside class="menu" [ngClass]="{'expanded': expanded}"> <aside class="menu" [ngClass]="{'expanded': expanded}">
<ul class="menu-list"> <ul class="menu-list">
<li><a [routerLink]="['/']" routerLinkActive="active-link" [routerLinkActiveOptions]="{ exact: true }"> <li><a [routerLink]="['/', 'producteur-de-donnees']" routerLinkActive="active-link">
<span class="icon"> <span class="icon">
<i class="fas fa-home"></i> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 23 23">
<g id="picto_x5F_acteur">
<path
d="M16.2 12.8c1.1-.8 1.8-2 1.8-3.3 0-2.2-1.8-4-4-4s-4 1.8-4 4c0 1.4.7 2.6 1.8 3.3-3 1-5.2 3.8-5.2 7.1 0 .3.2.5.5.5s.5-.2.5-.5c0-3.6 2.9-6.5 6.5-6.5s6.5 2.9 6.5 6.5c0 .3.2.5.5.5s.5-.2.5-.5c-.1-3.4-2.3-6.2-5.4-7.1zm-5.3-3.3c0-1.6 1.4-3 3-3s3 1.3 3 3-1.4 3-3 3-3-1.4-3-3zM7.9 9.5c0-.4 0-.8.1-1.2-1.2-.4-2.1-1.5-2.1-2.8 0-1.6 1.4-3 3-3 1.1 0 2.1.6 2.6 1.4.3-.1.6-.2 1-.3-.7-1.3-2-2.1-3.6-2.1-2.2 0-4 1.8-4 4 0 1.4.7 2.6 1.8 3.3-3 1-5.2 3.8-5.2 7.1 0 .3.2.5.5.5s.5-.2.5-.5c0-3.2 2.4-5.8 5.4-6.4z"
class="main" />
</g>
</svg>
</span> </span>
<span class="label-menu">Dashboard</span> <span class="label-menu">Producteurs de données</span>
</a>
</li>
<li><a [routerLink]="['/', 'organizations']" routerLinkActive="active-link">
<span class="icon">
<i class="fas fa-city"></i>
</span>
<span class="label-menu">Organisations</span>
</a> </a>
</li> </li>
<li><a [routerLink]="['/', 'resources']" routerLinkActive="active-link"> <li><a [routerLink]="['/', 'resources']" routerLinkActive="active-link">
<span class="icon"> <span class="icon">
<i class="fas fa-tint"></i> <i class="fas fa-tint"></i>
</span> </span>
<span class="label-menu">Ressources</span> <span class="label-menu">Ressources</span>
</a> </a>
</li> </li>
<li><a [routerLink]="['/', 'formats']" routerLinkActive="active-link"> <li><a [routerLink]="['/', 'formats']" routerLinkActive="active-link">
<span class="icon"> <span class="icon">
<i class="far fa-file"></i> <i class="far fa-file"></i>
</span> </span>
<span class="label-menu">Formats</span> <span class="label-menu">Formats</span>
</a> </a>
</li> </li>
</ul> </ul>
</aside> </aside>
\ No newline at end of file
@import '../../../scss/variables.scss';
.menu { .menu {
padding: 0px; padding: 0px;
padding-top: 20px;
span { span {
color: white; color: white;
} }
.icon svg {
stroke: white;
width: 1.2rem;
}
a { a {
white-space: nowrap; display: flex;
overflow-x: hidden; align-items: center;
overflow-y: hidden;
} }
.label-menu { .label-menu {
...@@ -21,13 +26,6 @@ ...@@ -21,13 +26,6 @@
} }
.menu.expanded { .menu.expanded {
a {
white-space: nowrap;
overflow-x: hidden;
overflow-y: hidden;
}
.label-menu { .label-menu {
padding-left: 10px; padding-left: 10px;
opacity: 1; opacity: 1;
...@@ -40,10 +38,28 @@ ...@@ -40,10 +38,28 @@
li a { li a {
border-left: 3px solid #333745; border-left: 3px solid #333745;
padding-left: calc(0.75em - 3px) ; padding: 1rem calc(1rem - 3px);
&.active-link { &.active-link {
border-color:#d5232a; background-color: $background-link-hover-color;
border-color: #d5232a;
span {
color: $menu-selected-color;
}
.icon svg {
stroke: $menu-selected-color;
}
}
&:hover {
color: white;
background-color: $background-link-hover-color;
}
&:hover:not(.active-link) {
border-left: 3px solid $background-link-hover-color;
} }
}
}
...@@ -11,8 +11,7 @@ export class MenuComponent { ...@@ -11,8 +11,7 @@ export class MenuComponent {
@Input() expanded: boolean; @Input() expanded: boolean;
constructor( constructor() {
) {
} }
} }
<ng-container *ngIf="organization"> <section class="section page-container" *ngIf="organization">
<app-page-header [pageInfo]="{title: title}"></app-page-header>
<app-back-button [route]="'/organizations'" [title]="'Retourner à la liste des organisations'"></app-back-button> <div class="columns is-centered">
<div class="column is-8">
<section class="section"> <div class="card">
<div class="columns is-centered"> <header class="card-header">
<div class="column is-8"> <p class="card-header-title has-text-centered">
<div class="card"> {{organization.name}}
<header class="card-header"> </p>
<p class="card-header-title has-text-centered"> </header>
{{organization.name}} <div class="card-image">
</p> <figure class="image">
</header> <img [src]="organization.logo" alt="Logo du producteur de données">
<div class="card-image"> </figure>
<figure class="image"> </div>
<img [src]="organization.logo" alt="Logo de l'organization"> <div class="card-content">
</figure>
</div>
<div class="card-content">
<div class="content">
<div>
<p>{{organization.description}}</p>
</div>
<br>
<div>
<p><span class="has-text-weight-bold">Id:</span> {{ organization.id}}</p>
</div>
<br>
<div>
<p class="has-text-weight-bold">Nom ElasticSearch de l'organisation:</p>
<p>{{ organization.elasticSearchName}}</p>
</div>
<br>
<div>
<p class="has-text-weight-bold">Liens</p>
<p *ngFor="let link of organization.links">
<a href="{{ link.url }}" target="_blank">{{link.url}}</a>
</p>
</div>
<div class="content">
<div>
<p>{{organization.description}}</p>
</div>
<br>
<div>
<p><span class="has-text-weight-bold">Id:</span> {{ organization.id}}</p>
</div>
<br>
<div>
<p class="has-text-weight-bold">Nom ElasticSearch de l'organisation:</p>
<p>{{ organization.elasticSearchName}}</p>
</div>
<br>
<div>
<p class="has-text-weight-bold">Liens</p>
<p *ngFor="let link of organization.links">
<a href="{{ link.url }}" target="_blank">{{link.url}}</a>
</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</section>
</section> \ No newline at end of file
</ng-container>
\ No newline at end of file
...@@ -14,16 +14,18 @@ import { OrganizationService } from 'src/app/services/organization.service'; ...@@ -14,16 +14,18 @@ import { OrganizationService } from 'src/app/services/organization.service';
export class OrganizationDetailComponent implements OnInit { export class OrganizationDetailComponent implements OnInit {
organization: Organization; organization: Organization;
title: string;
constructor( constructor(
private route: ActivatedRoute, private _route: ActivatedRoute,
private organizationService: OrganizationService, private _organizationService: OrganizationService,
) { ) {
} }
ngOnInit(): void { ngOnInit(): void {
this.route.paramMap.pipe( this.title = this._route.snapshot.data.title;
switchMap((params: ParamMap) => this.organizationService.findById(params.get('id')))) this._route.paramMap.pipe(
switchMap((params: ParamMap) => this._organizationService.findById(params.get('id'))))
.subscribe((organization: Organization) => this.organization = organization); .subscribe((organization: Organization) => this.organization = organization);
} }
} }