mirror of
https://github.com/xuthus83/pigallery2.git
synced 2025-01-14 14:43:17 +08:00
creating navbar design
This commit is contained in:
parent
d974c8f8ab
commit
75faadaef0
@ -4,4 +4,5 @@ export interface ISearchManager {
|
||||
autocomplete(text: string, cb: (error: any, result: Array<AutoCompleteItem>) => void): void;
|
||||
search(text: string, searchType: SearchTypes, cb: (error: any, result: SearchResultDTO) => void): void;
|
||||
instantSearch(text: string, cb: (error: any, result: SearchResultDTO) => void): void;
|
||||
isSupported(): boolean;
|
||||
}
|
@ -3,4 +3,5 @@ export interface ISharingManager {
|
||||
findOne(filter: any): Promise<SharingDTO>;
|
||||
createSharing(sharing: SharingDTO): Promise<SharingDTO>;
|
||||
updateSharing(sharing: SharingDTO): Promise<SharingDTO>;
|
||||
isSupported(): boolean;
|
||||
}
|
||||
|
@ -4,18 +4,21 @@ import {SearchResultDTO} from "../../../common/entities/SearchResult";
|
||||
|
||||
export class SearchManager implements ISearchManager {
|
||||
|
||||
isSupported(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
autocomplete(text: string, cb: (error: any, result: Array<AutoCompleteItem>) => void) {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
autocomplete(text: string, cb: (error: any, result: Array<AutoCompleteItem>) => void) {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
search(text: string, searchType: SearchTypes, cb: (error: any, result: SearchResultDTO) => void) {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
search(text: string, searchType: SearchTypes, cb: (error: any, result: SearchResultDTO) => void) {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
instantSearch(text: string, cb: (error: any, result: SearchResultDTO) => void) {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
instantSearch(text: string, cb: (error: any, result: SearchResultDTO) => void) {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -3,6 +3,10 @@ import {SharingDTO} from "../../../common/entities/SharingDTO";
|
||||
|
||||
export class SharingManager implements ISharingManager {
|
||||
|
||||
isSupported(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
findOne(filter: any): Promise<SharingDTO> {
|
||||
throw new Error("not implemented");
|
||||
}
|
||||
|
@ -8,184 +8,187 @@ import {PositionMetaData} from "../../../common/entities/PhotoDTO";
|
||||
|
||||
export class SearchManager implements ISearchManager {
|
||||
|
||||
isSupported(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
autocomplete(text: string, cb: (error: any, result: Array<AutoCompleteItem>) => void) {
|
||||
autocomplete(text: string, cb: (error: any, result: Array<AutoCompleteItem>) => void) {
|
||||
|
||||
MySQLConnection.getConnection().then(async connection => {
|
||||
try {
|
||||
let result: Array<AutoCompleteItem> = [];
|
||||
let photoRepository = connection.getRepository(PhotoEntity);
|
||||
let directoryRepository = connection.getRepository(DirectoryEntity);
|
||||
MySQLConnection.getConnection().then(async connection => {
|
||||
try {
|
||||
let result: Array<AutoCompleteItem> = [];
|
||||
let photoRepository = connection.getRepository(PhotoEntity);
|
||||
let directoryRepository = connection.getRepository(DirectoryEntity);
|
||||
|
||||
|
||||
(await photoRepository
|
||||
.createQueryBuilder('photo')
|
||||
.select('DISTINCT(photo.metadataKeywords)')
|
||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(5)
|
||||
.getRawMany())
|
||||
.map(r => <Array<string>>JSON.parse(r.metadataKeywords))
|
||||
.forEach(keywords => {
|
||||
result = result.concat(this.encapsulateAutoComplete(keywords.filter(k => k.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.keyword));
|
||||
});
|
||||
(await photoRepository
|
||||
.createQueryBuilder('photo')
|
||||
.select('DISTINCT(photo.metadataKeywords)')
|
||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(5)
|
||||
.getRawMany())
|
||||
.map(r => <Array<string>>JSON.parse(r.metadataKeywords))
|
||||
.forEach(keywords => {
|
||||
result = result.concat(this.encapsulateAutoComplete(keywords.filter(k => k.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.keyword));
|
||||
});
|
||||
|
||||
|
||||
(await photoRepository
|
||||
.createQueryBuilder('photo')
|
||||
.select('DISTINCT(photo.metadataPositionData)')
|
||||
.where('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(5)
|
||||
.getRawMany())
|
||||
.map(r => <PositionMetaData>JSON.parse(r.metadataPositionData))
|
||||
.map(pm => <Array<string>>[pm.city || "", pm.country || "", pm.state || ""])
|
||||
.forEach(positions => {
|
||||
result = result.concat(this.encapsulateAutoComplete(positions.filter(p => p.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.position));
|
||||
});
|
||||
(await photoRepository
|
||||
.createQueryBuilder('photo')
|
||||
.select('DISTINCT(photo.metadataPositionData)')
|
||||
.where('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(5)
|
||||
.getRawMany())
|
||||
.map(r => <PositionMetaData>JSON.parse(r.metadataPositionData))
|
||||
.map(pm => <Array<string>>[pm.city || "", pm.country || "", pm.state || ""])
|
||||
.forEach(positions => {
|
||||
result = result.concat(this.encapsulateAutoComplete(positions.filter(p => p.toLowerCase().indexOf(text.toLowerCase()) != -1), SearchTypes.position));
|
||||
});
|
||||
|
||||
|
||||
result = result.concat(this.encapsulateAutoComplete((await photoRepository
|
||||
.createQueryBuilder('photo')
|
||||
.select('DISTINCT(photo.name)')
|
||||
.where('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(5)
|
||||
.getRawMany())
|
||||
.map(r => r.name), SearchTypes.image));
|
||||
result = result.concat(this.encapsulateAutoComplete((await photoRepository
|
||||
.createQueryBuilder('photo')
|
||||
.select('DISTINCT(photo.name)')
|
||||
.where('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(5)
|
||||
.getRawMany())
|
||||
.map(r => r.name), SearchTypes.image));
|
||||
|
||||
result = result.concat(this.encapsulateAutoComplete((await directoryRepository
|
||||
.createQueryBuilder('dir')
|
||||
.select('DISTINCT(dir.name)')
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(5)
|
||||
.getRawMany())
|
||||
.map(r => r.name), SearchTypes.directory));
|
||||
result = result.concat(this.encapsulateAutoComplete((await directoryRepository
|
||||
.createQueryBuilder('dir')
|
||||
.select('DISTINCT(dir.name)')
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(5)
|
||||
.getRawMany())
|
||||
.map(r => r.name), SearchTypes.directory));
|
||||
|
||||
|
||||
return cb(null, this.autoCompleteItemsUnique(result));
|
||||
} catch (error) {
|
||||
return cb(error, null);
|
||||
}
|
||||
return cb(null, this.autoCompleteItemsUnique(result));
|
||||
} catch (error) {
|
||||
return cb(error, null);
|
||||
}
|
||||
|
||||
}).catch((error) => {
|
||||
return cb(error, null);
|
||||
});
|
||||
}
|
||||
}).catch((error) => {
|
||||
return cb(error, null);
|
||||
});
|
||||
}
|
||||
|
||||
search(text: string, searchType: SearchTypes, cb: (error: any, result: SearchResultDTO) => void) {
|
||||
MySQLConnection.getConnection().then(async connection => {
|
||||
search(text: string, searchType: SearchTypes, cb: (error: any, result: SearchResultDTO) => void) {
|
||||
MySQLConnection.getConnection().then(async connection => {
|
||||
|
||||
let result: SearchResultDTO = <SearchResultDTO>{
|
||||
searchText: text,
|
||||
searchType: searchType,
|
||||
directories: [],
|
||||
photos: []
|
||||
};
|
||||
let result: SearchResultDTO = <SearchResultDTO>{
|
||||
searchText: text,
|
||||
searchType: searchType,
|
||||
directories: [],
|
||||
photos: []
|
||||
};
|
||||
|
||||
let query = connection
|
||||
.getRepository(PhotoEntity)
|
||||
.createQueryBuilder("photo");
|
||||
let query = connection
|
||||
.getRepository(PhotoEntity)
|
||||
.createQueryBuilder("photo");
|
||||
|
||||
|
||||
if (!searchType || searchType === SearchTypes.image) {
|
||||
query.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
}
|
||||
if (!searchType || searchType === SearchTypes.image) {
|
||||
query.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
}
|
||||
|
||||
if (!searchType || searchType === SearchTypes.position) {
|
||||
query.orWhere('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
}
|
||||
if (!searchType || searchType === SearchTypes.keyword) {
|
||||
query.orWhere('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
}
|
||||
let photos = await query
|
||||
.innerJoinAndSelect("photo.directory", "directory")
|
||||
.getMany();
|
||||
if (!searchType || searchType === SearchTypes.position) {
|
||||
query.orWhere('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
}
|
||||
if (!searchType || searchType === SearchTypes.keyword) {
|
||||
query.orWhere('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"});
|
||||
}
|
||||
let photos = await query
|
||||
.innerJoinAndSelect("photo.directory", "directory")
|
||||
.getMany();
|
||||
|
||||
|
||||
if (photos) {
|
||||
for (let i = 0; i < photos.length; i++) {
|
||||
photos[i].metadata.keywords = <any>JSON.parse(<any>photos[i].metadata.keywords);
|
||||
photos[i].metadata.cameraData = <any>JSON.parse(<any>photos[i].metadata.cameraData);
|
||||
photos[i].metadata.positionData = <any>JSON.parse(<any>photos[i].metadata.positionData);
|
||||
photos[i].metadata.size = <any>JSON.parse(<any>photos[i].metadata.size);
|
||||
}
|
||||
result.photos = photos;
|
||||
}
|
||||
|
||||
result.directories = await connection
|
||||
.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder("dir")
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.getMany();
|
||||
|
||||
|
||||
return cb(null, result);
|
||||
}).catch((error) => {
|
||||
return cb(error, null);
|
||||
});
|
||||
}
|
||||
|
||||
instantSearch(text: string, cb: (error: any, result: SearchResultDTO) => void) {
|
||||
MySQLConnection.getConnection().then(async connection => {
|
||||
|
||||
let result: SearchResultDTO = <SearchResultDTO>{
|
||||
searchText: text,
|
||||
directories: [],
|
||||
photos: []
|
||||
};
|
||||
|
||||
let photos = await connection
|
||||
.getRepository(PhotoEntity)
|
||||
.createQueryBuilder("photo")
|
||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.innerJoinAndSelect("photo.directory", "directory")
|
||||
.setLimit(10)
|
||||
.getMany();
|
||||
|
||||
|
||||
if (photos) {
|
||||
for (let i = 0; i < photos.length; i++) {
|
||||
photos[i].metadata.keywords = <any>JSON.parse(<any>photos[i].metadata.keywords);
|
||||
photos[i].metadata.cameraData = <any>JSON.parse(<any>photos[i].metadata.cameraData);
|
||||
photos[i].metadata.positionData = <any>JSON.parse(<any>photos[i].metadata.positionData);
|
||||
photos[i].metadata.size = <any>JSON.parse(<any>photos[i].metadata.size);
|
||||
}
|
||||
result.photos = photos;
|
||||
}
|
||||
|
||||
let directories = await connection
|
||||
.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder("dir")
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(10)
|
||||
.getMany();
|
||||
|
||||
result.directories = directories;
|
||||
|
||||
return cb(null, result);
|
||||
}).catch((error) => {
|
||||
return cb(error, null);
|
||||
});
|
||||
}
|
||||
|
||||
private encapsulateAutoComplete(values: Array<string>, type: SearchTypes) {
|
||||
let res = [];
|
||||
values.forEach((value) => {
|
||||
res.push(new AutoCompleteItem(value, type));
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private autoCompleteItemsUnique(array: Array<AutoCompleteItem>) {
|
||||
let a = array.concat();
|
||||
for (let i = 0; i < a.length; ++i) {
|
||||
for (let j = i + 1; j < a.length; ++j) {
|
||||
if (a[i].equals(a[j]))
|
||||
a.splice(j--, 1);
|
||||
}
|
||||
if (photos) {
|
||||
for (let i = 0; i < photos.length; i++) {
|
||||
photos[i].metadata.keywords = <any>JSON.parse(<any>photos[i].metadata.keywords);
|
||||
photos[i].metadata.cameraData = <any>JSON.parse(<any>photos[i].metadata.cameraData);
|
||||
photos[i].metadata.positionData = <any>JSON.parse(<any>photos[i].metadata.positionData);
|
||||
photos[i].metadata.size = <any>JSON.parse(<any>photos[i].metadata.size);
|
||||
}
|
||||
result.photos = photos;
|
||||
}
|
||||
|
||||
return a;
|
||||
result.directories = await connection
|
||||
.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder("dir")
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.getMany();
|
||||
|
||||
|
||||
return cb(null, result);
|
||||
}).catch((error) => {
|
||||
return cb(error, null);
|
||||
});
|
||||
}
|
||||
|
||||
instantSearch(text: string, cb: (error: any, result: SearchResultDTO) => void) {
|
||||
MySQLConnection.getConnection().then(async connection => {
|
||||
|
||||
let result: SearchResultDTO = <SearchResultDTO>{
|
||||
searchText: text,
|
||||
directories: [],
|
||||
photos: []
|
||||
};
|
||||
|
||||
let photos = await connection
|
||||
.getRepository(PhotoEntity)
|
||||
.createQueryBuilder("photo")
|
||||
.where('photo.metadata.keywords LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.metadata.positionData LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.orWhere('photo.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.innerJoinAndSelect("photo.directory", "directory")
|
||||
.setLimit(10)
|
||||
.getMany();
|
||||
|
||||
|
||||
if (photos) {
|
||||
for (let i = 0; i < photos.length; i++) {
|
||||
photos[i].metadata.keywords = <any>JSON.parse(<any>photos[i].metadata.keywords);
|
||||
photos[i].metadata.cameraData = <any>JSON.parse(<any>photos[i].metadata.cameraData);
|
||||
photos[i].metadata.positionData = <any>JSON.parse(<any>photos[i].metadata.positionData);
|
||||
photos[i].metadata.size = <any>JSON.parse(<any>photos[i].metadata.size);
|
||||
}
|
||||
result.photos = photos;
|
||||
}
|
||||
|
||||
let directories = await connection
|
||||
.getRepository(DirectoryEntity)
|
||||
.createQueryBuilder("dir")
|
||||
.where('dir.name LIKE :text COLLATE utf8_general_ci', {text: "%" + text + "%"})
|
||||
.setLimit(10)
|
||||
.getMany();
|
||||
|
||||
result.directories = directories;
|
||||
|
||||
return cb(null, result);
|
||||
}).catch((error) => {
|
||||
return cb(error, null);
|
||||
});
|
||||
}
|
||||
|
||||
private encapsulateAutoComplete(values: Array<string>, type: SearchTypes) {
|
||||
let res = [];
|
||||
values.forEach((value) => {
|
||||
res.push(new AutoCompleteItem(value, type));
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
private autoCompleteItemsUnique(array: Array<AutoCompleteItem>) {
|
||||
let a = array.concat();
|
||||
for (let i = 0; i < a.length; ++i) {
|
||||
for (let j = i + 1; j < a.length; ++j) {
|
||||
if (a[i].equals(a[j]))
|
||||
a.splice(j--, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
}
|
@ -6,6 +6,10 @@ import {Config} from "../../../common/config/private/Config";
|
||||
|
||||
export class SharingManager implements ISharingManager {
|
||||
|
||||
isSupported(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
private async removeExpiredLink() {
|
||||
const connection = await MySQLConnection.getConnection();
|
||||
return connection
|
||||
|
@ -20,7 +20,7 @@ export class UserEntity implements UserDTO {
|
||||
@Column("int")
|
||||
role: UserRoles;
|
||||
|
||||
@Column("string")
|
||||
@Column("string", {nullable: true})
|
||||
permissions: string[];
|
||||
|
||||
}
|
||||
|
@ -143,6 +143,19 @@ export class Server {
|
||||
Config.Server.thumbnail.processingLibrary = ThumbnailProcessingLib.Jimp;
|
||||
}
|
||||
}
|
||||
|
||||
if (Config.Client.Search.searchEnabled == true &&
|
||||
ObjectManagerRepository.getInstance().SearchManager.isSupported() == false) {
|
||||
|
||||
Logger.warn(LOG_TAG, "Search is not supported with these settings, switching off..");
|
||||
Config.Client.Search.searchEnabled = false;
|
||||
}
|
||||
if (Config.Client.Sharing.enabled == true &&
|
||||
ObjectManagerRepository.getInstance().SharingManager.isSupported() == false) {
|
||||
|
||||
Logger.warn(LOG_TAG, "Sharing is not supported with these settings, switching off..");
|
||||
Config.Client.Sharing.enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,7 +22,7 @@ export class AppComponent implements OnInit {
|
||||
this._router.navigate(["gallery", ""]);
|
||||
}
|
||||
} else {
|
||||
if (this._router.isActive('login', true)) {
|
||||
if (!this._router.isActive('login', true)) {
|
||||
console.log("routing");
|
||||
this._router.navigate(["login"]);
|
||||
}
|
||||
|
@ -7,3 +7,34 @@ ng2-slim-loading-bar {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.admin-link {
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.divider-vertical:first-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.navbar .divider-vertical {
|
||||
height: 30px;
|
||||
margin: 10px 1px 10px 10px;
|
||||
border-right: 1px solid #ffffff;
|
||||
border-left: 1px solid #f2f2f2;
|
||||
}
|
||||
|
||||
.navbar-inverse .divider-vertical {
|
||||
border-right-color: #5d5d5d;
|
||||
border-left-color: #3d3d3d;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.navbar-collapse .nav > .divider-vertical {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,45 @@
|
||||
<nav class="navbar navbar-inverse navbar-static-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
|
||||
aria-expanded="false" aria-controls="navbar">
|
||||
<button type="button" class="navbar-toggle collapsed"
|
||||
data-toggle="collapse" data-target="#navbar"
|
||||
aria-expanded="false" aria-controls="navbar"
|
||||
(click)="toggleState()">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="#"><img src="assets/icon_inv.png" style="max-height: 26px; display: inline;"/>
|
||||
<a class="navbar-brand" [routerLink]="['/gallery','/']"><img src="assets/icon_inv.png"
|
||||
style="max-height: 26px; display: inline;"/>
|
||||
{{title}}</a>
|
||||
</div>
|
||||
<div id="navbar" class="collapse navbar-collapse">
|
||||
<div id="navbar" class="collapse navbar-collapse" [ngClass]="{ 'in': isIn }">
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="active"><a [routerLink]="['/gallery','/']">Gallery</a></li>
|
||||
<li><a [routerLink]="['/admin']">Admin</a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right" *ngIf="authenticationRequired">
|
||||
<li>
|
||||
<p class="navbar-text" *ngIf="user.value">{{user.value.name}}</p>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<ng-content select="[navbar]"></ng-content>
|
||||
<li class="divider-vertical">
|
||||
</li>
|
||||
<li>
|
||||
<a style="cursor: pointer" (click)="logout()">Logout</a>
|
||||
<p class="navbar-text" *ngIf="user.value">
|
||||
<span class="glyphicon glyphicon-user" aria-hidden="true"></span> {{user.value.name}}</p>
|
||||
</li>
|
||||
<li *ngIf="isAdmin()">
|
||||
<a style="cursor: pointer"
|
||||
class="admin-link"
|
||||
[routerLink]="['/admin']"><span class="glyphicon glyphicon-wrench" aria-hidden="true"></span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="authenticationRequired">
|
||||
<button class="btn btn-default navbar-btn"
|
||||
style="cursor: pointer"
|
||||
(click)="logout()">Logout <span class="glyphicon glyphicon-log-out" aria-hidden="true"></span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ng-content select="[navbar]"></ng-content>
|
||||
|
||||
</div><!--/.nav-collapse -->
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import {Component, ViewEncapsulation} from "@angular/core";
|
||||
import {RouterLink} from "@angular/router";
|
||||
import {AuthenticationService} from "../model/network/authentication.service";
|
||||
import {UserDTO} from "../../../common/entities/UserDTO";
|
||||
import {UserDTO, UserRoles} from "../../../common/entities/UserDTO";
|
||||
import {Config} from "../../../common/config/public/Config";
|
||||
import {BehaviorSubject} from "rxjs/BehaviorSubject";
|
||||
|
||||
@ -17,6 +17,7 @@ export class FrameComponent {
|
||||
user: BehaviorSubject<UserDTO>;
|
||||
authenticationRequired: boolean = false;
|
||||
public title: string;
|
||||
isIn: boolean = false;
|
||||
|
||||
constructor(private _authService: AuthenticationService) {
|
||||
this.user = this._authService.user;
|
||||
@ -24,10 +25,17 @@ export class FrameComponent {
|
||||
this.title = Config.Client.applicationTitle;
|
||||
}
|
||||
|
||||
toggleState() { // click handler
|
||||
this.isIn = !this.isIn;
|
||||
}
|
||||
|
||||
isAdmin() {
|
||||
return this.user.value && this.user.value.role >= UserRoles.Admin;
|
||||
}
|
||||
|
||||
|
||||
logout() {
|
||||
this._authService.logout();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,15 @@
|
||||
<gallery-lightbox #lightbox (onLastElement)="onLightboxLastElement()"></gallery-lightbox>
|
||||
<app-frame>
|
||||
|
||||
<div navbar>
|
||||
<gallery-share *ngIf="showShare"></gallery-share>
|
||||
<gallery-search #search *ngIf="showSearchBar"></gallery-search>
|
||||
</div>
|
||||
<ng-container navbar>
|
||||
<li *ngIf="showSearchBar">
|
||||
<gallery-search #search></gallery-search>
|
||||
</li>
|
||||
<li *ngIf="showShare">
|
||||
<gallery-share></gallery-share>
|
||||
</li>
|
||||
-
|
||||
</ng-container>
|
||||
|
||||
<div body class="container" style="width: 100%; padding:0" *ngIf="_galleryService.content.value.directory">
|
||||
<gallery-navbar [directory]="_galleryService.content.value.directory"></gallery-navbar>
|
||||
|
@ -28,3 +28,7 @@
|
||||
border-bottom-left-radius: 0;
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
form {
|
||||
padding-right: 50px;
|
||||
}
|
||||
|
@ -1,31 +1,30 @@
|
||||
<div class="col-sm-3 col-md-4 pull-right">
|
||||
<form class="navbar-form" role="search" #SearchForm="ngForm">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Search" (keyup)="onSearchChange($event)"
|
||||
(blur)="onFocusLost()" (focus)="onFocus()" [(ngModel)]="searchText" #name="ngModel"
|
||||
ngControl="search"
|
||||
name="srch-term" id="srch-term" autocomplete="off">
|
||||
<form class="navbar-form" role="search" #SearchForm="ngForm">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" placeholder="Search" (keyup)="onSearchChange($event)"
|
||||
(blur)="onFocusLost()" (focus)="onFocus()" [(ngModel)]="searchText" #name="ngModel"
|
||||
ngControl="search"
|
||||
name="srch-term" id="srch-term" autocomplete="off">
|
||||
|
||||
<div class="autocomplete-list" *ngIf="autoCompleteItems.length > 0"
|
||||
(mouseover)="setMouseOverAutoComplete(true)" (mouseout)="setMouseOverAutoComplete(false)">
|
||||
<div class="autocomplete-item" *ngFor="let item of autoCompleteItems">
|
||||
<a [routerLink]="['/search', item.text, {type: SearchTypes[item.type]}]">
|
||||
<div class="autocomplete-list" *ngIf="autoCompleteItems.length > 0"
|
||||
(mouseover)="setMouseOverAutoComplete(true)" (mouseout)="setMouseOverAutoComplete(false)">
|
||||
<div class="autocomplete-item" *ngFor="let item of autoCompleteItems">
|
||||
<a [routerLink]="['/search', item.text, {type: SearchTypes[item.type]}]">
|
||||
<span [ngSwitch]="item.type">
|
||||
<span *ngSwitchCase="0" class="glyphicon glyphicon-picture"></span>
|
||||
<span *ngSwitchCase="1" class="glyphicon glyphicon-folder-open"></span>
|
||||
<span *ngSwitchCase="2" class="glyphicon glyphicon-tag"></span>
|
||||
<span *ngSwitchCase="3" class="glyphicon glyphicon-map-marker"></span>
|
||||
</span>
|
||||
{{item.preText}}<strong>{{item.highLightText}}</strong>{{item.postText}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{{item.preText}}<strong>{{item.highLightText}}</strong>{{item.postText}}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="input-group-btn" style="display: block">
|
||||
<button class="btn btn-default dropdown-toggle" type="button" (click)="onSearch()"><i
|
||||
class="glyphicon glyphicon-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="input-group-btn" style="display: block">
|
||||
<button class="btn btn-default dropdown-toggle" type="button" (click)="onSearch()"><i
|
||||
class="glyphicon glyphicon-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
@ -2,3 +2,7 @@
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
button {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
<div class="col-sm-2 col-md-2 pull-right">
|
||||
<button id="shareButton" class="btn btn-default navbar-btn btn-link" type="button"
|
||||
data-toggle="modal" data-target="#shareModal" [disabled]="!enabled" (click)="get()">
|
||||
<span class="glyphicon glyphicon-share-alt"></span>
|
||||
Share
|
||||
</button>
|
||||
</div>
|
||||
<button id="shareButton" class="btn btn-default navbar-btn btn-link" type="button"
|
||||
data-toggle="modal" data-target="#shareModal" [disabled]="!enabled" (click)="get()">
|
||||
<span class="glyphicon glyphicon-share-alt"></span>
|
||||
Share
|
||||
</button>
|
||||
|
||||
<!-- sharing Modal-->
|
||||
<div class="modal fade" id="shareModal" tabindex="-1" role="dialog" aria-labelledby="shareModalLabel"
|
||||
data-backdrop="false"
|
||||
|
@ -14,7 +14,6 @@ export class UserService {
|
||||
}
|
||||
|
||||
public logout(): Promise<string> {
|
||||
console.log("call logout");
|
||||
return this._networkService.postJson("/user/logout");
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,5 @@
|
||||
<body style="overflow-y: scroll">
|
||||
<pi-gallery2-app>Loading...</pi-gallery2-app>
|
||||
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-2.2.3.min.js"
|
||||
integrity="sha256-a23g1Nt4dtEYOj7bR+vTu7+T8VP13humZFBJNIYoEJo="
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"
|
||||
integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS"
|
||||
crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -9,3 +9,7 @@ body {
|
||||
* {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
.navbar-right {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user