File

src/app/campaigns/campaign-editor.ts

Extends

Compbaser

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector campaign-editor
styles .btn.active.focus, .btn.active:focus, .btn.focus, .btn:active.focus, .btn:active:focus, .btn:focus { outline: 0; } label { border-radius: 0px; }
templateUrl ./campaign-editors.html

Outputs

onGoBack $event type: EventEmitter<any>
onToAddContent $event type: EventEmitter<any>
onToAddTimeline $event type: EventEmitter<any>
onToScreenLayoutEditor $event type: EventEmitter<any>

Constructor

constructor(yp: YellowPepperService, actions: AppdbAction, rp: RedPepperService, cd: ChangeDetectorRef)

Methods

_onAddContent
_onAddContent()
Returns : void
_timelineDurationChange
_timelineDurationChange(i_duration: any)
Returns : void
_campaignStoryTimelineCmd
_campaignStoryTimelineCmd(i_cmd: any)
Returns : void
_onStateChanged
_onStateChanged(state: ITimelineState)
Returns : void
_onRemoveTimeline
_onRemoveTimeline()
Returns : void
_changeZoom
_changeZoom(value: any)
Returns : void
_onTimelineViewMode
_onTimelineViewMode(i_mode: StoryBoardListViewModeEnum)
Returns : void
_onAddTimeline
_onAddTimeline()
Returns : void
_onEditScreenLayout
_onEditScreenLayout()
Returns : void
_onRemoveContent
_onRemoveContent()

Delete the selected block from the channel


Returns : void
_onCampaignPreview
_onCampaignPreview()
Returns : void
_onTimelinePreview
_onTimelinePreview()
Returns : void
_onGoBack
_onGoBack()
Returns : void
ngOnInit
ngOnInit()
Returns : void
destroy
destroy()
Returns : void

Properties

campaignModel
campaignModel: CampaignsModelExt
campaignStoryTimeline
campaignStoryTimeline: CampaignStoryTimeline
Decorators : ViewChild
campaignTimelinesModel
campaignTimelinesModel: CampaignTimelinesModel
channelModel
channelModel: CampaignTimelineChanelsModel
loginState
loginState: string
m_campaignTimelineChanelPlayersModel
m_campaignTimelineChanelPlayersModel: CampaignTimelineChanelPlayersModelExt
m_campaignTimelinesModels
m_campaignTimelinesModels: List<CampaignTimelinesModel>
m_duration
m_duration: number
Default value : 0
m_inDevMode
m_inDevMode: boolean
m_isVisible1
m_isVisible1: string
Default value : off
m_storyBoardListViewModeEnum
m_storyBoardListViewModeEnum: typeof StoryBoardListViewModeEnum
Default value : StoryBoardListViewModeEnum
m_storyBoardListViewModeSelection
m_storyBoardListViewModeSelection: StoryBoardListViewModeEnum
m_switchMode
m_switchMode: boolean
Default value : false
zoom
zoom: number
Default value : 1
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Output, ViewChild} from "@angular/core";
import {animate, state, style, transition, trigger} from "@angular/animations";
import {Compbaser} from "ng-mslib";
import {CampaignsModelExt, CampaignTimelineChanelPlayersModelExt} from "../../store/model/msdb-models-extended";
import {YellowPepperService} from "../../services/yellowpepper.service";
import {CampaignTimelineChanelsModel, CampaignTimelinesModel} from "../../store/imsdb.interfaces_auto";
import {List} from "immutable";
import {ACTION_UISTATE_UPDATE, AppdbAction, SideProps} from "../../store/actions/appdb.actions";
import {IUiState, StoryBoardListViewModeEnum} from "../../store/store.data";
import {PreviewModeEnum} from "../live-preview/live-preview";
import * as _ from "lodash";
import {RedPepperService} from "../../services/redpepper.service";
import {MainAppShowStateEnum} from "../app-component";
import {Lib} from "../../Lib";
import {CampaignStoryTimeline, ITimelineState} from "./campaign-story-timeline";

// https://github.com/AlexWD/ds-timeline-widget

@Component({
    selector: 'campaign-editor',
    templateUrl: './campaign-editors.html',
    changeDetection: ChangeDetectionStrategy.OnPush,
    styles: [`
        .btn.active.focus, .btn.active:focus, .btn.focus, .btn:active.focus, .btn:active:focus, .btn:focus {
            outline: 0;
        }

        label {
            border-radius: 0px;
        }
    `],
    animations: [
        trigger('visibilityChanged', [
            state('on', style({transform: 'rotate(0deg)'})),
            state('off', style({transform: 'rotate(180deg)'})),
            transition('* => *', animate('300ms'))
        ]),

        trigger('fadeInOut', [
            transition(':enter', [
                style({opacity: 0}),
                animate('400ms', style({opacity: 1}))
            ]),
            transition(':leave', [
                style({opacity: 1}),
                animate('200ms', style({opacity: 0}))
            ])
        ])

    ]
})

export class CampaignEditor extends Compbaser {

    campaignModel: CampaignsModelExt;
    campaignTimelinesModel: CampaignTimelinesModel;
    channelModel: CampaignTimelineChanelsModel;
    m_campaignTimelinesModels: List<CampaignTimelinesModel>;
    m_campaignTimelineChanelPlayersModel: CampaignTimelineChanelPlayersModelExt;
    m_isVisible1 = 'off';
    zoom = 1;
    loginState: string = '';
    m_inDevMode = Lib.DevMode();
    m_storyBoardListViewModeEnum = StoryBoardListViewModeEnum;
    m_storyBoardListViewModeSelection = StoryBoardListViewModeEnum.ListMode;
    m_switchMode = false;
    m_duration:number = 0;

    constructor(private yp: YellowPepperService, private actions: AppdbAction, private rp: RedPepperService, private cd: ChangeDetectorRef) {
        super();

        this.cancelOnDestroy(
            this.yp.listenStoryBoardListViewModeSelected()
                .subscribe((v) => {
                    this._onTimelineViewMode(v);
                }, (e) => console.error(e))
        );

        this.cancelOnDestroy(
            this.yp.listenCampaignSelected()
                .switchMap((i_campaignsModelExt: CampaignsModelExt) => {
                    this.campaignModel = i_campaignsModelExt;
                    return this.yp.listenCampaignTimelines(i_campaignsModelExt.getCampaignId())
                })
                .subscribe((i_campaignTimelinesModel: List<CampaignTimelinesModel>) => {
                    this.m_campaignTimelinesModels = i_campaignTimelinesModel;
                }, (e) => console.error(e))
        );

        this.cancelOnDestroy(
            this.yp.listenTimelineSelected(true)
                .subscribe((i_campaignTimelinesModel: CampaignTimelinesModel) => {
                    this.campaignTimelinesModel = i_campaignTimelinesModel;
                    if (this.campaignTimelinesModel){
                        this.m_duration = this.campaignTimelinesModel.getTimelineDuration();
                        console.log('duration ' + this.m_duration);
                        //todo: error when enabled but need for Duration component
                        // this.cd.detectChanges();
                    }

                }, (e) => console.error(e))
        );
        this.cancelOnDestroy(
            this.yp.listenChannelSelected(true)
                .subscribe((channel: CampaignTimelineChanelsModel) => {
                    this.channelModel = channel;
                }, (e) => {
                    console.error(e)
                })
        );
        this.cancelOnDestroy(
            this.yp.listenBlockChannelSelected(true)
                .subscribe((i_campaignTimelineChanelPlayersModel: CampaignTimelineChanelPlayersModelExt) => {
                    this.m_campaignTimelineChanelPlayersModel = i_campaignTimelineChanelPlayersModel;
                }, (e) => console.error(e))
        )
    }

    @ViewChild(CampaignStoryTimeline)
    campaignStoryTimeline:CampaignStoryTimeline;

    @Output()
    onToScreenLayoutEditor: EventEmitter<any> = new EventEmitter<any>();

    @Output()
    onToAddContent: EventEmitter<any> = new EventEmitter<any>();

    @Output()
    onToAddTimeline: EventEmitter<any> = new EventEmitter<any>();

    @Output()
    onGoBack: EventEmitter<any> = new EventEmitter<any>();

    _onAddContent() {
        if (!this.channelModel)
            return bootbox.alert('Select channel to add content to. First be sure to select a timeline and next, click the [Next Channel] button');
        this.onToAddContent.emit();
    }

    _timelineDurationChange(i_duration) {
        this.m_duration = i_duration;
        console.log('CampaignEditor db total new duration ' + i_duration + ' ' + this.campaignTimelinesModel.getCampaignTimelineId());
        this.rp.setTimelineTotalDuration(this.campaignTimelinesModel.getCampaignTimelineId(), i_duration);
        this.rp.reduxCommit();
        this.cd.markForCheck();
    }

    _campaignStoryTimelineCmd(i_cmd){
        this.campaignStoryTimeline[i_cmd]();
    }

    _onStateChanged(state:ITimelineState){
        // this.m_duration = state.duration;
    }

    _onRemoveTimeline() {
        if (!this.campaignTimelinesModel)
            return bootbox.alert('you must first select a timeline to remove');
        if (this.rp.getCampaignTimelines(this.campaignTimelinesModel.getCampaignId()).length == 1)
            return bootbox.alert('you must keep at least one Timeline')

        bootbox.confirm('are you sure you want to remove the selected timeline?', (i_result) => {
            if (i_result == true) {
                var boardTemplateID = this.rp.getGlobalTemplateIdOfTimeline(this.campaignTimelinesModel.getCampaignTimelineId());
                this.rp.removeTimelineFromCampaign(this.campaignTimelinesModel.getCampaignTimelineId());
                this.rp.removeSchedulerFromTime(this.campaignTimelinesModel.getCampaignTimelineId());
                var campaignTimelineBoardTemplateID = this.rp.removeBoardTemplateFromTimeline(this.campaignTimelinesModel.getCampaignTimelineId());
                this.rp.removeBoardTemplate(boardTemplateID);
                this.rp.removeTimelineBoardViewerChannels(campaignTimelineBoardTemplateID);
                this.rp.removeBoardTemplateViewers(boardTemplateID);
                this.rp.getChannelsOfTimeline(this.campaignTimelinesModel.getCampaignTimelineId()).forEach(i_campaign_timeline_chanel_id => {
                    this.rp.removeChannelFromTimeline(i_campaign_timeline_chanel_id);
                    this.rp.getChannelBlocks(i_campaign_timeline_chanel_id).forEach((i_block_id) => {
                        this.rp.removeBlockFromTimelineChannel(i_block_id);
                    })
                });
                var uiState: IUiState = {
                    uiSideProps: SideProps.miniDashboard,
                    campaign: {
                        timelineSelected: -1,
                        campaignTimelineChannelSelected: -1,
                        campaignTimelineBoardViewerSelected: -1
                    }
                }
                this.yp.ngrxStore.dispatch(({type: ACTION_UISTATE_UPDATE, payload: uiState}))
                this.rp.reduxCommit();
            }
        });
    }

    _changeZoom(value) {
        // console.log(value);
    }

    _onTimelineViewMode(i_mode: StoryBoardListViewModeEnum) {
        var uiState: IUiState = {
            campaign: {
                storyBoardListViewModeSelected: i_mode
            }
        }
        this.yp.ngrxStore.dispatch(({type: ACTION_UISTATE_UPDATE, payload: uiState}))
        this.m_storyBoardListViewModeSelection = i_mode;
    }

    _onAddTimeline() {
        this.onToAddTimeline.emit();
    }

    _onEditScreenLayout() {
        if (!this.campaignTimelinesModel)
            return bootbox.alert('no timeline selected')
        var uiState: IUiState = {uiSideProps: SideProps.screenLayoutEditor}
        this.yp.ngrxStore.dispatch(({type: ACTION_UISTATE_UPDATE, payload: uiState}))
        this.onToScreenLayoutEditor.emit();
    }

    /**
     Delete the selected block from the channel
     @method _deleteChannelBlock
     @return none
     **/
    _onRemoveContent() {
        if (!this.m_campaignTimelineChanelPlayersModel)
            return bootbox.alert('No item selected');
        this.rp.removeBlockFromTimelineChannel(this.m_campaignTimelineChanelPlayersModel.getCampaignTimelineChanelPlayerId());
        this.rp.reduxCommit();
        let uiState: IUiState = {
            uiSideProps: SideProps.miniDashboard,
            campaign: {
                blockChannelSelected: -1
            }
        }
        this.yp.ngrxStore.dispatch(({type: ACTION_UISTATE_UPDATE, payload: uiState}))
    }

    _onCampaignPreview() {
        let uiState: IUiState = {mainAppState: MainAppShowStateEnum.SAVE_AND_PREVIEW, previewMode: PreviewModeEnum.CAMPAIGN}
        this.yp.ngrxStore.dispatch(({type: ACTION_UISTATE_UPDATE, payload: uiState}))
    }

    _onTimelinePreview() {
        if (_.isUndefined(this.campaignTimelinesModel))
            return bootbox.alert('No timeline selected');
        let uiState: IUiState = {mainAppState: MainAppShowStateEnum.SAVE_AND_PREVIEW, previewMode: PreviewModeEnum.TIMELINE}
        this.yp.ngrxStore.dispatch(({type: ACTION_UISTATE_UPDATE, payload: uiState}))
    }

    _onGoBack() {
        this.actions.resetCampaignSelection();
        this.onGoBack.emit()
    }

    ngOnInit() {
    }

    destroy() {
    }
}
<small class="debug">{{me}}</small>
<h4 i18n>campaign editor</h4>
<!-- todo: need to investigate as performance sometime laggy when using the matchBodyHeight directive here -->
<!--<div matchBodyHeight="150" id="campaignView" style="margin-right: 30px; padding-right: 5px; overflow-y: auto">-->
<div id="campaignView" style="padding-right: 24px">
    <div class="panel-group" id="timelinesCollapsible">

        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">
                    <a (click)="m_isVisible1 = m_isVisible1 == 'on' ? 'off' : 'on'" id="toggleTimelinesCollapsible" data-toggle="collapse" data-parent="#timelinesCollapsible" href="#screenSelectorContainerCollapse">
                        <span style="position: relative; top: 3px" [@visibilityChanged]="m_isVisible1" class="glyphicon glyphicon-chevron-down"></span>
                    </a>
                    <button (click)="_onGoBack()" type="button" style="margin-left: 8px" title="add new timeline" data-localize-tooltip="backToCampaignsTooltip" class="btn btn-default btn-sm">
                        <span class="glyphicon glyphicon-chevron-left"></span>
                    </button>

                    <button (click)="_onAddTimeline()" id="addNewTimelineButton" type="button" title="add new timeline" data-localize-tooltip="addNewTimelineButtonToolTip" class="btn btn-default btn-sm">
                        <span class="glyphicon glyphicon-plus"></span>
                    </button>
                    <button (click)="_onRemoveTimeline()" id="removeTimelineButton" type="button" title="remove the selected timeline" data-localize-tooltip="removeTimelineButtonToolTip" class="btn btn-default btn-sm">
                        <span class="glyphicon glyphicon-minus"></span>
                    </button>
                    <button (click)="_onEditScreenLayout()" id="editScreenLayout" type="button" title="edit screen layout" data-localize-tooltip="editScreenLayout" class="btn btn-default btn-sm">
                        <i class="fa fa-object-group"></i>
                    </button>
                    <button id="campaignPreview" (click)="_onCampaignPreview()" type="button" title="campaign preview" data-localize-tooltip="campaignPreviewTooltip" class="btn btn-default btn-sm">
                        <i class="fa fa-play-circle"></i>
                    </button>

                    <div class="sequenceClass" style="float: right; margin-right: 35px; position: relative; top: 6px">
                        <campaign-duration></campaign-duration>
                    </div>
                </h4>
            </div>
            <div id="screenSelectorContainerCollapse" class="panel-collapse collapse in">
                <div class="panel-body">
                    <aside>
                        <aside>
                            <div id="screenSelectorContainer" vertical-align="middle">
                                <div id="screenLayoutsUL" style="overflow-x: scroll">
                                    <sequencer #sequencer (onEditLayout)="_onEditScreenLayout()" [setCampaignTimelinesModels]="m_campaignTimelinesModels"></sequencer>
                                </div>
                            </div>
                        </aside>
                    </aside>
                </div>
            </div>
        </div>
    </div>
    <div class="panel-group" id="storylineCollapsible">
        <div class="panel panel-default">
            <div class="panel-heading">
                <h4 class="panel-title">
                    <span data-localize="timeline">Timeline</span>
                    <button (click)="sequencer.onSelectNextChannel()" style="margin-left: 30px" id="selectNextChannel" type="button" class="btn btn-default btn-sm">
                        <i i18n class="fa fa-crosshairs"></i><span data-localize="nextChannel"> next channel</span>
                    </button>
                    <button id="addBlockButton" (click)="_onAddContent()" type="button" title="add content" class="btn btn-default btn-sm">
                        <i class="fa fa-plus"></i>
                    </button>
                    <button (click)="_onRemoveContent()" id="removeBlockButton" type="button" title="remove content" data-localize-tooltip="removeContent" class="btn btn-default btn-sm">
                        <i class="fa fa-minus"></i>
                    </button>
                    <button (click)="_onTimelinePreview()" id="timelinePreview" type="button" title="campaign preview" data-localize-tooltip="campaignPreviewTooltip" class="btn btn-default btn-sm">
                        <i class="fa fa-play-circle"></i>
                    </button>

                    <div style="height: 30px" class="btn-group" data-toggle="buttons">

                        <label title="view as list" (click)="_onTimelineViewMode(m_storyBoardListViewModeEnum.ListMode)" style="height: 30px"
                               [ngClass]="{active: m_storyBoardListViewModeSelection==m_storyBoardListViewModeEnum.ListMode}"
                               class="btn btn-default" data-active-class="success">
                            <i class="fa fa-list-ul"></i>
                            <input type="radio" name="options" id="option1" autocomplete="off"> list
                        </label>

                        <label title="view as timeline" (click)="_onTimelineViewMode(m_storyBoardListViewModeEnum.StoryMode)" style="height: 30px"
                               [ngClass]="{active: m_storyBoardListViewModeSelection==m_storyBoardListViewModeEnum.StoryMode}"
                               class="btn btn-default" data-active-class="danger">
                            <i class="fa fa-sliders"></i>
                            <input type="radio" name="options" id="option2" autocomplete="off"> timeline
                        </label>
                    </div>

                    <span style="float: right" *ngIf="m_storyBoardListViewModeSelection==m_storyBoardListViewModeEnum.StoryMode">
                        <button (click)="_campaignStoryTimelineCmd('closedGaps')" type="button" title="remove gaps" class="btn btn-default btn-sm">
                            <i class="fa fa-scissors"></i>
                        </button>
                        <button (click)="_campaignStoryTimelineCmd('resizeToLargest')"  type="button" title="resize to largest" class="btn btn-default btn-sm">
                            <i class="fa fa-arrows-h"></i>
                        </button>
                        <button (click)="_campaignStoryTimelineCmd('alignLeft')" type="button" title="align left" class="btn btn-default btn-sm">
                            <i class="fa fa fa-outdent"></i>
                        </button>
                        <button (click)="_campaignStoryTimelineCmd('alignLeft')" type="button" title="align right" class="btn btn-default btn-sm">
                            <i class="fa fa fa-indent"></i>
                        </button>
                        <!--<label title="switch place mode" style="height: 30px" (click)="m_switchMode = !m_switchMode"-->
                        <!--[ngClass]="{active: m_switchMode}"-->
                        <!--class="btn btn-default" data-active-class="danger">-->
                        <!--<i style="position: relative; top: -3px" class="fa fa-exchange"></i>-->
                        <!--</label>-->
                        <select style="float: right" title="zoom (ratio / pixels)" style="width: 70px; height: 30px; position: relative; top: 2px; border: solid 1px #d1d1d1" (change)="_changeZoom($event)" [(ngModel)]="zoom">
                              <option value="1">1.0 : 10</option>
                              <option value="2">2.0 : 10</option>
                              <option value="5">5.0 : 10</option>
                              <option value="10">10 : 10</option>
                              <option value="20">20 : 10</option>
                              <option value="40">40 : 10</option>
                        </select>
                        <app-duration-input style="float: right; position: relative; top: -3px"
                                            *ngIf="m_storyBoardListViewModeSelection == m_storyBoardListViewModeEnum.StoryMode"
                                            [setDuration]="m_duration"
                                            (durationChange)="_timelineDurationChange($event)">
                        </app-duration-input>
                        <!--<input value="{{m_duration}}"/>-->
                    </span>

                </h4>
            </div>
            <div [@fadeInOut] *ngIf="m_storyBoardListViewModeSelection==m_storyBoardListViewModeEnum.StoryMode">
                <!--<campaign-story-timeline (stateChanged)="_onStateChanged($event)" [duration]="m_duration" [switchMode]="m_switchMode" [zoom]="zoom"></campaign-story-timeline>-->
                <campaign-story-timeline #campaignStoryTimeline [switchMode]="m_switchMode" [zoom]="zoom"></campaign-story-timeline>
            </div>
            <div [@fadeInOut] *ngIf="m_storyBoardListViewModeSelection==m_storyBoardListViewModeEnum.ListMode">
                <campaign-channels></campaign-channels>
            </div>
            <div id="storylineContainerCollapse" class="panel-collapse collapse">
                <div class="panel-body">
                    <aside>
                        <aside>
                        </aside>
                    </aside>
                </div>
            </div>
        </div>
    </div>
</div>



Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""