parent
a27212a424
commit
df695672b6
@ -0,0 +1,79 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2018 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
import {Component, Inject, Input, OnInit} from '@angular/core'; |
||||
import {I18nToken, TimezoneServiceToken} from '../../../angular4-transition-utils'; |
||||
import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; |
||||
import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; |
||||
import {opUiComponentsModule} from 'core-app/angular-modules'; |
||||
import {downgradeComponent} from '@angular/upgrade/static'; |
||||
|
||||
@Component({ |
||||
template: require('!!raw-loader!./authoring.html'), |
||||
selector: 'authoring', |
||||
}) |
||||
export class AuthoringComponent implements OnInit { |
||||
// scope: { createdOn: '=', author: '=', showAuthorAsLink: '=', project: '=', activity: '=' },
|
||||
@Input('createdOn') createdOn:string; |
||||
@Input('author') author:HalResource; |
||||
@Input('showAuthorAsLink') showAuthorAsLink:boolean; |
||||
@Input('project') project:any; |
||||
@Input('activity') activity:any; |
||||
|
||||
public createdOnTime:any; |
||||
public timeago:any; |
||||
public time:any; |
||||
public userLink:string; |
||||
|
||||
public constructor(readonly PathHelper:PathHelperService, |
||||
@Inject(I18nToken) readonly I18n:op.I18n, |
||||
@Inject(TimezoneServiceToken) readonly TimezoneService:any) { |
||||
|
||||
} |
||||
|
||||
ngOnInit() { |
||||
this.createdOnTime = this.TimezoneService.parseDatetime(this.createdOn); |
||||
this.timeago = this.createdOnTime.fromNow(); |
||||
this.time = this.createdOnTime.format('LLL'); |
||||
this.userLink = this.PathHelper.userPath(this.author.id); |
||||
} |
||||
|
||||
public activityFromPath(from:any) { |
||||
var path = this.PathHelper.projectActivityPath(this.project); |
||||
|
||||
if (from) { |
||||
path += '?from=' + from; |
||||
} |
||||
|
||||
return path; |
||||
} |
||||
} |
||||
|
||||
opUiComponentsModule.directive('authoring', |
||||
downgradeComponent({component: AuthoringComponent}) |
||||
); |
@ -0,0 +1,18 @@ |
||||
<div class="authoring-entry"> |
||||
<span *ngIf="showAuthorAsLink" [textContent]="author.name"></span> |
||||
<span *ngIf="!showAuthorAsLink"> |
||||
<a [attr.href]="userLink" |
||||
[textContent]="author.name"></a> |
||||
</span> |
||||
|
||||
<span *ngIf="activity"> |
||||
<a [attr.title]="time" |
||||
[attr.href]="activityFromPath(createdOn.format('YYYY-MM-DD'))" |
||||
[textContent]="timeago"></a> |
||||
</span> |
||||
<span *ngIf="!activity" |
||||
class="timestamp" |
||||
[textContent]="timeago" |
||||
[attr.title]="time"> |
||||
</span> |
||||
</div> |
@ -0,0 +1,43 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2017 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-2017 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, Directive, ElementRef, Injector, Input, Output} from '@angular/core'; |
||||
import {UpgradeComponent} from '@angular/upgrade/static'; |
||||
import {UserResource} from 'core-components/api/api-v3/hal-resources/user-resource.service'; |
||||
|
||||
@Directive({ |
||||
selector: 'op-date-time' |
||||
}) |
||||
export class OpDateTimeUpgradedDirective extends UpgradeComponent { |
||||
|
||||
@Input('dateTimeValue') dateTimeValue:any; |
||||
|
||||
constructor(elementRef:ElementRef, injector:Injector) { |
||||
super('opDateTime', elementRef, injector); |
||||
} |
||||
} |
@ -0,0 +1,30 @@ |
||||
// This Angular directive will act as an interface to the "upgraded" AngularJS component
|
||||
// query-filters
|
||||
import { |
||||
Directive, DoCheck, ElementRef, Inject, Injector, Input, OnChanges, OnDestroy, |
||||
OnInit, SimpleChanges |
||||
} from '@angular/core'; |
||||
import {UpgradeComponent} from '@angular/upgrade/static'; |
||||
|
||||
@Directive({selector: 'ng1-attribute-help-text-wrapper'}) |
||||
export class Ng1AttributeHelpTextWrapper extends UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy { |
||||
@Input('attribute') public attribute:string; |
||||
@Input('attributeScope') public attributeScope:string; |
||||
@Input('helpTextId') public helpTextId?:string; |
||||
@Input('additionalLabel') public additionalLabel?:string; |
||||
|
||||
constructor(@Inject(ElementRef) elementRef:ElementRef, @Inject(Injector) injector:Injector) { |
||||
// We must pass the name of the directive as used by AngularJS to the super
|
||||
super('attributeHelpText', elementRef, injector); |
||||
} |
||||
|
||||
// For this class to work when compiled with AoT, we must implement these lifecycle hooks
|
||||
// because the AoT compiler will not realise that the super class implements them
|
||||
ngOnInit() { super.ngOnInit(); } |
||||
|
||||
ngOnChanges(changes:SimpleChanges) { super.ngOnChanges(changes); } |
||||
|
||||
ngDoCheck() { super.ngDoCheck(); } |
||||
|
||||
ngOnDestroy() { super.ngOnDestroy(); } |
||||
} |
@ -1,170 +0,0 @@ |
||||
<div ng-if="$ctrl.workPackage" class="work-package--single-view"> |
||||
<div class="wp-new--subject-wrapper" ng-if="$ctrl.workPackage.isNew"> |
||||
<wp-edit-field work-package-id="$ctrl.workPackage.id" |
||||
wrapper-classes="'-no-label'" |
||||
field-name="'subject'"></wp-edit-field> |
||||
</div> |
||||
|
||||
<div class="wp-info-wrapper"> |
||||
<wp-status-button ng-if="!$ctrl.workPackage.isNew" |
||||
work-package="$ctrl.workPackage" |
||||
allowed="$ctrl.workPackage.isEditable"></wp-status-button> |
||||
<attribute-help-text attribute="'status'" attribute-scope="WorkPackage" ng-if="!$ctrl.workPackage.isNew"></attribute-help-text> |
||||
|
||||
<div class="work-packages--info-row" ng-if="!$ctrl.workPackage.isNew"> |
||||
<span ng-bind="$ctrl.idLabel"/>: |
||||
<span ng-bind="$ctrl.text.infoRow.createdBy"/> |
||||
<user-link class="user-link" user="$ctrl.workPackage.author"></user-link>. |
||||
<span ng-bind="$ctrl.text.infoRow.lastUpdatedOn"/> |
||||
<op-date-time date-time-value="$ctrl.workPackage.updatedAt"></op-date-time>. |
||||
</div> |
||||
|
||||
<wp-custom-actions [work-package]="$ctrl.workPackage" class="custom-actions"></wp-custom-actions> |
||||
</div> |
||||
|
||||
<div class="attributes-group -project-context" ng-if="$ctrl.projectContext.field"> |
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"></div> |
||||
</div> |
||||
<div class=""> |
||||
<p ng-hide="$ctrl.projectContext.href" ng-bind="::$ctrl.text.project.required"></p> |
||||
<div class="attributes-key-value" |
||||
ng-class="{'-span-all-columns': descriptor.spanAll }" |
||||
ng-repeat="descriptor in $ctrl.projectContext.field track by descriptor.name"> |
||||
<div class="attributes-key-value--key" |
||||
wp-replacement-label="descriptor.name"> |
||||
{{ descriptor.label }} |
||||
<span class="required" ng-if="descriptor.field.required && descriptor.field.writable"> *</span> |
||||
<attribute-help-text title-text="descriptor.label" attribute="descriptor.name" attribute-scope="WorkPackage"></attribute-help-text> |
||||
</div> |
||||
<div class="attributes-key-value--value-container"> |
||||
<wp-edit-field work-package-id="$ctrl.workPackage.id" field-name="descriptor.name"></wp-edit-field> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="attributes-group -project-context hide-when-print" ng-if="!$ctrl.workPackage.isNew && !$ctrl.projectContext.matches"> |
||||
<div> |
||||
<p> |
||||
<span ng-bind-html="$ctrl.projectContextText"></span> |
||||
<br/> |
||||
<a ng-href="{{ $ctrl.projectContext.href }}" |
||||
class="project-context--switch-link" |
||||
ng-bind="::$ctrl.text.project.switchTo"> |
||||
</a> |
||||
</p> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="attributes-group description-group"> |
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text" |
||||
ng-bind="$ctrl.text.fields.description"></h3> |
||||
</div> |
||||
</div> |
||||
<div class="single-attribute wiki work-packages--details--description"> |
||||
<wp-edit-field field-name="'description'" |
||||
work-package-id="$ctrl.workPackage.id" |
||||
wrapper-classes="'-no-label'" |
||||
display-placeholder="$ctrl.I18n.t('js.work_packages.placeholders.description')" |
||||
wp-attachments-formattable> |
||||
</wp-edit-field> |
||||
</div> |
||||
</div> |
||||
|
||||
<div ng-repeat="group in $ctrl.groupedFields track by group.name" |
||||
ng-hide="$ctrl.shouldHideGroup(group)" |
||||
data-group-name="{{ group.name }}" |
||||
class="attributes-group"> |
||||
|
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text" |
||||
ng-bind="group.name"></h3> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="-columns-2"> |
||||
<div class="attributes-key-value" |
||||
ng-class="{'-span-all-columns': descriptor.spanAll }" |
||||
ng-repeat="descriptor in group.members track by descriptor.name" |
||||
ng-if="!$ctrl.shouldHideField(descriptor)"> |
||||
<div |
||||
class="attributes-key-value--key" |
||||
ng-if="!descriptor.multiple" |
||||
wp-replacement-label="descriptor.name"> |
||||
|
||||
{{ descriptor.label }} |
||||
<span class="required" ng-if="descriptor.field.required && descriptor.field.writable"> *</span> |
||||
<attribute-help-text attribute="descriptor.name" attribute-scope="WorkPackage"></attribute-help-text> |
||||
</div> |
||||
<div ng-if="!descriptor.multiple" |
||||
class="attributes-key-value--value-container"> |
||||
|
||||
<wp-edit-field ng-if="descriptor.field.isFormattable" |
||||
class="wp-edit-formattable-field" |
||||
work-package-id="$ctrl.workPackage.id" |
||||
field-name="descriptor.name" |
||||
wp-attachments-formattable> |
||||
</wp-edit-field> |
||||
<wp-edit-field ng-if="!descriptor.field.isFormattable" |
||||
work-package-id="$ctrl.workPackage.id" |
||||
field-name="descriptor.name"> |
||||
</wp-edit-field> |
||||
</div> |
||||
<div |
||||
class="attributes-key-value--key" |
||||
ng-if="descriptor.multiple" |
||||
wp-replacement-label="descriptor.label"> |
||||
{{ descriptor.label }} |
||||
<attribute-help-text attribute="descriptor.name" attribute-scope="WorkPackage"></attribute-help-text> |
||||
</div> |
||||
<div |
||||
ng-if="descriptor.multiple" |
||||
class="attributes-key-value--value-container -minimal"> |
||||
<wp-edit-field field-name="descriptor.fields[0].name" |
||||
work-package-id="$ctrl.workPackage.id" |
||||
wrapper-classes="'-small -shrink'" |
||||
display-placeholder="::$ctrl.text[descriptor.name][descriptor.fields[0].name]"> |
||||
</wp-edit-field> |
||||
|
||||
<span class="attributes-key-value--value-separator"></span> |
||||
|
||||
<wp-edit-field field-name="descriptor.fields[1].name" |
||||
work-package-id="$ctrl.workPackage.id" |
||||
wrapper-classes="'-small -shrink'" |
||||
display-placeholder="::$ctrl.text[descriptor.name][descriptor.fields[1].name]"> |
||||
</wp-edit-field> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="work-packages--attachments attributes-group"> |
||||
<div class="work-packages--atachments-container"> |
||||
<div class="attributes-group--header" |
||||
ng-if="$ctrl.workPackage.attachments.elements.length"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text"> |
||||
{{ ::$ctrl.I18n.t('js.label_attachments') }} |
||||
</h3> |
||||
</div> |
||||
</div> |
||||
|
||||
<wp-attachment-list work-package="$ctrl.workPackage"></wp-attachment-list> |
||||
<wp-attachments-upload work-package="$ctrl.workPackage" class="hide-when-print"> |
||||
<div class="work-package--attachments--drop-box"> |
||||
<div class="work-package--attachments--label"> |
||||
<op-icon icon-classes="icon-attachment"></op-icon> |
||||
<p> |
||||
{{ ::$ctrl.text.dropFiles }} <br> |
||||
{{ ::$ctrl.text.dropFilesHint }} |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</wp-attachments-upload> |
||||
</div> |
||||
</div> |
@ -0,0 +1,173 @@ |
||||
<div *ngIf="workPackage" |
||||
class="work-package--single-view"> |
||||
<div class="wp-new--subject-wrapper" |
||||
*ngIf="workPackage.isNew"> |
||||
<wp-edit-field [workPackageId]="workPackage.id" |
||||
[wrapperClasses]="'-no-label'" |
||||
[fieldName]="'subject'"></wp-edit-field> |
||||
</div> |
||||
|
||||
<div class="wp-info-wrapper"> |
||||
<wp-status-button *ngIf="!workPackage.isNew" |
||||
[workPackage]="workPackage" |
||||
[allowed]="workPackage.isEditable"></wp-status-button> |
||||
<ng1-attribute-help-text-wrapper [attribute]="'status'" |
||||
[attributeScope]="'WorkPackage'" |
||||
*ngIf="!workPackage.isNew"></ng1-attribute-help-text-wrapper> |
||||
|
||||
<div class="work-packages--info-row" |
||||
*ngIf="!workPackage.isNew"> |
||||
<span [textContent]="idLabel"></span>: |
||||
<span [textContent]="text.infoRow.createdBy"></span> |
||||
<user-link class="user-link" |
||||
[user]="workPackage.author"></user-link>. |
||||
<span [textContent]="text.infoRow.lastUpdatedOn"></span> |
||||
<op-date-time [dateTimeValue]="workPackage.updatedAt"></op-date-time>. |
||||
</div> |
||||
|
||||
<wp-custom-actions [workPackage]="workPackage"class="custom-actions"></wp-custom-actions> |
||||
</div> |
||||
|
||||
<div class="attributes-group -project-context" |
||||
*ngIf="projectContext.field"> |
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"></div> |
||||
</div> |
||||
<div> |
||||
<p [hidden]="projectContext.href" [textContent]="text.project.required"></p> |
||||
<div class="attributes-key-value" |
||||
[ngClass]="{'-span-all-columns': descriptor.spanAll }" |
||||
*ngFor="let descriptor of projectContext.field; trackBy:trackByName"> |
||||
<div class="attributes-key-value--key"> |
||||
<wp-replacement-label [fieldName]="descriptor.name"> |
||||
{{ descriptor.label }} |
||||
<span class="required" |
||||
*ngIf="descriptor.field.required && descriptor.field.writable">*</span> |
||||
<ng1-attribute-help-text-wrapper [attribute]="descriptor.name" |
||||
[attributeScope]="'WorkPackage'"></ng1-attribute-help-text-wrapper> |
||||
</wp-replacement-label> |
||||
</div> |
||||
<div class="attributes-key-value--value-container"> |
||||
<wp-edit-field [workPackageId]="workPackage.id" |
||||
[fieldName]="descriptor.name"></wp-edit-field> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="attributes-group -project-context hide-when-print" *ngIf="!workPackage.isNew && !projectContext.matches"> |
||||
<div> |
||||
<p> |
||||
<span [innerHTML]="projectContextText"></span> |
||||
<br/> |
||||
<a [attr.href]="projectContext.href" |
||||
class="project-context--switch-link" |
||||
[textContent]="text.project.switchTo"> |
||||
</a> |
||||
</p> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="attributes-group description-group"> |
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text" |
||||
[textContent]="text.fields.description"></h3> |
||||
</div> |
||||
</div> |
||||
<div class="single-attribute wiki work-packages--details--description"> |
||||
<wp-edit-field [fieldName]="'description'" |
||||
[workPackageId]="workPackage.id" |
||||
[wrapperClasses]="'-no-label'" |
||||
[displayPlaceholder]="text.description.placeholder" |
||||
wp-attachments-formattable> |
||||
</wp-edit-field> |
||||
</div> |
||||
</div> |
||||
|
||||
<div *ngFor="let group of groupedFields; trackBy:trackByName" |
||||
[hidden]="shouldHideGroup(group)" |
||||
[attr.data-group-name]="group.name" |
||||
class="attributes-group"> |
||||
|
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text" |
||||
[textContent]="group.name"></h3> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="-columns-2"> |
||||
<div class="attributes-key-value" |
||||
[ngClass]="{'-span-all-columns': descriptor.spanAll }" |
||||
*ngFor="let descriptor of group.members; trackBy:trackByName"> |
||||
<ng-template [ngIf]="!shouldHideField(descriptor)"> |
||||
<div |
||||
class="attributes-key-value--key" |
||||
*ngIf="!descriptor.multiple"> |
||||
<wp-replacement-label [fieldName]="descriptor.name"> |
||||
{{ descriptor.label }} |
||||
<span class="required" |
||||
*ngIf="descriptor.field.required && descriptor.field.writable"> *</span> |
||||
<ng1-attribute-help-text-wrapper attribute="descriptor.name" attribute-scope="WorkPackage"></ng1-attribute-help-text-wrapper> |
||||
</wp-replacement-label> |
||||
</div> |
||||
<div *ngIf="!descriptor.multiple" |
||||
class="attributes-key-value--value-container"> |
||||
|
||||
<wp-edit-field *ngIf="descriptor.field.isFormattable" |
||||
class="wp-edit-formattable-field" |
||||
[workPackageId]="workPackage.id" |
||||
[fieldName]="descriptor.name" |
||||
wp-attachments-formattable> |
||||
</wp-edit-field> |
||||
<wp-edit-field *ngIf="!descriptor.field.isFormattable" |
||||
[workPackageId]="workPackage.id" |
||||
[fieldName]="descriptor.name"> |
||||
</wp-edit-field> |
||||
</div> |
||||
<div |
||||
class="attributes-key-value--key" |
||||
*ngIf="descriptor.multiple"> |
||||
<wp-replacement-label [fieldName]="descriptor.name"> |
||||
{{ descriptor.label }} |
||||
<ng1-attribute-help-text-wrapper attribute="descriptor.name" attribute-scope="WorkPackage"></ng1-attribute-help-text-wrapper> |
||||
</wp-replacement-label> |
||||
</div> |
||||
<div |
||||
*ngIf="descriptor.multiple" |
||||
class="attributes-key-value--value-container -minimal"> |
||||
<wp-edit-field [fieldName]="descriptor.fields[0].name" |
||||
[workPackageId]="workPackage.id" |
||||
[wrapperClasses]="'-small -shrink'" |
||||
[displayPlaceholder]="text[descriptor.name][descriptor.fields[0].name]"> |
||||
</wp-edit-field> |
||||
|
||||
<span class="attributes-key-value--value-separator"></span> |
||||
|
||||
<wp-edit-field [fieldName]="descriptor.fields[1].name" |
||||
[workPackageId]="workPackage.id" |
||||
[wrapperClasses]="'-small -shrink'" |
||||
[displayPlaceholder]="text[descriptor.name][descriptor.fields[1].name]"> |
||||
</wp-edit-field> |
||||
</div> |
||||
</ng-template> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="work-packages--attachments attributes-group"> |
||||
<div class="work-packages--atachments-container"> |
||||
<div class="attributes-group--header" |
||||
*ngIf="workPackage.attachments"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text" [textContent]="text.attachments.label"></h3> |
||||
</div> |
||||
</div> |
||||
|
||||
<wp-attachment-list [workPackage]="workPackage"></wp-attachment-list> |
||||
<ng1-wp-attachments-upload-wrapper [workPackage]="workPackage" class="hide-when-print"> |
||||
</ng1-wp-attachments-upload-wrapper> |
||||
</div> |
||||
</div> |
@ -1,16 +0,0 @@ |
||||
<div class="work-package--attachments--files"> |
||||
<div class="work-package--details--long-field"> |
||||
<span |
||||
class="inplace-edit--read" |
||||
ng-include="::$ctrl.itemTemplateUrl" |
||||
ng-if="$ctrl.workPackage.pendingAttachments" |
||||
ng-repeat="attachment in $ctrl.workPackage.pendingAttachments track by attachment.name+$index"> |
||||
</span> |
||||
<span |
||||
class="inplace-edit--read" |
||||
ng-include="::$ctrl.itemTemplateUrl" |
||||
ng-if="$ctrl.workPackage.attachments.elements" |
||||
ng-repeat="attachment in $ctrl.workPackage.attachments.elements track by attachment.name+$index"> |
||||
</span> |
||||
</div> |
||||
</div> |
@ -0,0 +1,14 @@ |
||||
<div class="work-package--attachments--files"> |
||||
<div class="work-package--details--long-field"> |
||||
<span |
||||
class="inplace-edit--read" |
||||
*ngFor="let attachment of workPackage.pendingAttachments"> |
||||
<wp-attachment-list-item [attachment]="attachment" [workPackage]="workPackage"></wp-attachment-list-item> |
||||
</span> |
||||
<span |
||||
class="inplace-edit--read" |
||||
*ngFor="let attachment of workPackage.attachments.elements"> |
||||
<wp-attachment-list-item [attachment]="attachment" [workPackage]="workPackage"></wp-attachment-list-item> |
||||
</span> |
||||
</div> |
||||
</div> |
@ -0,0 +1,56 @@ |
||||
//-- 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.
|
||||
//++
|
||||
|
||||
// This Angular directive will act as an interface to the "upgraded" AngularJS component
|
||||
import { |
||||
Directive, DoCheck, ElementRef, Inject, Injector, Input, OnChanges, OnDestroy, |
||||
OnInit, SimpleChanges |
||||
} from '@angular/core'; |
||||
import {UpgradeComponent} from '@angular/upgrade/static'; |
||||
import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; |
||||
|
||||
@Directive({selector: 'ng1-wp-attachments-upload-wrapper'}) |
||||
export class Ng1WorkPackageAttachmentsUploadWrapper extends UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy { |
||||
@Input('workPackage') workPackage:WorkPackageResourceInterface; |
||||
|
||||
constructor(@Inject(ElementRef) elementRef:ElementRef, @Inject(Injector) injector:Injector) { |
||||
// We must pass the name of the directive as used by AngularJS to the super
|
||||
super('wpAttachmentsUpload', elementRef, injector); |
||||
} |
||||
|
||||
// For this class to work when compiled with AoT, we must implement these lifecycle hooks
|
||||
// because the AoT compiler will not realise that the super class implements them
|
||||
ngOnInit() { super.ngOnInit(); } |
||||
|
||||
ngOnChanges(changes:SimpleChanges) { super.ngOnChanges(changes); } |
||||
|
||||
ngDoCheck() { super.ngDoCheck(); } |
||||
|
||||
ngOnDestroy() { super.ngOnDestroy(); } |
||||
} |
||||
|
@ -0,0 +1,21 @@ |
||||
<div |
||||
class="wp-attachment-upload hide-when-print" |
||||
ng-if="$ctrl.workPackage.canAddAttachments" |
||||
ngf-drop |
||||
ngf-select |
||||
ngf-change="$ctrl.uploadFiles($files)" |
||||
ngf-multiple="true" |
||||
ngf-validate="{ size: {max: ::$ctrl.maxFileSize} }" |
||||
tabindex="0" |
||||
aria-label="{{ ::$ctrl.text.uploadLabel }}" |
||||
click-on-keypress="[13, 32]"> |
||||
<div class="work-package--attachments--drop-box"> |
||||
<div class="work-package--attachments--label"> |
||||
<op-icon icon-classes="icon-attachment"></op-icon> |
||||
<p> |
||||
{{ ::text.dropFiles }} <br> |
||||
{{ ::text.dropFilesHint }} |
||||
</p> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -1,14 +0,0 @@ |
||||
<div class="wp-status-button"> |
||||
<button class="button" |
||||
has-dropdown-menu |
||||
target="WpStatusContextMenu" |
||||
ng-init="workPackage = $ctrl.workPackage" |
||||
locals="workPackage" |
||||
ng-disabled="$ctrl.isDisabled()" |
||||
aria-label="{{ ::$ctrl.text.explanation }}"> |
||||
|
||||
<span class="button--text" |
||||
aria-hidden="true">{{$ctrl.getStatus.name}}</span> |
||||
<op-icon icon-classes="button--icon icon-small icon-pulldown"></op-icon> |
||||
</button> |
||||
</div> |
@ -0,0 +1,15 @@ |
||||
<div class="wp-status-button"> |
||||
<button class="button" |
||||
[disabled]="isDisabled()" |
||||
[attr.aria-label]="text.explanation" |
||||
|
||||
hasDropdownMenu |
||||
[hasDropdownMenu-locals]="{'workPackage': workPackage }" |
||||
[hasDropdownMenu-target]="'WpStatusContextMenu'"> |
||||
|
||||
<span class="button--text" |
||||
aria-hidden="true" |
||||
[textContent]="getStatus.name"></span> |
||||
<op-icon icon-classes="button--icon icon-small icon-pulldown"></op-icon> |
||||
</button> |
||||
</div> |
@ -1,4 +0,0 @@ |
||||
<ng-transclude |
||||
ng-click="vm.activate($event)" |
||||
tabindex="-1"> |
||||
</ng-transclude> |
@ -0,0 +1,4 @@ |
||||
<ng-content |
||||
(click)="activate($event)" |
||||
tabindex="-1"> |
||||
</ng-content> |
@ -1,11 +0,0 @@ |
||||
<wp-single-view work-package="$ctrl.workPackage" ng-if="$ctrl.workPackage"></wp-single-view> |
||||
|
||||
<div class="attributes-group" ng-if="$ctrl.workPackage"> |
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text">{{ I18n.t('js.label_latest_activity') }}</h3> |
||||
</div> |
||||
</div> |
||||
|
||||
<activity-panel template="overview" work-package="$ctrl.workPackage"></activity-panel> |
||||
</div> |
@ -0,0 +1,58 @@ |
||||
// -- 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, Inject, Input, OnDestroy} from '@angular/core'; |
||||
import {Transition} from '@uirouter/core'; |
||||
import {I18nToken} from '../../../angular4-transition-utils'; |
||||
import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; |
||||
import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; |
||||
import {componentDestroyed} from 'ng2-rx-componentdestroyed'; |
||||
@Component({ |
||||
template: require('!!raw-loader!./overview-tab.html'), |
||||
selector: 'wp-overview-tab', |
||||
}) |
||||
export class WorkPackageOverviewTabComponent implements OnDestroy { |
||||
public workPackageId:string; |
||||
public workPackage:WorkPackageResourceInterface; |
||||
public tabName = this.I18n.t('js.label_latest_activity'); |
||||
|
||||
public constructor(@Inject(I18nToken) readonly I18n:op.I18n, |
||||
readonly $transition:Transition, |
||||
readonly wpCacheService:WorkPackageCacheService) { |
||||
|
||||
this.workPackageId = this.$transition.params('to').workPackageId; |
||||
wpCacheService.loadWorkPackage(this.workPackageId) |
||||
.values$() |
||||
.takeUntil(componentDestroyed(this)) |
||||
.subscribe((wp) => this.workPackage = wp); |
||||
} |
||||
|
||||
ngOnDestroy() { |
||||
// Nothing to do
|
||||
} |
||||
} |
@ -0,0 +1,13 @@ |
||||
<wp-single-view [workPackage]="workPackage" |
||||
*ngIf="workPackage"></wp-single-view> |
||||
|
||||
<div class="attributes-group" *ngIf="workPackage"> |
||||
<div class="attributes-group--header"> |
||||
<div class="attributes-group--header-container"> |
||||
<h3 class="attributes-group--header-text" [textContent]="tabName"></h3> |
||||
</div> |
||||
</div> |
||||
|
||||
<!-- TODO --> |
||||
<!-- <activity-panel template="overview" work-package="workPackage"></activity-panel> --> |
||||
</div> |
@ -1 +0,0 @@ |
||||
<span ng-bind-html="I18n.t('js.label_added_time_by', { author: authorLink, age: timestamp })"></span> |
@ -1,67 +0,0 @@ |
||||
//-- copyright
|
||||
// OpenProject is a project management system.
|
||||
// Copyright (C) 2012-2018 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-2017 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 docs/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
// TODO move to UI components
|
||||
module.exports = function(I18n, PathHelper, TimezoneService) { |
||||
return { |
||||
restrict: 'E', |
||||
replace: true, |
||||
scope: { createdOn: '=', author: '=', showAuthorAsLink: '=', project: '=', activity: '=' }, |
||||
templateUrl: '/templates/components/authoring.html', |
||||
link: function(scope, element, attrs) { |
||||
moment.locale(I18n.locale); |
||||
|
||||
var createdOn = TimezoneService.parseDatetime(scope.createdOn); |
||||
var timeago = createdOn.fromNow(); |
||||
var time = createdOn.format('LLL'); |
||||
|
||||
function activityFromPath(project, from) { |
||||
var path = PathHelper.projectActivityPath(project); |
||||
|
||||
if (from) { |
||||
path += '?from=' + from; |
||||
} |
||||
|
||||
return path; |
||||
} |
||||
|
||||
scope.I18n = I18n; |
||||
if(scope.showAuthorAsLink === false) { |
||||
scope.authorLink = '<span>' + scope.author.name + '</span>'; |
||||
} else { |
||||
scope.authorLink = '<a href="'+ PathHelper.userPath(scope.author.id) + '">' + scope.author.name + '</a>'; |
||||
} |
||||
|
||||
if (scope.activity) { |
||||
scope.timestamp = '<a title="' + time + '" href="' + activityFromPath(scope.project, createdOn.format('YYYY-MM-DD')) + '">' + timeago + '</a>'; |
||||
} else { |
||||
scope.timestamp = '<span class="timestamp" title="' + time + '">' + timeago + '</span>'; |
||||
} |
||||
} |
||||
}; |
||||
}; |
Loading…
Reference in new issue