Add small fixes
Fixes an error where the back arrow in the motion block detail was missing Adds a prompt before deletion of Change Recommendation in motion details Adds timestamp localisation for history mode
This commit is contained in:
parent
0f24ba1951
commit
b9923201e4
@ -1,5 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { History } from 'app/shared/models/core/history';
|
||||
|
||||
/**
|
||||
* Holds information about OpenSlides. This is not included into other services to
|
||||
* avoid circular dependencies.
|
||||
@ -9,15 +11,15 @@ import { Injectable } from '@angular/core';
|
||||
})
|
||||
export class OpenSlidesStatusService {
|
||||
/**
|
||||
* Saves, if OpenSlides is in the history mode.
|
||||
* in History mode, saves the history point.
|
||||
*/
|
||||
private historyMode = false;
|
||||
private history: History = null;
|
||||
|
||||
/**
|
||||
* Returns, if OpenSlides is in the history mode.
|
||||
*/
|
||||
public get isInHistoryMode(): boolean {
|
||||
return this.historyMode;
|
||||
return !!this.history;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,16 +28,26 @@ export class OpenSlidesStatusService {
|
||||
public constructor() {}
|
||||
|
||||
/**
|
||||
* Enters the histroy mode
|
||||
* Calls the getLocaleString function of the history object, if present.
|
||||
*
|
||||
* @param format the required date representation format
|
||||
* @returns the timestamp as string
|
||||
*/
|
||||
public enterHistoryMode(): void {
|
||||
this.historyMode = true;
|
||||
public getHistoryTimeStamp(format: string): string {
|
||||
return this.history ? this.history.getLocaleString(format) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves the histroy mode
|
||||
* Enters the history mode
|
||||
*/
|
||||
public leaveHistroyMode(): void {
|
||||
this.historyMode = false;
|
||||
public enterHistoryMode(history: History): void {
|
||||
this.history = history;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves the history mode
|
||||
*/
|
||||
public leaveHistoryMode(): void {
|
||||
this.history = null;
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ export class TimeTravelService {
|
||||
* @param history the desired point in the history of OpenSlides
|
||||
*/
|
||||
public async loadHistoryPoint(history: History): Promise<void> {
|
||||
await this.stopTime();
|
||||
await this.stopTime(history);
|
||||
const fullDataHistory: HistoryData[] = await this.getHistoryData(history);
|
||||
for (const historyObject of fullDataHistory) {
|
||||
let collectionString: string;
|
||||
@ -78,13 +78,13 @@ export class TimeTravelService {
|
||||
|
||||
/**
|
||||
* Leaves the history mode. Just restart OpenSlides:
|
||||
* The active user is chacked, a new WS connection established and
|
||||
* all missed autoupdates are requested.
|
||||
* The active user is checked, a new WS connection established and
|
||||
* all missed auto updates are requested.
|
||||
*/
|
||||
public async resumeTime(): Promise<void> {
|
||||
await this.DS.set();
|
||||
await this.OpenSlides.reboot();
|
||||
this.OSStatus.leaveHistroyMode();
|
||||
this.OSStatus.leaveHistoryMode();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,10 +102,10 @@ export class TimeTravelService {
|
||||
/**
|
||||
* Clears the DataStore and stops the WebSocket connection
|
||||
*/
|
||||
private async stopTime(): Promise<void> {
|
||||
private async stopTime(history: History): Promise<void> {
|
||||
this.webSocketService.close();
|
||||
await this.cleanDataStore();
|
||||
this.OSStatus.enterHistoryMode();
|
||||
this.OSStatus.enterHistoryMode(history);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,4 +32,14 @@ export class History extends BaseModel {
|
||||
public constructor(input?: any) {
|
||||
super(History.COLLECTIONSTRING, input);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the date (this.now) to a time and date string.
|
||||
*
|
||||
* @param locale locale indicator, i.e 'de-DE'
|
||||
* @returns a human readable kind of time and date representation
|
||||
*/
|
||||
public getLocaleString(locale: string): string {
|
||||
return this.date.toLocaleString(locale);
|
||||
}
|
||||
}
|
||||
|
23
client/src/app/shared/utils/lang-to-locale.ts
Normal file
23
client/src/app/shared/utils/lang-to-locale.ts
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Helper function to convert a language indicator (en, de)
|
||||
* to a locale indicator (de-DE, en-US)
|
||||
*
|
||||
* Necessary to correctly format timestamps
|
||||
*/
|
||||
export function langToLocale(lang: string): string {
|
||||
switch (lang) {
|
||||
case 'en': {
|
||||
return 'en-GB';
|
||||
}
|
||||
case 'de': {
|
||||
return 'de-DE';
|
||||
}
|
||||
case 'cz': {
|
||||
return 'cs-CZ';
|
||||
}
|
||||
default: {
|
||||
// has YYYY-MM-DD HH:mm:SS
|
||||
return 'lt-LT';
|
||||
}
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@
|
||||
<!-- Timestamp -->
|
||||
<ng-container matColumnDef="time">
|
||||
<mat-header-cell *matHeaderCellDef translate>Timestamp</mat-header-cell>
|
||||
<mat-cell *matCellDef="let history">{{ history.getLocaleString('DE-de') }}</mat-cell>
|
||||
<mat-cell *matCellDef="let history">{{ getTimestamp(history) }}</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<!-- Element -->
|
||||
|
@ -13,6 +13,7 @@ import { ListViewBaseComponent } from 'app/site/base/list-view-base';
|
||||
import { OperatorService } from 'app/core/core-services/operator.service';
|
||||
import { ViewHistory } from '../../models/view-history';
|
||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
||||
import { langToLocale } from 'app/shared/utils/lang-to-locale';
|
||||
|
||||
/**
|
||||
* A list view for the history.
|
||||
@ -113,17 +114,19 @@ export class HistoryListComponent extends ListViewBaseComponent<ViewHistory, His
|
||||
if (this.operator.isInGroupIds(2)) {
|
||||
await this.repo.browseHistory(history);
|
||||
const element = this.viewModelStore.get(history.getCollectionString(), history.getModelId());
|
||||
let message = this.translate.instant('OpenSlides is temporarily reset to following timestamp:');
|
||||
message += ' ' + history.getLocaleString('DE-de');
|
||||
if (isDetailNavigable(element)) {
|
||||
this.raiseError(message);
|
||||
if (element && isDetailNavigable(element)) {
|
||||
this.router.navigate([element.getDetailStateURL()]);
|
||||
} else {
|
||||
const message = this.translate.instant('Cannot navigate to the selected history element.');
|
||||
this.raiseError(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getTimestamp(viewHistory: ViewHistory): string {
|
||||
return viewHistory.history.getLocaleString(langToLocale(this.translate.currentLang));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for the delete all button
|
||||
*/
|
||||
|
@ -87,16 +87,6 @@ export class ViewHistory extends BaseViewModel {
|
||||
this._user = user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the date (this.now) to a time and date string.
|
||||
*
|
||||
* @param locale locale indicator, i.e 'de-DE'
|
||||
* @returns a human readable kind of time and date representation
|
||||
*/
|
||||
public getLocaleString(locale: string): string {
|
||||
return this.history.date.toLocaleString(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts elementID into collection string
|
||||
* @returns the CollectionString to the model
|
||||
|
@ -1,4 +1,4 @@
|
||||
<os-head-bar>
|
||||
<os-head-bar [nav]="false">
|
||||
<!-- Title -->
|
||||
<div class="title-slot">
|
||||
<h2 *ngIf="block && !editBlock">{{ block.title }}</h2>
|
||||
|
@ -4,18 +4,19 @@ import { DomSanitizer, SafeHtml, Title } from '@angular/platform-browser';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { LineNumberingMode, ViewMotion } from '../../models/view-motion';
|
||||
import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../../../shared/models/motions/view-unified-change';
|
||||
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
|
||||
import { DiffService, LineRange, ModificationType } from 'app/core/ui-services/diff.service';
|
||||
import { ViewMotionChangeRecommendation } from '../../models/view-change-recommendation';
|
||||
import { BaseViewComponent } from '../../../base/base-view';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.service';
|
||||
import { DiffService, LineRange, ModificationType } from 'app/core/ui-services/diff.service';
|
||||
import { LineNumberingMode, ViewMotion } from '../../models/view-motion';
|
||||
import {
|
||||
MotionChangeRecommendationComponent,
|
||||
MotionChangeRecommendationComponentData
|
||||
} from '../motion-change-recommendation/motion-change-recommendation.component';
|
||||
import { BaseViewComponent } from '../../../base/base-view';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
|
||||
import { PromptService } from 'app/core/ui-services/prompt.service';
|
||||
import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../../../shared/models/motions/view-unified-change';
|
||||
import { ViewMotionChangeRecommendation } from '../../models/view-change-recommendation';
|
||||
|
||||
/**
|
||||
* This component displays the original motion text with the change blocks inside.
|
||||
@ -74,6 +75,7 @@ export class MotionDetailDiffComponent extends BaseViewComponent implements Afte
|
||||
* @param dialogService
|
||||
* @param configService
|
||||
* @param el
|
||||
* @param promptService
|
||||
*/
|
||||
public constructor(
|
||||
title: Title,
|
||||
@ -85,10 +87,10 @@ export class MotionDetailDiffComponent extends BaseViewComponent implements Afte
|
||||
private recoRepo: ChangeRecommendationRepositoryService,
|
||||
private dialogService: MatDialog,
|
||||
private configService: ConfigService,
|
||||
private el: ElementRef
|
||||
private el: ElementRef,
|
||||
private promptService: PromptService
|
||||
) {
|
||||
super(title, translate, matSnackBar);
|
||||
|
||||
this.configService.get<number>('motions_line_length').subscribe(lineLength => (this.lineLength = lineLength));
|
||||
}
|
||||
|
||||
@ -287,10 +289,13 @@ export class MotionDetailDiffComponent extends BaseViewComponent implements Afte
|
||||
* @param {ViewMotionChangeRecommendation} reco
|
||||
* @param {MouseEvent} $event
|
||||
*/
|
||||
public deleteChangeRecommendation(reco: ViewMotionChangeRecommendation, $event: MouseEvent): void {
|
||||
public async deleteChangeRecommendation(reco: ViewMotionChangeRecommendation, $event: MouseEvent): Promise<void> {
|
||||
$event.stopPropagation();
|
||||
$event.preventDefault();
|
||||
this.recoRepo.delete(reco).then(null, this.raiseError);
|
||||
const content = this.translate.instant('Delete this change recommendation');
|
||||
if (await this.promptService.open('Are you sure?', content)) {
|
||||
this.recoRepo.delete(reco).then(null, this.raiseError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,6 @@
|
||||
<div class="history-mode-indicator" *ngIf="OSStatus.isInHistoryMode">
|
||||
<span translate>You are using the history mode of OpenSlides. Changes will not be saved.</span>
|
||||
<span>({{ getHistoryTimestamp() }})</span>
|
||||
<a (click)="timeTravel.resumeTime()" translate>Exit</a>
|
||||
</div>
|
||||
<mat-sidenav-container #siteContainer class="main-container" (backdropClick)="toggleSideNav()">
|
||||
@ -29,11 +30,7 @@
|
||||
<span> {{ getLangName(this.translate.currentLang) }} </span>
|
||||
</a>
|
||||
<div *ngIf="isLoggedIn">
|
||||
<a
|
||||
[routerLink]="['/users/', operator.user.id]"
|
||||
(click)="mobileAutoCloseNav()"
|
||||
mat-list-item
|
||||
>
|
||||
<a [routerLink]="['/users/', operator.user.id]" (click)="mobileAutoCloseNav()" mat-list-item>
|
||||
<mat-icon>person</mat-icon>
|
||||
<span translate>Show profile</span>
|
||||
</a>
|
||||
|
@ -86,13 +86,13 @@ mat-sidenav-container {
|
||||
|
||||
/* History mode top bar*/
|
||||
.history-mode-indicator {
|
||||
position: fixed;
|
||||
position: relative; // was fixed before to prevent the overflow
|
||||
min-height: 20px;
|
||||
line-height: 20px;
|
||||
width: 100%;
|
||||
z-index: 10;
|
||||
// z-index: 10;
|
||||
background: repeating-linear-gradient(45deg, #ffee00, #ffee00 10px, #070600 10px, #000000 20px);
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
height: 20px;
|
||||
|
||||
span {
|
||||
padding: 2px;
|
||||
|
@ -13,6 +13,7 @@ import { ViewportService } from '../core/ui-services/viewport.service';
|
||||
import { MainMenuService } from '../core/core-services/main-menu.service';
|
||||
import { OpenSlidesStatusService } from '../core/core-services/openslides-status.service';
|
||||
import { TimeTravelService } from '../core/core-services/time-travel.service';
|
||||
import { langToLocale } from 'app/shared/utils/lang-to-locale';
|
||||
|
||||
@Component({
|
||||
selector: 'os-site',
|
||||
@ -194,4 +195,14 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
||||
this.searchform.reset();
|
||||
this.router.navigate(['/search'], { queryParams: { query: query } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the timestamp for the current point in history mode.
|
||||
* Tries to detect the ideal timestamp format using the translation service
|
||||
*
|
||||
* @returns the timestamp as string
|
||||
*/
|
||||
public getHistoryTimestamp(): string {
|
||||
return this.OSStatus.getHistoryTimeStamp(langToLocale(this.translate.currentLang));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user