diff --git a/src/app/@ansyn/ansyn/ansyn/ansyn.component.less b/src/app/@ansyn/ansyn/ansyn/ansyn.component.less index eb700aa97d..828516a79e 100644 --- a/src/app/@ansyn/ansyn/ansyn/ansyn.component.less +++ b/src/app/@ansyn/ansyn/ansyn/ansyn.component.less @@ -74,7 +74,7 @@ width: 100%; position: relative; overflow: hidden; - flex-direction: row; + flex-direction: column; background: @background-color-0; div.menu { @@ -82,11 +82,7 @@ } div.status { - position: absolute; - top: 0; - right: 0; width: 100%; - height: @status-bar-height; z-index: @z-index-status-bar-navigation-area; &.expand { @@ -101,13 +97,10 @@ div.layer { width: 100%; - height: calc(100% - @status-bar-height - @timeline-area-height); - top: @status-bar-height; color: white; + flex: 1; display: flex; - flex-direction: column; overflow: hidden; - position: relative; &.isCollapse { height: calc(100% - @status-bar-height); @@ -125,8 +118,6 @@ } div.footer { - position: absolute; - bottom: 0; width: 100%; z-index: @z-index-footer; } @@ -136,7 +127,7 @@ div.menu { animation: menu-init-rtl @animation-duration; transform: transitionX(0); - position: relative; + position: absolute; height: 100%; &.isCollapse { @@ -256,7 +247,7 @@ /deep/ .mat-slide-toggle.mat-checked .mat-slide-toggle-label { color: lightgreen !important; -} +} /deep/ .mat-slide-toggle-label { font-size: larger !important; diff --git a/src/app/@ansyn/ansyn/components/ansyn-footer/ansyn-footer.component.html b/src/app/@ansyn/ansyn/components/ansyn-footer/ansyn-footer.component.html index 495c7dbc5d..c908420467 100644 --- a/src/app/@ansyn/ansyn/components/ansyn-footer/ansyn-footer.component.html +++ b/src/app/@ansyn/ansyn/components/ansyn-footer/ansyn-footer.component.html @@ -1,12 +1,4 @@ -
- +
diff --git a/src/app/@ansyn/ansyn/components/ansyn-footer/ansyn-footer.component.ts b/src/app/@ansyn/ansyn/components/ansyn-footer/ansyn-footer.component.ts index c1476b4737..b250cab8a9 100644 --- a/src/app/@ansyn/ansyn/components/ansyn-footer/ansyn-footer.component.ts +++ b/src/app/@ansyn/ansyn/components/ansyn-footer/ansyn-footer.component.ts @@ -61,7 +61,7 @@ export class AnsynFooterComponent implements OnInit, OnDestroy { } this.collapse = collapse; - this.wrapperElement.nativeElement.classList.toggle('collapsed'); + this.wrapperElement.nativeElement.style.height = `${this.collapse ? '0px' : ''}`; this.forceRedraw() .then(() => this.store.dispatch(new ContainerChangedTriggerAction())); diff --git a/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts b/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts index df315a38ce..3d20363103 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/actions/status-bar.actions.ts @@ -5,6 +5,7 @@ import { IAdvancedSearchParameter } from '../models/statusBar-config.model'; import { IOverlaysCriteria } from '../../overlays/models/overlay.model'; export const StatusBarActionsTypes = { + TOGGLE_STATUS_BAR: 'TOGGLE_STATUS_BAR', SHOW_LINK_COPY_TOAST: 'SHOW_LINK_COPY_TOAST', COPY_SNAPSHOT_SHARE_LINK: 'COPY_SNAPSHOT_SHARE_LINK', EXPAND: 'EXPAND', @@ -97,9 +98,19 @@ export class SearchAction implements Action { } } +export class ToggleStatusBar implements Action, ILogMessage { + readonly type = StatusBarActionsTypes.TOGGLE_STATUS_BAR; + constructor(public payload: boolean) { + } + + logMessage() { + return `user is ${this.payload? 'show' : 'hide'} the status bar` + } +} export type StatusBarActions = CopySnapshotShareLinkAction | UpdateGeoFilterStatus | ExpandAction | MarkSecondSearchSensorsAction + | ToggleStatusBar diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/search-options/search-options.component.html b/src/app/@ansyn/ansyn/modules/status-bar/components/search-options/search-options.component.html index ebdc201392..ae3a0e7654 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/search-options/search-options.component.html +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/search-options/search-options.component.html @@ -6,8 +6,8 @@ >
-
-
+
+
diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/search-options/search-options.component.less b/src/app/@ansyn/ansyn/modules/status-bar/components/search-options/search-options.component.less index 6666582169..38e1cfb831 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/search-options/search-options.component.less +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/search-options/search-options.component.less @@ -5,9 +5,10 @@ :host { margin: 2px; display: flex; + flex-direction: column; align-items: center; - .search-icon { + .search-icon { border-radius: 50px; background: @background-color-6; padding: 5px 10px; @@ -17,16 +18,15 @@ } .presets { - background-color: rgba(23, 23, 23, 1); - position: absolute; - top: 102%; - min-height: 90px; - margin-bottom: 9px !important; - border-radius: 30px; - opacity: 0.9; - right: 5%; - display: flex; - + display: flex; + position: absolute; + top: 60px; + div { + background-color: rgba(23, 23, 23, 1); + min-height: 90px; + border-radius: 30px; + opacity: 0.9; + } } diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.html b/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.html index c5e9b664fe..eaf4de2022 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.html +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.html @@ -1,4 +1,5 @@ -
+
+
+
diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.less b/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.less index 667eea1e5e..d49da146b4 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.less +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.less @@ -4,50 +4,52 @@ @popup-padding-bottom: 15px; :host { - background-color: @status-bar-background; - height: @status-bar-height; - display: flex; - color: white; - - div.cases { + .status-container { + background-color: @status-bar-background; display: flex; - justify-content: center; - align-items: center; - padding-right: 10px; - div { - button { - width: 34px; - height: 34px; - margin: 0 5px; - padding: 1px; - border-radius: 3px; - background-color: #4c4c4c; - color: white; - outline: none; - border: none; - display: inline-flex; - justify-content: center; - align-items: center; - - i.icon { - margin: unset; - margin-top: 2px; - } + color: white; + + div.cases { + display: flex; + justify-content: center; + align-items: center; + padding-right: 10px; - &.favorite-button:disabled { - opacity: .6; + div { + button { + width: 34px; + height: 34px; + margin: 0 5px; + padding: 1px; + border-radius: 3px; + background-color: #4c4c4c; + color: white; + outline: none; + border: none; + display: inline-flex; + justify-content: center; + align-items: center; + + i.icon { + margin: unset; + margin-top: 2px; + } + + &.favorite-button:disabled { + opacity: .6; + } } } } - } - div.search { - display: flex; - flex: 1; - align-items: center; - } + div.search { + display: flex; + flex: 1; + align-items: center; + } - div.logo { - display: flex; + div.logo { + display: flex; + } } } diff --git a/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.ts b/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.ts index 9858436a3e..6ef346ea32 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/components/status-bar/status-bar.component.ts @@ -1,4 +1,4 @@ -import { Component, Inject, Input, OnDestroy, OnInit } from '@angular/core'; +import { Component, ElementRef, Inject, Input, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { ComponentVisibilityItems } from '../../../../app-providers/component-mode'; import { ComponentVisibilityService } from '../../../../app-providers/component-visibility.service'; import { UpdateFacetsAction } from '../../../filters/actions/filters.actions'; @@ -6,9 +6,12 @@ import { SelectMenuItemFromOutsideAction } from '@ansyn/menu'; import { MenuItemsKeys } from '../../../../config/ansyn.config'; import { selectEnableOnlyFavorites, selectShowOnlyFavorites } from '../../../filters/reducer/filters.reducer'; import { select, Store } from '@ngrx/store'; -import { distinctUntilChanged, map, tap } from 'rxjs/operators'; +import { distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators'; import { AutoSubscription, AutoSubscriptions } from 'auto-subscriptions'; -import { selectFourViewsMode } from '@ansyn/map-facade'; +import { selectFourViewsMode, UpdateMapSizeAction } from '@ansyn/map-facade'; +import { selectStatusBarVisibilityState } from '../../reducers/status-bar.reducer'; +import { ToggleStatusBar } from '../../actions/status-bar.actions'; +import { from } from 'rxjs'; @Component({ selector: 'ansyn-status-bar', @@ -26,14 +29,22 @@ export class StatusBarComponent implements OnInit, OnDestroy { readonly isToolsLineShow: boolean; // onlyFavorite: boolean; + @ViewChild('wrappedElement', {static: true}) wrapperElement: ElementRef; @Input() version; + visibilityState: boolean; onlyFavoriteEnable$ = this.store.pipe( select(selectEnableOnlyFavorites), distinctUntilChanged(), map((enable) => !enable) ); + @AutoSubscription + onChangeVisibilityState$ = this.store.select(selectStatusBarVisibilityState).pipe( + switchMap(this.onChangeVisibilityState.bind(this)), + tap( () => this.store.dispatch(new UpdateMapSizeAction())) + ); + @AutoSubscription onlyFavoriteSelected$ = this.store.pipe( select(selectShowOnlyFavorites), @@ -45,6 +56,7 @@ export class StatusBarComponent implements OnInit, OnDestroy { constructor( protected store: Store, + protected el: ElementRef, componentVisibilityService: ComponentVisibilityService ) { this.isSplitMapsShow = componentVisibilityService.get(ComponentVisibilityItems.SCREENS); @@ -74,4 +86,19 @@ export class StatusBarComponent implements OnInit, OnDestroy { })) } + onChangeVisibilityState(state) { + this.visibilityState = state; + const opacity = state ? 1 : 0; + const visibility = state ? 'visible' : 'hidden'; + const height = state ? '' : '0'; + this.wrapperElement.nativeElement.style.height = height; + let animate = this.el.nativeElement.animate([ + {opacity, visibility} + ], {duration: 250, fill: 'forwards'}) + return from(animate.finished) + } + + toggleStatusBar() { + this.store.dispatch(new ToggleStatusBar(!this.visibilityState)); + } } diff --git a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts index 6e6e164fc8..3b0d2da8e8 100644 --- a/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts +++ b/src/app/@ansyn/ansyn/modules/status-bar/reducers/status-bar.reducer.ts @@ -8,6 +8,7 @@ export interface IGeoFilterStatus { } export interface IStatusBarState { + visibilityState: boolean; geoFilterStatus?: IGeoFilterStatus; isCalenderOpen?: boolean; isAdvancedSearchOpen?: boolean; @@ -17,6 +18,7 @@ export interface IStatusBarState { } export const StatusBarInitialState: IStatusBarState = { + visibilityState: true, geoFilterStatus: { type: CaseGeoFilter.PinPoint, active: false @@ -33,6 +35,9 @@ export const statusBarStateSelector: MemoizedSelector = cr export function StatusBarReducer(state = StatusBarInitialState, action: StatusBarActions | any): IStatusBarState { switch (action.type) { + case StatusBarActionsTypes.TOGGLE_STATUS_BAR: + return { ...state, visibilityState: action.payload}; + case StatusBarActionsTypes.UPDATE_GEO_FILTER_STATUS: { const { payload } = action; if ( payload ) { @@ -69,6 +74,7 @@ export function StatusBarReducer(state = StatusBarInitialState, action: StatusBa } } +export const selectStatusBarVisibilityState = createSelector(statusBarStateSelector, (statusbar: IStatusBarState) => statusbar?.visibilityState); export const selectGeoFilterStatus = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.geoFilterStatus : StatusBarInitialState.geoFilterStatus); export const selectCalenderStatus = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.isCalenderOpen : StatusBarInitialState.isCalenderOpen); export const selectAdvancedSearchStatus = createSelector(statusBarStateSelector, (statusBar: IStatusBarState) => statusBar ? statusBar.isAdvancedSearchOpen : StatusBarInitialState.isAdvancedSearchOpen); diff --git a/src/app/@ansyn/ansyn/public_api.ts b/src/app/@ansyn/ansyn/public_api.ts index f25e34a37c..2071e94acd 100644 --- a/src/app/@ansyn/ansyn/public_api.ts +++ b/src/app/@ansyn/ansyn/public_api.ts @@ -45,7 +45,8 @@ export { IAddressConfig } from './modules/status-bar/models/address-config.model export { statusBarFeatureKey, StatusBarInitialState, - StatusBarReducer + StatusBarReducer, + selectStatusBarVisibilityState } from './modules/status-bar/reducers/status-bar.reducer'; export { statusBarStateSelector } from './modules/status-bar/reducers/status-bar.reducer'; export { comboBoxesOptions } from './modules/status-bar/models/combo-boxes.model'; diff --git a/src/app/@ansyn/map-facade/directives/minimize.directive.ts b/src/app/@ansyn/map-facade/directives/minimize.directive.ts new file mode 100644 index 0000000000..49db1eb751 --- /dev/null +++ b/src/app/@ansyn/map-facade/directives/minimize.directive.ts @@ -0,0 +1,84 @@ +import { AfterViewInit, Directive, ElementRef, EventEmitter, Input, Output } from '@angular/core'; +import { Store } from '@ngrx/store'; + +@Directive({ + selector: '[ansynMinimize]' +}) +export class MinimizeDirective implements AfterViewInit { + readonly btn: HTMLButtonElement = document.createElement('button'); + readonly iconDiv: HTMLDivElement = document.createElement('div'); + @Output() onToggle = new EventEmitter(); + private _startDegRotate = 0; + private _endDegRotate = 180; + private _toTop: boolean; + @Input() set toTop(val: boolean) { + this._toTop = val; + this._startDegRotate = val ? 180 : 0; + this._endDegRotate = val ? 0 : 180; + this.btn.setAttribute('tooltip-class', this._toTop ? 'bottom' : 'top'); + }; + + topOffset: number; + _minimize = false; + + get minimize() { + return this._minimize; + } + + set minimize(mini) { + this._minimize = mini; + this.btn.setAttribute('tooltip-value', this._minimize ? 'show' : 'hide'); + this.iconDiv.style.transform = `rotateX(${ this.minimize ? this._endDegRotate : this._startDegRotate }deg)`; + this.updatePositionStyle() + }; + + constructor(private el: ElementRef) { + this.iconDiv.innerHTML = ``; + this.iconDiv.style.transform = `rotateX(${this._startDegRotate}deg)`; + this.btn.appendChild(this.iconDiv); + this.btn.setAttribute('tooltip-class', /* default */ 'top'); + this.btn.onclick = this.toggle.bind(this); + this.el.nativeElement.appendChild(this.btn); + } + + ngAfterViewInit() { + this.minimize = false; + this.updateStyle(); + } + + toggle() { + this.minimize = !this.minimize; + this.onToggle.emit(); + } + + private updatePositionStyle() { + const offset = this.minimize ? '0' : `${this.topOffset}px`; + const keyFrames = {[this._toTop ? 'top' : 'bottom']: offset}; + this.btn.animate([keyFrames], {duration: 150, fill: 'forwards'}) + } + private updateStyle() { + this.btn.style.position = 'absolute'; + this.btn.style.left = '50%'; + this.btn.style.width = '50px'; + this.btn.style.color = 'white'; + this.btn.style.transform = 'translateX(-50%)'; + this.btn.style.border = 'none'; + this.btn.style.borderRadius = '10%'; + this.btn.style.boxShadow = '2px 0 4px -2px black'; + this.btn.style.outline = 'none'; + this.btn.style.transition = '.5s'; + this.btn.style.zIndex = '1000'; + this.btn.style.visibility = 'visible'; + this.btn.style.background = '#0e0e0e'; + + const parentHeight = this.el.nativeElement.offsetHeight; + const btnHeight = this.btn.offsetHeight; + this.topOffset = parentHeight - (btnHeight / 2); + if (this._toTop) { + this.btn.style.top = this.minimize ? '0' : `${this.topOffset}px`; + }else { + this.btn.style.bottom = this.minimize ? '0' : `${this.topOffset}px`; + } + } +} + diff --git a/src/app/@ansyn/map-facade/map-facade.module.ts b/src/app/@ansyn/map-facade/map-facade.module.ts index 89a53d6112..c93be2c9a7 100644 --- a/src/app/@ansyn/map-facade/map-facade.module.ts +++ b/src/app/@ansyn/map-facade/map-facade.module.ts @@ -35,6 +35,7 @@ import { MatAutocompleteModule } from '@angular/material/autocomplete'; import { MatInputModule } from '@angular/material/input'; import { InfiniteScrollDirective } from './directives/infinite-scroll.directive'; import { AnsynDatePipe } from './pipes/ansyn-date.pipe'; +import { MinimizeDirective } from './directives/minimize.directive'; @NgModule({ imports: [ @@ -72,7 +73,8 @@ import { AnsynDatePipe } from './pipes/ansyn-date.pipe'; GeoHolderComponent, UtmHolderComponent, FloatingMenuComponent, - AnsynDatePipe + AnsynDatePipe, + MinimizeDirective ], exports: [ ImageriesManagerComponent, @@ -86,7 +88,8 @@ import { AnsynDatePipe } from './pipes/ansyn-date.pipe'; EntryComponentDirective, GeoHolderComponent, UtmHolderComponent, - AnsynDatePipe + AnsynDatePipe, + MinimizeDirective ] })