diff --git a/package.json b/package.json index 566f40d8e2..e4a69e06fe 100755 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "license": "AGPL-3.0", "version": "0.16.74", "myplanet": { - "latest": "v0.22.23", - "min": "v0.21.23" + "latest": "v0.22.29", + "min": "v0.21.29" }, "scripts": { "ng": "ng", diff --git a/src/app/courses/courses.component.html b/src/app/courses/courses.component.html index 586eb3df19..b4e8a8045c 100644 --- a/src/app/courses/courses.component.html +++ b/src/app/courses/courses.component.html @@ -176,7 +176,7 @@

clear Leave - + feedback Feedback diff --git a/src/app/feedback/feedback-view.component.html b/src/app/feedback/feedback-view.component.html index 412e2f6189..4eb2ea01d3 100644 --- a/src/app/feedback/feedback-view.component.html +++ b/src/app/feedback/feedback-view.component.html @@ -12,7 +12,7 @@ speaker_notes - {{feedback.title || feedback.type + ' regarding ' + feedback.url}} + {{feedback.title || feedback.type + ' regarding ' + feedback.url}} edit @@ -32,15 +32,20 @@ - - - Go to Resource - Go to Course - Go to Meetup - Go to Team - Go to Enterprise - - + + + Go to Resource + Go to Course + Go to Meetup + Go to Team + Go to Enterprise + +
diff --git a/src/app/feedback/feedback-view.scss b/src/app/feedback/feedback-view.scss index 16ab05522f..900d43a3c5 100644 --- a/src/app/feedback/feedback-view.scss +++ b/src/app/feedback/feedback-view.scss @@ -33,3 +33,16 @@ width: 100%; } } + +.ellipsis-title { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + max-width: 100%; + display: inline-block; +} + +.no-shrink-button { + flex-shrink: 0; + margin-left: auto; +} diff --git a/src/app/feedback/feedback.component.html b/src/app/feedback/feedback.component.html index 3990964b1d..680343df66 100644 --- a/src/app/feedback/feedback.component.html +++ b/src/app/feedback/feedback.component.html @@ -68,8 +68,10 @@ Title - {{element.title || element.type + ' regarding ' + element.url}} - + + {{ element.title || element.type + ' regarding ' + element.url }} + + Type diff --git a/src/app/feedback/feedback.component.ts b/src/app/feedback/feedback.component.ts index 494792b1d6..2e7d5cbaed 100644 --- a/src/app/feedback/feedback.component.ts +++ b/src/app/feedback/feedback.component.ts @@ -23,12 +23,8 @@ import { DeviceInfoService, DeviceType } from '../shared/device-info.service'; @Component({ templateUrl: './feedback.component.html', - styles: [ ` - .mat-column-type { - display: flex; - align-items: center; - } - ` ] + styleUrls: [ './feedback.scss' ] + }) export class FeedbackComponent implements OnInit, AfterViewInit, OnDestroy { readonly dbName = 'feedback'; @@ -113,9 +109,20 @@ export class FeedbackComponent implements OnInit, AfterViewInit, OnDestroy { getFeedback() { const selector = !this.user.isUserAdmin ? { 'owner': this.user.name } : { '_id': { '$gt': null } }; this.couchService.findAll(this.dbName, findDocuments(selector, 0, [ { 'openTime': 'desc' } ])).subscribe((feedbackData: any[]) => { - this.feedback.data = feedbackData.map(feedback => ({ ...feedback, user: this.users.find(u => u.doc.name === feedback.owner) })); + this.feedback.data = feedbackData.map(feedback => { + const truncatedTitle = feedback.title.length > 100 + ? `${feedback.title.slice(0, 100)}...` + : feedback.title; + return { + ...feedback, + title: truncatedTitle, + user: this.users.find(u => u.doc.name === feedback.owner) + }; + }); this.dialogsLoadingService.stop(); - }, (error) => this.message = $localize`There is a problem of getting data.`); + }, (error) => { + this.message = $localize`There is a problem of getting data.`; + }); } deleteClick(feedback) { diff --git a/src/app/feedback/feedback.directive.ts b/src/app/feedback/feedback.directive.ts index edd9c7ff52..f26261bd0b 100644 --- a/src/app/feedback/feedback.directive.ts +++ b/src/app/feedback/feedback.directive.ts @@ -78,33 +78,72 @@ export class FeedbackDirective { ) {} addFeedback(post: any) { - const date = this.couchService.datePlaceholder; - const user = this.userService.get().name, - { message, ...feedbackInfo } = post, - startingMessage: Message = { message, time: date, user }, - newFeedback: Feedback = { - owner: user, - ...feedbackInfo, - openTime: date, - status: 'Open', - messages: [ startingMessage ], - url: this.router.url, - source: this.stateService.configuration.code, - parentCode: this.stateService.configuration.parentCode, - ...this.feedbackOf - }; - const feedbackUrl = newFeedback.url.substring(0, newFeedback.url.indexOf(';')) || newFeedback.url; - this.couchService.updateDocument('feedback', { - ...newFeedback, title: $localize`${newFeedback.type} regarding ${feedbackUrl}` }) - .subscribe((data) => { - this.feedbackService.setFeedback(); - this.planetMessageService.showMessage($localize`Thank you, your feedback is submitted!`); - }, - (error) => { - this.planetMessageService.showAlert($localize`Error, your feedback cannot be submitted`); - }); + const date = new Date(); + const user = this.userService.get().name; + const feedbackUrl = this.router.url && this.router.url !== '/' ? this.router.url.split(';')[0] : '/'; + const urlParts = feedbackUrl.split('/'); + const firstPart = urlParts[1] || 'home'; + const lastPart = urlParts.length > 2 ? urlParts[urlParts.length - 1] : null; + let feedback: any = { + ...post, + routerLink: null, + state: firstPart, + }; + if (firstPart === 'home') { + feedback.title = $localize`Feedback regarding home`; + feedback.routerLink = ['/home']; + this.updateFeedback(feedback, date, user, feedbackUrl); + } else if (this.feedbackOf?.name) { + feedback.title = $localize`Feedback regarding ${firstPart}/${this.feedbackOf.name}`; + feedback.routerLink = ['/', firstPart, 'view', this.feedbackOf.item]; + this.updateFeedback(feedback, date, user, feedbackUrl); + } else if (urlParts.length === 2) { + feedback.title = $localize`Feedback regarding ${firstPart}`; + feedback.routerLink = ['/', firstPart]; + this.updateFeedback(feedback, date, user, feedbackUrl); + } else if (lastPart) { + this.couchService.getDocumentByID(firstPart, lastPart).subscribe( + (document: any) => { + const resourceName = document?.type === 'enterprise' + ? document?.name + : document?.title || document?.courseTitle || document?.name || lastPart; + feedback.title = $localize`Feedback regarding ${firstPart}/${resourceName}`; + feedback.routerLink = ['/', firstPart, 'view', lastPart]; + this.updateFeedback(feedback, date, user, feedbackUrl); + }, + (error) => { + feedback.title = $localize`Feedback regarding ${firstPart}/${lastPart}`; + feedback.routerLink = ['/', firstPart, 'view', lastPart]; + this.updateFeedback(feedback, date, user, feedbackUrl); + } + ); + } } - + + private updateFeedback(feedback: any, date: Date, user: string, url: string) { + const startingMessage: Message = { message: feedback.message, time: date, user }; + const newFeedback: Feedback = { + owner: user, + ...feedback, + openTime: date, + status: 'Open', + messages: [startingMessage], + url, + source: this.stateService.configuration.code, + parentCode: this.stateService.configuration.parentCode, + ...this.feedbackOf, + }; + this.couchService.updateDocument('feedback', newFeedback).subscribe( + () => { + this.feedbackService.setFeedback(); + this.planetMessageService.showMessage($localize`Thank you, your feedback is submitted!`); + }, + () => { + this.planetMessageService.showAlert($localize`Error, your feedback cannot be submitted`); + } + ); + } + @HostListener('click') openFeedback() { const title = $localize`Feedback`; diff --git a/src/app/feedback/feedback.scss b/src/app/feedback/feedback.scss new file mode 100644 index 0000000000..2276d047a6 --- /dev/null +++ b/src/app/feedback/feedback.scss @@ -0,0 +1,14 @@ +.mat-column-type { + display: flex; + align-items: center; + } + +.ellipsis-title { + display: -webkit-box; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; + -webkit-line-clamp: 2; + white-space: normal; + word-break: break-word; + } diff --git a/src/app/meetups/meetups.component.html b/src/app/meetups/meetups.component.html index 36d84e5b81..4ceae1cc4d 100644 --- a/src/app/meetups/meetups.component.html +++ b/src/app/meetups/meetups.component.html @@ -65,7 +65,7 @@

clearLeave doneJoin - + feedback Feedback diff --git a/src/app/resources/resources.component.html b/src/app/resources/resources.component.html index 61657b0ac4..42d5189172 100644 --- a/src/app/resources/resources.component.html +++ b/src/app/resources/resources.component.html @@ -167,7 +167,7 @@

clearRemove from myLibrary - + feedback Feedback diff --git a/src/app/shared/couchdb.service.ts b/src/app/shared/couchdb.service.ts index 7ccb6de195..9d53140a3c 100644 --- a/src/app/shared/couchdb.service.ts +++ b/src/app/shared/couchdb.service.ts @@ -197,4 +197,14 @@ export class CouchService { return Date.UTC(localDate.getFullYear(), localDate.getMonth(), localDate.getDate()); } + getDocumentByID(db: string, docId: string): Observable { + const url = `${this.baseUrl}/${db}/${docId}`; + return this.http.get(url, this.defaultOpts).pipe( + catchError(err => { + this.planetMessageService.showAlert($localize`Error fetching document: ${err.message}`); + return throwError(err); + }) + ); + } + } diff --git a/src/app/surveys/surveys.component.ts b/src/app/surveys/surveys.component.ts index 5079e926d3..7e9ec3b1f6 100644 --- a/src/app/surveys/surveys.component.ts +++ b/src/app/surveys/surveys.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit, ViewChild, AfterViewInit, OnDestroy, Input } from '@angular/core'; +import { Component, OnInit, ViewChild, AfterViewInit, OnDestroy, Input, Output, EventEmitter } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; import { FormGroup } from '@angular/forms'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; @@ -34,6 +34,7 @@ export class SurveysComponent implements OnInit, AfterViewInit, OnDestroy { surveys = new MatTableDataSource(); @ViewChild(MatSort) sort: MatSort; @ViewChild(MatPaginator) paginator: MatPaginator; + @Output() surveyCount = new EventEmitter(); displayedColumns = (this.userService.doesUserHaveRole([ '_admin', 'manager' ]) ? [ 'select' ] : []).concat( [ 'name', 'taken', 'courseTitle', 'createdDate', 'action' ] ); @@ -97,7 +98,10 @@ export class SurveysComponent implements OnInit, AfterViewInit, OnDestroy { this.dialogsLoadingService.stop(); }); this.couchService.checkAuthorization(this.dbName).subscribe((isAuthorized) => this.isAuthorized = isAuthorized); - this.surveys.connect().subscribe(surveys => this.parentCount = surveys.filter(survey => survey.parent === true).length); + this.surveys.connect().subscribe(surveys => { + this.parentCount = surveys.filter(survey => survey.parent === true).length; + this.surveyCount.emit(surveys.length); + }); } ngAfterViewInit() { diff --git a/src/app/teams/teams-view.component.html b/src/app/teams/teams-view.component.html index 2fea687b5b..03c6da7a91 100644 --- a/src/app/teams/teams-view.component.html +++ b/src/app/teams/teams-view.component.html @@ -213,7 +213,10 @@

{{configuration - + + Surveys ({{surveysCount}}) + + diff --git a/src/app/teams/teams.component.html b/src/app/teams/teams.component.html index b2f889b592..8c64ef0b92 100644 --- a/src/app/teams/teams.component.html +++ b/src/app/teams/teams.component.html @@ -107,7 +107,7 @@

- diff --git a/src/app/users/users-profile/users-profile.scss b/src/app/users/users-profile/users-profile.scss index e687fb9e8c..d1a5142dcd 100644 --- a/src/app/users/users-profile/users-profile.scss +++ b/src/app/users/users-profile/users-profile.scss @@ -9,6 +9,15 @@ grid-column-gap: 2rem; } + .mat-list-item p{ + overflow-wrap: break-word; + white-space: normal; + word-break: break-word; + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + } + @media (max-width: $screen-sm) { .profile-image-section { grid-area: icon; diff --git a/src/app/users/users-update/users-update.component.ts b/src/app/users/users-update/users-update.component.ts index 80dd31c6fd..0b94f30a71 100644 --- a/src/app/users/users-update/users-update.component.ts +++ b/src/app/users/users-update/users-update.component.ts @@ -152,6 +152,7 @@ export class UsersUpdateComponent implements OnInit, CanComponentDeactivate { showFormErrors(this.editForm.controls); return; } + this.hasUnsavedChanges = false; this.submitUser(); }