Browse Source

Language handling improved

pull/65/head
Sebastian Stehle 10 years ago
parent
commit
0f8c91c06b
  1. 2
      src/Squidex.Infrastructure/Assets/FolderAssetStore.cs
  2. 1
      src/Squidex/Config/Domain/StoreMongoDbModule.cs
  3. 3
      src/Squidex/Controllers/Api/Apps/AppLanguagesController.cs
  4. 33
      src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts
  5. 22
      src/Squidex/app/features/administration/pages/users/users-page.component.ts
  6. 5
      src/Squidex/app/features/assets/pages/assets-page.component.ts
  7. 2
      src/Squidex/app/features/content/pages/contents/content-item.component.ts
  8. 16
      src/Squidex/app/features/schemas/pages/schema/field.component.html
  9. 59
      src/Squidex/app/features/schemas/pages/schema/field.component.scss
  10. 2
      src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.ts
  11. 14
      src/Squidex/app/features/settings/pages/languages/language.component.html
  12. 52
      src/Squidex/app/features/settings/pages/languages/language.component.scss
  13. 21
      src/Squidex/app/features/settings/pages/languages/language.component.ts
  14. 69
      src/Squidex/app/features/settings/pages/languages/languages-page.component.ts
  15. 5
      src/Squidex/app/shared/components/assets-editor.component.ts
  16. 68
      src/Squidex/app/theme/_lists.scss

2
src/Squidex.Infrastructure/Assets/FolderAssetStore.cs

@ -56,7 +56,7 @@ namespace Squidex.Infrastructure.Assets
try
{
using (var fileStream = file.OpenWrite())
using (var fileStream = file.OpenRead())
{
await fileStream.CopyToAsync(stream);
}

1
src/Squidex/Config/Domain/StoreMongoDbModule.cs

@ -137,7 +137,6 @@ namespace Squidex.Config.Domain
builder.RegisterType<MongoAppRepository>()
.WithParameter(ResolvedParameter.ForNamed<IMongoDatabase>(MongoDatabaseRegistration))
.As<IAppRepository>()
.As<IEventConsumer>()
.As<IExternalSystem>()
.AsSelf()
.SingleInstance();

3
src/Squidex/Controllers/Api/Apps/AppLanguagesController.cs

@ -7,6 +7,7 @@
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
@ -94,7 +95,7 @@ namespace Squidex.Controllers.Api.Apps
{
await CommandBus.PublishAsync(SimpleMapper.Map(request, new AddLanguage()));
var response = SimpleMapper.Map(request.Language, new AppLanguageDto());
var response = SimpleMapper.Map(request.Language, new AppLanguageDto { Fallback = new List<Language>() });
return CreatedAtAction(nameof(GetLanguages), new { app }, response);
}

33
src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts

@ -55,13 +55,10 @@ export class EventConsumersPageComponent extends ComponentBase implements OnInit
public start(name: string) {
this.eventConsumersService.startEventConsumer(name)
.subscribe(() => {
this.eventConsumers = this.eventConsumers.map(e => {
if (e.name === name) {
return new EventConsumerDto(name, e.lastHandledEventNumber, false, e.isResetting, e.error);
} else {
return e;
}
});
this.eventConsumers =
this.eventConsumers.replaceAll(
e => e.name === name,
e => new EventConsumerDto(name, e.lastHandledEventNumber, false, e.isResetting, e.error));
}, error => {
this.notifyError(error);
});
@ -70,13 +67,10 @@ export class EventConsumersPageComponent extends ComponentBase implements OnInit
public stop(name: string) {
this.eventConsumersService.stopEventConsumer(name)
.subscribe(() => {
this.eventConsumers = this.eventConsumers.map(e => {
if (e.name === name) {
return new EventConsumerDto(name, e.lastHandledEventNumber, true, e.isResetting, e.error);
} else {
return e;
}
});
this.eventConsumers =
this.eventConsumers.replaceAll(
e => e.name === name,
e => new EventConsumerDto(name, e.lastHandledEventNumber, true, e.isResetting, e.error));
}, error => {
this.notifyError(error);
});
@ -85,13 +79,10 @@ export class EventConsumersPageComponent extends ComponentBase implements OnInit
public reset(name: string) {
this.eventConsumersService.resetEventConsumer(name)
.subscribe(() => {
this.eventConsumers = this.eventConsumers.map(e => {
if (e.name === name) {
return new EventConsumerDto(name, e.lastHandledEventNumber, e.isStopped, true, e.error);
} else {
return e;
}
});
this.eventConsumers =
this.eventConsumers.replaceAll(
e => e.name === name,
e => new EventConsumerDto(name, e.lastHandledEventNumber, e.isStopped, true, e.error));
}, error => {
this.notifyError(error);
});

22
src/Squidex/app/features/administration/pages/users/users-page.component.ts

@ -68,13 +68,10 @@ export class UsersPageComponent extends ComponentBase implements OnInit {
public lock(id: string) {
this.userManagementService.lockUser(id)
.subscribe(() => {
this.usersItems = this.usersItems.map(u => {
if (u.id === id) {
return new UserDto(u.id, u.email, u.displayName, u.pictureUrl, true);
} else {
return u;
}
});
this.usersItems =
this.usersItems.replaceAll(
u => u.id === id,
u => new UserDto(u.id, u.email, u.displayName, u.pictureUrl, true));
}, error => {
this.notifyError(error);
});
@ -83,13 +80,10 @@ export class UsersPageComponent extends ComponentBase implements OnInit {
public unlock(id: string) {
this.userManagementService.unlockUser(id)
.subscribe(() => {
this.usersItems = this.usersItems.map(u => {
if (u.id === id) {
return new UserDto(u.id, u.email, u.displayName, u.pictureUrl, false);
} else {
return u;
}
});
this.usersItems =
this.usersItems.replaceAll(
u => u.id === id,
u => new UserDto(u.id, u.email, u.displayName, u.pictureUrl, false));
}, error => {
this.notifyError(error);
});

5
src/Squidex/app/features/assets/pages/assets-page.component.ts

@ -54,7 +54,10 @@ export class AssetsPageComponent extends AppComponentBase implements OnDestroy,
this.messageBus.of(AssetUpdated)
.subscribe(event => {
if (event.sender !== this) {
this.assetsItems = this.assetsItems.map(x => x.id === event.assetDto.id ? event.assetDto : x);
this.assetsItems =
this.assetsItems.replaceAll(
a => a.id === event.assetDto.id,
a => event.assetDto);
}
});

2
src/Squidex/app/features/content/pages/contents/content-item.component.ts

@ -74,7 +74,7 @@ export class ContentItemComponent extends AppComponentBase implements OnInit, On
}
}
public getValue(field: FieldDto): any {
private getValue(field: FieldDto): any {
const contentField = this.content.data[field.name];
if (!contentField) {

16
src/Squidex/app/features/schemas/pages/schema/field.component.html

@ -1,5 +1,5 @@
<div class="table-items-row field">
<div class="field-summary">
<div class="table-items-row table-items-row-expandable field">
<div class="table-items-row-summary">
<div class="row">
<div class="col col-6">
<span class="field-name">
@ -17,7 +17,7 @@
</div>
<div class="col col-3">
<div class="float-right">
<button type="button" class="btn btn-secondary field-edit-button" [class.active]="isEditing" (click)="toggleEditing()">
<button type="button" class="btn btn-secondary table-items-edit-button" [class.active]="isEditing" (click)="toggleEditing()">
<i class="icon-settings2"></i>
</button>
@ -48,9 +48,9 @@
</div>
</div>
<div class="field-details" *ngIf="isEditing">
<div class="table-items-row-details" *ngIf="isEditing">
<form [formGroup]="editForm" (ngSubmit)="save()">
<div class="field-details-tabs clearfix">
<div class="table-items-row-details-tabs clearfix">
<ul class="nav nav-inline nav-field-tabs">
<li class="nav-item">
<a class="nav-link" (click)="selectTab(0)" [class.active]="selectedTab === 0">Common</a>
@ -69,7 +69,7 @@
</div>
</div>
<div class="field-details-tab" [class.hidden]="selectedTab !== 0">
<div class="table-items-row-details-tab" [class.hidden]="selectedTab !== 0">
<div class="form-group row">
<label for="field-label" class="col col-3 col-form-label">Name</label>
@ -131,7 +131,7 @@
</div>
</div>
<div class="field-details-tab" [class.hidden]="selectedTab !== 1">
<div class="table-items-row-details-tab" [class.hidden]="selectedTab !== 1">
<div [ngSwitch]="field.properties.fieldType">
<div *ngSwitchCase="'Number'">
<sqx-number-validation [editForm]="editForm" [properties]="field.properties"></sqx-number-validation>
@ -157,7 +157,7 @@
</div>
</div>
<div class="field-details-tab" [class.hidden]="selectedTab !== 2">
<div class="table-items-row-details-tab" [class.hidden]="selectedTab !== 2">
<div [ngSwitch]="field.properties.fieldType">
<div *ngSwitchCase="'Number'">
<sqx-number-ui [editForm]="editForm" [properties]="field.properties"></sqx-number-ui>

59
src/Squidex/app/features/schemas/pages/schema/field.component.scss

@ -3,17 +3,7 @@
$field-header: #e7ebef;
.table-items-row {
padding: 0;
}
.field {
&-summary {
padding: 1rem 1.25rem;
position: relative;
line-height: 2.5rem;
}
&-icon {
margin-right: 1rem;
color: $color-border-dark;
@ -22,25 +12,6 @@ $field-header: #e7ebef;
vertical-align: middle;
}
&-edit-button {
& {
color: $color-theme-blue;
line-height: 1rem;
font-size: 1rem;
font-weight: normal;
}
&:hover {
color: $color-theme-blue-dark;
}
&.active {
background: $color-theme-blue;
border-color: $color-theme-blue;
color: $color-dark-foreground;
}
}
&-name {
@include truncate;
}
@ -49,36 +20,6 @@ $field-header: #e7ebef;
color: $color-border-dark;
}
&-hints {
color: lighten($color-text, 50%);
font-weight: normal;
font-size: .95rem;
margin-left: .3rem;
}
&-details {
& {
position: relative;
}
&::before {
@include caret-top;
@include absolute(-.5rem, 5.5rem, auto, auto);
border-color: transparent transparent $color-border;
border-width: .6rem;
}
&-tab {
padding: 1rem 1.25rem 1.25rem;
}
&-tabs {
background: $color-border;
position: relative;
padding: 1rem 1.25rem;
}
}
.tag {
@include opacity(.9);
min-width: 4rem;

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

@ -78,7 +78,7 @@ export class SchemasPageComponent extends AppComponentBase implements OnDestroy,
this.schemaUpdatedSubscription =
this.messageBus.of(SchemaUpdated)
.subscribe(m => {
this.updateSchemas(this.schemas.map(s => s.name === m.name ? updateSchema(s, this.authService, m) : s));
this.updateSchemas(this.schemas.replaceAll(s => s.name === m.name, s => updateSchema(s, this.authService, m)));
});
this.schemaDeletedSubscription =

14
src/Squidex/app/features/settings/pages/languages/language.component.html

@ -1,5 +1,5 @@
<div class="table-items-row language">
<div class="language-summary">
<div class="table-items-row table-items-row-expandable language">
<div class="table-items-row-summary">
<div class="row">
<div class="col col-2">
<span class="language-code" [class.language-master]="language.isMaster">{{language.iso2Code}}</span>
@ -9,7 +9,7 @@
</div>
<div class="col col-4">
<div class="float-right">
<button type="button" class="btn btn-secondary language-edit-button" [class.active]="isEditing" (click)="toggleEditing()" *ngIf="!language.isMaster || allLanguages.length > 1">
<button type="button" class="btn btn-secondary table-items-edit-button" [class.active]="isEditing" (click)="toggleEditing()" *ngIf="!language.isMaster || allLanguages.length > 1">
<i class="icon-settings2"></i>
</button>
@ -21,16 +21,16 @@
</div>
</div>
<div class="language-details" *ngIf="isEditing">
<div class="table-items-row-details" *ngIf="isEditing">
<form [formGroup]="editForm" (ngSubmit)="save()">
<div class="language-details-tabs clearfix">
<div class="table-items-row-details-tabs clearfix">
<div class="float-right">
<button type="reset" class="btn btn-link" (click)="cancel()">Cancel</button>
<button type="submit" class="btn btn-primary">Save</button>
</div>
</div>
<div class="language-details-tab">
<div class="table-items-row-details-tab">
<div class="form-group row" *ngIf="allLanguages.length > 1">
<label for="field-label" class="col col-3 col-form-label fallback-label">Fallback</label>
@ -67,7 +67,7 @@
</div>
</div>
<div class="form-check offset-3 col col-9" *ngIf="!language.isMaster">
<div class="form-check offset-3 col col-9" *ngIf="!isMaster">
<label class="form-check-label">
<input class="form-check-input" type="checkbox" formControlName="isOptional"> Is Optional
</label>

52
src/Squidex/app/features/settings/pages/languages/language.component.scss

@ -3,36 +3,7 @@
$field-header: #e7ebef;
.table-items-row {
padding: 0;
}
.language {
&-summary {
padding: 1rem 1.25rem;
position: relative;
line-height: 2.5rem;
}
&-edit-button {
& {
color: $color-theme-blue;
line-height: 1rem;
font-size: 1rem;
font-weight: normal;
}
&:hover {
color: $color-theme-blue-dark;
}
&.active {
background: $color-theme-blue;
border-color: $color-theme-blue;
color: $color-dark-foreground;
}
}
&-name {
@include truncate;
}
@ -40,29 +11,6 @@ $field-header: #e7ebef;
&-master {
font-weight: bold;
}
&-details {
& {
position: relative;
}
&::before {
@include caret-top;
@include absolute(-.5rem, 5.5rem, auto, auto);
border-color: transparent transparent $color-border;
border-width: .6rem;
}
&-tab {
padding: 1rem 1.25rem 1.25rem;
}
&-tabs {
background: $color-border;
position: relative;
padding: 1rem 1.25rem;
}
}
}
.btn-danger {

21
src/Squidex/app/features/settings/pages/languages/language.component.ts

@ -5,8 +5,9 @@
* Copyright (c) Sebastian Stehle. All rights reserved
*/
import { Component, EventEmitter, Input, OnChanges, Output, OnInit } from '@angular/core';
import { Component, EventEmitter, Input, OnChanges, OnDestroy, Output, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Subscription } from 'rxjs';
import {
AppLanguageDto,
@ -22,7 +23,9 @@ import {
fadeAnimation
]
})
export class LanguageComponent implements OnInit, OnChanges {
export class LanguageComponent implements OnInit, OnChanges, OnDestroy {
private isMasterSubscription: Subscription;
@Input()
public language: AppLanguageDto;
@ -40,6 +43,7 @@ export class LanguageComponent implements OnInit, OnChanges {
public fallbackLanguages: AppLanguageDto[] = [];
public isEditing = false;
public isMaster = false;
public editFormSubmitted = false;
public editForm: FormGroup =
@ -61,9 +65,20 @@ export class LanguageComponent implements OnInit, OnChanges {
}
public ngOnInit() {
this.isMasterSubscription =
this.editForm.get('isMaster').valueChanges
.subscribe(v => {
this.isMaster = v;
this.editForm.get('isOptional').setValue(false);
});
this.resetForm();
}
public ngOnDestroy() {
this.isMasterSubscription.unsubscribe();
}
public ngOnChanges() {
this.resetForm();
}
@ -122,6 +137,8 @@ export class LanguageComponent implements OnInit, OnChanges {
}
if (this.language) {
this.isMaster = this.language.isMaster;
this.fallbackLanguages =
this.allLanguages.filter(l =>
this.language.fallback.indexOf(l.iso2Code) >= 0).values;

69
src/Squidex/app/features/settings/pages/languages/languages-page.component.ts

@ -52,13 +52,7 @@ export class LanguagesPageComponent extends AppComponentBase implements OnInit {
}
public ngOnInit() {
this.languagesService.getLanguages().retry(2)
.subscribe(languages => {
this.allLanguages = languages;
}, error => {
this.notifyError(error);
});
this.loadAllLanguages();
this.load();
}
@ -72,16 +66,6 @@ export class LanguagesPageComponent extends AppComponentBase implements OnInit {
});
}
public updateLanguage(language: AppLanguageDto) {
this.appNameOnce()
.switchMap(app => this.appLanguagesService.updateLanguage(app, language.iso2Code, language, this.version))
.subscribe(dto => {
this.updateLanguages(this.appLanguages.map(l => l.iso2Code === language.iso2Code ? language : l));
}, error => {
this.notifyError(error);
});
}
public removeLanguage(language: AppLanguageDto) {
this.appNameOnce()
.switchMap(app => this.appLanguagesService.deleteLanguage(app, language.iso2Code, this.version))
@ -104,13 +88,58 @@ export class LanguagesPageComponent extends AppComponentBase implements OnInit {
});
}
private updateLanguages(languages: ImmutableArray<AppLanguageDto>) {
public updateLanguage(language: AppLanguageDto) {
this.appNameOnce()
.switchMap(app => this.appLanguagesService.updateLanguage(app, language.iso2Code, language, this.version))
.subscribe(dto => {
this.updateLanguages(
this.appLanguages.replaceAll(
l => l.iso2Code === language.iso2Code,
l => language),
language.isMaster ? language.iso2Code : undefined);
}, error => {
this.notifyError(error);
});
}
private loadAllLanguages() {
this.languagesService.getLanguages().retry(2)
.subscribe(languages => {
this.allLanguages = languages;
this.updateNewLanguages();
}, error => {
this.notifyError(error);
});
}
private updateLanguages(languages: ImmutableArray<AppLanguageDto>, masterId?: string) {
this.addLanguageForm.reset();
this.appLanguages = languages;
this.newLanguages = this.allLanguages.filter(x => !this.appLanguages.find(l => l.iso2Code === x.iso2Code));
this.appLanguages =
languages.map(l => {
return new AppLanguageDto(
l.iso2Code,
l.englishName,
masterId ? l.iso2Code === masterId : l.isMaster,
l.isOptional,
l.fallback.filter(f => !!languages.find(l2 => l2.iso2Code === f))
);
}).sort((a, b) => {
if (a.isMaster === b.isMaster) {
return a.iso2Code.localeCompare(b.iso2Code);
} else {
return (a.isMaster ? 0 : 1) - (b.isMaster ? 0 : 1);
}
});
this.updateNewLanguages();
this.messageBus.publish(new HistoryChannelUpdated());
}
private updateNewLanguages() {
this.newLanguages = this.allLanguages.filter(x => !this.appLanguages.find(l => l.iso2Code === x.iso2Code));
}
}

5
src/Squidex/app/shared/components/assets-editor.component.ts

@ -58,7 +58,10 @@ export class AssetsEditorComponent extends AppComponentBase implements ControlVa
this.messageBus.of(AssetUpdated)
.subscribe(event => {
if (event.sender !== this) {
this.oldAssets = this.oldAssets.map(x => x.id === event.assetDto.id ? event.assetDto : x);
this.oldAssets =
this.oldAssets.replaceAll(
a => a.id === event.assetDto.id,
a => event.assetDto);
}
});
}

68
src/Squidex/app/theme/_lists.scss

@ -67,22 +67,74 @@
}
}
&-row,
&-row {
& {
padding: 1rem 1.25rem;
background: $color-table;
border: 1px solid $color-border;
border-bottom-width: 2px;
margin-bottom: .25rem;
}
&-summary {
padding: 1rem 1.25rem;
position: relative;
line-height: 2.5rem;
}
&-expandable {
padding: 0;
}
&-details {
& {
position: relative;
}
&::before {
@include caret-top;
@include absolute(-.5rem, 5.5rem, auto, auto);
border-color: transparent transparent $color-border;
border-width: .6rem;
}
&-tab {
padding: 1rem 1.25rem 1.25rem;
}
&-tabs {
background: $color-border;
position: relative;
padding: 1rem 1.25rem;
}
}
}
&-footer {
padding: 1rem 1.25rem;
background: $color-table-footer;
border: 1px solid $color-border;
border-bottom-width: 2px;
margin-top: .8rem;
}
&-row {
background: $color-table;
margin-bottom: .25rem;
}
&-edit-button {
& {
color: $color-theme-blue;
line-height: 1rem;
font-size: 1rem;
font-weight: normal;
}
&-footer {
background: $color-table-footer;
margin-top: .8rem;
&:hover {
color: $color-theme-blue-dark;
}
&.active {
background: $color-theme-blue;
border-color: $color-theme-blue;
color: $color-dark-foreground;
}
}
.spacer {

Loading…
Cancel
Save