Browse Source

1) Caching improvement

2) Lazy Loading
pull/1/head
Sebastian 9 years ago
parent
commit
9ba7f4c68f
  1. 16
      src/Squidex/Startup.cs
  2. 2
      src/Squidex/app-config/webpack.config.js
  3. 15
      src/Squidex/app/app.routes.ts
  4. 54
      src/Squidex/app/features/settings/pages/clients/clients-page.component.html
  5. 98
      src/Squidex/app/features/settings/pages/contributors/contributors-page.component.html
  6. 125
      src/Squidex/app/features/settings/pages/languages/languages-page.component.html
  7. 38
      src/Squidex/app/features/settings/settings-area.component.html
  8. 2
      src/Squidex/app/shared/services/auth.service.ts
  9. 16
      src/Squidex/app/theme/_bootstrap.scss
  10. 66
      src/Squidex/app/theme/_panels.scss
  11. 1
      src/Squidex/package.json

16
src/Squidex/Startup.cs

@ -26,6 +26,7 @@ using Squidex.Config.Swagger;
using Squidex.Config.Web; using Squidex.Config.Web;
using Squidex.Pipeline; using Squidex.Pipeline;
using Squidex.Store.MongoDb; using Squidex.Store.MongoDb;
// ReSharper disable InvertIf
// ReSharper disable ConvertClosureToMethodGroup // ReSharper disable ConvertClosureToMethodGroup
// ReSharper disable AccessToModifiedClosure // ReSharper disable AccessToModifiedClosure
@ -179,14 +180,19 @@ namespace Squidex
app.UseStaticFiles(new StaticFileOptions app.UseStaticFiles(new StaticFileOptions
{ {
OnPrepareResponse = (context) => OnPrepareResponse = context =>
{ {
var headers = context.Context.Response.GetTypedHeaders(); var response = context.Context.Response;
headers.CacheControl = new CacheControlHeaderValue if (!string.Equals(response.ContentType, "text/html", StringComparison.OrdinalIgnoreCase))
{ {
MaxAge = TimeSpan.FromDays(60) var headers = response.GetTypedHeaders();
};
headers.CacheControl = new CacheControlHeaderValue
{
MaxAge = TimeSpan.FromDays(60)
};
}
} }
}); });
} }

2
src/Squidex/app-config/webpack.config.js

@ -45,7 +45,7 @@ module.exports = {
loaders: [ loaders: [
{ {
test: /\.ts$/, test: /\.ts$/,
loaders: ['awesome-typescript', helpers.root('app-config', 'auto-loader') + '?[file].html=template&[file].scss=styles', 'tslint'] loaders: ['awesome-typescript', 'angular2-router-loader', helpers.root('app-config', 'auto-loader') + '?[file].html=template&[file].scss=styles', 'tslint']
}, { }, {
test: /\.html$/, test: /\.html$/,
loader: 'html' loader: 'html'

15
src/Squidex/app/app.routes.ts

@ -23,11 +23,6 @@ import {
} from './shared'; } from './shared';
import { SqxFeatureAppsModule } from './features/apps'; 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 = [ export const routes: Ng2Router.Routes = [
{ {
@ -49,19 +44,19 @@ export const routes: Ng2Router.Routes = [
children: [ children: [
{ {
path: '', path: '',
loadChildren: () => SqxFeatureDashboardModule loadChildren: './features/dashboard/module#SqxFeatureDashboardModule'
}, { }, {
path: 'content', path: 'content',
loadChildren: () => SqxFeatureContentModule loadChildren: './features/content/module#SqxFeatureContentModule'
}, { }, {
path: 'media', path: 'media',
loadChildren: () => SqxFeatureMediaModule loadChildren: './features/media/module#SqxFeatureMediaModule'
}, { }, {
path: 'schemas', path: 'schemas',
loadChildren: () => SqxFeatureSchemasModule loadChildren: './features/schemas/module#SqxFeatureSchemaModule'
}, { }, {
path: 'settings', path: 'settings',
loadChildren: () => SqxFeatureSettingsModule loadChildren: './features/settings/module#SqxFeatureSettingsModule'
} }
] ]
} }

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

@ -9,37 +9,39 @@
</a> </a>
</div> </div>
<div class="panel-content"> <div class="panel-main">
<div class="table-items-row" *ngIf="appClients && appClients.length === 0"> <div class="panel-content">
No client created yet. <div class="table-items-row" *ngIf="appClients && appClients.length === 0">
</div> No client created yet.
</div>
<div *ngFor="let client of appClients"> <div *ngFor="let client of appClients">
<sqx-client [client]="client" [appName]="appName() | async" (renamed)="renameClient(client, $event)"></sqx-client> <sqx-client [client]="client" [appName]="appName() | async" (renamed)="renameClient(client, $event)"></sqx-client>
</div> </div>
<div class="table-items-footer"> <div class="table-items-footer">
<form class="form-inline" [formGroup]="createForm" (submit)="attachClient()"> <form class="form-inline" [formGroup]="createForm" (submit)="attachClient()">
<div class="errors-box" *ngIf="createForm.get('name').invalid && createForm.get('name').dirty"> <div class="errors-box" *ngIf="createForm.get('name').invalid && createForm.get('name').dirty">
<div class="errors"> <div class="errors">
<span *ngIf="createForm.get('name').hasError('required')"> <span *ngIf="createForm.get('name').hasError('required')">
Name is required. Name is required.
</span> </span>
<span *ngIf="createForm.get('name').hasError('maxlength')"> <span *ngIf="createForm.get('name').hasError('maxlength')">
Name can not have more than 40 characters. Name can not have more than 40 characters.
</span> </span>
<span *ngIf="createForm.get('name').hasError('pattern')"> <span *ngIf="createForm.get('name').hasError('pattern')">
Name can contain lower case letters (a-z), numbers and dashes (not at the end). Name can contain lower case letters (a-z), numbers and dashes (not at the end).
</span> </span>
</div>
</div> </div>
</div>
<div class="form-group"> <div class="form-group">
<input type="text" class="form-control" id="app-name" formControlName="name" maxlength="40" placeholder="Enter client name" /> <input type="text" class="form-control" id="app-name" formControlName="name" maxlength="40" placeholder="Enter client name" />
</div> </div>
<button type="submit" class="btn btn-success" [disabled]="createForm.invalid">Add Client</button> <button type="submit" class="btn btn-success" [disabled]="createForm.invalid">Add Client</button>
</form> </form>
</div>
</div> </div>
</div> </div>
</div> </div>

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

@ -9,57 +9,59 @@
</a> </a>
</div> </div>
<div class="panel-content"> <div class="panel-main">
<table class="table table-items table-fixed"> <div class="panel-content">
<colgroup> <table class="table table-items table-fixed">
<col style="width: 50px" /> <colgroup>
<col style="width: 50%" /> <col style="width: 50px" />
<col style="width: 50%" /> <col style="width: 50%" />
<col style="width: 150px" /> <col style="width: 50%" />
<col style="width: 80px" /> <col style="width: 150px" />
</colgroup> <col style="width: 80px" />
</colgroup>
<tbody> <tbody>
<template ngFor let-contributor [ngForOf]="appContributors"> <template ngFor let-contributor [ngForOf]="appContributors">
<tr> <tr>
<td> <td>
<img class="user-picture" [attr.src]="userPicture(contributor.contributorId) | async" /> <img class="user-picture" [attr.src]="userPicture(contributor.contributorId) | async" />
</td> </td>
<td> <td>
<span class="user-name">{{userName(contributor.contributorId) | async}}</span> <span class="user-name">{{userName(contributor.contributorId) | async}}</span>
</td> </td>
<td> <td>
<span class="user-email">{{userEmail(contributor.contributorId) | async}}</span> <span class="user-email">{{userEmail(contributor.contributorId) | async}}</span>
</td> </td>
<td> <td>
<select class="form-control" [(ngModel)]="contributor.permission" (ngModelChange)="changePermission(contributor, $event)" [disabled]="currentUserId === contributor.contributorId"> <select class="form-control" [(ngModel)]="contributor.permission" (ngModelChange)="changePermission(contributor, $event)" [disabled]="currentUserId === contributor.contributorId">
<option *ngFor="let permission of usersPermissions">{{permission}}</option> <option *ngFor="let permission of usersPermissions">{{permission}}</option>
</select> </select>
</td> </td>
<td> <td>
<button type="button" class="btn btn-link btn-danger" [disabled]="currrentUserId === contributor.contributorId" (click)="removeContributor(contributor)"> <button type="button" class="btn btn-link btn-danger" [disabled]="currrentUserId === contributor.contributorId" (click)="removeContributor(contributor)">
<i class="icon-bin"></i> <i class="icon-bin"></i>
</button> </button>
</td> </td>
</tr> </tr>
<tr class="spacer"></tr> <tr class="spacer"></tr>
</template> </template>
</tbody> </tbody>
</table> </table>
<div class="table-items-footer"> <div class="table-items-footer">
<form class="form-inline" (submit)="assignContributor()" > <form class="form-inline" (submit)="assignContributor()" >
<div class="form-group"> <div class="form-group">
<sqx-autocomplete [source]="usersDataSource" <sqx-autocomplete [source]="usersDataSource"
(ngModelChange)="selectUser($event.model)" (ngModelChange)="selectUser($event.model)"
[ngModel]="selectedUser" [ngModel]="selectedUser"
[ngModelOptions]="{standalone: true}" [ngModelOptions]="{standalone: true}"
[inputName]="contributor"> [inputName]="contributor">
</sqx-autocomplete> </sqx-autocomplete>
</div> </div>
<button type="submit" class="btn btn-success" [disabled]="!selectedUser">Add Contributor</button> <button type="submit" class="btn btn-success" [disabled]="!selectedUser">Add Contributor</button>
</form> </form>
</div>
</div> </div>
</div> </div>
</div> </div>

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

@ -9,68 +9,79 @@
</a> </a>
</div> </div>
<div class="panel-content"> <div class="panel-main">
<table class="table table-items table-fixed"> <div class="panel-content">
<colgroup> <table class="table table-items table-fixed">
<col style="width: 60px" /> <colgroup>
<col style="width: 100%" /> <col style="width: 60px" />
<col style="width: 200px" /> <col style="width: 100%" />
<col style="width: 80px" /> <col style="width: 200px" />
</colgroup> <col style="width: 80px" />
</colgroup>
<thead> <thead>
<tr>
<th>
Code
</th>
<th>
Name
</th>
<th>
Options
</th>
</tr>
</thead>
<tbody>
<template ngFor let-language [ngForOf]="appLanguages">
<tr> <tr>
<td> <th>
<span class="language-code"> Code
{{language.iso2Code}} </th>
</span> <th>
</td> Name
<td> </th>
<span class="language-name"> <th>
{{language.englishName}} Options
</span> </th>
</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>
<tr class="spacer"></tr> </thead>
</template>
</tbody> <tbody>
</table> <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"> <div class="table-items-footer">
<form class="form-inline" (submit)="addLanguage()" name="addLanguageForm"> <form class="form-inline" (submit)="addLanguage()" name="addLanguageForm">
<div class="form-group"> <div class="form-group">
<select class="form-control language-select" [(ngModel)]="selectedLanguage" name="newLanguage"> <select class="form-control language-select" [(ngModel)]="selectedLanguage" name="newLanguage">
<option *ngFor="let language of allLanguages" [ngValue]="language">{{language.englishName}}</option> <option *ngFor="let language of allLanguages" [ngValue]="language">{{language.englishName}}</option>
</select> </select>
</div> </div>
<button type="submit" class="btn btn-success" [disabled]="!selectedLanguage">Add Language</button> <button type="submit" class="btn btn-success" [disabled]="!selectedLanguage">Add Language</button>
</form> </form>
</div>
</div>
<div class="panel-sidebar">
<div class="nav nav-pills nav-stacked nav-light">
<li class="nav-item">
<a class="nav-link">
<i class="icon-filter"></i>
</a>
</li>
</div>
</div> </div>
</div> </div>
</div> </div>

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

@ -7,24 +7,26 @@
</a> </a>
</div> </div>
<div class="panel-content"> <div class="panel-main">
<ul class="nav nav-pills nav-stacked nav-dark"> <div class="panel-content">
<li class="nav-item"> <ul class="nav nav-pills nav-stacked nav-dark">
<a class="nav-link" routerLink="clients" routerLinkActive="active"> <li class="nav-item">
Clients <a class="nav-link" routerLink="clients" routerLinkActive="active">
</a> Clients
</li> </a>
<li class="nav-item"> </li>
<a class="nav-link" routerLink="contributors" routerLinkActive="active"> <li class="nav-item">
Contributors <a class="nav-link" routerLink="contributors" routerLinkActive="active">
</a> Contributors
</li> </a>
<li class="nav-item"> </li>
<a class="nav-link" routerLink="languages" routerLinkActive="active"> <li class="nav-item">
Languages <a class="nav-link" routerLink="languages" routerLinkActive="active">
</a> Languages
</li> </a>
</ul> </li>
</ul>
</div>
</div> </div>
</div> </div>

2
src/Squidex/app/shared/services/auth.service.ts

@ -188,7 +188,7 @@ export class AuthService {
private checkResponse(response: Observable<Ng2Http.Response>) { private checkResponse(response: Observable<Ng2Http.Response>) {
return response.catch((error: Ng2Http.Response) => { return response.catch((error: Ng2Http.Response) => {
if (error.status === 401) { if (error.status === 401 || error.status === 404) {
this.loginRedirect(); this.loginRedirect();
} else if (error.status === 403) { } else if (error.status === 403) {
this.router.navigate(['/404']); this.router.navigate(['/404']);

16
src/Squidex/app/theme/_bootstrap.scss

@ -255,8 +255,7 @@
&.nav-pills { &.nav-pills {
.nav-link { .nav-link {
&, & {
&.active {
color: $color-dark-foreground; color: $color-dark-foreground;
} }
@ -271,6 +270,7 @@
@include border-radius(0); @include border-radius(0);
background: $color-dark-selected; background: $color-dark-selected;
pointer-events: none; pointer-events: none;
color: lighten($color-dark-foreground, 30%);
} }
&:hover { &:hover {
@ -280,3 +280,15 @@
} }
} }
} }
.nav-light {
&.nav-pills {
.nav-link {
&.active {
& {
@include border-radius(0);
}
}
}
}
}

66
src/Squidex/app/theme/_panels.scss

@ -1,8 +1,9 @@
@import '_mixins'; @import '_mixins';
@import '_vars'; @import '_vars';
$panel-padding: 15px; $panel-padding: 20px;
$panel-header: 60px; $panel-header: 70px;
$panel-sidebar: 60px;
.panel-container { .panel-container {
@include absolute($size-navbar-height, 0, 0, $size-sidebar-width); @include absolute($size-navbar-height, 0, 0, $size-sidebar-width);
@ -17,13 +18,19 @@ $panel-header: 60px;
flex-direction: column; flex-direction: column;
} }
&-content, &-header,
&-header { &-content {
padding: 15px; padding: $panel-padding;
} }
&-main,
&-content { &-content {
overflow-y: auto; @include flex-grow(1);
}
&-main {
@include flex-box;
flex-direction: row;
} }
&-title { &-title {
@ -32,11 +39,38 @@ $panel-header: 60px;
} }
&-header { &-header {
height: $panel-header; min-height: $panel-header;
max-height: $panel-header;
position: relative; position: relative;
padding-right: 60px; padding-right: 60px;
} }
&-content {
& {
overflow-y: auto;
}
& .nav-stacked {
margin-left: -$panel-padding;
margin-right: -$panel-padding;
}
& .nav-link {
padding-left: $panel-padding;
}
}
&-sidebar {
& {
min-width: $panel-sidebar;
max-width: $panel-sidebar;
}
& .nav-link {
text-align: center;
}
}
&-close { &-close {
& { & {
@include absolute($panel-padding, $panel-padding, auto, auto); @include absolute($panel-padding, $panel-padding, auto, auto);
@ -77,12 +111,21 @@ $panel-header: 60px;
.panel-header { .panel-header {
background: $color-card-footer; background: $color-card-footer;
border-bottom: 1px solid $color-border; }
.panel-content {
border-top: 1px solid $color-border;
}
.panel-sidebar {
background: $color-card-footer;
border-left: 1px solid $color-border;
color: lighten($color-dark-foreground, 20%);
} }
.panel-close { .panel-close {
& { & {
color: $color-dark-foreground; color: lighten($color-dark-foreground, 20%);
} }
&:hover { &:hover {
@ -90,11 +133,6 @@ $panel-header: 60px;
} }
} }
} }
& .nav-stacked {
margin-left: -$panel-padding;
margin-right: -$panel-padding;
}
} }
.panel-menu { .panel-menu {

1
src/Squidex/package.json

@ -39,6 +39,7 @@
"@types/jasmine": "^2.5.38", "@types/jasmine": "^2.5.38",
"@types/mousetrap": "^1.5.32", "@types/mousetrap": "^1.5.32",
"@types/node": "^6.0.51", "@types/node": "^6.0.51",
"angular2-router-loader": "^0.3.4",
"awesome-typescript-loader": "^2.2.4", "awesome-typescript-loader": "^2.2.4",
"cpx": "^1.5.0", "cpx": "^1.5.0",
"css-loader": "^0.26.0", "css-loader": "^0.26.0",

Loading…
Cancel
Save