POC for interactive selection mode

pull/5261/head
Roman Roelofsen 8 years ago
parent f06fdccf53
commit a0c6b2c8d7
  1. 1
      app/assets/stylesheets/content/work_packages/timelines/_timelines.sass
  2. 42
      app/assets/stylesheets/content/work_packages/timelines/elements/_bar.sass
  3. 6
      app/assets/stylesheets/content/work_packages/timelines/elements/_milestone.sass
  4. 8
      app/assets/stylesheets/content/work_packages/timelines/elements/_relation.sass
  5. 12
      frontend/app/components/wp-table/timeline/cell-renderer/timeline-cell-renderer.ts
  6. 35
      frontend/app/components/wp-table/timeline/wp-timeline-container.directive.ts
  7. 29
      frontend/app/components/wp-table/timeline/wp-timeline-global.directive.ts
  8. 7
      frontend/app/components/wp-table/timeline/wp-timeline.ts

@ -1,6 +1,7 @@
@import '_slider'
@import 'elements/_bar'
@import 'elements/_milestone'
@import 'elements/_relation'
.wp-timeline--th
min-width: 600px !important

@ -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%

@ -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

@ -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

@ -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;
}

@ -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;

@ -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();
});
});
}

@ -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:

Loading…
Cancel
Save