mirror of https://github.com/Squidex/squidex.git
69 changed files with 1072 additions and 251 deletions
@ -0,0 +1,46 @@ |
|||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netcoreapp1.0</TargetFramework> |
||||
|
<AssemblyName>Squidex.Core</AssemblyName> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Compile Include="**\*.cs" /> |
||||
|
<EmbeddedResource Include="**\*.resx" /> |
||||
|
<EmbeddedResource Include="compiler\resources\**\*" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\Squidex.Infrastructure\Squidex.Infrastructure.csproj" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.NET.Sdk"> |
||||
|
<Version>1.0.0-alpha-20161104-2</Version> |
||||
|
<PrivateAssets>All</PrivateAssets> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="NETStandard.Library"> |
||||
|
<Version>1.6.0</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="NodaTime"> |
||||
|
<Version>2.0.0-alpha20160729</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="protobuf-net"> |
||||
|
<Version>2.1.0</Version> |
||||
|
</PackageReference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' "> |
||||
|
<PackageReference Include="Microsoft.NETCore.App"> |
||||
|
<Version>1.0.1</Version> |
||||
|
</PackageReference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
|
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
||||
|
</Project> |
||||
@ -0,0 +1,63 @@ |
|||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" /> |
||||
|
|
||||
|
<PropertyGroup> |
||||
|
<TargetFramework>netcoreapp1.0</TargetFramework> |
||||
|
<AssemblyName>Squidex.Infrastructure</AssemblyName> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<Compile Include="**\*.cs" /> |
||||
|
<EmbeddedResource Include="**\*.resx" Exclude="bin\**;obj\**;**\*.xproj;packages\**" /> |
||||
|
<EmbeddedResource Include="*.csv;compiler\resources\**\*" Exclude="bin\**;obj\**;**\*.xproj;packages\**" /> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup> |
||||
|
<PackageReference Include="Microsoft.NET.Sdk"> |
||||
|
<Version>1.0.0-alpha-20161104-2</Version> |
||||
|
<PrivateAssets>All</PrivateAssets> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="Autofac"> |
||||
|
<Version>4.1.0</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="EventStore.ClientAPI.NetCore"> |
||||
|
<Version>0.0.1-alpha</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="Microsoft.Extensions.Logging"> |
||||
|
<Version>1.0.0</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="NETStandard.Library"> |
||||
|
<Version>1.6.0</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="Newtonsoft.Json"> |
||||
|
<Version>9.0.2-beta1</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="NodaTime"> |
||||
|
<Version>2.0.0-alpha20160729</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="protobuf-net"> |
||||
|
<Version>2.1.0</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="System.Linq"> |
||||
|
<Version>4.1.0</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="System.Reflection.TypeExtensions"> |
||||
|
<Version>4.1.0</Version> |
||||
|
</PackageReference> |
||||
|
<PackageReference Include="System.Security.Claims"> |
||||
|
<Version>4.0.1</Version> |
||||
|
</PackageReference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp1.0' "> |
||||
|
<PackageReference Include="Microsoft.NETCore.App"> |
||||
|
<Version>1.0.1</Version> |
||||
|
</PackageReference> |
||||
|
</ItemGroup> |
||||
|
|
||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> |
||||
|
<DefineConstants>$(DefineConstants);RELEASE</DefineConstants> |
||||
|
</PropertyGroup> |
||||
|
|
||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |
||||
|
</Project> |
||||
@ -1,10 +1,14 @@ |
|||||
<div class="layout-content"> |
<div class="layout"> |
||||
<div class="layout-content-left layout-content-left--no-button"> |
<div class="layout-left"> |
||||
<sqx-left-menu></sqx-left-menu> |
<sqx-left-menu></sqx-left-menu> |
||||
</div> |
</div> |
||||
<div class="layout-content-main"> |
<div class="layout-middle"> |
||||
<h1> |
<div class="layout-middle-header"> |
||||
<i class="layout-title-icon icon-dashboard"></i> Dashboard |
<h1> |
||||
</h1> |
<i class="layout-title-icon icon-dashboard"></i> Dashboard |
||||
|
</h1> |
||||
|
</div> |
||||
|
<div class="layout-middle-content"> |
||||
|
</div> |
||||
</div> |
</div> |
||||
</div> |
</div> |
||||
@ -1,26 +1,38 @@ |
|||||
<ul class="nav"> |
<ul class="nav"> |
||||
<li class="nav-item"> |
<li class="nav-item nav-item--dashboard"> |
||||
<a class="nav-link nav-link--dashboard" routerLink="../dashboard" routerLinkActive="active"> |
<a class="nav-link" routerLink="../dashboard" routerLinkActive="active"> |
||||
<i class="icon-dashboard"></i> Dashboard |
<i class="icon-dashboard"></i> Dashboard |
||||
</a> |
</a> |
||||
</li> |
</li> |
||||
<li class="nav-item"> |
<li class="nav-items nav-item--schemas" *ngIf="permission !== 'Editor'"> |
||||
<a class="nav-link nav-link--schemas" routerLink="../schemas" routerLinkActive="active"> |
<a class="nav-link" routerLink="../schemas" routerLinkActive="active"> |
||||
<i class="icon-schemas"></i> Schemas |
<i class="icon-schemas"></i> Schemas |
||||
</a> |
</a> |
||||
</li> |
</li> |
||||
<li class="nav-item"> |
<li class="nav-item nav-item--content"> |
||||
<a class="nav-link nav-link--content"> |
<a class="nav-link"> |
||||
<i class="icon-content"></i> Content |
<i class="icon-content"></i> Content |
||||
</a> |
</a> |
||||
</li> |
</li> |
||||
<li class="nav-item"> |
<li class="nav-item nav-item--media"> |
||||
<a class="nav-link nav-link--media"> |
<a class="nav-link"> |
||||
<i class="icon-media"></i> Media</a> |
<i class="icon-media"></i> Media</a> |
||||
</li> |
</li> |
||||
<li class="nav-item"> |
<li class="nav-item nav-item--settings nav-item-group" *ngIf="permission === 'Owner'"> |
||||
<a class="nav-link nav-link--settings"> |
<a class="nav-link" (click)="toggleSettingsMenu()"> |
||||
<i class="icon-settings"></i> Settings |
<i class="icon-settings"></i> Settings |
||||
</a> |
</a> |
||||
|
|
||||
|
<ul class="subnav" *ngIf="showSettingsMenu"> |
||||
|
<li class="subnav-item"> |
||||
|
<a class="nav-link" routerLink="../contributors" routerLinkActive="active">Contributors</a> |
||||
|
</li> |
||||
|
<li class="subnav-item"> |
||||
|
<a class="nav-link" routerLink="../credentials" routerLinkActive="active">Credentials</a> |
||||
|
</li> |
||||
|
<li class="subnav-item"> |
||||
|
<a class="nav-link" routerLink="../languages" routerLinkActive="active">Languages</a> |
||||
|
</li> |
||||
|
</ul> |
||||
</li> |
</li> |
||||
</ul> |
</ul> |
||||
@ -1,12 +1,16 @@ |
|||||
<div class="layout-content"> |
<div class="layout"> |
||||
<div class="layout-content-left"> |
<div class="layout-left"> |
||||
<button class="layout-new-button btn btn-success">Create Schema</button> |
|
||||
|
|
||||
<sqx-left-menu></sqx-left-menu> |
<sqx-left-menu></sqx-left-menu> |
||||
</div> |
</div> |
||||
<div class="layout-content-main"> |
<div class="layout-middle"> |
||||
<h1> |
<div class="layout-middle-header"> |
||||
<i class="layout-title-icon icon-schemas"></i> Schemas |
<button class="layout-new-button btn btn-success pull-right">Create Schema</button> |
||||
</h1> |
|
||||
|
<h1> |
||||
|
<i class="layout-title-icon icon-schemas"></i> Schemas |
||||
|
</h1> |
||||
|
</div> |
||||
|
<div class="layout-middle-content"> |
||||
|
</div> |
||||
</div> |
</div> |
||||
</div> |
</div> |
||||
@ -0,0 +1,67 @@ |
|||||
|
<div class="layout"> |
||||
|
<div class="layout-left"> |
||||
|
<sqx-left-menu></sqx-left-menu> |
||||
|
</div> |
||||
|
<div class="layout-middle"> |
||||
|
<div class="layout-middle-header"> |
||||
|
<h1> |
||||
|
<i class="layout-title-icon icon-settings"></i> Contributors |
||||
|
</h1> |
||||
|
</div> |
||||
|
<div class="layout-middle-content"> |
||||
|
<div class="card"> |
||||
|
<div class="card-block"> |
||||
|
<table class="table table-borderless table-fixed"> |
||||
|
<colgroup> |
||||
|
<col style="width: 100%" /> |
||||
|
<col style="width: 150px" /> |
||||
|
<col style="width: 110px" /> |
||||
|
</colgroup> |
||||
|
|
||||
|
<tr *ngFor="let contributor of appContributors"> |
||||
|
<td class="col-xs-7"> |
||||
|
<img class="user-picture" [attr.src]="pictureUrl(contributor) | async" /> |
||||
|
|
||||
|
<span class="user-name"> |
||||
|
{{displayName(contributor) | async}} |
||||
|
</span> |
||||
|
<span class="user-email"> |
||||
|
{{email(contributor) | async}} |
||||
|
</span> |
||||
|
</td> |
||||
|
<td> |
||||
|
<select class="form-control" [(ngModel)]="contributor.permission" (ngModelChange)="saveContributor(contributor)" [disabled]="currrentUserId === contributor.contributorId"> |
||||
|
<option *ngFor="let permission of usersPermissions">{{permission}}</option> |
||||
|
</select> |
||||
|
</td> |
||||
|
<td> |
||||
|
<button class="btn btn-block btn-danger" [disabled]="currrentUserId === contributor.contributorId" (click)="revokeContributor(contributor)">Revoke</button> |
||||
|
</td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
<div class="card-footer"> |
||||
|
<form class="form-inline" (submit)="addContributor()" > |
||||
|
<div class="form-group"> |
||||
|
<ng2-completer |
||||
|
[autoMatch]="true" |
||||
|
[dataService]="usersDataSource" |
||||
|
[minSearchLength]="3" |
||||
|
[placeholder]="'Search user by e-email'" |
||||
|
[pause]="300" |
||||
|
[clearSelected]="false" |
||||
|
[textSearching]="'Searching...'" |
||||
|
[inputName]="contributor" |
||||
|
[ngModel]="selectedUserName" |
||||
|
[ngModelOptions]="{standalone: true}" |
||||
|
(selected)="selectUser($event)"> |
||||
|
</ng2-completer> |
||||
|
</div> |
||||
|
|
||||
|
<button type="submit" class="btn btn-primary" [disabled]="!selectedUser">Add</button> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,28 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
.layout-title-icon { |
||||
|
color: $color-section-settings; |
||||
|
} |
||||
|
|
||||
|
.card { |
||||
|
max-width: 700px; |
||||
|
} |
||||
|
|
||||
|
.user { |
||||
|
&-picture { |
||||
|
@include circle(2.2rem); |
||||
|
float: left; |
||||
|
} |
||||
|
|
||||
|
&-name, |
||||
|
&-email { |
||||
|
@include truncate; |
||||
|
padding-left: 10px; |
||||
|
} |
||||
|
|
||||
|
&-email { |
||||
|
font-size: .8rem; |
||||
|
font-style: italic; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,162 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { Observable, Subscription } from 'rxjs'; |
||||
|
|
||||
|
import { CompleterBaseData, CompleterItem } from 'ng2-completer'; |
||||
|
|
||||
|
import { |
||||
|
AppContributorDto, |
||||
|
AppContributorsService, |
||||
|
AppsStoreService, |
||||
|
AuthService, |
||||
|
TitleService, |
||||
|
UserDto, |
||||
|
UsersService, |
||||
|
UsersProviderService |
||||
|
} from 'shared'; |
||||
|
|
||||
|
class UsersDataSource extends CompleterBaseData { |
||||
|
private remoteSearch: Subscription; |
||||
|
|
||||
|
constructor( |
||||
|
private readonly usersService: UsersService, |
||||
|
private readonly component: ContributorsPageComponent, |
||||
|
) { |
||||
|
super(); |
||||
|
} |
||||
|
|
||||
|
public search(term: string): void { |
||||
|
this.cancel(); |
||||
|
|
||||
|
this.remoteSearch = |
||||
|
this.usersService.getUsers(term) |
||||
|
.map(users => { |
||||
|
const results: CompleterItem[] = []; |
||||
|
|
||||
|
for (let u of users) { |
||||
|
if (!this.component.appContributors || !this.component.appContributors.find(t => t.contributorId === u.id)) { |
||||
|
results.push({ title: u.displayName, image: u.pictureUrl, originalObject: u, description: u.email }); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
this.next(results); |
||||
|
|
||||
|
return results; |
||||
|
}) |
||||
|
.catch(err => { |
||||
|
this.error(err); |
||||
|
|
||||
|
return null; |
||||
|
}).subscribe(); |
||||
|
} |
||||
|
|
||||
|
public cancel() { |
||||
|
if (this.remoteSearch) { |
||||
|
this.remoteSearch.unsubscribe(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Ng2.Component({ |
||||
|
selector: 'sqx-contributor-page', |
||||
|
styles, |
||||
|
template |
||||
|
}) |
||||
|
export class ContributorsPageComponent implements Ng2.OnInit { |
||||
|
private appSubscription: any | null = null; |
||||
|
private appName: string; |
||||
|
|
||||
|
public appContributors: AppContributorDto[]; |
||||
|
|
||||
|
public selectedUserName: string | null = null; |
||||
|
public selectedUser: UserDto | null = null; |
||||
|
|
||||
|
public currrentUserId: string; |
||||
|
|
||||
|
public usersDataSource: UsersDataSource; |
||||
|
public usersPermissions = [ |
||||
|
'Owner', |
||||
|
'Developer', |
||||
|
'Editor' |
||||
|
]; |
||||
|
|
||||
|
constructor( |
||||
|
private readonly titles: TitleService, |
||||
|
private readonly authService: AuthService, |
||||
|
private readonly appsStore: AppsStoreService, |
||||
|
private readonly appContributorsService: AppContributorsService, |
||||
|
private readonly usersProvider: UsersProviderService, |
||||
|
private readonly usersService: UsersService |
||||
|
) { |
||||
|
this.usersDataSource = new UsersDataSource(usersService, this); |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.currrentUserId = this.authService.user.id; |
||||
|
|
||||
|
this.appSubscription = |
||||
|
this.appsStore.selectedApp.subscribe(app => { |
||||
|
if (app) { |
||||
|
this.appName = app.name; |
||||
|
|
||||
|
this.titles.setTitle('{appName} | Settings | Contributors', { appName: app.name }); |
||||
|
|
||||
|
this.appContributorsService.getContributors(app.name).subscribe(contributors => { |
||||
|
this.appContributors = contributors; |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.appSubscription.unsubscribe(); |
||||
|
} |
||||
|
|
||||
|
public addContributor() { |
||||
|
if (!this.selectedUser) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
const contributor = new AppContributorDto(this.selectedUser.id, 'Editor'); |
||||
|
|
||||
|
this.appContributorsService.postContributor(this.appName, contributor).subscribe(); |
||||
|
this.appContributors.push(contributor); |
||||
|
|
||||
|
this.selectedUser = null; |
||||
|
this.selectedUserName = null; |
||||
|
} |
||||
|
|
||||
|
public revokeContributor(contributor: AppContributorDto) { |
||||
|
this.appContributorsService.deleteContributor(this.appName, contributor.contributorId).subscribe(); |
||||
|
|
||||
|
this.appContributors.splice(this.appContributors.indexOf(contributor), 1); |
||||
|
} |
||||
|
|
||||
|
public saveContributor(contributor: AppContributorDto) { |
||||
|
this.appContributorsService.postContributor(this.appName, contributor).subscribe(); |
||||
|
} |
||||
|
|
||||
|
public selectUser(selection: CompleterItem | null) { |
||||
|
this.selectedUser = selection ? selection.originalObject : null; |
||||
|
} |
||||
|
|
||||
|
public email(contributor: AppContributorDto): Observable<string> { |
||||
|
return this.usersProvider.getUser(contributor.contributorId).map(u => u.email); |
||||
|
} |
||||
|
|
||||
|
public displayName(contributor: AppContributorDto): Observable<string> { |
||||
|
return this.usersProvider.getUser(contributor.contributorId).map(u => u.displayName); |
||||
|
} |
||||
|
|
||||
|
public pictureUrl(contributor: AppContributorDto): Observable<string> { |
||||
|
return this.usersProvider.getUser(contributor.contributorId).map(u => u.pictureUrl); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,14 @@ |
|||||
|
<div class="layout"> |
||||
|
<div class="layout-left"> |
||||
|
<sqx-left-menu></sqx-left-menu> |
||||
|
</div> |
||||
|
<div class="layout-middle"> |
||||
|
<div class="layout-middle-header"> |
||||
|
<h1> |
||||
|
<i class="layout-title-icon icon-settings"></i> Credentials |
||||
|
</h1> |
||||
|
</div> |
||||
|
<div class="layout-middle-content"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,6 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
.layout-title-icon { |
||||
|
color: $color-section-settings; |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { AppsStoreService, TitleService } from 'shared'; |
||||
|
|
||||
|
@Ng2.Component({ |
||||
|
selector: 'sqx-credentials-page', |
||||
|
styles, |
||||
|
template |
||||
|
}) |
||||
|
export class CredentialsPageComponent implements Ng2.OnInit { |
||||
|
private appSubscription: any | null = null; |
||||
|
|
||||
|
constructor( |
||||
|
private readonly titles: TitleService, |
||||
|
private readonly appsStore: AppsStoreService |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.appSubscription = |
||||
|
this.appsStore.selectedApp.subscribe(app => { |
||||
|
if (app) { |
||||
|
this.titles.setTitle('{appName} | Settings | Credentials', { appName: app.name }); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.appSubscription.unsubscribe(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,14 @@ |
|||||
|
<div class="layout"> |
||||
|
<div class="layout-left"> |
||||
|
<sqx-left-menu></sqx-left-menu> |
||||
|
</div> |
||||
|
<div class="layout-middle"> |
||||
|
<div class="layout-middle-header"> |
||||
|
<h1> |
||||
|
<i class="layout-title-icon icon-settings"></i> Languages |
||||
|
</h1> |
||||
|
</div> |
||||
|
<div class="layout-middle-content"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,6 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
.layout-title-icon { |
||||
|
color: $color-section-settings; |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { AppsStoreService, TitleService } from 'shared'; |
||||
|
|
||||
|
@Ng2.Component({ |
||||
|
selector: 'sqx-languages-page', |
||||
|
styles, |
||||
|
template |
||||
|
}) |
||||
|
export class LanguagesPageComponent implements Ng2.OnInit { |
||||
|
private appSubscription: any | null = null; |
||||
|
|
||||
|
constructor( |
||||
|
private readonly titles: TitleService, |
||||
|
private readonly appsStore: AppsStoreService |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.appSubscription = |
||||
|
this.appsStore.selectedApp.subscribe(app => { |
||||
|
if (app) { |
||||
|
this.titles.setTitle('{appName} | Settings | Languages', { appName: app.name }); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.appSubscription.unsubscribe(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,39 @@ |
|||||
|
@import '_mixins'; |
||||
|
@import '_vars'; |
||||
|
|
||||
|
.completer-dropdown { |
||||
|
& { |
||||
|
margin-top: 2px !important; |
||||
|
width: 400px !important; |
||||
|
} |
||||
|
|
||||
|
.completer { |
||||
|
&-image { |
||||
|
@include circle(2.2rem); |
||||
|
} |
||||
|
|
||||
|
&-row { |
||||
|
& { |
||||
|
@include clearfix; |
||||
|
width: auto !important; |
||||
|
margin: 0; |
||||
|
margin-bottom: 0 !important; |
||||
|
display: block !important; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&-selected-row { |
||||
|
background: $color-theme-blue-dark !important; |
||||
|
} |
||||
|
|
||||
|
&-description { |
||||
|
font-style: italic; |
||||
|
} |
||||
|
|
||||
|
&-title, |
||||
|
&-description { |
||||
|
@include truncate; |
||||
|
padding-left: .3rem; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,2 +1,3 @@ |
|||||
@import '_bootstrap.scss'; |
@import '_bootstrap.scss'; |
||||
@import '_layout.scss'; |
@import '_layout.scss'; |
||||
|
@import '_completer.scss'; |
||||
Loading…
Reference in new issue