handle not having any results

pull/6834/head
Jens Ulferts 6 years ago
parent 6e4ae13f6e
commit 5e04a563b3
No known key found for this signature in database
GPG Key ID: 3CAA4B1182CF5308
  1. 1
      app/assets/stylesheets/content/_table.sass
  2. 3
      config/locales/js-en.yml
  3. 4
      frontend/src/app/modules/common/no-results/no-results.component.html
  4. 41
      frontend/src/app/modules/common/no-results/no-results.component.ts
  5. 5
      frontend/src/app/modules/common/openproject-common.module.ts
  6. 10
      frontend/src/app/modules/grids/widgets/abstract-widget.component.ts
  7. 3
      frontend/src/app/modules/grids/widgets/documents/documents.component.html
  8. 9
      frontend/src/app/modules/grids/widgets/documents/documents.component.ts
  9. 3
      frontend/src/app/modules/grids/widgets/news/news.component.html
  10. 11
      frontend/src/app/modules/grids/widgets/news/news.component.ts
  11. 12
      frontend/src/app/modules/grids/widgets/time-entries-current-user/time-entries-current-user.component.html
  12. 9
      frontend/src/app/modules/grids/widgets/time-entries-current-user/time-entries-current-user.component.ts

@ -274,6 +274,7 @@ html.-supports-sticky-headers
border: 1px solid $gray
border-radius: $global-radius
padding: 14px 14px 14px 36px
display: block
> i,
.generic-table--no-results-title

@ -178,11 +178,14 @@ en:
widgets:
documents:
title: 'Documents'
no_results: 'No documents yet.'
news:
title: 'News'
at: 'at'
no_results: 'Nothing new to report.'
time_entries_current_user:
title: 'Spent time (last 7 days)'
no_results: 'No time entries for the last 7 days.'
work_packages_assigned:
title: 'Work packages assigned to me'
work_packages_created:

@ -0,0 +1,4 @@
<i class="icon-info1" aria-hidden="true"></i>
<span class="generic-table--no-results-title"
[textContent]="title">
</span>

@ -0,0 +1,41 @@
//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
import {Component, Input, HostBinding} from '@angular/core';
@Component({
templateUrl: './no-results.component.html',
selector: 'no-results'
})
export class NoResultsComponent {
@Input()
title:string;
@HostBinding('class.generic-table--no-results-container') setHostClass = true;
}

@ -70,6 +70,7 @@ import {UIRouterModule} from "@uirouter/angular";
import {PortalModule} from "@angular/cdk/portal";
import {CommonModule} from "@angular/common";
import {CollapsibleSectionComponent} from "core-app/modules/common/collapsible-section/collapsible-section.component";
import {NoResultsComponent} from "core-app/modules/common/no-results/no-results.component";
export function bootstrapModule(injector:Injector) {
return () => {
@ -138,6 +139,8 @@ export function bootstrapModule(injector:Injector) {
ZenModeButtonComponent,
OPContextMenuComponent,
NoResultsComponent,
],
declarations: [
OpDatePickerComponent,
@ -180,6 +183,8 @@ export function bootstrapModule(injector:Injector) {
// Zen mode button
ZenModeButtonComponent,
NoResultsComponent
],
entryComponents: [
OpDateTimeComponent,

@ -1,4 +1,4 @@
import {Component, HostBinding, Input, Output, EventEmitter} from "@angular/core";
import {HostBinding, Input} from "@angular/core";
import {GridWidgetResource} from "app/modules/hal/resources/grid-widget-resource";
import {I18nService} from "core-app/modules/common/i18n/i18n.service";
@ -11,12 +11,4 @@ export abstract class AbstractWidgetComponent {
@Input() resource:GridWidgetResource;
constructor(protected i18n:I18nService) { }
// TODO: check if still needed
public set widgetResource(resource:GridWidgetResource) {
this.gridColumnStart = resource.startColumn;
this.gridColumnEnd = resource.endColumn;
this.gridRowStart = resource.startRow;
this.gridRowEnd = resource.endRow;
}
}

@ -4,6 +4,9 @@
</h3>
<div class="grid--widget-content">
<no-results *ngIf="noEntries"
[title]="text.noResults">
</no-results>
<ng-container *ngFor="let document of entries">
<h4 class="document-category-elements--header">
<a [href]="documentPath(document)"

@ -14,9 +14,11 @@ import {DomSanitizer} from '@angular/platform-browser';
export class WidgetDocumentsComponent extends AbstractWidgetComponent implements OnInit {
public text = {
title: this.i18n.t('js.grid.widgets.documents.title'),
noResults: this.i18n.t('js.grid.widgets.documents.no_results'),
};
public entries:DocumentResource[] = [];
private entriesLoaded = false;
constructor(readonly halResource:HalResourceService,
readonly pathHelper:PathHelperService,
@ -30,12 +32,13 @@ export class WidgetDocumentsComponent extends AbstractWidgetComponent implements
let orders = JSON.stringify([['created_on', 'desc']]);
let url = `${this.pathHelper.api.v3.apiV3Base}/documents?sortBy=${orders}&pageSize=10`;
this.halResource
.get<CollectionResource>(url)
.toPromise()
.then((collection) => {
this.entries = collection.elements as DocumentResource[];
this.entriesLoaded = true;
});
}
@ -50,4 +53,8 @@ export class WidgetDocumentsComponent extends AbstractWidgetComponent implements
public documentDescription(document:DocumentResource) {
return this.domSanitizer.sanitize(SecurityContext.HTML, document.description.html);
}
public get noEntries() {
return !this.entries.length && this.entriesLoaded;
}
}

@ -4,6 +4,9 @@
</h3>
<div class="grid--widget-content">
<no-results *ngIf="noEntries"
[title]="text.noResults">
</no-results>
<ul class="widget-box--arrow-links">
<li class="-widget-box--arrow-multiline" *ngFor="let news of entries">
<div>

@ -17,9 +17,11 @@ export class WidgetNewsComponent extends AbstractWidgetComponent implements OnIn
title: this.i18n.t('js.grid.widgets.news.title'),
createdBy: this.i18n.t('js.label_created_by'),
at: this.i18n.t('js.grid.widgets.news.at'),
noResults: this.i18n.t('js.grid.widgets.news.no_results'),
};
public entries:NewsResource[] = [];
private entriesLoaded = false;
constructor(readonly halResource:HalResourceService,
readonly pathHelper:PathHelperService,
@ -31,14 +33,11 @@ export class WidgetNewsComponent extends AbstractWidgetComponent implements OnIn
}
ngOnInit() {
//let orders = JSON.stringify([['created_on', 'desc']]);
//let url = `${this.pathHelper.api.v3.apiV3Base}/news?sortBy=${orders}&pageSize=3`;
this.newsDm
.list({ sortBy: [['created_on', 'desc']], pageSize: 3 })
.then((collection) => {
this.entries = collection.elements as NewsResource[];
this.entriesLoaded = true;
this.entries.forEach((entry) => {
this.userCache
@ -77,4 +76,8 @@ export class WidgetNewsComponent extends AbstractWidgetComponent implements OnIn
public newsCreated(news:NewsResource) {
return this.timezone.formattedDatetime(news.createdAt);
}
public get noEntries() {
return !this.entries.length && this.entriesLoaded;
}
}

@ -3,9 +3,14 @@
<span class="widget-box--header-title" [textContent]="text.title"></span>
</h3>
<div class="total-hours">
<p>Total: <span [textContent]="total"></span></p>
</div>
<no-results *ngIf="noEntries"
[title]="text.noResults">
</no-results>
<ng-container *ngIf="!noEntries">
<div class="total-hours">
<p>Total: <span [textContent]="total"></span></p>
</div>
<div class="generic-table--results-container" *ngIf="anyEntries">
<table class="generic-table time-entries">
@ -92,3 +97,4 @@
</tbody>
</table>
</div>
</ng-container>

@ -25,9 +25,11 @@ export class WidgetTimeEntriesCurrentUserComponent extends AbstractWidgetCompone
confirmDelete: {
text: this.i18n.t('js.text_are_you_sure'),
title: this.i18n.t('js.modals.form_submit.title')
}
},
noResults: this.i18n.t('js.grid.widgets.time_entries_current_user.no_results'),
};
public entries:TimeEntryResource[] = [];
private entriesLoaded = false;
public rows:{ date:string, sum?:string, entry?:TimeEntryResource}[] = [];
constructor(readonly timeEntryDm:TimeEntryDmService,
@ -45,6 +47,7 @@ export class WidgetTimeEntriesCurrentUserComponent extends AbstractWidgetCompone
this.timeEntryDm.list({ filters: filters })
.then((collection) => {
this.buildEntries(collection.elements);
this.entriesLoaded = true;
});
}
@ -152,4 +155,8 @@ export class WidgetTimeEntriesCurrentUserComponent extends AbstractWidgetCompone
private formatNumber(value:number) {
return formatNumber(value, this.i18n.locale, '1.2-2');
}
public get noEntries() {
return !this.entries.length && this.entriesLoaded;
}
}

Loading…
Cancel
Save