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 { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { History } from 'app/shared/models/core/history';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds information about OpenSlides. This is not included into other services to
|
* Holds information about OpenSlides. This is not included into other services to
|
||||||
* avoid circular dependencies.
|
* avoid circular dependencies.
|
||||||
@ -9,15 +11,15 @@ import { Injectable } from '@angular/core';
|
|||||||
})
|
})
|
||||||
export class OpenSlidesStatusService {
|
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.
|
* Returns, if OpenSlides is in the history mode.
|
||||||
*/
|
*/
|
||||||
public get isInHistoryMode(): boolean {
|
public get isInHistoryMode(): boolean {
|
||||||
return this.historyMode;
|
return !!this.history;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,16 +28,26 @@ export class OpenSlidesStatusService {
|
|||||||
public constructor() {}
|
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 {
|
public getHistoryTimeStamp(format: string): string {
|
||||||
this.historyMode = true;
|
return this.history ? this.history.getLocaleString(format) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Leaves the histroy mode
|
* Enters the history mode
|
||||||
*/
|
*/
|
||||||
public leaveHistroyMode(): void {
|
public enterHistoryMode(history: History): void {
|
||||||
this.historyMode = false;
|
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
|
* @param history the desired point in the history of OpenSlides
|
||||||
*/
|
*/
|
||||||
public async loadHistoryPoint(history: History): Promise<void> {
|
public async loadHistoryPoint(history: History): Promise<void> {
|
||||||
await this.stopTime();
|
await this.stopTime(history);
|
||||||
const fullDataHistory: HistoryData[] = await this.getHistoryData(history);
|
const fullDataHistory: HistoryData[] = await this.getHistoryData(history);
|
||||||
for (const historyObject of fullDataHistory) {
|
for (const historyObject of fullDataHistory) {
|
||||||
let collectionString: string;
|
let collectionString: string;
|
||||||
@ -78,13 +78,13 @@ export class TimeTravelService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Leaves the history mode. Just restart OpenSlides:
|
* Leaves the history mode. Just restart OpenSlides:
|
||||||
* The active user is chacked, a new WS connection established and
|
* The active user is checked, a new WS connection established and
|
||||||
* all missed autoupdates are requested.
|
* all missed auto updates are requested.
|
||||||
*/
|
*/
|
||||||
public async resumeTime(): Promise<void> {
|
public async resumeTime(): Promise<void> {
|
||||||
await this.DS.set();
|
await this.DS.set();
|
||||||
await this.OpenSlides.reboot();
|
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
|
* Clears the DataStore and stops the WebSocket connection
|
||||||
*/
|
*/
|
||||||
private async stopTime(): Promise<void> {
|
private async stopTime(history: History): Promise<void> {
|
||||||
this.webSocketService.close();
|
this.webSocketService.close();
|
||||||
await this.cleanDataStore();
|
await this.cleanDataStore();
|
||||||
this.OSStatus.enterHistoryMode();
|
this.OSStatus.enterHistoryMode(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,4 +32,14 @@ export class History extends BaseModel {
|
|||||||
public constructor(input?: any) {
|
public constructor(input?: any) {
|
||||||
super(History.COLLECTIONSTRING, input);
|
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 -->
|
<!-- Timestamp -->
|
||||||
<ng-container matColumnDef="time">
|
<ng-container matColumnDef="time">
|
||||||
<mat-header-cell *matHeaderCellDef translate>Timestamp</mat-header-cell>
|
<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>
|
</ng-container>
|
||||||
|
|
||||||
<!-- Element -->
|
<!-- Element -->
|
||||||
|
@ -13,6 +13,7 @@ import { ListViewBaseComponent } from 'app/site/base/list-view-base';
|
|||||||
import { OperatorService } from 'app/core/core-services/operator.service';
|
import { OperatorService } from 'app/core/core-services/operator.service';
|
||||||
import { ViewHistory } from '../../models/view-history';
|
import { ViewHistory } from '../../models/view-history';
|
||||||
import { ViewModelStoreService } from 'app/core/core-services/view-model-store.service';
|
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.
|
* A list view for the history.
|
||||||
@ -113,17 +114,19 @@ export class HistoryListComponent extends ListViewBaseComponent<ViewHistory, His
|
|||||||
if (this.operator.isInGroupIds(2)) {
|
if (this.operator.isInGroupIds(2)) {
|
||||||
await this.repo.browseHistory(history);
|
await this.repo.browseHistory(history);
|
||||||
const element = this.viewModelStore.get(history.getCollectionString(), history.getModelId());
|
const element = this.viewModelStore.get(history.getCollectionString(), history.getModelId());
|
||||||
let message = this.translate.instant('OpenSlides is temporarily reset to following timestamp:');
|
if (element && isDetailNavigable(element)) {
|
||||||
message += ' ' + history.getLocaleString('DE-de');
|
|
||||||
if (isDetailNavigable(element)) {
|
|
||||||
this.raiseError(message);
|
|
||||||
this.router.navigate([element.getDetailStateURL()]);
|
this.router.navigate([element.getDetailStateURL()]);
|
||||||
} else {
|
} else {
|
||||||
|
const message = this.translate.instant('Cannot navigate to the selected history element.');
|
||||||
this.raiseError(message);
|
this.raiseError(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getTimestamp(viewHistory: ViewHistory): string {
|
||||||
|
return viewHistory.history.getLocaleString(langToLocale(this.translate.currentLang));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for the delete all button
|
* Handler for the delete all button
|
||||||
*/
|
*/
|
||||||
|
@ -87,16 +87,6 @@ export class ViewHistory extends BaseViewModel {
|
|||||||
this._user = user;
|
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
|
* Converts elementID into collection string
|
||||||
* @returns the CollectionString to the model
|
* @returns the CollectionString to the model
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<os-head-bar>
|
<os-head-bar [nav]="false">
|
||||||
<!-- Title -->
|
<!-- Title -->
|
||||||
<div class="title-slot">
|
<div class="title-slot">
|
||||||
<h2 *ngIf="block && !editBlock">{{ block.title }}</h2>
|
<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 { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { LineNumberingMode, ViewMotion } from '../../models/view-motion';
|
import { BaseViewComponent } from '../../../base/base-view';
|
||||||
import { ViewUnifiedChange, ViewUnifiedChangeType } from '../../../../shared/models/motions/view-unified-change';
|
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||||
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 { ChangeRecommendationRepositoryService } from 'app/core/repositories/motions/change-recommendation-repository.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 {
|
import {
|
||||||
MotionChangeRecommendationComponent,
|
MotionChangeRecommendationComponent,
|
||||||
MotionChangeRecommendationComponentData
|
MotionChangeRecommendationComponentData
|
||||||
} from '../motion-change-recommendation/motion-change-recommendation.component';
|
} from '../motion-change-recommendation/motion-change-recommendation.component';
|
||||||
import { BaseViewComponent } from '../../../base/base-view';
|
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
|
||||||
import { ConfigService } from 'app/core/ui-services/config.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.
|
* 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 dialogService
|
||||||
* @param configService
|
* @param configService
|
||||||
* @param el
|
* @param el
|
||||||
|
* @param promptService
|
||||||
*/
|
*/
|
||||||
public constructor(
|
public constructor(
|
||||||
title: Title,
|
title: Title,
|
||||||
@ -85,10 +87,10 @@ export class MotionDetailDiffComponent extends BaseViewComponent implements Afte
|
|||||||
private recoRepo: ChangeRecommendationRepositoryService,
|
private recoRepo: ChangeRecommendationRepositoryService,
|
||||||
private dialogService: MatDialog,
|
private dialogService: MatDialog,
|
||||||
private configService: ConfigService,
|
private configService: ConfigService,
|
||||||
private el: ElementRef
|
private el: ElementRef,
|
||||||
|
private promptService: PromptService
|
||||||
) {
|
) {
|
||||||
super(title, translate, matSnackBar);
|
super(title, translate, matSnackBar);
|
||||||
|
|
||||||
this.configService.get<number>('motions_line_length').subscribe(lineLength => (this.lineLength = lineLength));
|
this.configService.get<number>('motions_line_length').subscribe(lineLength => (this.lineLength = lineLength));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,11 +289,14 @@ export class MotionDetailDiffComponent extends BaseViewComponent implements Afte
|
|||||||
* @param {ViewMotionChangeRecommendation} reco
|
* @param {ViewMotionChangeRecommendation} reco
|
||||||
* @param {MouseEvent} $event
|
* @param {MouseEvent} $event
|
||||||
*/
|
*/
|
||||||
public deleteChangeRecommendation(reco: ViewMotionChangeRecommendation, $event: MouseEvent): void {
|
public async deleteChangeRecommendation(reco: ViewMotionChangeRecommendation, $event: MouseEvent): Promise<void> {
|
||||||
$event.stopPropagation();
|
$event.stopPropagation();
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
|
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);
|
this.recoRepo.delete(reco).then(null, this.raiseError);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edits a change recommendation.
|
* Edits a change recommendation.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<div class="history-mode-indicator" *ngIf="OSStatus.isInHistoryMode">
|
<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 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>
|
<a (click)="timeTravel.resumeTime()" translate>Exit</a>
|
||||||
</div>
|
</div>
|
||||||
<mat-sidenav-container #siteContainer class="main-container" (backdropClick)="toggleSideNav()">
|
<mat-sidenav-container #siteContainer class="main-container" (backdropClick)="toggleSideNav()">
|
||||||
@ -29,11 +30,7 @@
|
|||||||
<span> {{ getLangName(this.translate.currentLang) }} </span>
|
<span> {{ getLangName(this.translate.currentLang) }} </span>
|
||||||
</a>
|
</a>
|
||||||
<div *ngIf="isLoggedIn">
|
<div *ngIf="isLoggedIn">
|
||||||
<a
|
<a [routerLink]="['/users/', operator.user.id]" (click)="mobileAutoCloseNav()" mat-list-item>
|
||||||
[routerLink]="['/users/', operator.user.id]"
|
|
||||||
(click)="mobileAutoCloseNav()"
|
|
||||||
mat-list-item
|
|
||||||
>
|
|
||||||
<mat-icon>person</mat-icon>
|
<mat-icon>person</mat-icon>
|
||||||
<span translate>Show profile</span>
|
<span translate>Show profile</span>
|
||||||
</a>
|
</a>
|
||||||
|
@ -86,13 +86,13 @@ mat-sidenav-container {
|
|||||||
|
|
||||||
/* History mode top bar*/
|
/* History mode top bar*/
|
||||||
.history-mode-indicator {
|
.history-mode-indicator {
|
||||||
position: fixed;
|
position: relative; // was fixed before to prevent the overflow
|
||||||
|
min-height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 10;
|
// z-index: 10;
|
||||||
background: repeating-linear-gradient(45deg, #ffee00, #ffee00 10px, #070600 10px, #000000 20px);
|
background: repeating-linear-gradient(45deg, #ffee00, #ffee00 10px, #070600 10px, #000000 20px);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
line-height: 20px;
|
|
||||||
height: 20px;
|
|
||||||
|
|
||||||
span {
|
span {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
@ -13,6 +13,7 @@ import { ViewportService } from '../core/ui-services/viewport.service';
|
|||||||
import { MainMenuService } from '../core/core-services/main-menu.service';
|
import { MainMenuService } from '../core/core-services/main-menu.service';
|
||||||
import { OpenSlidesStatusService } from '../core/core-services/openslides-status.service';
|
import { OpenSlidesStatusService } from '../core/core-services/openslides-status.service';
|
||||||
import { TimeTravelService } from '../core/core-services/time-travel.service';
|
import { TimeTravelService } from '../core/core-services/time-travel.service';
|
||||||
|
import { langToLocale } from 'app/shared/utils/lang-to-locale';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'os-site',
|
selector: 'os-site',
|
||||||
@ -194,4 +195,14 @@ export class SiteComponent extends BaseComponent implements OnInit {
|
|||||||
this.searchform.reset();
|
this.searchform.reset();
|
||||||
this.router.navigate(['/search'], { queryParams: { query: query } });
|
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