From a0c6b2c8d78214beaaaa7a33cc480f52551ca605 Mon Sep 17 00:00:00 2001 From: Roman Roelofsen Date: Wed, 15 Mar 2017 11:32:40 +0100 Subject: [PATCH] POC for interactive selection mode --- .../work_packages/timelines/_timelines.sass | 1 + .../timelines/elements/_bar.sass | 42 +++++++++++++++++++ .../timelines/elements/_milestone.sass | 6 +++ .../timelines/elements/_relation.sass | 8 ++++ .../cell-renderer/timeline-cell-renderer.ts | 12 ++++++ .../wp-timeline-container.directive.ts | 35 +++++++++++++--- .../timeline/wp-timeline-global.directive.ts | 29 +++++++------ .../wp-table/timeline/wp-timeline.ts | 7 +++- 8 files changed, 119 insertions(+), 21 deletions(-) create mode 100644 app/assets/stylesheets/content/work_packages/timelines/elements/_relation.sass diff --git a/app/assets/stylesheets/content/work_packages/timelines/_timelines.sass b/app/assets/stylesheets/content/work_packages/timelines/_timelines.sass index 1c222836ca..e35435f8f3 100644 --- a/app/assets/stylesheets/content/work_packages/timelines/_timelines.sass +++ b/app/assets/stylesheets/content/work_packages/timelines/_timelines.sass @@ -1,6 +1,7 @@ @import '_slider' @import 'elements/_bar' @import 'elements/_milestone' +@import 'elements/_relation' .wp-timeline--th min-width: 600px !important diff --git a/app/assets/stylesheets/content/work_packages/timelines/elements/_bar.sass b/app/assets/stylesheets/content/work_packages/timelines/elements/_bar.sass index fe7b05c5fb..43c4f25218 100644 --- a/app/assets/stylesheets/content/work_packages/timelines/elements/_bar.sass +++ b/app/assets/stylesheets/content/work_packages/timelines/elements/_bar.sass @@ -47,3 +47,45 @@ right: -85px padding: 0 5px 0 5px font-size: 10px + +.active-selection-mode + .timeline-element.bar + border: 1px solid orange !important + outline: 1px solid orange !important + cursor: pointer !important + background: linear-gradient(270deg, #eeeeee, #bbbbbb) + background-size: 400% 400% + + -webkit-animation: AnimationName 2s ease infinite + -moz-animation: AnimationName 2s ease infinite + animation: AnimationName 2s ease infinite + + .leftHandle + cursor: pointer !important + + .rightHandle + cursor: pointer !important + + @-webkit-keyframes AnimationName + 0% + background-position: 0% 50% + 50% + background-position: 100% 50% + 100% + background-position: 0% 50% + + @-moz-keyframes AnimationName + 0% + background-position: 0% 50% + 50% + background-position: 100% 50% + 100% + background-position: 0% 50% + + @keyframes AnimationName + 0% + background-position: 0% 50% + 50% + background-position: 100% 50% + 100% + background-position: 0% 50% diff --git a/app/assets/stylesheets/content/work_packages/timelines/elements/_milestone.sass b/app/assets/stylesheets/content/work_packages/timelines/elements/_milestone.sass index de7589bb9e..d14f40d5a5 100644 --- a/app/assets/stylesheets/content/work_packages/timelines/elements/_milestone.sass +++ b/app/assets/stylesheets/content/work_packages/timelines/elements/_milestone.sass @@ -18,3 +18,9 @@ padding: 0 5px 0 5px font-size: 10px +.active-selection-mode + .timeline-element.milestone + .diamond + border: 1px solid orange !important + outline: 1px solid orange !important + background: #EEEEEE none !important diff --git a/app/assets/stylesheets/content/work_packages/timelines/elements/_relation.sass b/app/assets/stylesheets/content/work_packages/timelines/elements/_relation.sass new file mode 100644 index 0000000000..23435d872a --- /dev/null +++ b/app/assets/stylesheets/content/work_packages/timelines/elements/_relation.sass @@ -0,0 +1,8 @@ +.timeline-element.relation-line + position: absolute + float: left + background-color: blue + +.active-selection-mode + .timeline-element.relation-line + background-color: #cacaca !important diff --git a/frontend/app/components/wp-table/timeline/cell-renderer/timeline-cell-renderer.ts b/frontend/app/components/wp-table/timeline/cell-renderer/timeline-cell-renderer.ts index ee3e29313e..caa61164b6 100644 --- a/frontend/app/components/wp-table/timeline/cell-renderer/timeline-cell-renderer.ts +++ b/frontend/app/components/wp-table/timeline/cell-renderer/timeline-cell-renderer.ts @@ -112,6 +112,13 @@ export class TimelineCellRenderer { renderInfo: RenderInfo, elem: HTMLElement): "left" | "right" | "both" | "dragright" | "create" { + // check for active selection mode + if (renderInfo.viewParams.activeSelectionMode) { + renderInfo.viewParams.activeSelectionMode(renderInfo.workPackage); + ev.preventDefault(); + return "both"; // irrelevant + } + renderInfo.workPackage.storePristine('startDate'); renderInfo.workPackage.storePristine('dueDate'); let direction: "left" | "right" | "both" | "create" | "dragright"; @@ -223,6 +230,11 @@ export class TimelineCellRenderer { bar.style.minWidth = "30px"; } + // check for active selection mode + if (renderInfo.viewParams.activeSelectionMode) { + bar.style.backgroundImage = null; // required! unable to disable "fade out bar" with css + } + return true; } diff --git a/frontend/app/components/wp-table/timeline/wp-timeline-container.directive.ts b/frontend/app/components/wp-table/timeline/wp-timeline-container.directive.ts index 9028cb9907..eb3555216d 100644 --- a/frontend/app/components/wp-table/timeline/wp-timeline-container.directive.ts +++ b/frontend/app/components/wp-table/timeline/wp-timeline-container.directive.ts @@ -27,17 +27,20 @@ // ++ import {openprojectModule} from "../../../angular-modules"; import {TimelineViewParameters, RenderInfo, timelineElementCssClass} from "./wp-timeline"; -import {WorkPackageResourceInterface} from "./../../api/api-v3/hal-resources/work-package-resource.service"; -import {HalRequestService} from '../../api/api-v3/hal-request/hal-request.service'; +import { + WorkPackageResourceInterface, + WorkPackageResource +} from "./../../api/api-v3/hal-resources/work-package-resource.service"; +import {HalRequestService} from "../../api/api-v3/hal-request/hal-request.service"; import {WpTimelineHeader} from "./wp-timeline.header"; import {States} from "./../../states.service"; import {BehaviorSubject, Observable} from "rxjs"; -import * as moment from 'moment'; +import * as moment from "moment"; +import {WpTimelineGlobalService} from "./wp-timeline-global.directive"; +import {opDimensionEventName} from "../../common/ui/detect-dimension-changes.directive"; import Moment = moment.Moment; import IDirective = angular.IDirective; import IScope = angular.IScope; -import { WpTimelineGlobalService } from "./wp-timeline-global.directive"; -import { opDimensionEventName } from "../../common/ui/detect-dimension-changes.directive"; export class WorkPackageTimelineTableController { @@ -87,6 +90,16 @@ export class WorkPackageTimelineTableController { // TODO: Load only necessary types from API TypeResource.loadAll(); + + // TODO ////////////////////////////////////// + (window as any).tt = () => { + this.activateSelectionMode(endWorkPackage => { + console.log("done", endWorkPackage.id); + }); + }; + setTimeout(() => { + (window as any).tt(); + }, 3000); } /** @@ -152,6 +165,18 @@ export class WorkPackageTimelineTableController { ); } + activateSelectionMode(callback: (wp: WorkPackageResource) => any) { + this._viewParameters.activeSelectionMode = (wp: WorkPackageResource) => { + callback(wp); + this._viewParameters.activeSelectionMode = null; + this.$element.removeClass("active-selection-mode"); + this.refreshView(); + }; + this.$element.addClass("active-selection-mode"); + console.log(this.$element); + this.refreshView(); + } + private calculateViewParams(currentParams: TimelineViewParameters): boolean { if (this.disableViewParamsCalculation) { return false; diff --git a/frontend/app/components/wp-table/timeline/wp-timeline-global.directive.ts b/frontend/app/components/wp-table/timeline/wp-timeline-global.directive.ts index 5e186fd98f..0bc8fe8de3 100644 --- a/frontend/app/components/wp-table/timeline/wp-timeline-global.directive.ts +++ b/frontend/app/components/wp-table/timeline/wp-timeline-global.directive.ts @@ -1,4 +1,3 @@ - // -- copyright // OpenProject is a project management system. // Copyright (C) 2012-2017 the OpenProject Foundation (OPF) @@ -39,7 +38,7 @@ import {WorkPackageResource} from "../../api/api-v3/hal-resources/work-package-r import IScope = angular.IScope; -export const timelineGlobalElementCssClassname = 'timeline-global-element'; +export const timelineGlobalElementCssClassname = "relation-line"; function newSegment(vp: TimelineViewParameters, classId: string, @@ -50,11 +49,11 @@ function newSegment(vp: TimelineViewParameters, height: number): HTMLElement { const segment = document.createElement('div'); - segment.classList.add(timelineElementCssClass, timelineGlobalElementCssClassname, classId); - segment.style.position = 'absolute'; - segment.style.cssFloat = 'left'; - segment.style.backgroundColor = 'blue'; - // segment.style.backgroundColor = color; + segment.classList.add( + timelineElementCssClass, + timelineGlobalElementCssClassname, + classId); + segment.style.marginLeft = vp.scrollOffsetInPx + 'px'; segment.style.top = top + 'px'; segment.style.left = left + 'px'; @@ -97,16 +96,16 @@ export class WpTimelineGlobalService { halRequest.get( '/api/v3/relations', { - filter: [{ involved: {operator: '=', values: this.workPackageIdOrder } }] + filter: [{involved: {operator: '=', values: this.workPackageIdOrder}}] }).then((collection: CollectionResource) => { - this.removeAllElements(); - collection.elements.forEach((relation: RelationResource) => { - const fromId = WorkPackageResource.idFromLink(relation.from.href!); - const toId = WorkPackageResource.idFromLink(relation.to.href!); - this.displayRelation(fromId, toId); - }); - this.renderElements(); + this.removeAllElements(); + collection.elements.forEach((relation: RelationResource) => { + const fromId = WorkPackageResource.idFromLink(relation.from.href!); + const toId = WorkPackageResource.idFromLink(relation.to.href!); + this.displayRelation(fromId, toId); }); + this.renderElements(); + }); }); } diff --git a/frontend/app/components/wp-table/timeline/wp-timeline.ts b/frontend/app/components/wp-table/timeline/wp-timeline.ts index d60a405e9a..a6146e32a8 100644 --- a/frontend/app/components/wp-table/timeline/wp-timeline.ts +++ b/frontend/app/components/wp-table/timeline/wp-timeline.ts @@ -26,7 +26,10 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ import * as moment from "moment"; -import {WorkPackageResourceInterface} from "../../api/api-v3/hal-resources/work-package-resource.service"; +import { + WorkPackageResourceInterface, + WorkPackageResource +} from "../../api/api-v3/hal-resources/work-package-resource.service"; import {WpTimelineHeader} from "./wp-timeline.header"; import Moment = moment.Moment; @@ -65,6 +68,8 @@ export class TimelineViewParameters { timelineHeader: WpTimelineHeader; + activeSelectionMode: null|((wp: WorkPackageResource) => any) = null; + get pixelPerDay() { switch (this.settings.zoomLevel) { case ZoomLevel.DAYS: