Browse Source

Layout fixes

pull/1/head
Sebastian 9 years ago
parent
commit
4f993bc947
  1. 16
      src/Squidex/app/app.module.ts
  2. 58
      src/Squidex/app/app.routes.ts
  3. 24
      src/Squidex/app/components/auth/module.ts
  4. 11
      src/Squidex/app/components/index.ts
  5. 1
      src/Squidex/app/components/internal/app/app-area.component.html
  6. 17
      src/Squidex/app/components/internal/app/dashboard/dashboard-page.component.html
  7. 6
      src/Squidex/app/components/internal/app/dashboard/dashboard-page.component.scss
  8. 38
      src/Squidex/app/components/internal/app/left-menu.component.html
  9. 121
      src/Squidex/app/components/internal/app/left-menu.component.scss
  10. 16
      src/Squidex/app/components/internal/app/schemas/schemas-page.component.html
  11. 6
      src/Squidex/app/components/internal/app/schemas/schemas-page.component.scss
  12. 39
      src/Squidex/app/components/internal/app/schemas/schemas-page.component.ts
  13. 47
      src/Squidex/app/components/internal/app/settings/clients-page.component.html
  14. 67
      src/Squidex/app/components/internal/app/settings/contributors-page.component.html
  15. 78
      src/Squidex/app/components/internal/app/settings/languages-page.component.html
  16. 18
      src/Squidex/app/components/internal/declarations.ts
  17. 47
      src/Squidex/app/components/internal/module.ts
  18. 11
      src/Squidex/app/components/layout/declarations.ts
  19. 9
      src/Squidex/app/components/public/declarations.ts
  20. 26
      src/Squidex/app/components/public/module.ts
  21. 2
      src/Squidex/app/features/apps/declarations.ts
  22. 0
      src/Squidex/app/features/apps/index.ts
  23. 34
      src/Squidex/app/features/apps/module.ts
  24. 2
      src/Squidex/app/features/apps/pages/apps-page.component.html
  25. 0
      src/Squidex/app/features/apps/pages/apps-page.component.scss
  26. 6
      src/Squidex/app/features/apps/pages/apps-page.component.ts
  27. 8
      src/Squidex/app/features/content/declarations.ts
  28. 2
      src/Squidex/app/features/content/index.ts
  29. 34
      src/Squidex/app/features/content/module.ts
  30. 14
      src/Squidex/app/features/content/pages/content-page.component.html
  31. 7
      src/Squidex/app/features/content/pages/content-page.component.scss
  32. 27
      src/Squidex/app/features/content/pages/content-page.component.ts
  33. 8
      src/Squidex/app/features/dashboard/declarations.ts
  34. 2
      src/Squidex/app/features/dashboard/index.ts
  35. 33
      src/Squidex/app/features/dashboard/module.ts
  36. 10
      src/Squidex/app/features/dashboard/pages/dashboard-page.component.html
  37. 7
      src/Squidex/app/features/dashboard/pages/dashboard-page.component.scss
  38. 0
      src/Squidex/app/features/dashboard/pages/dashboard-page.component.ts
  39. 8
      src/Squidex/app/features/media/declarations.ts
  40. 2
      src/Squidex/app/features/media/index.ts
  41. 34
      src/Squidex/app/features/media/module.ts
  42. 14
      src/Squidex/app/features/media/pages/media-page.component.html
  43. 7
      src/Squidex/app/features/media/pages/media-page.component.scss
  44. 27
      src/Squidex/app/features/media/pages/media-page.component.ts
  45. 8
      src/Squidex/app/features/schemas/declarations.ts
  46. 9
      src/Squidex/app/features/schemas/index.ts
  47. 34
      src/Squidex/app/features/schemas/module.ts
  48. 14
      src/Squidex/app/features/schemas/pages/schemas-page.component.html
  49. 7
      src/Squidex/app/features/schemas/pages/schemas-page.component.scss
  50. 27
      src/Squidex/app/features/schemas/pages/schemas-page.component.ts
  51. 13
      src/Squidex/app/features/settings/declarations.ts
  52. 9
      src/Squidex/app/features/settings/index.ts
  53. 57
      src/Squidex/app/features/settings/module.ts
  54. 2
      src/Squidex/app/features/settings/pages/clients/client.component.html
  55. 0
      src/Squidex/app/features/settings/pages/clients/client.component.scss
  56. 6
      src/Squidex/app/features/settings/pages/clients/client.component.ts
  57. 45
      src/Squidex/app/features/settings/pages/clients/clients-page.component.html
  58. 5
      src/Squidex/app/features/settings/pages/clients/clients-page.component.scss
  59. 0
      src/Squidex/app/features/settings/pages/clients/clients-page.component.ts
  60. 65
      src/Squidex/app/features/settings/pages/contributors/contributors-page.component.html
  61. 5
      src/Squidex/app/features/settings/pages/contributors/contributors-page.component.scss
  62. 0
      src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts
  63. 76
      src/Squidex/app/features/settings/pages/languages/languages-page.component.html
  64. 5
      src/Squidex/app/features/settings/pages/languages/languages-page.component.scss
  65. 0
      src/Squidex/app/features/settings/pages/languages/languages-page.component.ts
  66. 0
      src/Squidex/app/features/settings/routes.ts
  67. 31
      src/Squidex/app/features/settings/settings-area.component.html
  68. 7
      src/Squidex/app/features/settings/settings-area.component.scss
  69. 17
      src/Squidex/app/features/settings/settings-area.component.ts
  70. 58
      src/Squidex/app/framework/angular/panel-container.directive.ts
  71. 30
      src/Squidex/app/framework/angular/panel.directive.ts
  72. 3
      src/Squidex/app/framework/declarations.ts
  73. 6
      src/Squidex/app/framework/module.ts
  74. 51
      src/Squidex/app/framework/services/panel.service.ts
  75. 4
      src/Squidex/app/shared/components/app-form.component.html
  76. 13
      src/Squidex/app/shared/components/app-form.component.ts
  77. 43
      src/Squidex/app/shared/components/dashboard-link.directive.ts
  78. 28
      src/Squidex/app/shared/declarations.ts
  79. 22
      src/Squidex/app/shared/index.ts
  80. 14
      src/Squidex/app/shared/module.ts
  81. 20
      src/Squidex/app/shell/declarations.ts
  82. 9
      src/Squidex/app/shell/index.ts
  83. 47
      src/Squidex/app/shell/module.ts
  84. 7
      src/Squidex/app/shell/pages/app/app-area.component.html
  85. 0
      src/Squidex/app/shell/pages/app/app-area.component.ts
  86. 24
      src/Squidex/app/shell/pages/app/left-menu.component.html
  87. 72
      src/Squidex/app/shell/pages/app/left-menu.component.scss
  88. 0
      src/Squidex/app/shell/pages/app/left-menu.component.ts
  89. 0
      src/Squidex/app/shell/pages/home/home-page.component.html
  90. 0
      src/Squidex/app/shell/pages/home/home-page.component.scss
  91. 0
      src/Squidex/app/shell/pages/home/home-page.component.ts
  92. 4
      src/Squidex/app/shell/pages/internal/apps-menu.component.html
  93. 0
      src/Squidex/app/shell/pages/internal/apps-menu.component.scss
  94. 6
      src/Squidex/app/shell/pages/internal/apps-menu.component.ts
  95. 6
      src/Squidex/app/shell/pages/internal/internal-area.component.html
  96. 3
      src/Squidex/app/shell/pages/internal/internal-area.component.scss
  97. 6
      src/Squidex/app/shell/pages/internal/internal-area.component.ts
  98. 2
      src/Squidex/app/shell/pages/internal/profile-menu.component.html
  99. 0
      src/Squidex/app/shell/pages/internal/profile-menu.component.scss
  100. 6
      src/Squidex/app/shell/pages/internal/profile-menu.component.ts

16
src/Squidex/app/app.module.ts

@ -27,19 +27,16 @@ import {
MustBeAuthenticatedGuard,
MustBeNotAuthenticatedGuard,
NotificationService,
PanelService,
SqxFrameworkModule,
SqxSharedModule,
TitlesConfig,
TitleService,
UsersProviderService,
UsersService
} from './shared';
import {
SqxAppModule,
SqxAuthModule,
SqxLayoutModule,
SqxPublicModule
} from './components';
import { SqxShellModule } from './shell';
import { routing } from './app.routes';
@ -62,11 +59,9 @@ export function configCurrency() {
@Ng2.NgModule({
imports: [
Ng2Browser.BrowserModule,
SqxAppModule,
SqxAuthModule,
SqxLayoutModule,
SqxFrameworkModule,
SqxPublicModule,
SqxSharedModule,
SqxShellModule,
routing
],
declarations: [
@ -86,6 +81,7 @@ export function configCurrency() {
MustBeAuthenticatedGuard,
MustBeNotAuthenticatedGuard,
NotificationService,
PanelService,
TitleService,
UsersProviderService,
UsersService,

58
src/Squidex/app/app.routes.ts

@ -10,17 +10,11 @@ import * as Ng2Router from '@angular/router';
import {
AppAreaComponent,
AppsPageComponent,
ClientsPageComponent,
ContributorsPageComponent,
DashboardPageComponent,
HomePageComponent,
InternalAreaComponent,
LanguagesPageComponent,
LogoutPageComponent,
NotFoundPageComponent,
SchemasPageComponent
} from './components';
NotFoundPageComponent
} from './shell';
import {
AppMustExistGuard,
@ -28,50 +22,46 @@ import {
MustBeNotAuthenticatedGuard
} from './shared';
import { SqxFeatureAppsModule } from './features/apps';
import { SqxFeatureContentModule } from './features/content';
import { SqxFeatureDashboardModule } from './features/dashboard';
import { SqxFeatureMediaModule } from './features/media';
import { SqxFeatureSchemasModule } from './features/schemas';
import { SqxFeatureSettingsModule } from './features/settings';
export const routes: Ng2Router.Routes = [
{
path: '',
component: HomePageComponent,
canActivate: [MustBeNotAuthenticatedGuard]
},
{
}, {
path: 'app',
component: InternalAreaComponent,
canActivate: [MustBeAuthenticatedGuard],
children: [
{
path: '',
component: AppsPageComponent
},
{
loadChildren: () => SqxFeatureAppsModule
}, {
path: ':appName',
component: AppAreaComponent,
canActivate: [AppMustExistGuard],
children: [
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
component: DashboardPageComponent
},
{
loadChildren: () => SqxFeatureDashboardModule
}, {
path: 'content',
loadChildren: () => SqxFeatureContentModule
}, {
path: 'media',
loadChildren: () => SqxFeatureMediaModule
}, {
path: 'schemas',
component: SchemasPageComponent
},
{
path: 'contributors',
component: ContributorsPageComponent
},
{
path: 'clients',
component: ClientsPageComponent
},
{
path: 'languages',
component: LanguagesPageComponent
loadChildren: () => SqxFeatureSchemasModule
}, {
path: 'settings',
loadChildren: () => SqxFeatureSettingsModule
}
]
}

24
src/Squidex/app/components/auth/module.ts

@ -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 { }

11
src/Squidex/app/components/index.ts

@ -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
src/Squidex/app/components/internal/app/app-area.component.html

@ -1 +0,0 @@
<router-outlet></router-outlet>

17
src/Squidex/app/components/internal/app/dashboard/dashboard-page.component.html

@ -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>

6
src/Squidex/app/components/internal/app/dashboard/dashboard-page.component.scss

@ -1,6 +0,0 @@
@import '_vars';
@import '_mixins';
.layout-title-icon {
color: $color-section-dashboard;
}

38
src/Squidex/app/components/internal/app/left-menu.component.html

@ -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>

121
src/Squidex/app/components/internal/app/left-menu.component.scss

@ -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;
}
}
}

16
src/Squidex/app/components/internal/app/schemas/schemas-page.component.html

@ -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>

6
src/Squidex/app/components/internal/app/schemas/schemas-page.component.scss

@ -1,6 +0,0 @@
@import '_vars';
@import '_mixins';
.layout-title-icon {
color: $color-section-schemas;
}

39
src/Squidex/app/components/internal/app/schemas/schemas-page.component.ts

@ -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();
}
}

47
src/Squidex/app/components/internal/app/settings/clients-page.component.html

@ -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>

67
src/Squidex/app/components/internal/app/settings/contributors-page.component.html

@ -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>

78
src/Squidex/app/components/internal/app/settings/languages-page.component.html

@ -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>

18
src/Squidex/app/components/internal/declarations.ts

@ -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';

47
src/Squidex/app/components/internal/module.ts

@ -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 { }

11
src/Squidex/app/components/layout/declarations.ts

@ -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';

9
src/Squidex/app/components/public/declarations.ts

@ -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';

26
src/Squidex/app/components/public/module.ts

@ -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 { }

2
src/Squidex/app/components/auth/declarations.ts → src/Squidex/app/features/apps/declarations.ts

@ -5,4 +5,4 @@
* Copyright (c) Sebastian Stehle. All rights reserved
*/
export * from './logout-page.component';
export * from './pages/apps-page.component';

0
src/Squidex/app/components/internal/index.ts → src/Squidex/app/features/apps/index.ts

34
src/Squidex/app/features/apps/module.ts

@ -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 { }

2
src/Squidex/app/components/internal/apps/apps-page.component.html → src/Squidex/app/features/apps/pages/apps-page.component.html

@ -6,7 +6,7 @@
</div>
</content>
<div class="modal" *sqxModalView="modalDialog" [@fade]>
<div class="modal" *sqxModalView="modalDialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">

0
src/Squidex/app/components/internal/apps/apps-page.component.scss → src/Squidex/app/features/apps/pages/apps-page.component.scss

6
src/Squidex/app/components/internal/apps/apps-page.component.ts → src/Squidex/app/features/apps/pages/apps-page.component.ts

@ -9,7 +9,6 @@ import * as Ng2 from '@angular/core';
import {
AppsStoreService,
fadeAnimation,
ModalView,
TitleService
} from 'shared';
@ -17,10 +16,7 @@ import {
@Ng2.Component({
selector: 'sqx-apps-page',
styles,
template,
animations: [
fadeAnimation
]
template
})
export class AppsPageComponent implements Ng2.OnInit {
public modalDialog = new ModalView();

8
src/Squidex/app/features/content/declarations.ts

@ -0,0 +1,8 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
export * from './pages/content-page.component';

2
src/Squidex/app/components/public/index.ts → src/Squidex/app/features/content/index.ts

@ -1,4 +1,4 @@
/*
/*
* Squidex Headless CMS
*
* @license

34
src/Squidex/app/features/content/module.ts

@ -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 { }

14
src/Squidex/app/features/content/pages/content-page.component.html

@ -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>

7
src/Squidex/app/features/content/pages/content-page.component.scss

@ -0,0 +1,7 @@
@import '_vars';
@import '_mixins';
.panel {
min-width: 600px;
max-width: 600px;
}

27
src/Squidex/app/features/content/pages/content-page.component.ts

@ -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);
}
}

8
src/Squidex/app/features/dashboard/declarations.ts

@ -0,0 +1,8 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
export * from './pages/dashboard-page.component';

2
src/Squidex/app/components/auth/index.ts → src/Squidex/app/features/dashboard/index.ts

@ -1,4 +1,4 @@
/*
/*
* Squidex Headless CMS
*
* @license

33
src/Squidex/app/features/dashboard/module.ts

@ -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 { }

10
src/Squidex/app/features/dashboard/pages/dashboard-page.component.html

@ -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>

7
src/Squidex/app/features/dashboard/pages/dashboard-page.component.scss

@ -0,0 +1,7 @@
@import '_vars';
@import '_mixins';
.panel {
min-width: 600px;
max-width: 600px;
}

0
src/Squidex/app/components/internal/app/dashboard/dashboard-page.component.ts → src/Squidex/app/features/dashboard/pages/dashboard-page.component.ts

8
src/Squidex/app/features/media/declarations.ts

@ -0,0 +1,8 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
export * from './pages/media-page.component';

2
src/Squidex/app/components/layout/index.ts → src/Squidex/app/features/media/index.ts

@ -1,4 +1,4 @@
/*
/*
* Squidex Headless CMS
*
* @license

34
src/Squidex/app/features/media/module.ts

@ -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 { }

14
src/Squidex/app/features/media/pages/media-page.component.html

@ -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>

7
src/Squidex/app/features/media/pages/media-page.component.scss

@ -0,0 +1,7 @@
@import '_vars';
@import '_mixins';
.panel {
min-width: 600px;
max-width: 600px;
}

27
src/Squidex/app/features/media/pages/media-page.component.ts

@ -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);
}
}

8
src/Squidex/app/features/schemas/declarations.ts

@ -0,0 +1,8 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
export * from './pages/schemas-page.component';

9
src/Squidex/app/features/schemas/index.ts

@ -0,0 +1,9 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
export * from './declarations';
export * from './module';

34
src/Squidex/app/features/schemas/module.ts

@ -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 { }

14
src/Squidex/app/features/schemas/pages/schemas-page.component.html

@ -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>

7
src/Squidex/app/features/schemas/pages/schemas-page.component.scss

@ -0,0 +1,7 @@
@import '_vars';
@import '_mixins';
.panel {
min-width: 600px;
max-width: 600px;
}

27
src/Squidex/app/features/schemas/pages/schemas-page.component.ts

@ -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);
}
}

13
src/Squidex/app/features/settings/declarations.ts

@ -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';

9
src/Squidex/app/features/settings/index.ts

@ -0,0 +1,9 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
export * from './declarations';
export * from './module';

57
src/Squidex/app/features/settings/module.ts

@ -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 { }

2
src/Squidex/app/components/internal/app/settings/client.component.html → src/Squidex/app/features/settings/pages/clients/client.component.html

@ -63,7 +63,7 @@
</table>
</div>
<div class="modal" *sqxModalView="modalDialog" [@fade]>
<div class="modal" *sqxModalView="modalDialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">

0
src/Squidex/app/components/internal/app/settings/client.component.scss → src/Squidex/app/features/settings/pages/clients/client.component.scss

6
src/Squidex/app/components/internal/app/settings/client.component.ts → src/Squidex/app/features/settings/pages/clients/client.component.ts

@ -11,7 +11,6 @@ import * as Ng2Forms from '@angular/forms';
import {
AccessTokenDto,
AppClientDto,
fadeAnimation,
ModalView
} from 'shared';
@ -20,10 +19,7 @@ const ESCAPE_KEY = 27;
@Ng2.Component({
selector: 'sqx-client',
styles,
template,
animations: [
fadeAnimation
]
template
})
export class ClientComponent {
public isRenaming = false;

45
src/Squidex/app/features/settings/pages/clients/clients-page.component.html

@ -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>

5
src/Squidex/app/components/internal/app/settings/clients-page.component.scss → src/Squidex/app/features/settings/pages/clients/clients-page.component.scss

@ -1,8 +1,9 @@
@import '_vars';
@import '_mixins';
.layout-title-icon {
color: $color-section-settings;
.panel {
min-width: 600px;
max-width: 600px;
}
.card {

0
src/Squidex/app/components/internal/app/settings/clients-page.component.ts → src/Squidex/app/features/settings/pages/clients/clients-page.component.ts

65
src/Squidex/app/features/settings/pages/contributors/contributors-page.component.html

@ -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>

5
src/Squidex/app/components/internal/app/settings/contributors-page.component.scss → src/Squidex/app/features/settings/pages/contributors/contributors-page.component.scss

@ -1,8 +1,9 @@
@import '_vars';
@import '_mixins';
.layout-title-icon {
color: $color-section-settings;
.panel {
min-width: 600px;
max-width: 600px;
}
.card {

0
src/Squidex/app/components/internal/app/settings/contributors-page.component.ts → src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts

76
src/Squidex/app/features/settings/pages/languages/languages-page.component.html

@ -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>

5
src/Squidex/app/components/internal/app/settings/languages-page.component.scss → src/Squidex/app/features/settings/pages/languages/languages-page.component.scss

@ -1,8 +1,9 @@
@import '_vars';
@import '_mixins';
.layout-title-icon {
color: $color-section-settings;
.panel {
min-width: 600px;
max-width: 600px;
}
.language {

0
src/Squidex/app/components/internal/app/settings/languages-page.component.ts → src/Squidex/app/features/settings/pages/languages/languages-page.component.ts

0
src/Squidex/app/features/settings/routes.ts

31
src/Squidex/app/features/settings/settings-area.component.html

@ -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>

7
src/Squidex/app/features/settings/settings-area.component.scss

@ -0,0 +1,7 @@
@import '_vars';
@import '_mixins';
.panel {
min-width: 180px;
max-width: 180px;
}

17
src/Squidex/app/features/settings/settings-area.component.ts

@ -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 {
}

58
src/Squidex/app/framework/angular/panel-container.directive.ts

@ -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;
}
}
}

30
src/Squidex/app/framework/angular/panel.directive.ts

@ -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);
}
}

3
src/Squidex/app/framework/declarations.ts

@ -19,6 +19,8 @@ export * from './angular/focus-on-init.directive';
export * from './angular/image-drop.directive';
export * from './angular/modal-view.directive';
export * from './angular/money.pipe';
export * from './angular/panel.directive';
export * from './angular/panel-container.directive';
export * from './angular/scroll-active.directive';
export * from './angular/shortcut.component';
export * from './angular/slider.component';
@ -31,6 +33,7 @@ export * from './services/clipboard.service';
export * from './services/drag.service';
export * from './services/local-store.service';
export * from './services/notification.service';
export * from './services/panel.service';
export * from './services/shortcut.service';
export * from './services/title.service';

6
src/Squidex/app/framework/module.ts

@ -26,6 +26,8 @@ import {
ModalViewDirective,
MoneyPipe,
MonthPipe,
PanelContainerDirective,
PanelDirective,
ScrollActiveDirective,
ShortcutComponent,
ShortDatePipe,
@ -59,6 +61,8 @@ import {
ModalViewDirective,
MoneyPipe,
MonthPipe,
PanelContainerDirective,
PanelDirective,
ScrollActiveDirective,
ShortcutComponent,
ShortDatePipe,
@ -83,6 +87,8 @@ import {
ModalViewDirective,
MoneyPipe,
MonthPipe,
PanelContainerDirective,
PanelDirective,
ScrollActiveDirective,
ShortcutComponent,
ShortDatePipe,

51
src/Squidex/app/framework/services/panel.service.ts

@ -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);
}
}

4
src/Squidex/app/components/layout/app-form.component.html → src/Squidex/app/shared/components/app-form.component.html

@ -1,5 +1,5 @@
<form [formGroup]="createForm" (ngSubmit)="createApp()">
<div *ngIf="creationError" [@fade]>
<div *ngIf="creationError">
<div class="form-error">
{{creationError}}
</div>
@ -8,7 +8,7 @@
<div class="form-group">
<label for="app-name">Name</label>
<div class="errors-box" *ngIf="createForm.get('name').invalid && createForm.get('name').dirty" [@fade]>
<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.

13
src/Squidex/app/components/layout/app-form.component.ts → src/Squidex/app/shared/components/app-form.component.ts

@ -8,21 +8,14 @@
import * as Ng2 from '@angular/core';
import * as Ng2Forms from '@angular/forms';
import {
AppDto,
AppsStoreService,
CreateAppDto,
fadeAnimation
} from 'shared';
import { AppsStoreService } from './../services/apps-store.service';
import { AppDto, CreateAppDto } from './../services/apps.service';
const FALLBACK_NAME = 'my-app';
@Ng2.Component({
selector: 'sqx-app-form',
template,
animations: [
fadeAnimation
]
template
})
export class AppFormComponent implements Ng2.OnInit {
@Ng2.Input()

43
src/Squidex/app/shared/components/dashboard-link.directive.ts

@ -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]);
}
}
}

28
src/Squidex/app/shared/declarations.ts

@ -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';

22
src/Squidex/app/shared/index.ts

@ -1,25 +1,9 @@
/*
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
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';
export * from './declarations';
export * from './module';

14
src/Squidex/app/components/layout/module.ts → src/Squidex/app/shared/module.ts

@ -11,9 +11,7 @@ import { SqxFrameworkModule } from 'shared';
import {
AppFormComponent,
AppsMenuComponent,
ProfileMenuComponent,
SearchFormComponent
DashboardLinkDirective
} from './declarations';
@Ng2.NgModule({
@ -22,15 +20,11 @@ import {
],
declarations: [
AppFormComponent,
AppsMenuComponent,
ProfileMenuComponent,
SearchFormComponent
DashboardLinkDirective
],
exports: [
AppFormComponent,
AppsMenuComponent,
ProfileMenuComponent,
SearchFormComponent
DashboardLinkDirective
]
})
export class SqxLayoutModule { }
export class SqxSharedModule { }

20
src/Squidex/app/shell/declarations.ts

@ -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';

9
src/Squidex/app/shell/index.ts

@ -0,0 +1,9 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
export * from './declarations';
export * from './module';

47
src/Squidex/app/shell/module.ts

@ -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 { }

7
src/Squidex/app/shell/pages/app/app-area.component.html

@ -0,0 +1,7 @@
<div class="sidebar">
<sqx-left-menu></sqx-left-menu>
</div>
<div class="panel-container">
<router-outlet></router-outlet>
</div>

0
src/Squidex/app/components/internal/app/app-area.component.ts → src/Squidex/app/shell/pages/app/app-area.component.ts

24
src/Squidex/app/shell/pages/app/left-menu.component.html

@ -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>

72
src/Squidex/app/shell/pages/app/left-menu.component.scss

@ -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);
}
}
}

0
src/Squidex/app/components/internal/app/left-menu.component.ts → src/Squidex/app/shell/pages/app/left-menu.component.ts

0
src/Squidex/app/components/public/home-page.component.html → src/Squidex/app/shell/pages/home/home-page.component.html

0
src/Squidex/app/components/public/home-page.component.scss → src/Squidex/app/shell/pages/home/home-page.component.scss

0
src/Squidex/app/components/public/home-page.component.ts → src/Squidex/app/shell/pages/home/home-page.component.ts

4
src/Squidex/app/components/layout/apps-menu.component.html → src/Squidex/app/shell/pages/internal/apps-menu.component.html

@ -2,7 +2,7 @@
<li class="nav-item dropdown">
<span class="nav-link dropdown-toggle" id="app-name" (click)="modalMenu.toggle()">{{appName}}</span>
<div class="dropdown-menu" *sqxModalView="modalMenu" closeAlways="true" [@fade]>
<div class="dropdown-menu" *sqxModalView="modalMenu" closeAlways="true">
<a class="dropdown-item all-apps" [routerLink]="['/app']">
<span class="all-apps-text">All Apps</span>
<span class="all-apps-pill tag tag-pill tag-default">{{apps.length || 0}}</span>
@ -23,7 +23,7 @@
</li>
</ul>
<div class="modal" *sqxModalView="modalDialog" [@fade]>
<div class="modal" *sqxModalView="modalDialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">

0
src/Squidex/app/components/layout/apps-menu.component.scss → src/Squidex/app/shell/pages/internal/apps-menu.component.scss

6
src/Squidex/app/components/layout/apps-menu.component.ts → src/Squidex/app/shell/pages/internal/apps-menu.component.ts

@ -11,7 +11,6 @@ import * as Ng2Router from '@angular/router';
import {
AppDto,
AppsStoreService,
fadeAnimation,
ModalView
} from 'shared';
@ -20,10 +19,7 @@ const FALLBACK_NAME = 'Apps Overview';
@Ng2.Component({
selector: 'sqx-apps-menu',
styles,
template,
animations: [
fadeAnimation
]
template
})
export class AppsMenuComponent implements Ng2.OnInit, Ng2.OnDestroy {
private appsSubscription: any | null = null;

6
src/Squidex/app/components/internal/internal-area.component.html → src/Squidex/app/shell/pages/internal/internal-area.component.html

@ -16,10 +16,12 @@
</div>
</nav>
<router-outlet></router-outlet>
<div class="main">
<router-outlet></router-outlet>
</div>
<div class="notification-container">
<div class="notification-item notification-{{notification.messageType}}" *ngFor="let notification of notifications" (click)="close(notification)" [@fade]>
<div class="notification-item notification-{{notification.messageType}}" *ngFor="let notification of notifications" (click)="close(notification)">
{{notification.message}}
</div>
</div>

3
src/Squidex/app/components/internal/internal-area.component.scss → src/Squidex/app/shell/pages/internal/internal-area.component.scss

@ -6,11 +6,14 @@
}
.navbar-brand {
text-align: center;
padding-top: 0;
padding-bottom: 0;
margin-top: -.2rem;
margin-bottom: -.2rem;
margin-right: 40px;
font-size: 1.8rem;
width: 70px;
}
.search-form {

6
src/Squidex/app/components/internal/internal-area.component.ts → src/Squidex/app/shell/pages/internal/internal-area.component.ts

@ -8,7 +8,6 @@
import * as Ng2 from '@angular/core';
import {
fadeAnimation,
Notification,
NotificationService
} from 'shared';
@ -16,10 +15,7 @@ import {
@Ng2.Component({
selector: 'sqx-internal-area',
styles,
template,
animations: [
fadeAnimation
]
template
})
export class InternalAreaComponent implements Ng2.OnInit, Ng2.OnDestroy {
private notificationsSubscription: any;

2
src/Squidex/app/components/layout/profile-menu.component.html → src/Squidex/app/shell/pages/internal/profile-menu.component.html

@ -8,7 +8,7 @@
</span>
</span>
<div class="dropdown-menu" *sqxModalView="modalMenu" closeAlways="true" [@fade]>
<div class="dropdown-menu" *sqxModalView="modalMenu" closeAlways="true">
<a class="dropdown-item" (click)="logout()">Logout</a>
</div>
</li>

0
src/Squidex/app/components/layout/profile-menu.component.scss → src/Squidex/app/shell/pages/internal/profile-menu.component.scss

6
src/Squidex/app/components/layout/profile-menu.component.ts → src/Squidex/app/shell/pages/internal/profile-menu.component.ts

@ -9,17 +9,13 @@ import * as Ng2 from '@angular/core';
import {
AuthService,
fadeAnimation,
ModalView
} from 'shared';
@Ng2.Component({
selector: 'sqx-profile-menu',
styles,
template,
animations: [
fadeAnimation
]
template
})
export class ProfileMenuComponent implements Ng2.OnInit, Ng2.OnDestroy {
private authenticationSubscription: any | null = null;

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save