<commit_before>angular.module('carpooling.controllers.viaggio', [])

.controller('ViaggioCtrl', function ($scope, $rootScope, $q, $state, $stateParams, $ionicPopup, $ionicActionSheet, $filter, MapSrv, Config, CacheSrv, UserSrv, Utils, StorageSrv, PassengerSrv, DriverSrv) {
    $scope.travelDateFormat = 'dd MMMM yyyy';
    $scope.travelTimeFormat = 'HH:mm';

    $scope.isMine = null;
    $scope.isPastTrip = null;
    $scope.driverInfo = {};

    $scope.selectedTrip = {};
    $scope.travelId = null;
    $scope.bookingCounters = {};

    // myBooking.accepted values: -1 rejected, 0 requested, 1 accepted
    $scope.myBooking = {
        accepted: null
    };

    var addPathToMap = function (selectedTrip) {
        $scope.pathLine = MapSrv.getTripPolyline(selectedTrip.route);
        $scope.markers = {
            start: {
                lat: Number(selectedTrip.route.from.lat),
                lng: Number(selectedTrip.route.from.lon),
                icon: {
                    iconUrl: 'img/ic_start.png',
                    iconSize: [18, 25],
                    iconAnchor: [9, 25]
                }
            },
            stop: {
                lat: Number(selectedTrip.route.to.lat),
                lng: Number(selectedTrip.route.to.lon),
                icon: {
                    iconUrl: 'img/ic_flag.png',
                    iconSize: [18, 25],
                    iconAnchor: [0, 25]
                }
            }
        }

        var boundsArray = [];
        var boundstart = [$scope.markers.start.lat, $scope.markers.start.lng];
        boundsArray.push(boundstart);
        var boundstop = [$scope.markers.stop.lat, $scope.markers.stop.lng];
        boundsArray.push(boundstop);

        if (boundsArray.length > 0) {
            var bounds = L.latLngBounds(boundsArray);
            MapSrv.getMap('tripMap').then(function (map) {
                map.fitBounds(bounds);
            });
        }
    };

    var refreshTrip = function (trip) {
        $scope.selectedTrip = trip;
        var today = Date.now();
        if (today > $scope.selectedTrip.when) {
            $scope.isPastTrip = true;
        } else {
            $scope.isPastTrip = false;
        }
        $scope.mainCommunity = mainCommunity();

        if (!!$scope.selectedTrip) {
            addPathToMap($scope.selectedTrip);
        }

        $scope.isMine = $scope.selectedTrip.userId === StorageSrv.getUserId();
        $scope.bookingCounters = Utils.getBookingCounters($scope.selectedTrip);
        $scope.dowString = Utils.getRecurrencyString($scope.selectedTrip);

        if (!$scope.isMine) {
            $scope.selectedTrip.bookings.forEach(function (booking) {
                if (booking.traveller.userId === StorageSrv.getUserId()) {
                    // my booking
                    $scope.myBooking = booking;
                }
            });

            UserSrv.getUser($scope.selectedTrip.userId).then(
                function (userInfo) {
                    $scope.driverInfo = userInfo;
                    Utils.loaded();
                },
                function (error) {
                    Utils.loaded();
                    console.error(error);
                    Utils.toast();
                }
            );
        } else {
            $scope.initMap();
            Utils.loaded();
        }
    };

    var init = function () {
        Utils.loading();

        $scope.travelId = $stateParams.travelId;

        PassengerSrv.getTrip($scope.travelId).then(
            function (data) {
                refreshTrip(data);
            },
            function (error) {
                Utils.loaded();
                Utils.toast();
            }
        );
    };

    init();

    /*
     * Rating
     */
    $scope.rate = function (booking) {
        $scope.ratingMax = Config.getRatingMax();
        $scope.rating = 0;
        $scope.setRating = function (rating) {
            $scope.rating = rating;
        };

        var rateUserParams = {
            username: $scope.isMine ? booking.traveller.name + ' ' + booking.traveller.surname : $scope.driverInfo.name + ' ' + $scope.driverInfo.surname,
            role: $scope.isMine ? $filter('translate')('lbl_passenger') : $filter('translate')('lbl_driver')
        };

        var showRatingPopup = $ionicPopup.show({
            scope: $scope,
            title: $filter('translate')('popup_rate_user', rateUserParams),
            templateUrl: 'templates/popup_rate.html',
            buttons: [
                {
                    text: $filter('translate')('cancel'),
                    //type: 'button-stable',
                    onTap: function (event) {}
                },
                {
                    text: $filter('translate')('action_rate'),
                    type: 'button-carpooling',
                    onTap: function (event) {
                        if ($scope.rating > 0) {
                            var success = function () {
                                Utils.toast($filter('translate')('toast_rating_success'));
                            };

                            var failure = function (error) {
                                Utils.toast();
                            };

                            if ($scope.isMine) {
                                // Driver
                                DriverSrv.ratePassenger(booking.traveller.userId, $scope.rating, booking).then(success, failure);
                            } else {
                                // Passenger
                                PassengerSrv.rateDriver($scope.driverInfo.userId, $scope.rating, booking).then(success, failure);
                            }
                        } else {
                            event.preventDefault();
                        }
                    }
                }
            ]
        });
    };

    /*
     * Driver
     */
    $scope.reject = function (booking, isRecurrent) {
        var deferred = $q.defer();

        var success = function (data) {
            Utils.loaded();
            refreshTrip(data);
            CacheSrv.setReloadDriverTrip($scope.selectedTrip.id);
            Utils.toast(($filter('translate')('toast_booking_rejected')));
            deferred.resolve();
        };

        var error = function (error) {
            Utils.loaded();
            Utils.toast();
            deferred.reject();
        };

        if (!!isRecurrent) {
            $scope.recurrencypopup = {
                recurrent : false
            };

            var showRejectRecurrencyPopup = $ionicPopup.show({
                scope: $scope,
                title: $filter('translate')('popup_recurrency_reject'),
                templateUrl: 'templates/popup_recurrency.html',
                buttons: [
                    {
                        text: $filter('translate')('cancel'),
                        //type: 'button-stable',
                        onTap: function (event) {}
                    },
                    {
                        text: $filter('translate')('action_confirm'),
                        type: 'button-carpooling',
                        onTap: function (event) {
                            Utils.loading();
                            var newBooking = {
                                traveller: angular.copy(booking.traveller),
                                accepted: -1
                            }
                            DriverSrv.decideRecurrentTrip($scope.selectedTrip.recurrentId, newBooking).then(success, error);
                        }
                    }
                ]
            });
        } else {
            // confirmation popup for reject
            var showRejectSinglePopup = $ionicPopup.confirm({
                title: $filter('translate')('popup_confirm_reject', {
                    username: booking.traveller.name + ' ' + booking.traveller.surname
                }),
                cancelText: $filter('translate')('cancel'),
                okText: $filter('translate')('action_rejectbtn'),
                okType: 'button-carpooling'
            }).then(
                function (ok) {
                    if (ok) {
                        Utils.loading();
                        var newBooking = angular.copy(booking);
                        newBooking['accepted'] = -1;
                        DriverSrv.decideTrip($scope.selectedTrip.id, newBooking).then(success, error);
                    }
                }
            );
        }

        return deferred.promise;
    };

    $scope.accept = function (booking, isRecurrent) {
        // confirmation popup for accept
        $ionicPopup.confirm({
            title: $filter('translate')('popup_confirm_accept', {
                username: booking.traveller.name + ' ' + booking.traveller.surname
            }),
            cancelText: $filter('translate')('cancel'),
            okText: $filter('translate')('action_acceptbtn'),
            okType: 'button-carpooling'
        }).then(
            function (ok) {
                if (ok) {
                    Utils.loading();
                    var newBooking = angular.copy(booking);
                    newBooking['accepted'] = 1;

                    DriverSrv.decideTrip($scope.selectedTrip.id, newBooking).then(
                        function (data) {
                            Utils.loaded();
                            refreshTrip(data);
                            CacheSrv.setReloadDriverTrip($scope.selectedTrip.id);
                            Utils.toast(($filter('translate')('toast_booking_accepted')));
                        },
                        function (error) {
                            Utils.loaded();
                            Utils.toast();
                        }
                    );
                }
            }
        );
    };

    $scope.chat = function (booking) {
        $state.go('app.chat', {
            travelId: $scope.travelId,
            personId: booking.traveller.userId
        });
    };

    $scope.showActions = function (booking) {
        var hideActionSheet = $ionicActionSheet.show({
            titleText: booking.traveller.name + ' ' + booking.traveller.surname,
            buttons: [
                {
                    text: ' ' + $filter('translate')('action_chat')
                },
                {
                    text: ' ' + $filter('translate')('action_rate_passenger')
                }
            ],
            buttonClicked: function (index) {
                switch (index) {
                    case 0:
                        $scope.chat(booking);
                        return true;
                        break;
                    case 1:
                        $scope.rate(booking);
                        return true;
                        break;
                    default:
                        return false;
                }
            },
            destructiveText: ' ' + $filter('translate')('action_reject'),
            destructiveButtonClicked: function () {
                $scope.reject(booking, ($rootScope.isRecurrencyEnabled() && !!$scope.selectedTrip.recurrentId)).then(
                    function () {
                        hideActionSheet();
                    }
                );
                return false;
            },
            cancelText: $filter('translate')('cancel')
        });
    };

    $scope.positiveAction = function (booking) {
        // NOTE accept booking or show all the actions
        if (booking['accepted'] === 0) {
            $scope.accept(booking);
        } else if (booking.accepted === 1) {
            //$scope.chat(booking);
            $scope.showActions(booking);
        }
    };

    /*
     * Passenger
     */
    $scope.book = function () {
        var me = StorageSrv.getUser();
        var booking = {
            recurrent: false,
            traveller: {
                userId: me.userId,
                name: me.name,
                surname: me.surname,
                email: me.email
            }
        };

        if ($rootScope.isRecurrencyEnabled() && !!$scope.selectedTrip.recurrentId) {
            // popup: single or recurrent booking
            $scope.recurrencypopup = {
                recurrent : false
            };
            var showBookingRecurrencyPopup = $ionicPopup.show({
                scope: $scope,
                title: $filter('translate')('popup_recurrency_book'),
                templateUrl: 'templates/popup_recurrency.html',
                buttons: [
                    {
                        text: $filter('translate')('cancel'),
                        //type: 'button-stable',
                        onTap: function (event) {}
                    },
                    {
                        text: $filter('translate')('action_confirm'),
                        type: 'button-carpooling',
                        onTap: function (event) {
                            if ($scope.recurrencypopup.recurrent === true) {
                                Utils.loading();
                                delete booking.recurrent;
                                PassengerSrv.bookRecurrentTrip($scope.selectedTrip.recurrentId, booking).then(
                                    function (updatedRecurrentTrip) {
                                        Utils.loaded();
                                        // TODO reload partecipated trips list!
                                    },
                                    function (error) {
                                        Utils.loaded();
                                        Utils.toast();
                                    }
                                );
                            } else {
                                Utils.loading();
                                booking.date = new Date($scope.selectedTrip.when);
                                PassengerSrv.bookTrip($scope.travelId, booking).then(
                                    function (updatedTrip) {
                                        Utils.loaded();
                                        refreshTrip(updatedTrip);
                                        CacheSrv.setReloadPassengerTrips(true);
                                    },
                                    function (error) {
                                        Utils.loaded();
                                        Utils.toast();
                                    }
                                );
                            }
                        }
                    }
                ]
            });
        } else {
            Utils.loading();
            booking.date = new Date($scope.selectedTrip.when);
            PassengerSrv.bookTrip($scope.travelId, booking).then(
                function (updatedTrip) {
                    Utils.loaded();
                    refreshTrip(updatedTrip);
                },
                function (error) {
                    Utils.loaded();
                    Utils.toast();
                }
            );
        }
    };

    $scope.bookingAction = function () {
        if ($scope.myBooking.accepted === null) {
            $scope.book();
        } else if ($scope.myBooking.accepted === 0) {
            // FUTURE the passenger can cancel the travelRequest
        } else if ($scope.myBooking.accepted === 1) {
            $scope.rate($scope.myBooking);
        }
    };

    $scope.chatWithDriver = function () {
        $state.go('app.chat', {
            travelId: $scope.travelId,
            personId: $scope.selectedTrip.userId
        });
    };

    /*
     * Map stuff
     */
    $scope.initMap = function () {
        //if ($scope.isMine === false) {
        MapSrv.initMap('tripMap').then(function () {
            //add polyline
        });
        //}
    };

    angular.extend($scope, {
        center: {
            lat: Config.getLat(),
            lng: Config.getLon(),
            zoom: Config.getZoom()
        },
        events: {},
        markers: {},
        pathLine: {}
    });

    /* Show User */
    $scope.showUser = function (index) {
        $state.go('app.profilo', {
            'user': $scope.driverInfo
        });
    };

    /* Show Passenger */
    $scope.showPassenger = function (booking) {
        UserSrv.getUser(booking.traveller.userId).then(
            function (userInfo) {
                $state.go('app.profilo', {
                    'user': userInfo
                });
                Utils.loaded();
            },
            function (error) {
                Utils.loaded();
                console.error(error);
                Utils.toast();
            }
        );
    };

    var mainCommunity = function () {
        if (!!$scope.selectedTrip.communityIds && $scope.selectedTrip.communityIds.length === 1) {
            return StorageSrv.getCommunityById($scope.selectedTrip.communityIds[0]);
        }
        return null;
    };

    $scope.showCommunity = function () {
        $state.go('app.comunitainfo', {
            'community': $scope.mainCommunity
        });
    }
});
<commit_msg>work in progress<commit_after>angular.module('carpooling.controllers.viaggio', [])

.controller('ViaggioCtrl', function ($scope, $rootScope, $q, $state, $stateParams, $ionicPopup, $ionicActionSheet, $filter, MapSrv, Config, CacheSrv, UserSrv, Utils, StorageSrv, PassengerSrv, DriverSrv) {
    $scope.travelDateFormat = 'dd MMMM yyyy';
    $scope.travelTimeFormat = 'HH:mm';

    $scope.isMine = null;
    $scope.isPastTrip = null;
    $scope.driverInfo = {};

    $scope.selectedTrip = {};
    $scope.travelId = null;
    $scope.bookingCounters = {};

    // myBooking.accepted values: -1 rejected, 0 requested, 1 accepted
    $scope.myBooking = {
        accepted: null
    };

    var addPathToMap = function (selectedTrip) {
        $scope.pathLine = MapSrv.getTripPolyline(selectedTrip.route);
        $scope.markers = {
            start: {
                lat: Number(selectedTrip.route.from.lat),
                lng: Number(selectedTrip.route.from.lon),
                icon: {
                    iconUrl: 'img/ic_start.png',
                    iconSize: [18, 25],
                    iconAnchor: [9, 25]
                }
            },
            stop: {
                lat: Number(selectedTrip.route.to.lat),
                lng: Number(selectedTrip.route.to.lon),
                icon: {
                    iconUrl: 'img/ic_flag.png',
                    iconSize: [18, 25],
                    iconAnchor: [0, 25]
                }
            }
        }

        var boundsArray = [];
        var boundstart = [$scope.markers.start.lat, $scope.markers.start.lng];
        boundsArray.push(boundstart);
        var boundstop = [$scope.markers.stop.lat, $scope.markers.stop.lng];
        boundsArray.push(boundstop);

        if (boundsArray.length > 0) {
            var bounds = L.latLngBounds(boundsArray);
            MapSrv.getMap('tripMap').then(function (map) {
                map.fitBounds(bounds);
            });
        }
    };

    var refreshTrip = function (trip) {
        $scope.selectedTrip = trip;
        var today = Date.now();
        if (today > $scope.selectedTrip.when) {
            $scope.isPastTrip = true;
        } else {
            $scope.isPastTrip = false;
        }
        $scope.mainCommunity = mainCommunity();

        if (!!$scope.selectedTrip) {
            addPathToMap($scope.selectedTrip);
        }

        $scope.isMine = $scope.selectedTrip.userId === StorageSrv.getUserId();
        $scope.bookingCounters = Utils.getBookingCounters($scope.selectedTrip);
        $scope.dowString = Utils.getRecurrencyString($scope.selectedTrip);

        if (!$scope.isMine) {
            $scope.selectedTrip.bookings.forEach(function (booking) {
                if (booking.traveller.userId === StorageSrv.getUserId()) {
                    // my booking
                    $scope.myBooking = booking;
                }
            });

            UserSrv.getUser($scope.selectedTrip.userId).then(
                function (userInfo) {
                    $scope.driverInfo = userInfo;
                    Utils.loaded();
                },
                function (error) {
                    Utils.loaded();
                    console.error(error);
                    Utils.toast();
                }
            );
        } else {
            $scope.initMap();
            Utils.loaded();
        }
    };

    var init = function () {
        Utils.loading();

        $scope.travelId = $stateParams.travelId;

        PassengerSrv.getTrip($scope.travelId).then(
            function (data) {
                refreshTrip(data);
            },
            function (error) {
                Utils.loaded();
                Utils.toast();
            }
        );
    };

    init();

    /*
     * Rating
     */
    $scope.rate = function (booking) {
        $scope.ratingMax = Config.getRatingMax();
        $scope.rating = 0;
        $scope.setRating = function (rating) {
            $scope.rating = rating;
        };

        var rateUserParams = {
            username: $scope.isMine ? booking.traveller.name + ' ' + booking.traveller.surname : $scope.driverInfo.name + ' ' + $scope.driverInfo.surname,
            role: $scope.isMine ? $filter('translate')('lbl_passenger') : $filter('translate')('lbl_driver')
        };

        var showRatingPopup = $ionicPopup.show({
            scope: $scope,
            title: $filter('translate')('popup_rate_user', rateUserParams),
            templateUrl: 'templates/popup_rate.html',
            buttons: [
                {
                    text: $filter('translate')('cancel'),
                    //type: 'button-stable',
                    onTap: function (event) {}
                },
                {
                    text: $filter('translate')('action_rate'),
                    type: 'button-carpooling',
                    onTap: function (event) {
                        if ($scope.rating > 0) {
                            var success = function () {
                                Utils.toast($filter('translate')('toast_rating_success'));
                            };

                            var failure = function (error) {
                                Utils.toast();
                            };

                            if ($scope.isMine) {
                                // Driver
                                DriverSrv.ratePassenger(booking.traveller.userId, $scope.rating, booking).then(success, failure);
                            } else {
                                // Passenger
                                PassengerSrv.rateDriver($scope.driverInfo.userId, $scope.rating, booking).then(success, failure);
                            }
                        } else {
                            event.preventDefault();
                        }
                    }
                }
            ]
        });
    };

    /*
     * Driver
     */
    $scope.reject = function (booking) {
        var deferred = $q.defer();

        var success = function (data) {
            Utils.loaded();
            refreshTrip(data);
            CacheSrv.setReloadDriverTrip($scope.selectedTrip.id);
            Utils.toast(($filter('translate')('toast_booking_rejected')));
            deferred.resolve();
        };

        var error = function (error) {
            Utils.loaded();
            Utils.toast();
            deferred.reject();
        };

        if (booking.recurrent == undefined || booking.recurrent === true) {
            $scope.recurrencypopup = {
                recurrent: false
            };

            var showRejectRecurrencyPopup = $ionicPopup.show({
                scope: $scope,
                title: $filter('translate')('popup_recurrency_reject'),
                templateUrl: 'templates/popup_recurrency.html',
                buttons: [
                    {
                        text: $filter('translate')('cancel'),
                        //type: 'button-stable',
                        onTap: function (event) {}
                                },
                    {
                        text: $filter('translate')('action_confirm'),
                        type: 'button-carpooling',
                        onTap: function (event) {
                            Utils.loading();
                            if ($scope.recurrencypopup.recurrent === false) {
                                var newBooking = angular.copy(booking);
                                newBooking['accepted'] = -1;
                                DriverSrv.decideTrip($scope.selectedTrip.id, newBooking).then(success, error);
                            } else {
                                var newBooking = {
                                    traveller: angular.copy(booking.traveller),
                                    accepted: -1
                                }
                                DriverSrv.decideRecurrentTrip($scope.selectedTrip.recurrentId, newBooking).then(success, error);
                            }
                        }
                    }
                ]
            });
        } else {
            // confirmation popup for reject
            var showRejectSinglePopup = $ionicPopup.confirm({
                title: $filter('translate')('popup_confirm_reject', {
                    username: booking.traveller.name + ' ' + booking.traveller.surname
                }),
                cancelText: $filter('translate')('cancel'),
                okText: $filter('translate')('action_rejectbtn'),
                okType: 'button-carpooling'
            }).then(
                function (ok) {
                    if (ok) {
                        Utils.loading();
                        var newBooking = angular.copy(booking);
                        newBooking['accepted'] = -1;
                        DriverSrv.decideTrip($scope.selectedTrip.id, newBooking).then(success, error);
                    }
                }
            );
        }

        return deferred.promise;
    };

    $scope.accept = function (booking) {
        // confirmation popup for accept
        $ionicPopup.confirm({
            title: $filter('translate')('popup_confirm_accept', {
                username: booking.traveller.name + ' ' + booking.traveller.surname
            }),
            cancelText: $filter('translate')('cancel'),
            okText: $filter('translate')('action_acceptbtn'),
            okType: 'button-carpooling'
        }).then(
            function (ok) {
                if (ok) {
                    Utils.loading();
                    var newBooking = angular.copy(booking);
                    newBooking['accepted'] = 1;

                    DriverSrv.decideTrip($scope.selectedTrip.id, newBooking).then(
                        function (data) {
                            Utils.loaded();
                            refreshTrip(data);
                            CacheSrv.setReloadDriverTrip($scope.selectedTrip.id);
                            Utils.toast(($filter('translate')('toast_booking_accepted')));
                        },
                        function (error) {
                            Utils.loaded();
                            Utils.toast();
                        }
                    );
                }
            }
        );
    };

    $scope.chat = function (booking) {
        $state.go('app.chat', {
            travelId: $scope.travelId,
            personId: booking.traveller.userId
        });
    };

    $scope.showActions = function (booking) {
        var hideActionSheet = $ionicActionSheet.show({
            titleText: booking.traveller.name + ' ' + booking.traveller.surname,
            buttons: [
                {
                    text: ' ' + $filter('translate')('action_chat')
                },
                {
                    text: ' ' + $filter('translate')('action_rate_passenger')
                }
            ],
            buttonClicked: function (index) {
                switch (index) {
                    case 0:
                        $scope.chat(booking);
                        return true;
                        break;
                    case 1:
                        $scope.rate(booking);
                        return true;
                        break;
                    default:
                        return false;
                }
            },
            destructiveText: ' ' + $filter('translate')('action_reject'),
            destructiveButtonClicked: function () {
                $scope.reject(booking).then(
                    function () {
                        hideActionSheet();
                    }
                );
                return false;
            },
            cancelText: $filter('translate')('cancel')
        });
    };

    $scope.positiveAction = function (booking) {
        // NOTE accept booking or show all the actions
        if (booking['accepted'] === 0) {
            $scope.accept(booking);
        } else if (booking.accepted === 1) {
            //$scope.chat(booking);
            $scope.showActions(booking);
        }
    };

    /*
     * Passenger
     */
    $scope.book = function () {
        var me = StorageSrv.getUser();
        var booking = {
            recurrent: false,
            traveller: {
                userId: me.userId,
                name: me.name,
                surname: me.surname,
                email: me.email
            }
        };

        if ($rootScope.isRecurrencyEnabled() && !!$scope.selectedTrip.recurrentId) {
            // popup: single or recurrent booking
            $scope.recurrencypopup = {
                recurrent: false
            };
            var showBookingRecurrencyPopup = $ionicPopup.show({
                scope: $scope,
                title: $filter('translate')('popup_recurrency_book'),
                templateUrl: 'templates/popup_recurrency.html',
                buttons: [
                    {
                        text: $filter('translate')('cancel'),
                        //type: 'button-stable',
                        onTap: function (event) {}
                    },
                    {
                        text: $filter('translate')('action_confirm'),
                        type: 'button-carpooling',
                        onTap: function (event) {
                            if ($scope.recurrencypopup.recurrent === true) {
                                Utils.loading();
                                delete booking.recurrent;
                                PassengerSrv.bookRecurrentTrip($scope.selectedTrip.recurrentId, booking).then(
                                    function (updatedRecurrentTrip) {
                                        Utils.loaded();
                                        // TODO reload partecipated trips list!
                                    },
                                    function (error) {
                                        Utils.loaded();
                                        Utils.toast();
                                    }
                                );
                            } else {
                                Utils.loading();
                                booking.date = new Date($scope.selectedTrip.when);
                                PassengerSrv.bookTrip($scope.travelId, booking).then(
                                    function (updatedTrip) {
                                        Utils.loaded();
                                        refreshTrip(updatedTrip);
                                        CacheSrv.setReloadPassengerTrips(true);
                                    },
                                    function (error) {
                                        Utils.loaded();
                                        Utils.toast();
                                    }
                                );
                            }
                        }
                    }
                ]
            });
        } else {
            Utils.loading();
            booking.date = new Date($scope.selectedTrip.when);
            PassengerSrv.bookTrip($scope.travelId, booking).then(
                function (updatedTrip) {
                    Utils.loaded();
                    refreshTrip(updatedTrip);
                },
                function (error) {
                    Utils.loaded();
                    Utils.toast();
                }
            );
        }
    };

    $scope.bookingAction = function () {
        if ($scope.myBooking.accepted === null) {
            $scope.book();
        } else if ($scope.myBooking.accepted === 0) {
            // FUTURE the passenger can cancel the travelRequest
        } else if ($scope.myBooking.accepted === 1) {
            $scope.rate($scope.myBooking);
        }
    };

    $scope.chatWithDriver = function () {
        $state.go('app.chat', {
            travelId: $scope.travelId,
            personId: $scope.selectedTrip.userId
        });
    };

    /*
     * Map stuff
     */
    $scope.initMap = function () {
        //if ($scope.isMine === false) {
        MapSrv.initMap('tripMap').then(function () {
            //add polyline
        });
        //}
    };

    angular.extend($scope, {
        center: {
            lat: Config.getLat(),
            lng: Config.getLon(),
            zoom: Config.getZoom()
        },
        events: {},
        markers: {},
        pathLine: {}
    });

    /* Show User */
    $scope.showUser = function (index) {
        $state.go('app.profilo', {
            'user': $scope.driverInfo
        });
    };

    /* Show Passenger */
    $scope.showPassenger = function (booking) {
        UserSrv.getUser(booking.traveller.userId).then(
            function (userInfo) {
                $state.go('app.profilo', {
                    'user': userInfo
                });
                Utils.loaded();
            },
            function (error) {
                Utils.loaded();
                console.error(error);
                Utils.toast();
            }
        );
    };

    var mainCommunity = function () {
        if (!!$scope.selectedTrip.communityIds && $scope.selectedTrip.communityIds.length === 1) {
            return StorageSrv.getCommunityById($scope.selectedTrip.communityIds[0]);
        }
        return null;
    };

    $scope.showCommunity = function () {
        $state.go('app.comunitainfo', {
            'community': $scope.mainCommunity
        });
    }
});
<|endoftext|>


<commit_before>!function($) {

  'use strict';

  angular.module('qtip2', [])
    .directive('qtip', function() {
      return {
        restrict: 'A',
        scope : {
            qtipVisible : '='
        },
        link: function(scope, element, attrs) {
          var my = attrs.qtipMy || 'bottom center'
            , at = attrs.qtipAt || 'top center'
            , qtipClass = attrs.qtipClass || 'qtip'
            , content = attrs.qtipContent || attrs.qtip;

          if (attrs.qtipTitle) {
            content = {'title': attrs.qtipTitle, 'text': attrs.qtip};
          }

          $(element).qtip({
            content: content,
            position: {
              my: my,
              at: at,
              target: element
            },
            hide: {
              fixed : true,
              delay : 100
            },
            style: qtipClass
          });

          if(attrs.qtipVisible) {
//              var qt_api = $(element).qtip('api');
              scope.$watch('qtipVisible', function (newValue, oldValue) {
                  console.log('new value!', newValue);
                  $(element).qtip('toggle', newValue);
              });
          }
        }
      }
    })

}(window.jQuery);
<commit_msg>removed logging<commit_after>!function($) {

  'use strict';

  angular.module('qtip2', [])
    .directive('qtip', function() {
      return {
        restrict: 'A',
        scope : {
            qtipVisible : '='
        },
        link: function(scope, element, attrs) {
          var my = attrs.qtipMy || 'bottom center'
            , at = attrs.qtipAt || 'top center'
            , qtipClass = attrs.qtipClass || 'qtip'
            , content = attrs.qtipContent || attrs.qtip;

          if (attrs.qtipTitle) {
            content = {'title': attrs.qtipTitle, 'text': attrs.qtip};
          }

          $(element).qtip({
            content: content,
            position: {
              my: my,
              at: at,
              target: element
            },
            hide: {
              fixed : true,
              delay : 100
            },
            style: qtipClass
          });

          if(attrs.qtipVisible) {
              scope.$watch('qtipVisible', function (newValue, oldValue) {
                  $(element).qtip('toggle', newValue);
              });
          }
        }
      }
    })

}(window.jQuery);
<|endoftext|>


<commit_before>(function(base){

base.Chloroform = function(imageUrl, options) {
  var o;

  o = this.options = options || {};

  o.count     || (o.count     = 3);
  o.subsample || (o.subsample = 0);

  this.imageUrl          = imageUrl;
  this.colors            = {};
  this.canvas            = document.createElement('canvas');
  this.canvas.width      = this.width;
  this.canvas.height     = this.height;
  this.ctx               = this.canvas.getContext('2d');
  this.image             = new Image();

  if (!/^data:/.test(this.imageUrl)) {
    this.image.crossOrigin = "anonymous";
  }
}

base.Chloroform.prototype = {
  width:    100,
  height:   100,

  afterImageLoads: function(fn) {
    this.image.onload = fn.bind(this);
    this.image.src    = this.imageUrl;

    return this;
  },

  analyze: function(callback) {
    this.afterImageLoads(function(){
      this.analyzeNow();
      callback && callback(this.colors);
    });

    return this;
  },

  analyzeNow: function() {
    var colors, lastFoundColor;

    this.ctx.drawImage(this.image, 0, 0, this.width, this.height);

    this.colors.background = this.findBackground();
    this.colors.contrast   = this.isDark(this.colors.background) ? '255,255,255' : '0,0,0';
    lastFoundColor         = this.colors.contrast;

    colors = this.findColors(this.imageData(), {subsample: 1});

    for (var i = 0; i < this.options.count; i++) {
      lastFoundColor = this.colors[i] = colors[i] || lastFoundColor;
    }

    return this;
  },

  imageData: function(left, top, width, height) {
    left   || (left   = 0);
    top    || (top    = 0);
    width  || (width  = this.width);
    height || (height = this.height);

    return this.ctx.getImageData(left, top, width, height).data;
  },

  findBackground: function(size, offset) {
    var edgePixels;

    size   || (size   = 1);
    offset || (offset = 0);

    edgePixels = [];

    // bottom
    [].push.apply(
      edgePixels,
      this.imageData(
        offset,
        this.height - offset - size,
        this.width - offset * 2,
        size
      )
    );

    // right
    [].push.apply(
      edgePixels,
      this.imageData(
        this.width - offset - size,
        offset,
        size,
        this.height - offset * 2 - size
      )
    );

    return this.findColors(edgePixels, { count: 1 })[0]
  },

  findColors: function(pixels, options) {
    var numberOfColors, diff, stepSize, subsample, counts, groupedCounts;

    options || (options = {});

    numberOfColors = options.count         || 3;
    diff           = options.startDistance || 0;
    stepSize       = options.stepBy        || 500;
    subsample      = options.subsample     || 0;

    counts = groupedCounts = this.countColors(pixels, subsample);

    for (var i = 0; i < 10; i++) {
      if (Object.keys(counts).length <= numberOfColors) break;

      counts = groupedCounts;
      groupedCounts = this.groupColorsByCount(counts, diff += stepSize);
    }

    return this.colorsSortedByCount(counts);
  },

  countColors: function(pixels, subsample) {
    var counts, step, key, rgb;

    counts = {};
    step = 4 * (subsample + 1);

    for (var i = 0; i < pixels.length; i += step) {
      rgb = [pixels[i], pixels[i + 1], pixels[i + 2]];

      if (this.colors.background && !this.contrastsBackground(rgb)) continue;

      key = rgb.join(',');

      counts[key] || (counts[key] = 0);
      counts[key]  += 1;
    }

    return counts;
  },

  colorsSortedByCount: function(counts) {
    return Object.keys(counts).sort(function(a, b) {
      return counts[b] - counts[a];
    });
  },

  groupColorsByCount: function(counts, diff) {
    var groups, colors, i, j;

    groups = {};
    colors = this.colorsSortedByCount(counts);
    i      = 0;

    while (bucket = colors[i++]) {
      groups[bucket] = counts[bucket];
      j = i;

      while (colors[j]) {
        if (this.areDiffering(bucket, colors[j], diff)) {
          j++;
        } else {
          groups[bucket] += counts[colors[j]];
          colors.splice(j, 1);
        }
      }
    }

    return groups;
  },

  ybr: function(rgb) {
    if (typeof rgb === 'string') return this.ybr(rgb.split(','));

    r = rgb[0];
    g = rgb[1];
    b = rgb[2];

    y  =       (0.299    * r) + (0.587    * g) + (0.114    * b);
    cb = 128 - (0.168736 * r) - (0.331264 * g) + (0.5      * b);
    cr = 128 + (0.5      * r) - (0.418688 * g) - (0.081312 * b);

    return [y, cb, cr];
  },

  distanceSquared: function(a, b) {
    var sum;

    a   = this.ybr(a);
    b   = this.ybr(b);

    sum  = Math.pow(a[0] - b[0], 2);
    sum += Math.pow(a[1] - b[1], 2);
    sum += Math.pow(a[2] - b[2], 2);

    return sum;
  },

  areDiffering: function(a, b, diff) {
    diff || (diff = 3000)
    return this.distanceSquared(a, b) > diff;
  },

  isDark: function(color) {
    return this.ybr(color)[0] < 127;
  },

  areContrasting: function(a, b, diff) {
    diff || (diff = 75)
    return Math.abs(this.ybr(a)[0] - this.ybr(b)[0]) > diff;
  },

  contrastsBackground: function(colorKey) {
    return this.areContrasting(this.colors.background, colorKey);
  }
}

Chloroform.analyze = function(imageUrl, options, callback) {
  if (!callback) {
    callback = options;
    options  = {};
  }

  return new Chloroform(imageUrl, options).analyze(callback);
}

})(this);
<commit_msg>use all edges to find background color<commit_after>(function(base){

base.Chloroform = function(imageUrl, options) {
  var o;

  o = this.options = options || {};

  o.count     || (o.count     = 3);
  o.subsample || (o.subsample = 0);

  this.imageUrl          = imageUrl;
  this.colors            = {};
  this.canvas            = document.createElement('canvas');
  this.canvas.width      = this.width;
  this.canvas.height     = this.height;
  this.ctx               = this.canvas.getContext('2d');
  this.image             = new Image();

  if (!/^data:/.test(this.imageUrl)) {
    this.image.crossOrigin = "anonymous";
  }
}

base.Chloroform.prototype = {
  width:    100,
  height:   100,

  afterImageLoads: function(fn) {
    this.image.onload = fn.bind(this);
    this.image.src    = this.imageUrl;

    return this;
  },

  analyze: function(callback) {
    this.afterImageLoads(function(){
      this.analyzeNow();
      callback && callback(this.colors);
    });

    return this;
  },

  analyzeNow: function() {
    var colors, lastFoundColor;

    this.ctx.drawImage(this.image, 0, 0, this.width, this.height);

    this.colors.background = this.findBackground();
    this.colors.contrast   = this.isDark(this.colors.background) ? '255,255,255' : '0,0,0';
    lastFoundColor         = this.colors.contrast;

    colors = this.findColors(this.imageData(), {subsample: 1});

    for (var i = 0; i < this.options.count; i++) {
      lastFoundColor = this.colors[i] = colors[i] || lastFoundColor;
    }

    return this;
  },

  imageData: function(left, top, width, height) {
    left   || (left   = 0);
    top    || (top    = 0);
    width  || (width  = this.width);
    height || (height = this.height);

    return this.ctx.getImageData(left, top, width, height).data;
  },

  findBackground: function(size, offset) {
    var edgePixels;

    size   || (size   = 1);
    offset || (offset = 0);

    edgePixels = [];

    // top
    [].push.apply(edgePixels, this.imageData(
      offset,
      offset,
      this.width - offset * 2,
      size
    ));

      // right
    [].push.apply(edgePixels, this.imageData(
      this.width - offset - size,
      offset,
      size,
      this.height - offset * 2
    ));

      // bottom
    [].push.apply(edgePixels, this.imageData(
      offset,
      this.height - offset - size,
      this.width - offset * 2,
      size
    ));

    // left
    [].push.apply(edgePixels, this.imageData(
      offset,
      offset,
      size,
      this.height - offset * 2
    ));

    return this.findColors(edgePixels, { count: 1 })[0]
  },

  findColors: function(pixels, options) {
    var numberOfColors, diff, stepSize, subsample, counts, groupedCounts;

    options || (options = {});

    numberOfColors = options.count         || 3;
    diff           = options.startDistance || 0;
    stepSize       = options.stepBy        || 500;
    subsample      = options.subsample     || 0;

    counts = groupedCounts = this.countColors(pixels, subsample);

    for (var i = 0; i < 10; i++) {
      if (Object.keys(counts).length <= numberOfColors) break;

      counts = groupedCounts;
      groupedCounts = this.groupColorsByCount(counts, diff += stepSize);
    }

    return this.colorsSortedByCount(counts);
  },

  countColors: function(pixels, subsample) {
    var counts, step, key, rgb;

    counts = {};
    step = 4 * (subsample + 1);

    for (var i = 0; i < pixels.length; i += step) {
      rgb = [pixels[i], pixels[i + 1], pixels[i + 2]];

      if (this.colors.background && !this.contrastsBackground(rgb)) continue;

      key = rgb.join(',');

      counts[key] || (counts[key] = 0);
      counts[key]  += 1;
    }

    return counts;
  },

  colorsSortedByCount: function(counts) {
    return Object.keys(counts).sort(function(a, b) {
      return counts[b] - counts[a];
    });
  },

  groupColorsByCount: function(counts, diff) {
    var groups, colors, i, j;

    groups = {};
    colors = this.colorsSortedByCount(counts);
    i      = 0;

    while (bucket = colors[i++]) {
      groups[bucket] = counts[bucket];
      j = i;

      while (colors[j]) {
        if (this.areDiffering(bucket, colors[j], diff)) {
          j++;
        } else {
          groups[bucket] += counts[colors[j]];
          colors.splice(j, 1);
        }
      }
    }

    return groups;
  },

  ybr: function(rgb) {
    if (typeof rgb === 'string') return this.ybr(rgb.split(','));

    r = rgb[0];
    g = rgb[1];
    b = rgb[2];

    y  =       (0.299    * r) + (0.587    * g) + (0.114    * b);
    cb = 128 - (0.168736 * r) - (0.331264 * g) + (0.5      * b);
    cr = 128 + (0.5      * r) - (0.418688 * g) - (0.081312 * b);

    return [y, cb, cr];
  },

  distanceSquared: function(a, b) {
    var sum;

    a   = this.ybr(a);
    b   = this.ybr(b);

    sum  = Math.pow(a[0] - b[0], 2);
    sum += Math.pow(a[1] - b[1], 2);
    sum += Math.pow(a[2] - b[2], 2);

    return sum;
  },

  areDiffering: function(a, b, diff) {
    diff || (diff = 3000)
    return this.distanceSquared(a, b) > diff;
  },

  isDark: function(color) {
    return this.ybr(color)[0] < 127;
  },

  areContrasting: function(a, b, diff) {
    diff || (diff = 75)
    return Math.abs(this.ybr(a)[0] - this.ybr(b)[0]) > diff;
  },

  contrastsBackground: function(colorKey) {
    return this.areContrasting(this.colors.background, colorKey);
  }
}

Chloroform.analyze = function(imageUrl, options, callback) {
  if (!callback) {
    callback = options;
    options  = {};
  }

  return new Chloroform(imageUrl, options).analyze(callback);
}

})(this);
<|endoftext|>


<commit_before>/**
 * Very simple in-browser unit-test library, with zero deps.
 *
 * Background turns green if all tests pass, otherwise red.
 * View the JavaScript console to see failure reasons.
 *
 * Example:
 *
 *   adder.js (code under test)
 *
 *     function add(a, b) {
 *       return a + b;
 *     }
 *
 *   adder-test.html (tests - just open a browser to see results)
 *
 *     <script src="tinytest.js"></script>
 *     <script src="adder.js"></script>
 *     <script>
 *
 *     tests({
 *
 *       'adds numbers': function() {
 *         eq(6, add(2, 4));
 *         eq(6.6, add(2.6, 4));
 *       },
 *
 *       'subtracts numbers': function() {
 *         eq(-2, add(2, -4));
 *       },
 *
 *     });
 *     </script>
 *
 * That's it. Stop using over complicated frameworks that get in your way.
 *
 * -Joe Walnes
 * MIT License. See https://github.com/joewalnes/jstinytest/
 */
const TinyTest = {

    run: function (tests) {
        let failures = 0;
        for (let testName in tests) {
            let testAction = tests[testName];
            try {
                testAction();
                console.log('Test:', testName, 'OK');
            } catch (e) {
                failures++;
                console.error('Test:', testName, 'FAILED', e);
                console.error(e.stack);
            }
        }
        setTimeout(function () { // Give document a chance to complete
            if (window.document && document.body) {
                document.body.style.backgroundColor = (failures == 0 ? '#99ff99' : '#ff9999');
            }
        }, 0);
    },

    fail: function (msg) {
        throw new Error('fail(): ' + msg);
    },

    assert: function (value, msg) {
        if (!value) {
            throw new Error('assert(): ' + msg);
        }
    },

    assertEquals: function (expected, actual) {
        if (expected != actual) {
            throw new Error('assertEquals() "' + expected + '" != "' + actual + '"');
        }
    },

    assertStrictEquals: function (expected, actual) {
        if (expected !== actual) {
            throw new Error('assertStrictEquals() "' + expected + '" !== "' + actual + '"');
        }
    },

};

const fail = TinyTest.fail,
    assert = TinyTest.assert,
    assertEquals = TinyTest.assertEquals,
    eq = TinyTest.assertEquals, // alias for assertEquals
    assertStrictEquals = TinyTest.assertStrictEquals,
    tests = TinyTest.run;
<commit_msg>Update tinytest.js<commit_after>/**
 * Very simple in-browser unit-test library, with zero deps.
 *
 * Background turns green if all tests pass, otherwise red.
 * View the JavaScript console to see failure reasons.
 *
 * Example:
 *
 *   adder.js (code under test)
 *
 *     function add(a, b) {
 *       return a + b;
 *     }
 *
 *   adder-test.html (tests - just open a browser to see results)
 *
 *     <script src="tinytest.js"></script>
 *     <script src="adder.js"></script>
 *     <script>
 *
 *     tests({
 *
 *       'adds numbers': function() {
 *         eq(6, add(2, 4));
 *         eq(6.6, add(2.6, 4));
 *       },
 *
 *       'subtracts numbers': function() {
 *         eq(-2, add(2, -4));
 *       },
 *
 *     });
 *     </script>
 *
 * That's it. Stop using over complicated frameworks that get in your way.
 *
 * -Joe Walnes
 * MIT License. See https://github.com/joewalnes/jstinytest/
 */
const TinyTest = {

    run: function(tests) {
        let failures = 0;
        for (let testName in tests) {
            let testAction = tests[testName];
            try {
                testAction();
                console.log('Test:', testName, 'OK');
            } catch (e) {
                failures++;
                console.error('Test:', testName, 'FAILED', e);
                console.error(e.stack);
            }
        }
        setTimeout(function() { // Give document a chance to complete
            if (window.document && document.body) {
                document.body.style.backgroundColor = (failures == 0 ? '#99ff99' : '#ff9999');
            }
        }, 0);
    },

    fail: function(msg) {
        throw new Error('fail(): ' + msg);
    },

    assert: function(value, msg) {
        if (!value) {
            throw new Error('assert(): ' + msg);
        }
    },

    assertEquals: function(expected, actual) {
        if (expected != actual) {
            throw new Error('assertEquals() "' + expected + '" != "' + actual + '"');
        }
    },

    assertStrictEquals: function(expected, actual) {
        if (expected !== actual) {
            throw new Error('assertStrictEquals() "' + expected + '" !== "' + actual + '"');
        }
    },

};

const fail                = TinyTest.fail,
      assert              = TinyTest.assert,
      assertEquals        = TinyTest.assertEquals,
      eq                  = TinyTest.assertEquals, // alias for assertEquals
      assertStrictEquals  = TinyTest.assertStrictEquals,
      tests               = TinyTest.run;
<|endoftext|>


<commit_before>/**
 * Example adaptor for node redis client: https://github.com/mranney/node_redis
 */

var Ribbon = require('../lib/ribbon');
var Redis = require('redis');

module.exports = function(port, host, opts){
  var redisRibbon = new Ribbon();
  if (typeof opts !== 'object') opts = {};

  var conf = {
    retry_max_delay: 10000
  };

  for (var prop in opts) {
    if (opts.hasOwnProperty(prop)) {
      conf[prop] = opts[prop];
    }
  }

  redisRibbon.setStartUp(function(ribbon, redis, cb){
    redis = Redis.createClient(port, host, conf);

    redis.on('ready', function(){

      if (typeof conf.database !== 'undefined') redis.select(conf.database);

      // Ensure startup callback is invoked only once
        if (ribbon.isStartingUp()) cb(null, redis);
        else ribbon.declareUp();
    });

    redis.on('end', function(){
      ribbon.declareDown();
    });
  });

  redisRibbon.setShutDown(function(ribbon, redis, cb){
    redis.quit(cb);
  });

  redisRibbon.setTerminate(function(ribbon, redis, cb){
    redis.end();
    return cb();
  });

  return redisRibbon;
};
<commit_msg>redis integration<commit_after>/**
 * Example adaptor for node redis client: https://github.com/mranney/node_redis
 */

var Ribbon = require('ribbon');
var Redis = require('redis');

module.exports = function(port, host, opts){
  var redisRibbon = new Ribbon();
  if (typeof opts !== 'object') opts = {};

  var conf = {
    retry_max_delay: 10000
  };

  for (var prop in opts) {
    if (opts.hasOwnProperty(prop)) {
      conf[prop] = opts[prop];
    }
  }

  redisRibbon.setStartUp(function(ribbon, redis, cb){

    if (!cb) cb = function() {};

    redis = Redis.createClient(port, host, conf);
    ribbon.client(redis);

    if (typeof conf.database !== 'undefined') redis.select(conf.database);

    redis.on('ready', function(){
      // Invoke callback only if we're starting up for the first time.
      // Otherwise, notify ribbon that redis is once again up
      if (ribbon.isStartingUp()) cb(null, redis);
      else ribbon.declareUp();
    });

    /**
     *
     * Errors are emitted on the redis client if:
     *   1. The underlying socket emitted 'error'
     *   2. The redis parser emitted 'error'
     *   3. A callback to a redis command threw an exception but there isn't
     *      an active process.domain to capture the error.
     *
     * When errors are handled and do not cause a process crash, redis tries
     * to reconnect if configured to do so.
     */
    redis.on('error', function(err) {
      // Re-emit the error on the ribbon object
      ribbon.emit('error', err);
    });

    /**
     * An 'end' event signifies that the redis connection is no longer
     * available for some reason (error, socket closed, shutdown).
     * See https://github.com/mranney/node_redis/blob/2ff2a74ef6cfe8289752e8fbcc7d2f60610088db/index.js#L442
     */
    redis.on('end', function(){
      ribbon.declareDown();
    });
  });

  redisRibbon.setShutDown(function(ribbon, redis, cb){
    redis.quit(cb);
  });

  redisRibbon.setTerminate(function(ribbon, redis, cb){
    redis.end();
    return cb();
  });

  return redisRibbon;
};
<|endoftext|>


<commit_before>import Widget from "./base_widget.js";
import { generate_route, shorten_number } from "./utils";

export default class NumberCardWidget extends Widget {
	constructor(opts) {
		super(opts);
	}

	get_config() {
		return {
			name: this.name,
			label: this.label,
			color: this.color,
			hidden: this.hidden,
		};
	}

	refresh() {
		this.set_body();
	}

	set_body() {
		this.widget.addClass("number-widget-box");
		this.make_card();
	}

	set_title() {
		$(this.title_field).html(`<div class="number-label">${this.card_doc.label}</div>`);
	}

	make_card() {
		frappe.model.with_doc('Number Card', this.name).then(card => {
			if (!card) {
				if (this.document_type) {
					frappe.run_serially([
						() => this.create_number_card(),
						() => this.render_card(),
					]);
				} else {
					// widget doesn't exist so delete
					this.delete(false);
					return;
				}
			} else {
				this.card_doc = card;
				this.render_card();
			}

			this.set_events();
		});
	}

	create_number_card() {
		this.set_doc_args();
		return frappe.xcall(
			'frappe.desk.doctype.number_card.number_card.create_number_card',
			{
				'args': this.card_doc
			}
		).then(doc => {
			this.name = doc.name;
			this.card_doc = doc;
			this.widget.attr('data-widget-name', this.name);
		});
	}

	set_events() {
		$(this.body).click(() => {
			if (this.in_customize_mode || this.card_doc.type == 'Custom') return;
			this.set_route();
		});
	}

	set_route() {
		const is_document_type = this.card_doc.type !== 'Report';
		const name = is_document_type ? this.card_doc.document_type : this.card_doc.report_name;
		const route = generate_route({
			name: name,
			type: is_document_type ? 'doctype' : 'report',
			is_query_report: !is_document_type,
		});

		if (is_document_type) {
			const filters = JSON.parse(this.card_doc.filters_json);
			frappe.route_options = filters.reduce((acc, filter) => {
				return Object.assign(acc, {
					[`${filter[0]}.${filter[1]}`]: [filter[2], filter[3]]
				});
			}, {});
		}

		frappe.set_route(route);
	}

	set_doc_args() {
		this.card_doc = Object.assign({}, {
			document_type: this.document_type,
			label: this.label,
			function: this.function,
			aggregate_function_based_on: this.aggregate_function_based_on,
			color: this.color,
			filters_json: this.stats_filter
		});
	}

	get_settings(type) {
		this.filters = this.get_filters();
		const settings_map = {
			'Custom': {
				method: this.card_doc.method,
				args: {
					filters: this.filters
				},
				get_number: res => this.get_number_for_custom_card(res),
			},
			'Report': {
				method: 'frappe.desk.query_report.run',
				args: {
					report_name: this.card_doc.report_name,
					filters: this.filters,
					ignore_prepared_report: 1
				},
				get_number: res => this.get_number_for_report_card(res),
			},
			'Document Type': {
				method: 'frappe.desk.doctype.number_card.number_card.get_result',
				args: {
					doc: this.card_doc,
					filters: this.filters,
				},
				get_number: res => this.get_number_for_doctype_card(res),
			}
		};
		return settings_map[type];
	}

	get_filters() {
		const filters = frappe.dashboard_utils.get_all_filters(this.card_doc);
		return filters;
	}

	render_card() {
		this.prepare_actions();
		this.set_title();
		this.set_loading_state();

		if (!this.card_doc.type) {
			this.card_doc.type = 'Document Type';
		}

		this.settings = this.get_settings(this.card_doc.type);

		frappe.run_serially([
			() => this.render_number(),
			() => this.render_stats(),
		]);
	}

	set_loading_state() {
		$(this.body).html(`

			${__('Loading...')}

`);
	}

	get_number() {
		return frappe.xcall(this.settings.method, this.settings.args).then(res => {
			this.settings.get_number(res);
		});
	}

	get_number_for_custom_card(res) {
		if (typeof res === 'object') {
			this.number = res.value;
			this.get_formatted_number(res);
		} else {
			this.formatted_number = res;
		}
	}

	get_number_for_doctype_card(res) {
		this.number = res;
		if (this.card_doc.function !== 'Count') {
			return frappe.model.with_doctype(this.card_doc.document_type, () => {
				const based_on_df =
					frappe.meta.get_docfield(this.card_doc.document_type, this.card_doc.aggregate_function_based_on);
				this.get_formatted_number(based_on_df);
			});
		} else {
			this.formatted_number = res;
		}
	}

	get_number_for_report_card(res) {
		const field = this.card_doc.report_field;
		const vals = res.result.reduce((acc, col) => {
			col[field] && acc.push(col[field]);
			return acc;
		}, []);
		const col = res.columns.find(col => col.fieldname == field);
		this.number = frappe.report_utils.get_result_of_fn(this.card_doc.report_function, vals);
		this.get_formatted_number(col);
	}

	get_formatted_number(df) {
		const default_country = frappe.sys_defaults.country;
		const shortened_number = shorten_number(this.number, default_country);
		let number_parts = shortened_number.split(' ');

		const symbol = number_parts[1] || '';
		const formatted_number = $(frappe.format(number_parts[0], df)).text();

		this.formatted_number = formatted_number + ' ' + symbol;
	}

	render_number() {
		return this.get_number().then(() => {
			$(this.body).html(`

${this.formatted_number}

`);
		});
	}

	render_stats() {
		if (this.card_doc.type !== 'Document Type') {
			return;
		}

		let caret_html = '';
		let color_class = '';

		return this.get_percentage_stats().then(() => {
			if (this.percentage_stat == undefined) return;

			if (this.percentage_stat == 0) {
				color_class = 'grey-stat';
			} else if (this.percentage_stat > 0) {
				caret_html = '';
				color_class = 'green-stat';
			} else {
				caret_html = '';
				color_class = 'red-stat';
			}

			const stats_qualifier_map = {
				'Daily': __('since yesterday'),
				'Weekly': __('since last week'),
				'Monthly': __('since last month'),
				'Yearly': __('since last year')
			};
			const stats_qualifier = stats_qualifier_map[this.card_doc.stats_time_interval];

			$(this.body).find('.widget-content').append(`

					${caret_html}
					${Math.abs(this.percentage_stat)} %

					${stats_qualifier}

`);
		});
	}

	get_percentage_stats() {
		return frappe.xcall('frappe.desk.doctype.number_card.number_card.get_percentage_difference', {
			doc: this.card_doc,
			filters: this.filters,
			result: this.number
		}).then(res => {
			if (res !== undefined) {
				this.percentage_stat = +res.toFixed(2);
			}
		});
	}

	prepare_actions() {
		let actions = [
			{
				label: __('Refresh'),
				action: 'action-refresh',
				handler: () => {
					this.render_card();
				}
			},
			{
				label: __('Edit'),
				action: 'action-edit',
				handler: () => {
					frappe.set_route(
						'Form',
						'Number Card',
						this.name
					);
				}
			},
		];

		this.set_card_actions(actions);
	}

	set_card_actions(actions) {
		/* eslint-disable indent */
		this.card_actions =
			$(`

					<button class="btn btn-default btn-xs"></button>

					${actions
						.map(
							action =>
								`

									${action.label}

`
						).join('')}

`);
		/* eslint-disable indent */

		this.card_actions.find("a[data-action]").each((i, o) => {
			const action = o.dataset.action;
			$(o).click(actions.find(a => a.action === action));
		});

		this.action_area.html(this.card_actions);
	}
}
<commit_msg>fix(Number Card): return value in promise<commit_after>import Widget from "./base_widget.js";
import { generate_route, shorten_number } from "./utils";

export default class NumberCardWidget extends Widget {
	constructor(opts) {
		super(opts);
	}

	get_config() {
		return {
			name: this.name,
			label: this.label,
			color: this.color,
			hidden: this.hidden,
		};
	}

	refresh() {
		this.set_body();
	}

	set_body() {
		this.widget.addClass("number-widget-box");
		this.make_card();
	}

	set_title() {
		$(this.title_field).html(`<div class="number-label">${this.card_doc.label}</div>`);
	}

	make_card() {
		frappe.model.with_doc('Number Card', this.name).then(card => {
			if (!card) {
				if (this.document_type) {
					frappe.run_serially([
						() => this.create_number_card(),
						() => this.render_card(),
					]);
				} else {
					// widget doesn't exist so delete
					this.delete(false);
					return;
				}
			} else {
				this.card_doc = card;
				this.render_card();
			}

			this.set_events();
		});
	}

	create_number_card() {
		this.set_doc_args();
		return frappe.xcall(
			'frappe.desk.doctype.number_card.number_card.create_number_card',
			{
				'args': this.card_doc
			}
		).then(doc => {
			this.name = doc.name;
			this.card_doc = doc;
			this.widget.attr('data-widget-name', this.name);
		});
	}

	set_events() {
		$(this.body).click(() => {
			if (this.in_customize_mode || this.card_doc.type == 'Custom') return;
			this.set_route();
		});
	}

	set_route() {
		const is_document_type = this.card_doc.type !== 'Report';
		const name = is_document_type ? this.card_doc.document_type : this.card_doc.report_name;
		const route = generate_route({
			name: name,
			type: is_document_type ? 'doctype' : 'report',
			is_query_report: !is_document_type,
		});

		if (is_document_type) {
			const filters = JSON.parse(this.card_doc.filters_json);
			frappe.route_options = filters.reduce((acc, filter) => {
				return Object.assign(acc, {
					[`${filter[0]}.${filter[1]}`]: [filter[2], filter[3]]
				});
			}, {});
		}

		frappe.set_route(route);
	}

	set_doc_args() {
		this.card_doc = Object.assign({}, {
			document_type: this.document_type,
			label: this.label,
			function: this.function,
			aggregate_function_based_on: this.aggregate_function_based_on,
			color: this.color,
			filters_json: this.stats_filter
		});
	}

	get_settings(type) {
		this.filters = this.get_filters();
		const settings_map = {
			'Custom': {
				method: this.card_doc.method,
				args: {
					filters: this.filters
				},
				get_number: res => this.get_number_for_custom_card(res),
			},
			'Report': {
				method: 'frappe.desk.query_report.run',
				args: {
					report_name: this.card_doc.report_name,
					filters: this.filters,
					ignore_prepared_report: 1
				},
				get_number: res => this.get_number_for_report_card(res),
			},
			'Document Type': {
				method: 'frappe.desk.doctype.number_card.number_card.get_result',
				args: {
					doc: this.card_doc,
					filters: this.filters,
				},
				get_number: res => this.get_number_for_doctype_card(res),
			}
		};
		return settings_map[type];
	}

	get_filters() {
		const filters = frappe.dashboard_utils.get_all_filters(this.card_doc);
		return filters;
	}

	render_card() {
		this.prepare_actions();
		this.set_title();
		this.set_loading_state();

		if (!this.card_doc.type) {
			this.card_doc.type = 'Document Type';
		}

		this.settings = this.get_settings(this.card_doc.type);

		frappe.run_serially([
			() => this.render_number(),
			() => this.render_stats(),
		]);
	}

	set_loading_state() {
		$(this.body).html(`

			${__('Loading...')}

`);
	}

	get_number() {
		return frappe.xcall(this.settings.method, this.settings.args).then(res => {
			return this.settings.get_number(res);
		});
	}

	get_number_for_custom_card(res) {
		if (typeof res === 'object') {
			this.number = res.value;
			this.get_formatted_number(res);
		} else {
			this.formatted_number = res;
		}
	}

	get_number_for_doctype_card(res) {
		this.number = res;
		if (this.card_doc.function !== 'Count') {
			return frappe.model.with_doctype(this.card_doc.document_type, () => {
				const based_on_df =
					frappe.meta.get_docfield(this.card_doc.document_type, this.card_doc.aggregate_function_based_on);
				this.get_formatted_number(based_on_df);
			});
		} else {
			this.formatted_number = res;
		}
	}

	get_number_for_report_card(res) {
		const field = this.card_doc.report_field;
		const vals = res.result.reduce((acc, col) => {
			col[field] && acc.push(col[field]);
			return acc;
		}, []);
		const col = res.columns.find(col => col.fieldname == field);
		this.number = frappe.report_utils.get_result_of_fn(this.card_doc.report_function, vals);
		this.get_formatted_number(col);
	}

	get_formatted_number(df) {
		const default_country = frappe.sys_defaults.country;
		const shortened_number = shorten_number(this.number, default_country);
		let number_parts = shortened_number.split(' ');

		const symbol = number_parts[1] || '';
		const formatted_number = $(frappe.format(number_parts[0], df)).text();

		this.formatted_number = formatted_number + ' ' + symbol;
	}

	render_number() {
		return this.get_number().then(() => {
			$(this.body).html(`

${this.formatted_number}

`);
		});
	}

	render_stats() {
		if (this.card_doc.type !== 'Document Type') {
			return;
		}

		let caret_html = '';
		let color_class = '';

		return this.get_percentage_stats().then(() => {
			if (this.percentage_stat == undefined) return;

			if (this.percentage_stat == 0) {
				color_class = 'grey-stat';
			} else if (this.percentage_stat > 0) {
				caret_html = '';
				color_class = 'green-stat';
			} else {
				caret_html = '';
				color_class = 'red-stat';
			}

			const stats_qualifier_map = {
				'Daily': __('since yesterday'),
				'Weekly': __('since last week'),
				'Monthly': __('since last month'),
				'Yearly': __('since last year')
			};
			const stats_qualifier = stats_qualifier_map[this.card_doc.stats_time_interval];

			$(this.body).find('.widget-content').append(`

					${caret_html}
					${Math.abs(this.percentage_stat)} %

					${stats_qualifier}

`);
		});
	}

	get_percentage_stats() {
		return frappe.xcall('frappe.desk.doctype.number_card.number_card.get_percentage_difference', {
			doc: this.card_doc,
			filters: this.filters,
			result: this.number
		}).then(res => {
			if (res !== undefined) {
				this.percentage_stat = +res.toFixed(2);
			}
		});
	}

	prepare_actions() {
		let actions = [
			{
				label: __('Refresh'),
				action: 'action-refresh',
				handler: () => {
					this.render_card();
				}
			},
			{
				label: __('Edit'),
				action: 'action-edit',
				handler: () => {
					frappe.set_route(
						'Form',
						'Number Card',
						this.name
					);
				}
			},
		];

		this.set_card_actions(actions);
	}

	set_card_actions(actions) {
		/* eslint-disable indent */
		this.card_actions =
			$(`

					<button class="btn btn-default btn-xs"></button>

					${actions
						.map(
							action =>
								`

									${action.label}

`
						).join('')}

`);
		/* eslint-disable indent */

		this.card_actions.find("a[data-action]").each((i, o) => {
			const action = o.dataset.action;
			$(o).click(actions.find(a => a.action === action));
		});

		this.action_area.html(this.card_actions);
	}
}
<|endoftext|>


<commit_before>'use babel'

/* @flow */

declare module 'debugger' {

  declare type FunctionBreakpoint = { function: string }
  declare type LineBreakpoint     = { filePath: string, bufferRow: number }
  declare type BreakpointLocation = LineBreakpoint | FunctionBreakpoint

  declare interface Breakpoint {
    location:        BreakpointLocation;
    enabled:         boolean;
    condition:       ?string;
    activeBufferRow: ?number;

    constructor(location: BreakpointLocation, condition?: string): void;

    getLocation(): BreakpointLocation;

    isEnabled(): bool;

    equals(other: Breakpoint): bool;

    toHumanized(): string;
  }

  declare type BreakpointEventType  = 'inserted' | 'removed' | 'enabled' |
                                      'disabled' | 'moved' |
                                      'condition-added' | 'condition-removed'

  declare interface BreakpointEvent {
    type:       BreakpointEventType;
    breakpoint: Breakpoint;
    bufferRow:  ?number;

    constructor(
      type: BreakpointEventType, breakpoint: Breakpoint, bufferRow?: number): void;
  }

  declare type SessionEventType         = 'launched' | 'will-terminate' |
                                          'terminated' | 'resumed' | 'suspended'
  declare type SessionTerminationReason = 'normally' | 'interrupt'
  declare type SessionSuspensionReason  = 'breakpoint' | 'step'

  declare type ExecutionLine = { filePath: string, bufferRow: number }

  declare class SessionEvent {
    type:          SessionEventType;
    reason:        SessionTerminationReason | SessionSuspensionReason;
    executionLine: ExecutionLine;

    constructor(
      type:           SessionEventType,
      reason?:        SessionTerminationReason | SessionSuspensionReason,
      executionLine?: ExecutionLine): void;
  }

  declare interface EventDefs {
    BreakpointEvent: BreakpointEvent;
    SessionEvent: SessionEvent;
  }

  declare interface DebuggerTarget  {
    filePath: string,
    args: ?string[]
  }

  declare interface DebuggerProxy {

    onSessionEvent(callback: ((event: SessionEvent) => void)): Disposable;

    onBreakpointEvent(callback: ((event: BreakpointEvent) => void)): Disposable;

    findBreakpoint(location: BreakpointLocation): ?Breakpoint;

    removeBreakpoint(breakpoint: Breakpoint): boolean;
  }

  declare interface DebuggerRegistry {

    getDebuggerProxy(): DebuggerProxy;
  }

  declare interface DebuggerController {

    debuggerRegistry: DebuggerRegistry;
  }
}
<commit_msg>Update debugger interface<commit_after>'use babel'

/* @flow */

declare module 'debugger' {

  declare type FunctionBreakpoint = { function: string }
  declare type LineBreakpoint     = { filePath: string, bufferRow: number }
  declare type BreakpointLocation = LineBreakpoint | FunctionBreakpoint

  declare interface Breakpoint {
    location:        BreakpointLocation;
    enabled:         boolean;
    condition:       ?string;
    activeBufferRow: ?number;

    constructor(location: BreakpointLocation, condition?: string): void;

    getLocation(): BreakpointLocation;

    isEnabled(): bool;

    equals(other: Breakpoint): bool;

    toHumanized(): string;
  }

  declare type BreakpointEventType  = 'inserted' | 'removed' | 'enabled' |
                                      'disabled' | 'moved' |
                                      'condition-added' | 'condition-removed'

  declare interface BreakpointEvent {
    type:       BreakpointEventType;
    breakpoint: Breakpoint;
    bufferRow:  ?number;

    constructor(
      type: BreakpointEventType, breakpoint: Breakpoint, bufferRow?: number): void;
  }

  declare type SessionEventType         = 'launched' | 'will-terminate' |
                                          'terminated' | 'resumed' | 'suspended'
  declare type SessionTerminationReason = 'normally' | 'interrupt'
  declare type SessionSuspensionReason  = 'breakpoint' | 'step'

  declare type ExecutionLine = { filePath: string, bufferRow: number }

  declare type StackFrame = {
    level: number,
    address: string,
    function: string,
    filePath: string,
    bufferRow: number
  }

  declare type Variable = {
    name: string,
    value: string,
    type: ?string
  }

  declare class SessionEvent {
    type:          SessionEventType;
    reason:        SessionTerminationReason | SessionSuspensionReason;
    executionLine: ExecutionLine;

    constructor(
      type:           SessionEventType,
      reason?:        SessionTerminationReason | SessionSuspensionReason,
      executionLine?: ExecutionLine): void;
  }

  declare type TargetEventType = 'output'

  declare class TargetEvent {
    type: TargetEventType;
    message: string;

    constructor(type: TargetEventType, message: string): void;
  }

  declare interface EventDefs {
    BreakpointEvent: BreakpointEvent;
    SessionEvent:    SessionEvent;
    TargetEvent:     TargetEvent;
  }

  declare interface DebuggerTarget  {
    filePath: string,
    args: ?string[]
  }

  declare interface DebuggerProxy {

    onSessionEvent(callback: ((event: SessionEvent) => void)): Disposable;

    onBreakpointEvent(callback: ((event: BreakpointEvent) => void)): Disposable;

    onTargetEvent(callback: ((event: TargetEvent) => void)): Disposable;

    findBreakpoint(location: BreakpointLocation): ?Breakpoint;

    removeBreakpoint(breakpoint: Breakpoint): boolean;

    getCallStack(): Promise<Array<StackFrame>>;

    getVariableList(): Promise<Array<Variable>>;
  }

  declare interface DebuggerRegistry {

    getDebuggerProxy(): DebuggerProxy;
  }

  declare interface DebuggerController {

    debuggerRegistry: DebuggerRegistry;
  }
}
<|endoftext|>


<commit_before>var child_process = require('child_process');

module.exports = function(grunt) {
  'use strict';

  require('load-grunt-tasks')(grunt);

  var pkg = require('./package.json');
  var protractorConfig = grunt.option('protractorConfig') || 'ui/common/tests/ci.conf.js';

  var config = pkg.gruntConfig || {};

  config.grunt = grunt;
  config.pkg = pkg;
  config.protractorConfig = protractorConfig;

  var browserifyConf = { };

  require('./ui/admin/grunt/config/browserify')(config, browserifyConf);
  require('./ui/tasklist/grunt/config/browserify')(config, browserifyConf);
  require('./ui/cockpit/grunt/config/browserify')(config, browserifyConf);

  var babelConf = { };
  require('./ui/admin/grunt/config/babel')(config, babelConf);
  require('./ui/tasklist/grunt/config/babel')(config, babelConf);
  require('./ui/cockpit/grunt/config/babel')(config, babelConf);

  var copyConf = require('./grunt/config/copy');
  require('./ui/admin/grunt/config/copy')(config, copyConf);
  require('./ui/cockpit/grunt/config/copy')(config, copyConf);
  require('./ui/tasklist/grunt/config/copy')(config, copyConf);

  var lessConf = { };
  require('./grunt/config/less')(config, lessConf, {
    appName: 'admin',
    sourceDir: pkg.gruntConfig.adminSourceDir,
    buildTarget: pkg.gruntConfig.adminBuildTarget
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'admin',
    sourceDir: pkg.gruntConfig.pluginSourceDir + '/admin/plugins',
    buildTarget: pkg.gruntConfig.pluginBuildTarget + '/admin/app',
    plugin: true
  });

  require('./grunt/config/less')(config, lessConf, {
    appName: 'cockpit',
    sourceDir: pkg.gruntConfig.cockpitSourceDir,
    buildTarget: pkg.gruntConfig.cockpitBuildTarget
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'cockpit',
    sourceDir: pkg.gruntConfig.pluginSourceDir + '/cockpit/plugins',
    buildTarget: pkg.gruntConfig.pluginBuildTarget + '/cockpit/app',
    plugin: true
  });

  require('./grunt/config/less')(config, lessConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.tasklistSourceDir,
    buildTarget: pkg.gruntConfig.tasklistBuildTarget
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.pluginSourceDir + '/tasklist/plugins',
    buildTarget: pkg.gruntConfig.pluginBuildTarget + '/tasklist/app',
    plugin: true
  });

  var localesConf = { };
  require('./grunt/config/localescompile')(config, localesConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.tasklistSourceDir,
    buildTarget: pkg.gruntConfig.tasklistBuildTarget
  });

  var watchConf = {
    commons_styles: {
      options: {
        liverreload: false,
      },
      files: [
        'ui/common/styles/**/*.less',
        'node_modules/camunda-commons-ui/{lib,resources}/**/*.less'
      ],
      tasks: ['less']
    }
  };
  require('./ui/tasklist/grunt/config/watch')(config, watchConf);
  require('./ui/cockpit/grunt/config/watch')(config, watchConf);
  require('./ui/admin/grunt/config/watch')(config, watchConf);

  var uglifyConf = {};
  require('./grunt/config/uglify')(config, uglifyConf);
  require('./ui/admin/grunt/config/uglify')(config, uglifyConf);
  require('./ui/tasklist/grunt/config/uglify')(config, uglifyConf);
  require('./ui/cockpit/grunt/config/uglify')(config, uglifyConf);

  grunt.initConfig({
    buildMode:        'dev',

    pkg:              pkg,

    browserify:       browserifyConf,

    persistify:       browserifyConf,

    copy:             copyConf,

    less:             lessConf,

    localescompile:   localesConf,

    uglify:           uglifyConf,

    babel:            babelConf,

    clean:            require('./grunt/config/clean')(config),

    watch:            watchConf,

    ensureLibs: {
      thirdParty: {}
    },

    protractor:       require('./grunt/config/protractor')(config)
  });

  require('camunda-commons-ui/grunt/tasks/localescompile')(grunt);
  require('camunda-commons-ui/grunt/tasks/persistify')(grunt);
  require('camunda-commons-ui/grunt/tasks/ensureLibs')(grunt);

grunt.registerTask('build', function(mode, app) {

    if(typeof app !== 'undefined') {
      console.log(' ------------  will build ' + app + ' -------------');
      var objs = [browserifyConf, copyConf, lessConf, localesConf, watchConf, uglifyConf];
      for(var i = 0; i < objs.length; i++) {
        var obj = objs[i];
        for (var key in obj) {
          if (obj.hasOwnProperty(key) && key.toLowerCase().indexOf(app) === -1 && key !== 'options' &&
                                         key.toLowerCase().indexOf('webapp') === -1 &&
                                         key.toLowerCase().indexOf('sdk') === -1) {
              delete obj[key];
          }
        }
      }
    }

    grunt.config.data.buildMode = mode || 'prod';

    var tasksToRun = [
      'clean',
      'ensureLibs',
      'persistify',
      'copy',
      'less'
    ];

    if(typeof app === 'undefined' || app === 'tasklist') {
      tasksToRun.push('localescompile');
    }

    if(grunt.config.data.buildMode === 'prod' || process.env.IE) {
      tasksToRun.push('babel');
    }

    if(grunt.config.data.buildMode === 'prod') {
      tasksToRun.push('uglify');
    }

    grunt.task.run(tasksToRun);

  });

  grunt.registerTask('auto-build', function(app) {
    if(app) {
      grunt.task.run([
        'build:dev:' + app,
        'watch'
      ]);
    } else {
      grunt.task.run([
        'build:dev',
        'watch'
      ]);
    }
  });

  grunt.registerTask('ensureSelenium', function() {
    // async task
    var done = this.async();

    child_process.execFile('node', [__dirname + '/node_modules/grunt-protractor-runner/node_modules/protractor/bin/webdriver-manager', '--chrome', 'update'], function(err) {
      done();
    });
  });

  grunt.registerTask('default', ['build']);

  grunt.registerTask('test-e2e', ['ensureSelenium', 'protractor:e2e']);
};
<commit_msg>chore(build): produce warning when trying to incremental build IE<commit_after>var child_process = require('child_process');

module.exports = function(grunt) {
  'use strict';

  require('load-grunt-tasks')(grunt);

  var pkg = require('./package.json');
  var protractorConfig = grunt.option('protractorConfig') || 'ui/common/tests/ci.conf.js';

  var config = pkg.gruntConfig || {};

  config.grunt = grunt;
  config.pkg = pkg;
  config.protractorConfig = protractorConfig;

  var browserifyConf = { };

  require('./ui/admin/grunt/config/browserify')(config, browserifyConf);
  require('./ui/tasklist/grunt/config/browserify')(config, browserifyConf);
  require('./ui/cockpit/grunt/config/browserify')(config, browserifyConf);

  var babelConf = { };
  require('./ui/admin/grunt/config/babel')(config, babelConf);
  require('./ui/tasklist/grunt/config/babel')(config, babelConf);
  require('./ui/cockpit/grunt/config/babel')(config, babelConf);

  var copyConf = require('./grunt/config/copy');
  require('./ui/admin/grunt/config/copy')(config, copyConf);
  require('./ui/cockpit/grunt/config/copy')(config, copyConf);
  require('./ui/tasklist/grunt/config/copy')(config, copyConf);

  var lessConf = { };
  require('./grunt/config/less')(config, lessConf, {
    appName: 'admin',
    sourceDir: pkg.gruntConfig.adminSourceDir,
    buildTarget: pkg.gruntConfig.adminBuildTarget
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'admin',
    sourceDir: pkg.gruntConfig.pluginSourceDir + '/admin/plugins',
    buildTarget: pkg.gruntConfig.pluginBuildTarget + '/admin/app',
    plugin: true
  });

  require('./grunt/config/less')(config, lessConf, {
    appName: 'cockpit',
    sourceDir: pkg.gruntConfig.cockpitSourceDir,
    buildTarget: pkg.gruntConfig.cockpitBuildTarget
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'cockpit',
    sourceDir: pkg.gruntConfig.pluginSourceDir + '/cockpit/plugins',
    buildTarget: pkg.gruntConfig.pluginBuildTarget + '/cockpit/app',
    plugin: true
  });

  require('./grunt/config/less')(config, lessConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.tasklistSourceDir,
    buildTarget: pkg.gruntConfig.tasklistBuildTarget
  });
  require('./grunt/config/less')(config, lessConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.pluginSourceDir + '/tasklist/plugins',
    buildTarget: pkg.gruntConfig.pluginBuildTarget + '/tasklist/app',
    plugin: true
  });

  var localesConf = { };
  require('./grunt/config/localescompile')(config, localesConf, {
    appName: 'tasklist',
    sourceDir: pkg.gruntConfig.tasklistSourceDir,
    buildTarget: pkg.gruntConfig.tasklistBuildTarget
  });

  var watchConf = {
    commons_styles: {
      options: {
        liverreload: false,
      },
      files: [
        'ui/common/styles/**/*.less',
        'node_modules/camunda-commons-ui/{lib,resources}/**/*.less'
      ],
      tasks: ['less']
    }
  };
  require('./ui/tasklist/grunt/config/watch')(config, watchConf);
  require('./ui/cockpit/grunt/config/watch')(config, watchConf);
  require('./ui/admin/grunt/config/watch')(config, watchConf);

  var uglifyConf = {};
  require('./grunt/config/uglify')(config, uglifyConf);
  require('./ui/admin/grunt/config/uglify')(config, uglifyConf);
  require('./ui/tasklist/grunt/config/uglify')(config, uglifyConf);
  require('./ui/cockpit/grunt/config/uglify')(config, uglifyConf);

  grunt.initConfig({
    buildMode:        'dev',

    pkg:              pkg,

    browserify:       browserifyConf,

    persistify:       browserifyConf,

    copy:             copyConf,

    less:             lessConf,

    localescompile:   localesConf,

    uglify:           uglifyConf,

    babel:            babelConf,

    clean:            require('./grunt/config/clean')(config),

    watch:            watchConf,

    ensureLibs: {
      thirdParty: {}
    },

    protractor:       require('./grunt/config/protractor')(config)
  });

  require('camunda-commons-ui/grunt/tasks/localescompile')(grunt);
  require('camunda-commons-ui/grunt/tasks/persistify')(grunt);
  require('camunda-commons-ui/grunt/tasks/ensureLibs')(grunt);

grunt.registerTask('build', function(mode, app) {

    if(typeof app !== 'undefined') {
      console.log(' ------------  will build ' + app + ' -------------');
      var objs = [browserifyConf, copyConf, lessConf, localesConf, watchConf, uglifyConf, babelConf];
      for(var i = 0; i < objs.length; i++) {
        var obj = objs[i];
        for (var key in obj) {
          if (obj.hasOwnProperty(key) && key.toLowerCase().indexOf(app) === -1 && key !== 'options' &&
                                         key.toLowerCase().indexOf('webapp') === -1 &&
                                         key.toLowerCase().indexOf('sdk') === -1) {
              delete obj[key];
          }
        }
      }
    }

    grunt.config.data.buildMode = mode || 'prod';

    var tasksToRun = [
      'clean',
      'ensureLibs',
      'persistify',
      'copy',
      'less'
    ];

    if(typeof app === 'undefined' || app === 'tasklist') {
      tasksToRun.push('localescompile');
    }

    if(grunt.config.data.buildMode === 'prod' || process.env.IE) {
      tasksToRun.push('babel');
    }

    if(grunt.config.data.buildMode === 'prod') {
      tasksToRun.push('uglify');
    }

    grunt.task.run(tasksToRun);

  });

  grunt.registerTask('auto-build', function(app) {
    if(process.env.IE) {
      grunt.warn('IE compatible incremental build is not supported.');
    }
    if(app) {
      grunt.task.run([
        'build:dev:' + app,
        'watch'
      ]);
    } else {
      grunt.task.run([
        'build:dev',
        'watch'
      ]);
    }
  });

  grunt.registerTask('ensureSelenium', function() {
    // async task
    var done = this.async();

    child_process.execFile('node', [__dirname + '/node_modules/grunt-protractor-runner/node_modules/protractor/bin/webdriver-manager', '--chrome', 'update'], function(err) {
      done();
    });
  });

  grunt.registerTask('default', ['build']);

  grunt.registerTask('test-e2e', ['ensureSelenium', 'protractor:e2e']);
};
<|endoftext|>