Make autozoom a regular zoom level option

pull/7182/head
Oliver Günther 6 years ago
parent e7cf1986e6
commit 80dfe61339
No known key found for this signature in database
GPG Key ID: A3A8BDAD7C0C552C
  1. 2
      app/models/query/timelines.rb
  2. 11
      db/migrate/20190411122815_set_timeline_auto_zoom.rb
  3. 7
      frontend/src/app/components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.component.ts
  4. 4
      frontend/src/app/components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.html
  5. 38
      frontend/src/app/components/wp-fast-table/state/wp-table-timeline.service.ts
  6. 2
      frontend/src/app/components/wp-fast-table/wp-table-timeline.ts
  7. 10
      frontend/src/app/components/wp-table/configuration-modal/tabs/timelines-tab.component.ts
  8. 14
      frontend/src/app/components/wp-table/timeline/container/wp-timeline-container.directive.ts
  9. 4
      frontend/src/app/components/wp-table/timeline/header/wp-timeline-header.directive.ts
  10. 2
      frontend/src/app/components/wp-table/timeline/wp-timeline.ts
  11. 2
      frontend/src/app/modules/hal/resources/query-resource.ts
  12. 19
      spec/features/work_packages/timeline/timeline_navigation_spec.rb
  13. 4
      spec/support/pages/work_packages/work_packages_timeline.rb

@ -31,7 +31,7 @@ module Query::Timelines
extend ActiveSupport::Concern
included do
enum timeline_zoom_level: %i(days weeks months quarters years)
enum timeline_zoom_level: %i(days weeks months quarters years auto)
validates :timeline_zoom_level, inclusion: { in: timeline_zoom_levels.keys }
serialize :timeline_labels, Hash

@ -0,0 +1,11 @@
class SetTimelineAutoZoom < ActiveRecord::Migration[5.2]
def up
Query.where(timeline_zoom_level: :days).update_all(timeline_zoom_level: :auto)
change_column_default :queries, :timeline_zoom_level, 5
end
def down
Query.where(timeline_zoom_level: :auto).update_all(timeline_zoom_level: :days)
change_column_default :queries, :timeline_zoom_level, 0
end
end

@ -83,7 +83,7 @@ export class WorkPackageTimelineButtonComponent extends AbstractWorkPackageButto
return this.wpTableTimeline.isVisible;
}
public isAutoZoom() {
public get isAutoZoom() {
return this.wpTableTimeline.isAutoZoom();
}
@ -104,11 +104,10 @@ export class WorkPackageTimelineButtonComponent extends AbstractWorkPackageButto
}
public enableAutoZoom() {
this.wpTableTimeline.toggleAutoZoomEnabled(true);
this.wpTableTimeline.toggleAutoZoom(true);
this.wpTableTimeline.enableAutozoom();
}
public getAutoZoomToggleClass():string {
return this.isAutoZoom() ? '-disabled' : '';
return this.isAutoZoom ? '-disabled' : '';
}
}

@ -15,7 +15,7 @@
<button id="work-packages-timeline-zoom-out-button"
class="button timeline-toolbar--button toolbar-icon"
[attr.title]="text.zoomOut"
[disabled]="currentZoom == maxZoomLevel"
[disabled]="!isAutoZoom && currentZoom == maxZoomLevel"
(click)="updateZoomWithDelta(1)">
<op-icon icon-classes="icon-zoom-out button--icon"></op-icon>
</button>
@ -25,7 +25,7 @@
<button id="work-packages-timeline-zoom-in-button"
class="button timeline-toolbar--button toolbar-icon"
[attr.title]="text.zoomIn"
[disabled]="currentZoom == minZoomLevel"
[disabled]="!isAutoZoom && currentZoom == minZoomLevel"
(click)="updateZoomWithDelta(-1)">
<op-icon icon-classes="icon-zoom-in button--icon"></op-icon>
</button>

@ -74,18 +74,6 @@ export class WorkPackageTableTimelineService extends WorkPackageQueryStateServic
public toggle() {
let currentState = this.current;
this.setVisible(!currentState.visible);
if (this.isAutoZoomEnabled() === undefined) {
this.toggleAutoZoomEnabled(true);
}
/**
* On first opening, activate auto zoom.
* Afterwards keep the zoom level.
*/
if (!currentState.visible && this.isAutoZoomEnabled()) {
this.toggleAutoZoom(true);
}
}
public setVisible(value:boolean) {
@ -136,8 +124,12 @@ export class WorkPackageTableTimelineService extends WorkPackageQueryStateServic
}
public updateZoomWithDelta(delta:number) {
this.toggleAutoZoom(false);
if (this.isAutoZoom()) {
const target = delta < 0 ? 'days' : 'years';
this.setZoomLevel(target);
return;
}
let idx = zoomLevelOrder.indexOf(this.current.zoomLevel);
idx += delta;
@ -146,20 +138,12 @@ export class WorkPackageTableTimelineService extends WorkPackageQueryStateServic
}
}
public toggleAutoZoom(value = !this.current.autoZoom) {
this.modify({ autoZoom: value });
}
public isAutoZoom():boolean {
return this.current.autoZoom;
}
public isAutoZoomEnabled():boolean|undefined {
return this.current.autoZoomEnabled;
return this.current.zoomLevel === 'auto';
}
public toggleAutoZoomEnabled(val = !this.current.autoZoomEnabled) {
this.modify({ autoZoomEnabled: val });
public enableAutozoom() {
this.modify({ zoomLevel: "auto" });
}
public get current():WorkPackageTableTimelineState {
@ -184,9 +168,7 @@ export class WorkPackageTableTimelineService extends WorkPackageQueryStateServic
private get defaultState():WorkPackageTableTimelineState {
return {
autoZoom: false,
autoZoomEnabled: undefined,
zoomLevel: 'days',
zoomLevel: 'auto',
visible: false,
labels: this.defaultLabels
};

@ -32,8 +32,6 @@ import {
} from 'core-app/modules/hal/resources/query-resource';
export interface WorkPackageTableTimelineState {
autoZoom:boolean;
autoZoomEnabled:boolean|undefined;
visible:boolean;
zoomLevel:TimelineZoomLevel;
labels:TimelineLabels;

@ -19,7 +19,10 @@ export class WpTableConfigurationTimelinesTab implements TabComponent {
public availableLabels:string[];
public zoomLevel:TimelineZoomLevel;
public availableZoomLevels = zoomLevelOrder;
// Manualy build available zoom levels with zoom
// because it is not part of the order.
public availableZoomLevels:TimelineZoomLevel[] = ['auto', ...zoomLevelOrder];
public text = {
title: this.I18n.t('js.timelines.gantt_chart'),
@ -33,7 +36,7 @@ export class WpTableConfigurationTimelinesTab implements TabComponent {
months: this.I18n.t('js.timelines.zoom.months'),
quarters: this.I18n.t('js.timelines.zoom.quarters'),
years: this.I18n.t('js.timelines.zoom.years'),
autozoom: this.I18n.t('js.timelines.zoom.auto')
auto: this.I18n.t('js.timelines.zoom.auto')
},
labels: {
title: this.I18n.t('js.timelines.labels.title'),
@ -53,9 +56,8 @@ export class WpTableConfigurationTimelinesTab implements TabComponent {
}
public onSave() {
this.wpTableTimeline.toggleAutoZoom(false);
let current = this.wpTableTimeline.current;
current.visible = this.timelineVisible
current.visible = this.timelineVisible;
current.labels = this.labels;
current.zoomLevel = this.zoomLevel;
this.wpTableTimeline.state.putValue(current);

@ -149,8 +149,6 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest
takeUntil(componentDestroyed(this))
)
.subscribe((timelineState:WorkPackageTableTimelineState) => {
this.viewParameters.settings.autoZoom = timelineState.autoZoom;
this.viewParameters.settings.zoomLevel = timelineState.zoomLevel;
this.refreshRequest.putValue(undefined);
});
}
@ -214,12 +212,13 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest
return;
}
if (this.wpTableTimeline.isAutoZoomEnabled()) {
if (this.wpTableTimeline.isAutoZoom()) {
// Update autozoom level
this.applyAutoZoomLevel();
} else {
this._viewParameters.settings.zoomLevel = this.wpTableTimeline.zoomLevel;
}
// Require dynamic CSS to be visible
this.dynamicCssService.requireHighlighting();
@ -423,15 +422,10 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest
}
private applyAutoZoomLevel() {
if (this.workPackageTable.configuration.isEmbedded || !this.viewParameters.settings.autoZoom) {
return;
}
if (this.workPackageIdOrder.length === 0) {
return;
}
this.wpTableTimeline.toggleAutoZoomEnabled(false);
const daysSpan = calculateDaySpan(this.workPackageIdOrder, this.states.workPackages, this._viewParameters);
const timelineWidthInPx = this.$element.parent().width()! - (2 * requiredPixelMarginLeft);
@ -445,7 +439,7 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest
// did the zoom level changed?
if (previousZoomLevel !== zoomLevel) {
this.wpTableTimeline.setZoomLevel(zoomLevel);
this._viewParameters.settings.zoomLevel = zoomLevel;
this.wpTableDirective.timeline.scrollLeft = 0;
}
return;

@ -33,6 +33,7 @@ import * as moment from 'moment';
import {calculatePositionValueForDayCount, getTimeSlicesForHeader, TimelineViewParameters} from '../wp-timeline';
import Moment = moment.Moment;
import {I18nService} from "core-app/modules/common/i18n/i18n.service";
import {WorkPackageTableTimelineService} from "core-components/wp-fast-table/state/wp-table-timeline.service";
export const timelineHeaderCSSClass = 'wp-timeline--header-element';
@ -51,6 +52,7 @@ export class WorkPackageTimelineHeaderController implements OnInit {
constructor(elementRef:ElementRef,
readonly I18n:I18nService,
readonly wpTimelineService:WorkPackageTableTimelineService,
readonly workPackageTimelineTableController:WorkPackageTimelineTableController) {
this.$element = jQuery(elementRef.nativeElement);
@ -72,7 +74,7 @@ export class WorkPackageTimelineHeaderController implements OnInit {
}
this.innerHeader.empty();
this.innerHeader.attr('data-current-zoom-level', vp.settings.zoomLevel);
this.innerHeader.attr('data-current-zoom-level', this.wpTimelineService.zoomLevel);
switch (vp.settings.zoomLevel) {
case 'days':

@ -44,8 +44,6 @@ export class TimelineViewParametersSettings {
zoomLevel:TimelineZoomLevel = 'days';
autoZoom:boolean = true;
}
// Can't properly map the enum to a string aray

@ -44,7 +44,7 @@ export interface QueryResourceEmbedded {
filters:QueryFilterInstanceResource[];
}
export type TimelineZoomLevel = 'days'|'weeks'|'months'|'quarters'|'years';
export type TimelineZoomLevel = 'days'|'weeks'|'months'|'quarters'|'years'|'auto';
export interface TimelineLabels {
left:string|null;

@ -126,8 +126,13 @@ RSpec.feature 'Work package timeline navigation', js: true, selenium: true do
# Should have an active element rendered
wp_timeline.expect_timeline_element(work_package)
# Expect zoom at days
# Expect zoom out from auto to days
wp_timeline.expect_zoom_at :auto
# Zooming in = days
wp_timeline.zoom_in
wp_timeline.expect_zoom_at :days
# From there, zoom behaves normally
wp_timeline.zoom_out
wp_timeline.expect_zoom_at :weeks
@ -138,6 +143,7 @@ RSpec.feature 'Work package timeline navigation', js: true, selenium: true do
# Check the query
query = Query.last
expect(query.timeline_visible).to be_truthy
expect(query.timeline_zoom_level).to eq 'weeks'
# Revisit page
wp_timeline.visit_query query
@ -147,6 +153,17 @@ RSpec.feature 'Work package timeline navigation', js: true, selenium: true do
# Expect zoom at weeks
wp_timeline.expect_zoom_at :weeks
# Go back to autozoom
wp_timeline.autozoom
wp_timeline.expect_zoom_at :auto
# Save
wp_timeline.save
wp_timeline.expect_and_dismiss_notification message: 'Successful update'
query.reload
expect(query.timeline_zoom_level).to eq 'auto'
end
describe 'with a hierarchy being shown' do

@ -95,6 +95,10 @@ module Pages
page.find('#work-packages-timeline-zoom-out-button').click
end
def autozoom
page.find('#work-packages-timeline-zoom-auto-button').click
end
def expect_zoom_at(value)
unless ::Query.timeline_zoom_levels.key?(value)
raise ArgumentError, "Invalid value"

Loading…
Cancel
Save