mirror of https://github.com/Squidex/squidex.git
111 changed files with 1319 additions and 776 deletions
@ -1,24 +0,0 @@ |
|||||
/* |
|
||||
* Squidex Headless CMS |
|
||||
* |
|
||||
* @license |
|
||||
* Copyright (c) Sebastian Stehle. All rights reserved |
|
||||
*/ |
|
||||
|
|
||||
import * as Ng2 from '@angular/core'; |
|
||||
|
|
||||
import { SqxFrameworkModule } from 'shared'; |
|
||||
|
|
||||
import { |
|
||||
LogoutPageComponent |
|
||||
} from './declarations'; |
|
||||
|
|
||||
@Ng2.NgModule({ |
|
||||
imports: [ |
|
||||
SqxFrameworkModule |
|
||||
], |
|
||||
declarations: [ |
|
||||
LogoutPageComponent |
|
||||
] |
|
||||
}) |
|
||||
export class SqxAuthModule { } |
|
||||
@ -1,11 +0,0 @@ |
|||||
/* |
|
||||
* Squidex Headless CMS |
|
||||
* |
|
||||
* @license |
|
||||
* Copyright (c) Sebastian Stehle. All rights reserved |
|
||||
*/ |
|
||||
|
|
||||
export * from './auth'; |
|
||||
export * from './internal'; |
|
||||
export * from './layout'; |
|
||||
export * from './public'; |
|
||||
@ -1 +0,0 @@ |
|||||
<router-outlet></router-outlet> |
|
||||
@ -1,17 +0,0 @@ |
|||||
<sqx-title message="{app} | Dashboard" parameter="app" value="{{appName() | async}}"></sqx-title> |
|
||||
|
|
||||
|
|
||||
<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-dashboard"></i> Dashboard |
|
||||
</h1> |
|
||||
</div> |
|
||||
<div class="layout-middle-content"> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
@ -1,6 +0,0 @@ |
|||||
@import '_vars'; |
|
||||
@import '_mixins'; |
|
||||
|
|
||||
.layout-title-icon { |
|
||||
color: $color-section-dashboard; |
|
||||
} |
|
||||
@ -1,38 +0,0 @@ |
|||||
<ul class="nav"> |
|
||||
<li class="nav-item nav-item--dashboard"> |
|
||||
<a class="nav-link" routerLink="../dashboard" routerLinkActive="active"> |
|
||||
<i class="icon-dashboard"></i> Dashboard |
|
||||
</a> |
|
||||
</li> |
|
||||
<li class="nav-items nav-item--schemas" *ngIf="permission !== 'Editor'"> |
|
||||
<a class="nav-link" routerLink="../schemas" routerLinkActive="active"> |
|
||||
<i class="icon-schemas"></i> Schemas |
|
||||
</a> |
|
||||
</li> |
|
||||
<li class="nav-item nav-item--content"> |
|
||||
<a class="nav-link"> |
|
||||
<i class="icon-content"></i> Content |
|
||||
</a> |
|
||||
</li> |
|
||||
<li class="nav-item nav-item--media"> |
|
||||
<a class="nav-link"> |
|
||||
<i class="icon-media"></i> Media</a> |
|
||||
</li> |
|
||||
<li class="nav-item nav-item--settings nav-item-group" *ngIf="permission === 'Owner'"> |
|
||||
<a class="nav-link" (click)="toggleSettingsMenu()"> |
|
||||
<i class="icon-settings"></i> Settings |
|
||||
</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="../clients" routerLinkActive="active">Clients</a> |
|
||||
</li> |
|
||||
<li class="subnav-item"> |
|
||||
<a class="nav-link" routerLink="../languages" routerLinkActive="active">Languages</a> |
|
||||
</li> |
|
||||
</ul> |
|
||||
</li> |
|
||||
</ul> |
|
||||
@ -1,121 +0,0 @@ |
|||||
@import '_vars'; |
|
||||
@import '_mixins'; |
|
||||
|
|
||||
$color-selection-background: #ebf0f2; |
|
||||
$color-subnav-text: #818181; |
|
||||
$color-subnav-dot: #bdc6d0; |
|
||||
$color-border-left-width: 4px; |
|
||||
|
|
||||
@mixin build-item($color) { |
|
||||
& .nav-link { |
|
||||
&:hover, |
|
||||
&.active { |
|
||||
border-color: $color; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
& i { |
|
||||
margin-right: .5rem; |
|
||||
color: $color; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.nav { |
|
||||
& { |
|
||||
list-style: none; |
|
||||
padding: 0; |
|
||||
margin-left: -$padding-layout-h - 1px; |
|
||||
margin-right: -$padding-layout-h; |
|
||||
} |
|
||||
|
|
||||
&-item { |
|
||||
&--media { |
|
||||
@include build-item($color-section-media); |
|
||||
} |
|
||||
|
|
||||
&--content { |
|
||||
@include build-item($color-section-content); |
|
||||
} |
|
||||
|
|
||||
&--dashboard { |
|
||||
@include build-item($color-section-dashboard); |
|
||||
} |
|
||||
|
|
||||
&--schemas { |
|
||||
@include build-item($color-section-schemas); |
|
||||
} |
|
||||
|
|
||||
&--settings { |
|
||||
@include build-item($color-section-settings); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
&-item-group > a { |
|
||||
& { |
|
||||
position: relative; |
|
||||
} |
|
||||
|
|
||||
&::after { |
|
||||
@include absolute(50%, 30px, auto, auto); |
|
||||
@include caret-bottom; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
&-link { |
|
||||
& { |
|
||||
@include transition(background .2s ease); |
|
||||
border-left: $color-border-left-width solid transparent; |
|
||||
color: $color-text; |
|
||||
cursor: pointer; |
|
||||
display: block; |
|
||||
font-size: 1rem; |
|
||||
font-weight: 450; |
|
||||
line-height: 3rem; |
|
||||
padding-left: $padding-layout-h - $color-border-left-width; |
|
||||
padding-right: $padding-layout-h; |
|
||||
} |
|
||||
|
|
||||
&:hover, |
|
||||
&.active { |
|
||||
background: $color-selection-background; |
|
||||
} |
|
||||
|
|
||||
&.active { |
|
||||
font-weight: bold; |
|
||||
} |
|
||||
|
|
||||
&:hover { |
|
||||
text-decoration: none; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.subnav { |
|
||||
& { |
|
||||
list-style: none; |
|
||||
margin: 0; |
|
||||
padding: 0; |
|
||||
overflow: hidden; |
|
||||
} |
|
||||
|
|
||||
.nav-link { |
|
||||
& { |
|
||||
color: $color-subnav-text; |
|
||||
padding-left: 55px; |
|
||||
font-size: .9rem; |
|
||||
font-weight: 450; |
|
||||
line-height: 2rem; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
&-item { |
|
||||
&::before { |
|
||||
content: '•'; |
|
||||
color: $color-subnav-dot; |
|
||||
float: left; |
|
||||
font-weight: bold; |
|
||||
line-height: 2rem; |
|
||||
margin-left: 35px; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,16 +0,0 @@ |
|||||
<div class="layout"> |
|
||||
<div class="layout-left"> |
|
||||
<sqx-left-menu></sqx-left-menu> |
|
||||
</div> |
|
||||
<div class="layout-middle"> |
|
||||
<div class="layout-middle-header"> |
|
||||
<button class="layout-new-button btn btn-success float-xs-right">Create Schema</button> |
|
||||
|
|
||||
<h1> |
|
||||
<i class="layout-title-icon icon-schemas"></i> Schemas |
|
||||
</h1> |
|
||||
</div> |
|
||||
<div class="layout-middle-content"> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
@ -1,6 +0,0 @@ |
|||||
@import '_vars'; |
|
||||
@import '_mixins'; |
|
||||
|
|
||||
.layout-title-icon { |
|
||||
color: $color-section-schemas; |
|
||||
} |
|
||||
@ -1,39 +0,0 @@ |
|||||
/* |
|
||||
* 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-schemas-page', |
|
||||
styles, |
|
||||
template |
|
||||
}) |
|
||||
export class SchemasPageComponent 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} | Schemas', { appName: app.name }); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
public ngOnDestroy() { |
|
||||
this.appSubscription.unsubscribe(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
@ -1,47 +0,0 @@ |
|||||
<sqx-title message="{app} | Clients | Settings" parameter="app" value="{{appName() | async}}"></sqx-title> |
|
||||
|
|
||||
<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> Clients |
|
||||
</h1> |
|
||||
</div> |
|
||||
<div class="layout-middle-content"> |
|
||||
<div class="table-items-row" *ngIf="appClients && appClients.length === 0"> |
|
||||
No client created yet. |
|
||||
</div> |
|
||||
|
|
||||
<div *ngFor="let client of appClients"> |
|
||||
<sqx-client [client]="client" [appName]="appName() | async" (renamed)="renameClient(client, $event)"></sqx-client> |
|
||||
</div> |
|
||||
|
|
||||
<div class="table-items-footer"> |
|
||||
<form class="form-inline" [formGroup]="createForm" (submit)="attachClient()"> |
|
||||
<div class="errors-box" *ngIf="createForm.get('name').invalid && createForm.get('name').dirty"> |
|
||||
<div class="errors"> |
|
||||
<span *ngIf="createForm.get('name').hasError('required')"> |
|
||||
Name is required. |
|
||||
</span> |
|
||||
<span *ngIf="createForm.get('name').hasError('maxlength')"> |
|
||||
Name can not have more than 40 characters. |
|
||||
</span> |
|
||||
<span *ngIf="createForm.get('name').hasError('pattern')"> |
|
||||
Name can contain lower case letters (a-z), numbers and dashes (not at the end). |
|
||||
</span> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<div class="form-group"> |
|
||||
<input type="text" class="form-control" id="app-name" formControlName="name" maxlength="40" placeholder="Enter client name" /> |
|
||||
</div> |
|
||||
|
|
||||
<button type="submit" class="btn btn-success" [disabled]="createForm.invalid">Add Client</button> |
|
||||
</form> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
@ -1,67 +0,0 @@ |
|||||
<sqx-title message="{app} | Contributors | Settings" parameter="app" value="{{appName() | async}}"></sqx-title> |
|
||||
|
|
||||
<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"> |
|
||||
<table class="table table-items table-fixed"> |
|
||||
<colgroup> |
|
||||
<col style="width: 50px" /> |
|
||||
<col style="width: 50%" /> |
|
||||
<col style="width: 50%" /> |
|
||||
<col style="width: 150px" /> |
|
||||
<col style="width: 80px" /> |
|
||||
</colgroup> |
|
||||
|
|
||||
<tbody> |
|
||||
<template ngFor let-contributor [ngForOf]="appContributors"> |
|
||||
<tr> |
|
||||
<td> |
|
||||
<img class="user-picture" [attr.src]="userPicture(contributor.contributorId) | async" /> |
|
||||
</td> |
|
||||
<td> |
|
||||
<span class="user-name">{{userName(contributor.contributorId) | async}}</span> |
|
||||
</td> |
|
||||
<td> |
|
||||
<span class="user-email">{{userEmail(contributor.contributorId) | async}}</span> |
|
||||
</td> |
|
||||
<td> |
|
||||
<select class="form-control" [(ngModel)]="contributor.permission" (ngModelChange)="changePermission(contributor, $event)" [disabled]="currentUserId === contributor.contributorId"> |
|
||||
<option *ngFor="let permission of usersPermissions">{{permission}}</option> |
|
||||
</select> |
|
||||
</td> |
|
||||
<td> |
|
||||
<button type="button" class="btn btn-link btn-danger" [disabled]="currrentUserId === contributor.contributorId" (click)="removeContributor(contributor)"> |
|
||||
<i class="icon-bin"></i> |
|
||||
</button> |
|
||||
</td> |
|
||||
</tr> |
|
||||
<tr class="spacer"></tr> |
|
||||
</template> |
|
||||
</tbody> |
|
||||
</table> |
|
||||
|
|
||||
<div class="table-items-footer"> |
|
||||
<form class="form-inline" (submit)="assignContributor()" > |
|
||||
<div class="form-group"> |
|
||||
<sqx-autocomplete [source]="usersDataSource" |
|
||||
(ngModelChange)="selectUser($event.model)" |
|
||||
[ngModel]="selectedUser" |
|
||||
[ngModelOptions]="{standalone: true}" |
|
||||
[inputName]="contributor"> |
|
||||
</sqx-autocomplete> |
|
||||
</div> |
|
||||
|
|
||||
<button type="submit" class="btn btn-success" [disabled]="!selectedUser">Add Contributor</button> |
|
||||
</form> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
@ -1,78 +0,0 @@ |
|||||
<sqx-title message="{app} | Languages | Settings" parameter="app" value="{{appName() | async}}"></sqx-title> |
|
||||
|
|
||||
<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"> |
|
||||
<table class="table table-items table-fixed"> |
|
||||
<colgroup> |
|
||||
<col style="width: 60px" /> |
|
||||
<col style="width: 100%" /> |
|
||||
<col style="width: 200px" /> |
|
||||
<col style="width: 80px" /> |
|
||||
</colgroup> |
|
||||
|
|
||||
<thead> |
|
||||
<tr> |
|
||||
<th> |
|
||||
Code |
|
||||
</th> |
|
||||
<th> |
|
||||
Name |
|
||||
</th> |
|
||||
<th> |
|
||||
Options |
|
||||
</th> |
|
||||
</tr> |
|
||||
</thead> |
|
||||
|
|
||||
<tbody> |
|
||||
<template ngFor let-language [ngForOf]="appLanguages"> |
|
||||
<tr> |
|
||||
<td> |
|
||||
<span class="language-code"> |
|
||||
{{language.iso2Code}} |
|
||||
</span> |
|
||||
</td> |
|
||||
<td> |
|
||||
<span class="language-name"> |
|
||||
{{language.englishName}} |
|
||||
</span> |
|
||||
</td> |
|
||||
<td> |
|
||||
<label class="language-default"> |
|
||||
<input type="radio" [value]="true" [ngModel]="language.isMasterLanguage" (ngModelChange)="setMasterLanguage(language)"> Master Language |
|
||||
</label> |
|
||||
</td> |
|
||||
<td> |
|
||||
<button type="button" class="btn btn-link btn-danger" [disabled]="language.isMasterLanguage" (click)="removeLanguage(language)"> |
|
||||
<i class="icon-bin"></i> |
|
||||
</button> |
|
||||
</td> |
|
||||
</tr> |
|
||||
<tr class="spacer"></tr> |
|
||||
</template> |
|
||||
</tbody> |
|
||||
</table> |
|
||||
|
|
||||
<div class="table-items-footer"> |
|
||||
<form class="form-inline" (submit)="addLanguage()" name="addLanguageForm"> |
|
||||
<div class="form-group"> |
|
||||
<select class="form-control language-select" [(ngModel)]="selectedLanguage" name="newLanguage"> |
|
||||
<option *ngFor="let language of allLanguages" [ngValue]="language">{{language.englishName}}</option> |
|
||||
</select> |
|
||||
</div> |
|
||||
|
|
||||
<button type="submit" class="btn btn-success" [disabled]="!selectedLanguage">Add Language</button> |
|
||||
</form> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
@ -1,18 +0,0 @@ |
|||||
/* |
|
||||
* Squidex Headless CMS |
|
||||
* |
|
||||
* @license |
|
||||
* Copyright (c) Sebastian Stehle. All rights reserved |
|
||||
*/ |
|
||||
|
|
||||
export * from './apps/apps-page.component'; |
|
||||
export * from './app/app-area.component'; |
|
||||
export * from './app/left-menu.component'; |
|
||||
export * from './app/dashboard/dashboard-page.component'; |
|
||||
export * from './app/schemas/schemas-page.component'; |
|
||||
export * from './app/settings/client.component'; |
|
||||
export * from './app/settings/clients-page.component'; |
|
||||
export * from './app/settings/contributors-page.component'; |
|
||||
export * from './app/settings/languages-page.component'; |
|
||||
|
|
||||
export * from './internal-area.component'; |
|
||||
@ -1,47 +0,0 @@ |
|||||
/* |
|
||||
* Squidex Headless CMS |
|
||||
* |
|
||||
* @license |
|
||||
* Copyright (c) Sebastian Stehle. All rights reserved |
|
||||
*/ |
|
||||
|
|
||||
import * as Ng2 from '@angular/core'; |
|
||||
|
|
||||
import { SqxLayoutModule } from 'components/layout'; |
|
||||
import { SqxFrameworkModule } from 'shared'; |
|
||||
|
|
||||
import { |
|
||||
AppAreaComponent, |
|
||||
AppsPageComponent, |
|
||||
ClientComponent, |
|
||||
ClientsPageComponent, |
|
||||
ContributorsPageComponent, |
|
||||
DashboardPageComponent, |
|
||||
InternalAreaComponent, |
|
||||
LanguagesPageComponent, |
|
||||
LeftMenuComponent, |
|
||||
SchemasPageComponent |
|
||||
} from './declarations'; |
|
||||
|
|
||||
@Ng2.NgModule({ |
|
||||
imports: [ |
|
||||
SqxFrameworkModule, |
|
||||
SqxLayoutModule |
|
||||
], |
|
||||
exports: [ |
|
||||
LeftMenuComponent |
|
||||
], |
|
||||
declarations: [ |
|
||||
AppAreaComponent, |
|
||||
AppsPageComponent, |
|
||||
ClientComponent, |
|
||||
ClientsPageComponent, |
|
||||
ContributorsPageComponent, |
|
||||
DashboardPageComponent, |
|
||||
InternalAreaComponent, |
|
||||
LanguagesPageComponent, |
|
||||
LeftMenuComponent, |
|
||||
SchemasPageComponent |
|
||||
] |
|
||||
}) |
|
||||
export class SqxAppModule { } |
|
||||
@ -1,11 +0,0 @@ |
|||||
/* |
|
||||
* Squidex Headless CMS |
|
||||
* |
|
||||
* @license |
|
||||
* Copyright (c) Sebastian Stehle. All rights reserved |
|
||||
*/ |
|
||||
|
|
||||
export * from './app-form.component'; |
|
||||
export * from './apps-menu.component'; |
|
||||
export * from './profile-menu.component'; |
|
||||
export * from './search-form.component'; |
|
||||
@ -1,9 +0,0 @@ |
|||||
/* |
|
||||
* Squidex Headless CMS |
|
||||
* |
|
||||
* @license |
|
||||
* Copyright (c) Sebastian Stehle. All rights reserved |
|
||||
*/ |
|
||||
|
|
||||
export * from './home-page.component'; |
|
||||
export * from './not-found-page.component'; |
|
||||
@ -1,26 +0,0 @@ |
|||||
/* |
|
||||
* Squidex Headless CMS |
|
||||
* |
|
||||
* @license |
|
||||
* Copyright (c) Sebastian Stehle. All rights reserved |
|
||||
*/ |
|
||||
|
|
||||
import * as Ng2 from '@angular/core'; |
|
||||
|
|
||||
import { SqxFrameworkModule } from 'shared'; |
|
||||
|
|
||||
import { |
|
||||
HomePageComponent, |
|
||||
NotFoundPageComponent |
|
||||
} from './declarations'; |
|
||||
|
|
||||
@Ng2.NgModule({ |
|
||||
imports: [ |
|
||||
SqxFrameworkModule |
|
||||
], |
|
||||
declarations: [ |
|
||||
NotFoundPageComponent, |
|
||||
HomePageComponent |
|
||||
] |
|
||||
}) |
|
||||
export class SqxPublicModule { } |
|
||||
@ -0,0 +1,34 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
import * as Ng2Router from '@angular/router'; |
||||
|
|
||||
|
import { SqxFrameworkModule, SqxSharedModule } from 'shared'; |
||||
|
|
||||
|
import { |
||||
|
AppsPageComponent |
||||
|
} from './declarations'; |
||||
|
|
||||
|
const routes: Ng2Router.Routes = [ |
||||
|
{ |
||||
|
path: '', |
||||
|
component: AppsPageComponent |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
@Ng2.NgModule({ |
||||
|
imports: [ |
||||
|
SqxFrameworkModule, |
||||
|
SqxSharedModule, |
||||
|
Ng2Router.RouterModule.forChild(routes) |
||||
|
], |
||||
|
declarations: [ |
||||
|
AppsPageComponent |
||||
|
] |
||||
|
}) |
||||
|
export class SqxFeatureAppsModule { } |
||||
@ -0,0 +1,8 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './pages/content-page.component'; |
||||
@ -1,4 +1,4 @@ |
|||||
/* |
/* |
||||
* Squidex Headless CMS |
* Squidex Headless CMS |
||||
* |
* |
||||
* @license |
* @license |
||||
@ -0,0 +1,34 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
import * as Ng2Router from '@angular/router'; |
||||
|
|
||||
|
import { SqxFrameworkModule, SqxSharedModule } from 'shared'; |
||||
|
|
||||
|
import { |
||||
|
ContentPageComponent |
||||
|
} from './declarations'; |
||||
|
|
||||
|
const routes: Ng2Router.Routes = [ |
||||
|
{ |
||||
|
path: '', |
||||
|
component: ContentPageComponent |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
@Ng2.NgModule({ |
||||
|
imports: [ |
||||
|
SqxFrameworkModule, |
||||
|
SqxSharedModule, |
||||
|
Ng2Router.RouterModule.forChild(routes) |
||||
|
], |
||||
|
declarations: [ |
||||
|
ContentPageComponent |
||||
|
] |
||||
|
}) |
||||
|
export class SqxFeatureContentModule { } |
||||
@ -0,0 +1,14 @@ |
|||||
|
<sqx-title message="{app} | Content" parameter="app" value="{{appName() | async}}"></sqx-title> |
||||
|
|
||||
|
<div class="panel panel-light"> |
||||
|
<div class="panel-header"> |
||||
|
<h3 class="panel-title">Content</h3> |
||||
|
|
||||
|
<a class="panel-close" dashboardLink> |
||||
|
<i class="icon-close"></i> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-content"> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,7 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
.panel { |
||||
|
min-width: 600px; |
||||
|
max-width: 600px; |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { |
||||
|
AppComponentBase, |
||||
|
AppsStoreService, |
||||
|
NotificationService, |
||||
|
UsersProviderService |
||||
|
} from 'shared'; |
||||
|
|
||||
|
@Ng2.Component({ |
||||
|
selector: 'sqx-content-page', |
||||
|
styles, |
||||
|
template |
||||
|
}) |
||||
|
export class ContentPageComponent extends AppComponentBase { |
||||
|
constructor(apps: AppsStoreService, notifications: NotificationService, users: UsersProviderService) { |
||||
|
super(apps, notifications, users); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,8 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './pages/dashboard-page.component'; |
||||
@ -1,4 +1,4 @@ |
|||||
/* |
/* |
||||
* Squidex Headless CMS |
* Squidex Headless CMS |
||||
* |
* |
||||
* @license |
* @license |
||||
@ -0,0 +1,33 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
import * as Ng2Router from '@angular/router'; |
||||
|
|
||||
|
import { SqxFrameworkModule } from 'shared'; |
||||
|
|
||||
|
import { |
||||
|
DashboardPageComponent |
||||
|
} from './declarations'; |
||||
|
|
||||
|
const routes: Ng2Router.Routes = [ |
||||
|
{ |
||||
|
path: '', |
||||
|
component: DashboardPageComponent |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
@Ng2.NgModule({ |
||||
|
imports: [ |
||||
|
SqxFrameworkModule, |
||||
|
Ng2Router.RouterModule.forChild(routes) |
||||
|
], |
||||
|
declarations: [ |
||||
|
DashboardPageComponent |
||||
|
] |
||||
|
}) |
||||
|
export class SqxFeatureDashboardModule { } |
||||
@ -0,0 +1,10 @@ |
|||||
|
<sqx-title message="{app} | Dashboard" parameter="app" value="{{appName() | async}}"></sqx-title> |
||||
|
|
||||
|
<div class="panel panel-light"> |
||||
|
<div class="panel-header"> |
||||
|
<h3 class="panel-title">Dashboard</h3> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-content"> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,7 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
.panel { |
||||
|
min-width: 600px; |
||||
|
max-width: 600px; |
||||
|
} |
||||
@ -0,0 +1,8 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './pages/media-page.component'; |
||||
@ -1,4 +1,4 @@ |
|||||
/* |
/* |
||||
* Squidex Headless CMS |
* Squidex Headless CMS |
||||
* |
* |
||||
* @license |
* @license |
||||
@ -0,0 +1,34 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
import * as Ng2Router from '@angular/router'; |
||||
|
|
||||
|
import { SqxFrameworkModule, SqxSharedModule } from 'shared'; |
||||
|
|
||||
|
import { |
||||
|
MediaPageComponent |
||||
|
} from './declarations'; |
||||
|
|
||||
|
const routes: Ng2Router.Routes = [ |
||||
|
{ |
||||
|
path: '', |
||||
|
component: MediaPageComponent |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
@Ng2.NgModule({ |
||||
|
imports: [ |
||||
|
SqxFrameworkModule, |
||||
|
SqxSharedModule, |
||||
|
Ng2Router.RouterModule.forChild(routes) |
||||
|
], |
||||
|
declarations: [ |
||||
|
MediaPageComponent |
||||
|
] |
||||
|
}) |
||||
|
export class SqxFeatureMediaModule { } |
||||
@ -0,0 +1,14 @@ |
|||||
|
<sqx-title message="{app} | Media" parameter="app" value="{{appName() | async}}"></sqx-title> |
||||
|
|
||||
|
<div class="panel panel-light"> |
||||
|
<div class="panel-header"> |
||||
|
<h3 class="panel-title">Media</h3> |
||||
|
|
||||
|
<a class="panel-close" dashboardLink> |
||||
|
<i class="icon-close"></i> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-content"> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,7 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
.panel { |
||||
|
min-width: 600px; |
||||
|
max-width: 600px; |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { |
||||
|
AppComponentBase, |
||||
|
AppsStoreService, |
||||
|
NotificationService, |
||||
|
UsersProviderService |
||||
|
} from 'shared'; |
||||
|
|
||||
|
@Ng2.Component({ |
||||
|
selector: 'sqx-media-page', |
||||
|
styles, |
||||
|
template |
||||
|
}) |
||||
|
export class MediaPageComponent extends AppComponentBase { |
||||
|
constructor(apps: AppsStoreService, notifications: NotificationService, users: UsersProviderService) { |
||||
|
super(apps, notifications, users); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,8 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './pages/schemas-page.component'; |
||||
@ -0,0 +1,9 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './declarations'; |
||||
|
export * from './module'; |
||||
@ -0,0 +1,34 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
import * as Ng2Router from '@angular/router'; |
||||
|
|
||||
|
import { SqxFrameworkModule, SqxSharedModule } from 'shared'; |
||||
|
|
||||
|
import { |
||||
|
SchemasPageComponent |
||||
|
} from './declarations'; |
||||
|
|
||||
|
const routes: Ng2Router.Routes = [ |
||||
|
{ |
||||
|
path: '', |
||||
|
component: SchemasPageComponent |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
@Ng2.NgModule({ |
||||
|
imports: [ |
||||
|
SqxFrameworkModule, |
||||
|
SqxSharedModule, |
||||
|
Ng2Router.RouterModule.forChild(routes) |
||||
|
], |
||||
|
declarations: [ |
||||
|
SchemasPageComponent |
||||
|
] |
||||
|
}) |
||||
|
export class SqxFeatureSchemasModule { } |
||||
@ -0,0 +1,14 @@ |
|||||
|
<sqx-title message="{app} | Schemas" parameter="app" value="{{appName() | async}}"></sqx-title> |
||||
|
|
||||
|
<div class="panel panel-light"> |
||||
|
<div class="panel-header"> |
||||
|
<h3 class="panel-title">Schemas</h3> |
||||
|
|
||||
|
<a class="panel-close" dashboardLink> |
||||
|
<i class="icon-close"></i> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-content"> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,7 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
.panel { |
||||
|
min-width: 600px; |
||||
|
max-width: 600px; |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { |
||||
|
AppComponentBase, |
||||
|
AppsStoreService, |
||||
|
NotificationService, |
||||
|
UsersProviderService |
||||
|
} from 'shared'; |
||||
|
|
||||
|
@Ng2.Component({ |
||||
|
selector: 'sqx-schemas-page', |
||||
|
styles, |
||||
|
template |
||||
|
}) |
||||
|
export class SchemasPageComponent extends AppComponentBase { |
||||
|
constructor(apps: AppsStoreService, notifications: NotificationService, users: UsersProviderService) { |
||||
|
super(apps, notifications, users); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,13 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './pages/clients/client.component'; |
||||
|
export * from './pages/clients/clients-page.component'; |
||||
|
export * from './pages/contributors/contributors-page.component'; |
||||
|
export * from './pages/languages/languages-page.component'; |
||||
|
|
||||
|
export * from './settings-area.component'; |
||||
@ -0,0 +1,9 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './declarations'; |
||||
|
export * from './module'; |
||||
@ -0,0 +1,57 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
import * as Ng2Router from '@angular/router'; |
||||
|
|
||||
|
import { SqxFrameworkModule, SqxSharedModule } from 'shared'; |
||||
|
|
||||
|
import { |
||||
|
ClientComponent, |
||||
|
ClientsPageComponent, |
||||
|
ContributorsPageComponent, |
||||
|
LanguagesPageComponent, |
||||
|
SettingsAreaComponent |
||||
|
} from './declarations'; |
||||
|
|
||||
|
const routes: Ng2Router.Routes = [ |
||||
|
{ |
||||
|
path: '', |
||||
|
component: SettingsAreaComponent, |
||||
|
children: [ |
||||
|
{ |
||||
|
path: '' |
||||
|
}, |
||||
|
{ |
||||
|
path: 'clients', |
||||
|
component: ClientsPageComponent |
||||
|
}, { |
||||
|
path: 'contributors', |
||||
|
component: ContributorsPageComponent |
||||
|
}, { |
||||
|
path: 'languages', |
||||
|
component: LanguagesPageComponent |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
]; |
||||
|
|
||||
|
@Ng2.NgModule({ |
||||
|
imports: [ |
||||
|
SqxFrameworkModule, |
||||
|
SqxSharedModule, |
||||
|
Ng2Router.RouterModule.forChild(routes) |
||||
|
], |
||||
|
declarations: [ |
||||
|
ClientComponent, |
||||
|
ClientsPageComponent, |
||||
|
ContributorsPageComponent, |
||||
|
LanguagesPageComponent, |
||||
|
SettingsAreaComponent |
||||
|
] |
||||
|
}) |
||||
|
export class SqxFeatureSettingsModule { } |
||||
@ -0,0 +1,45 @@ |
|||||
|
<sqx-title message="{app} | Clients | Settings" parameter="app" value="{{appName() | async}}"></sqx-title> |
||||
|
|
||||
|
<div class="panel panel-light"> |
||||
|
<div class="panel-header"> |
||||
|
<h3 class="panel-title">Clients</h3> |
||||
|
|
||||
|
<a class="panel-close" routerLink="../"> |
||||
|
<i class="icon-close"></i> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-content"> |
||||
|
<div class="table-items-row" *ngIf="appClients && appClients.length === 0"> |
||||
|
No client created yet. |
||||
|
</div> |
||||
|
|
||||
|
<div *ngFor="let client of appClients"> |
||||
|
<sqx-client [client]="client" [appName]="appName() | async" (renamed)="renameClient(client, $event)"></sqx-client> |
||||
|
</div> |
||||
|
|
||||
|
<div class="table-items-footer"> |
||||
|
<form class="form-inline" [formGroup]="createForm" (submit)="attachClient()"> |
||||
|
<div class="errors-box" *ngIf="createForm.get('name').invalid && createForm.get('name').dirty"> |
||||
|
<div class="errors"> |
||||
|
<span *ngIf="createForm.get('name').hasError('required')"> |
||||
|
Name is required. |
||||
|
</span> |
||||
|
<span *ngIf="createForm.get('name').hasError('maxlength')"> |
||||
|
Name can not have more than 40 characters. |
||||
|
</span> |
||||
|
<span *ngIf="createForm.get('name').hasError('pattern')"> |
||||
|
Name can contain lower case letters (a-z), numbers and dashes (not at the end). |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="form-group"> |
||||
|
<input type="text" class="form-control" id="app-name" formControlName="name" maxlength="40" placeholder="Enter client name" /> |
||||
|
</div> |
||||
|
|
||||
|
<button type="submit" class="btn btn-success" [disabled]="createForm.invalid">Add Client</button> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
@ -1,8 +1,9 @@ |
|||||
@import '_vars'; |
@import '_vars'; |
||||
@import '_mixins'; |
@import '_mixins'; |
||||
|
|
||||
.layout-title-icon { |
.panel { |
||||
color: $color-section-settings; |
min-width: 600px; |
||||
|
max-width: 600px; |
||||
} |
} |
||||
|
|
||||
.card { |
.card { |
||||
@ -0,0 +1,65 @@ |
|||||
|
<sqx-title message="{app} | Contributors | Settings" parameter="app" value="{{appName() | async}}"></sqx-title> |
||||
|
|
||||
|
<div class="panel panel-light"> |
||||
|
<div class="panel-header"> |
||||
|
<h3 class="panel-title">Contributors</h3> |
||||
|
|
||||
|
<a class="panel-close" routerLink="../"> |
||||
|
<i class="icon-close"></i> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-content"> |
||||
|
<table class="table table-items table-fixed"> |
||||
|
<colgroup> |
||||
|
<col style="width: 50px" /> |
||||
|
<col style="width: 50%" /> |
||||
|
<col style="width: 50%" /> |
||||
|
<col style="width: 150px" /> |
||||
|
<col style="width: 80px" /> |
||||
|
</colgroup> |
||||
|
|
||||
|
<tbody> |
||||
|
<template ngFor let-contributor [ngForOf]="appContributors"> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<img class="user-picture" [attr.src]="userPicture(contributor.contributorId) | async" /> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="user-name">{{userName(contributor.contributorId) | async}}</span> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="user-email">{{userEmail(contributor.contributorId) | async}}</span> |
||||
|
</td> |
||||
|
<td> |
||||
|
<select class="form-control" [(ngModel)]="contributor.permission" (ngModelChange)="changePermission(contributor, $event)" [disabled]="currentUserId === contributor.contributorId"> |
||||
|
<option *ngFor="let permission of usersPermissions">{{permission}}</option> |
||||
|
</select> |
||||
|
</td> |
||||
|
<td> |
||||
|
<button type="button" class="btn btn-link btn-danger" [disabled]="currrentUserId === contributor.contributorId" (click)="removeContributor(contributor)"> |
||||
|
<i class="icon-bin"></i> |
||||
|
</button> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr class="spacer"></tr> |
||||
|
</template> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
<div class="table-items-footer"> |
||||
|
<form class="form-inline" (submit)="assignContributor()" > |
||||
|
<div class="form-group"> |
||||
|
<sqx-autocomplete [source]="usersDataSource" |
||||
|
(ngModelChange)="selectUser($event.model)" |
||||
|
[ngModel]="selectedUser" |
||||
|
[ngModelOptions]="{standalone: true}" |
||||
|
[inputName]="contributor"> |
||||
|
</sqx-autocomplete> |
||||
|
</div> |
||||
|
|
||||
|
<button type="submit" class="btn btn-success" [disabled]="!selectedUser">Add Contributor</button> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
@ -1,8 +1,9 @@ |
|||||
@import '_vars'; |
@import '_vars'; |
||||
@import '_mixins'; |
@import '_mixins'; |
||||
|
|
||||
.layout-title-icon { |
.panel { |
||||
color: $color-section-settings; |
min-width: 600px; |
||||
|
max-width: 600px; |
||||
} |
} |
||||
|
|
||||
.card { |
.card { |
||||
@ -0,0 +1,76 @@ |
|||||
|
<sqx-title message="{app} | Languages | Settings" parameter="app" value="{{appName() | async}}"></sqx-title> |
||||
|
|
||||
|
<div class="panel panel-light"> |
||||
|
<div class="panel-header"> |
||||
|
<h3 class="panel-title">Settings</h3> |
||||
|
|
||||
|
<a class="panel-close" routerLink="../"> |
||||
|
<i class="icon-close"></i> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-content"> |
||||
|
<table class="table table-items table-fixed"> |
||||
|
<colgroup> |
||||
|
<col style="width: 60px" /> |
||||
|
<col style="width: 100%" /> |
||||
|
<col style="width: 200px" /> |
||||
|
<col style="width: 80px" /> |
||||
|
</colgroup> |
||||
|
|
||||
|
<thead> |
||||
|
<tr> |
||||
|
<th> |
||||
|
Code |
||||
|
</th> |
||||
|
<th> |
||||
|
Name |
||||
|
</th> |
||||
|
<th> |
||||
|
Options |
||||
|
</th> |
||||
|
</tr> |
||||
|
</thead> |
||||
|
|
||||
|
<tbody> |
||||
|
<template ngFor let-language [ngForOf]="appLanguages"> |
||||
|
<tr> |
||||
|
<td> |
||||
|
<span class="language-code"> |
||||
|
{{language.iso2Code}} |
||||
|
</span> |
||||
|
</td> |
||||
|
<td> |
||||
|
<span class="language-name"> |
||||
|
{{language.englishName}} |
||||
|
</span> |
||||
|
</td> |
||||
|
<td> |
||||
|
<label class="language-default"> |
||||
|
<input type="radio" [value]="true" [ngModel]="language.isMasterLanguage" (ngModelChange)="setMasterLanguage(language)"> Master Language |
||||
|
</label> |
||||
|
</td> |
||||
|
<td> |
||||
|
<button type="button" class="btn btn-link btn-danger" [disabled]="language.isMasterLanguage" (click)="removeLanguage(language)"> |
||||
|
<i class="icon-bin"></i> |
||||
|
</button> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr class="spacer"></tr> |
||||
|
</template> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
|
||||
|
<div class="table-items-footer"> |
||||
|
<form class="form-inline" (submit)="addLanguage()" name="addLanguageForm"> |
||||
|
<div class="form-group"> |
||||
|
<select class="form-control language-select" [(ngModel)]="selectedLanguage" name="newLanguage"> |
||||
|
<option *ngFor="let language of allLanguages" [ngValue]="language">{{language.englishName}}</option> |
||||
|
</select> |
||||
|
</div> |
||||
|
|
||||
|
<button type="submit" class="btn btn-success" [disabled]="!selectedLanguage">Add Language</button> |
||||
|
</form> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
@ -1,8 +1,9 @@ |
|||||
@import '_vars'; |
@import '_vars'; |
||||
@import '_mixins'; |
@import '_mixins'; |
||||
|
|
||||
.layout-title-icon { |
.panel { |
||||
color: $color-section-settings; |
min-width: 600px; |
||||
|
max-width: 600px; |
||||
} |
} |
||||
|
|
||||
.language { |
.language { |
||||
@ -0,0 +1,31 @@ |
|||||
|
<div class="panel panel-dark"> |
||||
|
<div class="panel-header"> |
||||
|
<h3 class="panel-title">Settings</h3> |
||||
|
|
||||
|
<a class="panel-close" dashboardLink> |
||||
|
<i class="icon-close"></i> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-content"> |
||||
|
<ul class="nav nav-pills nav-stacked nav-dark"> |
||||
|
<li class="nav-item"> |
||||
|
<a class="nav-link" routerLink="clients" routerLinkActive="active"> |
||||
|
Clients |
||||
|
</a> |
||||
|
</li> |
||||
|
<li class="nav-item"> |
||||
|
<a class="nav-link" routerLink="contributors" routerLinkActive="active"> |
||||
|
Contributors |
||||
|
</a> |
||||
|
</li> |
||||
|
<li class="nav-item"> |
||||
|
<a class="nav-link" routerLink="languages" routerLinkActive="active"> |
||||
|
Languages |
||||
|
</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<router-outlet></router-outlet> |
||||
@ -0,0 +1,7 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
.panel { |
||||
|
min-width: 180px; |
||||
|
max-width: 180px; |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
@Ng2.Component({ |
||||
|
selector: 'sqx-settings-area', |
||||
|
styles, |
||||
|
template |
||||
|
}) |
||||
|
export class SettingsAreaComponent { |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,58 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { PanelService } from './../services/panel.service'; |
||||
|
|
||||
|
@Ng2.Directive({ |
||||
|
selector: '.panel-container' |
||||
|
}) |
||||
|
export class PanelContainerDirective implements Ng2.OnInit, Ng2.OnDestroy { |
||||
|
private subscription: any; |
||||
|
private panelsSize: number | null = null; |
||||
|
|
||||
|
constructor( |
||||
|
private readonly element: Ng2.ElementRef, |
||||
|
private readonly panels: PanelService |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
@Ng2.HostListener('window:resize') |
||||
|
public onResize() { |
||||
|
this.resize(); |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.subscription = |
||||
|
this.panels.changed.subscribe(width => { |
||||
|
this.panelsSize = width; |
||||
|
|
||||
|
this.resize(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.subscription.unsubscribe(); |
||||
|
} |
||||
|
|
||||
|
private resize() { |
||||
|
if (!this.panelsSize) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
const currentWidth = this.element.nativeElement.getBoundingClientRect().width; |
||||
|
|
||||
|
const diff = this.panelsSize - currentWidth; |
||||
|
|
||||
|
if (diff > 0) { |
||||
|
this.element.nativeElement.scrollLeft = diff; |
||||
|
} else { |
||||
|
this.element.nativeElement.scrollLeft = 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { PanelService } from './../services/panel.service'; |
||||
|
|
||||
|
@Ng2.Directive({ |
||||
|
selector: '.panel' |
||||
|
}) |
||||
|
export class PanelDirective implements Ng2.OnInit, Ng2.OnDestroy { |
||||
|
constructor( |
||||
|
private readonly element: Ng2.ElementRef, |
||||
|
private readonly renderer: Ng2.Renderer, |
||||
|
private readonly panels: PanelService |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.panels.push(this.element.nativeElement, this.renderer); |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.panels.pop(this.element.nativeElement, this.renderer); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { Observable, Subject } from 'rxjs'; |
||||
|
|
||||
|
export const PanelServiceFactory = () => { |
||||
|
return new PanelService(); |
||||
|
}; |
||||
|
|
||||
|
@Ng2.Injectable() |
||||
|
export class PanelService { |
||||
|
private readonly elements: any[] = []; |
||||
|
private readonly changed$ = new Subject<number>(); |
||||
|
|
||||
|
public get changed(): Observable<number> { |
||||
|
return this.changed$; |
||||
|
} |
||||
|
|
||||
|
public push(element: any, renderer: Ng2.Renderer) { |
||||
|
this.elements.push(element); |
||||
|
this.update(renderer); |
||||
|
} |
||||
|
|
||||
|
public pop(element: any, renderer: Ng2.Renderer) { |
||||
|
this.elements.splice(-1, 1); |
||||
|
this.update(renderer); |
||||
|
} |
||||
|
|
||||
|
private update(renderer: Ng2.Renderer) { |
||||
|
let currentPosition = 0; |
||||
|
let currentLayer = this.elements.length * 10; |
||||
|
|
||||
|
for (let element of this.elements) { |
||||
|
const width = element.getBoundingClientRect().width; |
||||
|
|
||||
|
renderer.setElementStyle(element, 'left', currentPosition + 'px'); |
||||
|
renderer.setElementStyle(element, 'z-index', currentLayer.toString()); |
||||
|
|
||||
|
currentPosition += width; |
||||
|
currentLayer -= 10; |
||||
|
} |
||||
|
|
||||
|
this.changed$.next(currentPosition); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
import * as Ng2Router from '@angular/router'; |
||||
|
|
||||
|
import { AppsStoreService } from './../services/apps-store.service'; |
||||
|
|
||||
|
@Ng2.Directive({ |
||||
|
selector: '[dashboardLink]' |
||||
|
}) |
||||
|
export class DashboardLinkDirective implements Ng2.OnInit, Ng2.OnDestroy { |
||||
|
private appSubscription: any; |
||||
|
private appName: string; |
||||
|
|
||||
|
constructor( |
||||
|
private readonly appsStore: AppsStoreService, |
||||
|
private readonly router: Ng2Router.Router |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.appSubscription = |
||||
|
this.appsStore.selectedApp.subscribe(app => { |
||||
|
this.appName = app.name; |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
public ngOnDestroy() { |
||||
|
this.appSubscription.unsubscribe(); |
||||
|
} |
||||
|
|
||||
|
@Ng2.HostListener('click') |
||||
|
public onClick() { |
||||
|
if (this.appName) { |
||||
|
this.router.navigate(['app', this.appName]); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,28 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './components/app-form.component'; |
||||
|
export * from './components/dashboard-link.directive'; |
||||
|
|
||||
|
export * from './guards/app-must-exist.guard'; |
||||
|
export * from './guards/must-be-authenticated.guard'; |
||||
|
export * from './guards/must-be-not-authenticated.guard'; |
||||
|
|
||||
|
export * from './services/app-contributors.service'; |
||||
|
export * from './services/app-clients.service'; |
||||
|
export * from './services/app-languages.service'; |
||||
|
export * from './services/apps-store.service'; |
||||
|
export * from './services/apps.service'; |
||||
|
export * from './services/auth.service'; |
||||
|
export * from './services/common'; |
||||
|
export * from './services/languages.service'; |
||||
|
export * from './services/users-provider.service'; |
||||
|
export * from './services/users.service'; |
||||
|
|
||||
|
export * from './app-component-base'; |
||||
|
|
||||
|
export * from 'framework'; |
||||
@ -1,25 +1,9 @@ |
|||||
/* |
/* |
||||
* Squidex Headless CMS |
* Squidex Headless CMS |
||||
* |
* |
||||
* @license |
* @license |
||||
* Copyright (c) Sebastian Stehle. All rights reserved |
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
*/ |
*/ |
||||
|
|
||||
export * from './guards/app-must-exist.guard'; |
export * from './declarations'; |
||||
export * from './guards/must-be-authenticated.guard'; |
export * from './module'; |
||||
export * from './guards/must-be-not-authenticated.guard'; |
|
||||
|
|
||||
export * from './services/app-contributors.service'; |
|
||||
export * from './services/app-clients.service'; |
|
||||
export * from './services/app-languages.service'; |
|
||||
export * from './services/apps-store.service'; |
|
||||
export * from './services/apps.service'; |
|
||||
export * from './services/auth.service'; |
|
||||
export * from './services/common'; |
|
||||
export * from './services/languages.service'; |
|
||||
export * from './services/users-provider.service'; |
|
||||
export * from './services/users.service'; |
|
||||
|
|
||||
export * from './app-component-base'; |
|
||||
|
|
||||
export * from 'framework'; |
|
||||
@ -0,0 +1,20 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './pages/app/app-area.component'; |
||||
|
export * from './pages/app/left-menu.component'; |
||||
|
|
||||
|
export * from './pages/home/home-page.component'; |
||||
|
|
||||
|
export * from './pages/internal/apps-menu.component'; |
||||
|
export * from './pages/internal/internal-area.component'; |
||||
|
export * from './pages/internal/profile-menu.component'; |
||||
|
export * from './pages/internal/search-form.component'; |
||||
|
|
||||
|
export * from './pages/logout/logout-page.component'; |
||||
|
|
||||
|
export * from './pages/not-found/not-found-page.component'; |
||||
@ -0,0 +1,9 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
export * from './declarations'; |
||||
|
export * from './module'; |
||||
@ -0,0 +1,47 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Sebastian Stehle. All rights reserved |
||||
|
*/ |
||||
|
|
||||
|
import * as Ng2 from '@angular/core'; |
||||
|
|
||||
|
import { SqxFrameworkModule, SqxSharedModule } from 'shared'; |
||||
|
|
||||
|
import { |
||||
|
AppAreaComponent, |
||||
|
AppsMenuComponent, |
||||
|
HomePageComponent, |
||||
|
InternalAreaComponent, |
||||
|
LeftMenuComponent, |
||||
|
LogoutPageComponent, |
||||
|
NotFoundPageComponent, |
||||
|
ProfileMenuComponent, |
||||
|
SearchFormComponent |
||||
|
} from './declarations'; |
||||
|
|
||||
|
@Ng2.NgModule({ |
||||
|
imports: [ |
||||
|
SqxFrameworkModule, |
||||
|
SqxSharedModule |
||||
|
], |
||||
|
exports: [ |
||||
|
AppAreaComponent, |
||||
|
HomePageComponent, |
||||
|
InternalAreaComponent, |
||||
|
NotFoundPageComponent |
||||
|
], |
||||
|
declarations: [ |
||||
|
AppAreaComponent, |
||||
|
AppsMenuComponent, |
||||
|
HomePageComponent, |
||||
|
InternalAreaComponent, |
||||
|
LeftMenuComponent, |
||||
|
LogoutPageComponent, |
||||
|
NotFoundPageComponent, |
||||
|
ProfileMenuComponent, |
||||
|
SearchFormComponent |
||||
|
] |
||||
|
}) |
||||
|
export class SqxShellModule { } |
||||
@ -0,0 +1,7 @@ |
|||||
|
<div class="sidebar"> |
||||
|
<sqx-left-menu></sqx-left-menu> |
||||
|
</div> |
||||
|
|
||||
|
<div class="panel-container"> |
||||
|
<router-outlet></router-outlet> |
||||
|
</div> |
||||
@ -0,0 +1,24 @@ |
|||||
|
<div class="sidebar panel-dark"> |
||||
|
<ul class="nav nav-pills nav-stacked nav-dark"> |
||||
|
<li class="nav-item nav-item--schemas" *ngIf="permission !== 'Editor'"> |
||||
|
<a class="nav-link" routerLink="schemas" routerLinkActive="active"> |
||||
|
<i class="nav-icon icon-schemas"></i> <span class="nav-text">Schemas</span> |
||||
|
</a> |
||||
|
</li> |
||||
|
<li class="nav-item nav-item--content"> |
||||
|
<a class="nav-link" routerLink="content" routerLinkActive="active"> |
||||
|
<i class="nav-icon icon-content"></i> <span class="nav-text">Content</span> |
||||
|
</a> |
||||
|
</li> |
||||
|
<li class="nav-item nav-item--media"> |
||||
|
<a class="nav-link" routerLink="media" routerLinkActive="active"> |
||||
|
<i class="nav-icon icon-media"></i> <span class="nav-text">Media</span> |
||||
|
</a> |
||||
|
</li> |
||||
|
<li class="nav-item nav-item--settings" *ngIf="permission === 'Owner'"> |
||||
|
<a class="nav-link" routerLink="settings" routerLinkActive="active"> |
||||
|
<i class="nav-icon icon-settings"></i> <span class="nav-text">Settings</span> |
||||
|
</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
@ -0,0 +1,72 @@ |
|||||
|
@import '_vars'; |
||||
|
@import '_mixins'; |
||||
|
|
||||
|
.sidebar { |
||||
|
@include fixed($size-navbar-height, auto, 0, 0); |
||||
|
min-width: $size-sidebar-width; |
||||
|
max-width: $size-sidebar-width; |
||||
|
z-index: 100; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
@mixin build-item($color) { |
||||
|
.nav-link { |
||||
|
&.active { |
||||
|
& { |
||||
|
background: $color-dark-selected; |
||||
|
} |
||||
|
|
||||
|
i { |
||||
|
color: $color; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&:hover { |
||||
|
i { |
||||
|
color: $color; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.nav { |
||||
|
&-link { |
||||
|
padding: 20px; |
||||
|
} |
||||
|
|
||||
|
&-icon { |
||||
|
font-size: 30px; |
||||
|
} |
||||
|
|
||||
|
&-text { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
&-item { |
||||
|
& { |
||||
|
color: $color-dark-foreground; |
||||
|
cursor: pointer; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
&--media { |
||||
|
@include build-item($color-section-media); |
||||
|
} |
||||
|
|
||||
|
&--content { |
||||
|
@include build-item($color-section-content); |
||||
|
} |
||||
|
|
||||
|
&--dashboard { |
||||
|
@include build-item($color-section-dashboard); |
||||
|
} |
||||
|
|
||||
|
&--schemas { |
||||
|
@include build-item($color-section-schemas); |
||||
|
} |
||||
|
|
||||
|
&--settings { |
||||
|
@include build-item($color-section-settings); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue