<commit_before>angular.module('ot.view.branch', [
    'ui.router',
    'ot.service.core',
    'ot.service.task',
    'ot.service.form',
    'ot.service.structure',
    'ot.service.buildfilter',
    'ot.service.copy',
    'ot.service.template',
    'ot.dialog.validationStampRunView',
    'ot.dialog.promotionRuns'
])
    .config(function ($stateProvider) {
        $stateProvider.state('branch', {
            url: '/branch/{branchId}',
            templateUrl: 'app/view/view.branch.tpl.html',
            controller: 'BranchCtrl'
        });
    })
    .controller('BranchCtrl', function ($state, $scope, $stateParams, $http, $modal, $location, ot, otFormService, otStructureService, otBuildFilterService, otAlertService, otTaskService, otNotificationService, otCopyService, otTemplateService) {
        var view = ot.view();
        // Branch's id
        var branchId = $stateParams.branchId;

        // Auto refresh status
        function refreshBuildView() {
            loadBuildView();
        }

        var refreshTaskName = 'Branch build view refresh';
        $scope.$watch('autoRefresh', function () {
            if ($scope.autoRefresh) {
                otTaskService.register(refreshTaskName, refreshBuildView, 30 * 1000);
            } else {
                otTaskService.stop(refreshTaskName);
            }
        });
        $scope.autoRefresh = localStorage.getItem('autoRefresh');
        $scope.toggleAutoRefresh = function () {
            $scope.autoRefresh = !$scope.autoRefresh;
            localStorage.setItem('autoRefresh', $scope.autoRefresh);
        };

        // Selected builds
        $scope.selectedBuild = {
            from: undefined,
            to: undefined
        };

        // Loading the build filters
        function loadBuildFilters() {
            // Loads filter forms
            ot.call($http.get($scope.branch._buildFilterForms)).then(function (buildFilterForms) {
                $scope.buildFilterForms = buildFilterForms;
                // Loads existing filters
                return otBuildFilterService.loadFilters($scope.branch);
            }).then(function (buildFilterResources) {
                $scope.buildFilterResources = buildFilterResources;
                // Loading the build view AFTER the filter have been loaded
                loadBuildView();
            });
        }

        // Loading the build view
        function loadBuildView() {
            // Parameters for the call
            var uri = $scope.branch._view;
            var config = {};
            // Adds the filter parameters
            var currentBuildFilterResource = otBuildFilterService.getCurrentFilter(branchId);
            if (currentBuildFilterResource) {
                $scope.currentBuildFilterResource = currentBuildFilterResource;
                config.params = currentBuildFilterResource.data;
                uri += '/' + currentBuildFilterResource.type;
            } else {
                $scope.currentBuildFilterResource = undefined;
            }
            // Call
            $scope.loadingBuildView = true;
            ot.call($http.get(uri, config)).then(
                function success(branchBuildView) {
                    $scope.loadingBuildView = false;
                    $scope.branchBuildView = branchBuildView;
                    // Selection of build boundaries
                    var buildViews = branchBuildView.buildViews;
                    if (buildViews && buildViews.length > 0) {
                        $scope.selectedBuild.from = buildViews[0].build.id;
                        $scope.selectedBuild.to = buildViews[buildViews.length - 1].build.id;
                    }
                }, function error() {
                    $scope.loadingBuildView = false;
                }
            );
        }

        // Loading the promotion levels
        function loadPromotionLevels() {
            ot.call($http.get($scope.branch._promotionLevels)).then(function (collection) {
                $scope.promotionLevelCollection = collection;
                $scope.promotionLevelSortOptions = {
                    disabled: !$scope.branch._reorderPromotionLevels,
                    stop: function (event, ui) {
                        var ids = $scope.promotionLevelCollection.resources.map(function (pl) {
                            return pl.id;
                        });
                        ot.call($http.put(
                            $scope.branch._reorderPromotionLevels,
                            { ids: ids}
                        ));
                    }
                };
            });
        }

        // Loading the validation stamps
        function loadValidationStamps() {
            ot.call($http.get($scope.branch._validationStamps)).then(function (collection) {
                $scope.validationStampCollection = collection;
                $scope.validationStampSortOptions = {
                    disabled: !$scope.branch._reorderValidationStamps,
                    stop: function (event, ui) {
                        var ids = $scope.validationStampCollection.resources.map(function (pl) {
                            return pl.id;
                        });
                        ot.call($http.put(
                            $scope.branch._reorderValidationStamps,
                            { ids: ids}
                        ));
                    }
                };
            });
        }

        // Loading of the other branches
        function loadOtherBranches() {
            ot.call($http.get($scope.branch._branches)).then(function (branchCollection) {
                view.commands.push({
                    id: 'switch-branch',
                    name: "Switch",
                    group: true,
                    actions: branchCollection.resources
                        .filter(function (theBranch) {
                            return theBranch.id != branchId;
                        })
                        .map(function (theBranch) {
                            return {
                                id: 'switch-' + theBranch.id,
                                name: theBranch.name,
                                uri: 'branch/' + theBranch.id
                            };
                        })
                });
            });
        }

        // Loading the branch
        function loadBranch() {
            otStructureService.getBranch(branchId).then(function (branchResource) {
                $scope.branch = branchResource;
                // View settings
                view.breadcrumbs = ot.projectBreadcrumbs(branchResource.project);
                // Branch template instance details
                if ($scope.branch._templateInstance) {
                    ot.call($http.get($scope.branch._templateInstance)).then(function (templateInstance) {
                        return otStructureService.getBranch(templateInstance.templateDefinitionId);
                    }).then(function (templateDefinition) {
                        $scope.templateDefinition = templateDefinition;
                    });
                }
                // Branch commands
                view.commands = [
                    {
                        condition: function () {
                            return branchResource._createBuild;
                        },
                        id: 'createBuild',
                        name: "Create build",
                        cls: 'ot-command-build-new',
                        action: function () {
                            otStructureService.createBuild(branchResource._createBuild).then(loadBuildView);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._templateDefinition;
                        },
                        id: 'templateDefinitionBranch',
                        name: "Template definition",
                        cls: 'ot-command-branch-template-definition',
                        action: function () {
                            otTemplateService.templateDefinition(branchResource._templateDefinition).then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._templateSync;
                        },
                        id: 'templateSyncBranch',
                        name: "Sync. template",
                        cls: 'ot-command-branch-template-sync',
                        action: function () {
                            otTemplateService.templateSync(branchResource._templateSync);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._templateInstanceCreate;
                        },
                        id: 'templateInstanceBranch',
                        name: "Create template instance",
                        cls: 'ot-command-branch-template-instance',
                        action: function () {
                            otTemplateService.createTemplateInstance(branchResource._templateInstanceCreate).then(
                                function (instance) {
                                    $state.go('branch', {branchId: instance.id});
                                }
                            );
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._templateInstanceDisconnect;
                        },
                        id: 'templateInstanceDisconnect',
                        name: "Disconnect from template",
                        cls: 'ot-command-branch-template-instance-disconnect',
                        action: function () {
                            otTemplateService.templateInstanceDisconnect(branchResource._templateInstanceDisconnect)
                                .then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._disable;
                        },
                        id: 'disableBranch',
                        name: "Disable branch",
                        cls: 'ot-command-branch-disable',
                        action: function () {
                            ot.pageCall($http.put(branchResource._disable)).then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._enable;
                        },
                        id: 'enableBranch',
                        name: "Enable branch",
                        cls: 'ot-command-branch-enable',
                        action: function () {
                            ot.pageCall($http.put(branchResource._enable)).then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._update;
                        },
                        id: 'updateBranch',
                        name: "Update branch",
                        cls: 'ot-command-branch-update',
                        action: function () {
                            otStructureService.update(
                                branchResource._update,
                                "Update branch"
                            ).then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return $scope.branch._delete;
                        },
                        id: 'deleteBranch',
                        name: "Delete branch",
                        cls: 'ot-command-branch-delete',
                        action: function () {
                            otAlertService.confirm({
                                title: "Deleting a branch",
                                message: "Do you really want to delete the branch " + $scope.branch.name +
                                    " and all its associated data?"
                            }).then(function () {
                                return ot.call($http.delete($scope.branch._delete));
                            }).then(function () {
                                $state.go('project', {projectId: $scope.branch.project.id});
                            });
                        }
                    },
                    ot.viewCloseCommand('/project/' + branchResource.project.id),
                    ot.viewActionsCommand(
                        $scope.branch._actions,
                        getTools($scope.branch)
                    )
                ];
                // Loads the build filters
                loadBuildFilters();
                // Loads the promotion levels
                loadPromotionLevels();
                // Loads the validation stamps
                loadValidationStamps();
                // Loads the other branches
                loadOtherBranches();
            });
        }

        // Initialization
        loadPermalink();
        loadBranch();

        // Reload callback available in the scope
        $scope.reloadBranch = loadBranch;

        // Gets the list of tools for a branch
        function getTools(branch) {
            var tools = [];
            // Clone into branch
            if (branch._clone) {
                tools.push({
                    id: 'branch-clone',
                    name: "Clone branch",
                    action: cloneBranch
                });
            }
            // Copy from branch
            if (branch._copy) {
                tools.push({
                    id: 'branch-copy',
                    name: "Copy config. from branch",
                    action: copyFromBranch
                });
            }
            // Bulk update
            if (branch._bulkUpdate) {
                tools.push({
                    id: 'branch-bulk-update',
                    name: "Bulk update",
                    action: bulkUpdateBranch
                });
            }
            // OK
            return tools;
        }

        // Bulk update of a branch
        function bulkUpdateBranch() {
            otCopyService.bulkUpdate($scope.branch).then(loadBranch);
        }

        // Cloning a branch
        function cloneBranch() {
            otCopyService.cloneBranch($scope.branch).then(function (newBranch) {
                $state.go('branch', {
                    branchId: newBranch.id
                });
            });
        }

        // Copy from a branch
        function copyFromBranch() {
            otCopyService.copyFrom($scope.branch).then(loadBranch);
        }

        // Creation of a promotion level
        $scope.createPromotionLevel = function () {
            otStructureService.create($scope.branch._createPromotionLevel, "New promotion level").then(loadBranch);
        };

        // Creation of a validation stamp
        $scope.createValidationStamp = function () {
            otStructureService.create($scope.branch._createValidationStamp, 'New validation stamp').then(loadBranch);
        };

        /**
         * Creating a validation run
         */
        $scope.createValidationRun = function (buildView, validationStampRunView) {
            otStructureService.create(
                buildView.build._validate,
                'Validation for the build',
                {
                    postForm: function (form) {
                        return otFormService.updateFieldValue(form, 'validationStamp', validationStampRunView.validationStamp.id);
                    }
                }
            ).then(loadBuildView);
        };

        /**
         * Displaying the promotion runs
         */
        $scope.displayPromotionRuns = function (buildView, promotionRun) {
            $modal.open({
                templateUrl: 'app/dialog/dialog.promotionRuns.tpl.html',
                controller: 'otDialogPromotionRuns',
                resolve: {
                    config: function () {
                        return {
                            build: buildView.build,
                            promotionLevel: promotionRun.promotionLevel,
                            uri: promotionRun._all
                        };
                    }
                }
            }).result.then(loadBuildView, loadBuildView);
        };

        /**
         * Displaying the validation runs
         */
        $scope.displayValidationRuns = function (buildView, validationStampRunView) {
            $modal.open({
                templateUrl: 'app/dialog/dialog.validationStampRunView.tpl.html',
                controller: 'otDialogValidationStampRunView',
                resolve: {
                    config: function () {
                        return {
                            buildView: buildView,
                            validationStampRunView: validationStampRunView
                        };
                    }
                }
            });
        };

        /**
         * Build diff action
         */
        $scope.buildDiff = function (action) {
            var selectedBuild = $scope.selectedBuild;
            if (selectedBuild.from && selectedBuild.to && selectedBuild.from != selectedBuild.to) {
                $state.go(action.id, {
                    branch: branchId,
                    from: selectedBuild.from,
                    to: selectedBuild.to
                });
            }
        };

        /**
         * Build filter: new one
         */
        $scope.buildFilterNew = function (buildFilterForm) {
            otBuildFilterService.createBuildFilter({
                branchId: branchId,
                buildFilterForm: buildFilterForm
            }).then(function () {
                // Reloads the filters
                loadBuildFilters();
            });
        };

        /**
         * Editing a filter
         */
        $scope.buildFilterEdit = function (buildFilterResource) {
            otBuildFilterService.editBuildFilter({
                branch: $scope.branch,
                buildFilterResource: buildFilterResource,
                buildFilterForms: $scope.buildFilterForms
            }).then(function () {
                // Reloads the filters
                loadBuildFilters();
            });
        };

        /**
         * Applying a filter
         */
        $scope.buildFilterApply = function (buildFilterResource) {
            if (!buildFilterResource.removing) {
                otBuildFilterService.storeCurrent(branchId, buildFilterResource);
                loadBuildView();
            }
        };

        /**
         * Removing the current filter
         */
        $scope.buildFilterErase = function () {
            otBuildFilterService.eraseCurrent(branchId);
            loadBuildView();
        };

        /**
         * Removing an existing filter
         */
        $scope.buildFilterRemove = function (buildFilterResource) {
            buildFilterResource.removing = true;
            otBuildFilterService.removeFilter($scope.branch, buildFilterResource).then(loadBuildFilters);
        };

        /**
         * Saving a local filter
         */
        $scope.buildFilterSave = function (buildFilterResource) {
            otBuildFilterService.saveFilter($scope.branch, buildFilterResource).then(loadBuildFilters);
        };

        /**
         * Sharing a saved filter
         */
        $scope.buildFilterShare = function (buildFilterResource) {
            otBuildFilterService.shareFilter($scope.branch, buildFilterResource).then(loadBuildFilters);
        };

        /**
         * Permalink to the current filter
         */
        $scope.buildFilterLink = function () {
            var currentFilter = otBuildFilterService.getCurrentFilter(branchId);
            if (currentFilter) {
                var jsonFilter = JSON.stringify(currentFilter);
                $location.hash(jsonFilter);
            }
        };

        /**
         * Loading the permalink at startup
         */
        function loadPermalink() {
            var jsonFilter = $location.hash();
            if (jsonFilter) {
                // Parsing the JSON
                try {
                    var json = JSON.parse(jsonFilter);
                    // Applies the filter
                    otBuildFilterService.storeCurrent(branchId, json);
                    // Removes the hash after use
                    $location.hash('');
                } catch (e) {
                    otNotificationService.error("Cannot get the filter from the permalink.");
                }
            }
        }

    })
;<commit_msg>#132 API link on the branch page<commit_after>angular.module('ot.view.branch', [
    'ui.router',
    'ot.service.core',
    'ot.service.task',
    'ot.service.form',
    'ot.service.structure',
    'ot.service.buildfilter',
    'ot.service.copy',
    'ot.service.template',
    'ot.dialog.validationStampRunView',
    'ot.dialog.promotionRuns'
])
    .config(function ($stateProvider) {
        $stateProvider.state('branch', {
            url: '/branch/{branchId}',
            templateUrl: 'app/view/view.branch.tpl.html',
            controller: 'BranchCtrl'
        });
    })
    .controller('BranchCtrl', function ($state, $scope, $stateParams, $http, $modal, $location, ot, otFormService, otStructureService, otBuildFilterService, otAlertService, otTaskService, otNotificationService, otCopyService, otTemplateService) {
        var view = ot.view();
        // Branch's id
        var branchId = $stateParams.branchId;

        // Auto refresh status
        function refreshBuildView() {
            loadBuildView();
        }

        var refreshTaskName = 'Branch build view refresh';
        $scope.$watch('autoRefresh', function () {
            if ($scope.autoRefresh) {
                otTaskService.register(refreshTaskName, refreshBuildView, 30 * 1000);
            } else {
                otTaskService.stop(refreshTaskName);
            }
        });
        $scope.autoRefresh = localStorage.getItem('autoRefresh');
        $scope.toggleAutoRefresh = function () {
            $scope.autoRefresh = !$scope.autoRefresh;
            localStorage.setItem('autoRefresh', $scope.autoRefresh);
        };

        // Selected builds
        $scope.selectedBuild = {
            from: undefined,
            to: undefined
        };

        // Loading the build filters
        function loadBuildFilters() {
            // Loads filter forms
            ot.call($http.get($scope.branch._buildFilterForms)).then(function (buildFilterForms) {
                $scope.buildFilterForms = buildFilterForms;
                // Loads existing filters
                return otBuildFilterService.loadFilters($scope.branch);
            }).then(function (buildFilterResources) {
                $scope.buildFilterResources = buildFilterResources;
                // Loading the build view AFTER the filter have been loaded
                loadBuildView();
            });
        }

        // Loading the build view
        function loadBuildView() {
            // Parameters for the call
            var uri = $scope.branch._view;
            var config = {};
            // Adds the filter parameters
            var currentBuildFilterResource = otBuildFilterService.getCurrentFilter(branchId);
            if (currentBuildFilterResource) {
                $scope.currentBuildFilterResource = currentBuildFilterResource;
                config.params = currentBuildFilterResource.data;
                uri += '/' + currentBuildFilterResource.type;
            } else {
                $scope.currentBuildFilterResource = undefined;
            }
            // Call
            $scope.loadingBuildView = true;
            ot.call($http.get(uri, config)).then(
                function success(branchBuildView) {
                    $scope.loadingBuildView = false;
                    $scope.branchBuildView = branchBuildView;
                    // Selection of build boundaries
                    var buildViews = branchBuildView.buildViews;
                    if (buildViews && buildViews.length > 0) {
                        $scope.selectedBuild.from = buildViews[0].build.id;
                        $scope.selectedBuild.to = buildViews[buildViews.length - 1].build.id;
                    }
                }, function error() {
                    $scope.loadingBuildView = false;
                }
            );
        }

        // Loading the promotion levels
        function loadPromotionLevels() {
            ot.call($http.get($scope.branch._promotionLevels)).then(function (collection) {
                $scope.promotionLevelCollection = collection;
                $scope.promotionLevelSortOptions = {
                    disabled: !$scope.branch._reorderPromotionLevels,
                    stop: function (event, ui) {
                        var ids = $scope.promotionLevelCollection.resources.map(function (pl) {
                            return pl.id;
                        });
                        ot.call($http.put(
                            $scope.branch._reorderPromotionLevels,
                            { ids: ids}
                        ));
                    }
                };
            });
        }

        // Loading the validation stamps
        function loadValidationStamps() {
            ot.call($http.get($scope.branch._validationStamps)).then(function (collection) {
                $scope.validationStampCollection = collection;
                $scope.validationStampSortOptions = {
                    disabled: !$scope.branch._reorderValidationStamps,
                    stop: function (event, ui) {
                        var ids = $scope.validationStampCollection.resources.map(function (pl) {
                            return pl.id;
                        });
                        ot.call($http.put(
                            $scope.branch._reorderValidationStamps,
                            { ids: ids}
                        ));
                    }
                };
            });
        }

        // Loading of the other branches
        function loadOtherBranches() {
            ot.call($http.get($scope.branch._branches)).then(function (branchCollection) {
                view.commands.push({
                    id: 'switch-branch',
                    name: "Switch",
                    group: true,
                    actions: branchCollection.resources
                        .filter(function (theBranch) {
                            return theBranch.id != branchId;
                        })
                        .map(function (theBranch) {
                            return {
                                id: 'switch-' + theBranch.id,
                                name: theBranch.name,
                                uri: 'branch/' + theBranch.id
                            };
                        })
                });
            });
        }

        // Loading the branch
        function loadBranch() {
            otStructureService.getBranch(branchId).then(function (branchResource) {
                $scope.branch = branchResource;
                // View settings
                view.breadcrumbs = ot.projectBreadcrumbs(branchResource.project);
                // Branch template instance details
                if ($scope.branch._templateInstance) {
                    ot.call($http.get($scope.branch._templateInstance)).then(function (templateInstance) {
                        return otStructureService.getBranch(templateInstance.templateDefinitionId);
                    }).then(function (templateDefinition) {
                        $scope.templateDefinition = templateDefinition;
                    });
                }
                // Branch commands
                view.commands = [
                    {
                        condition: function () {
                            return branchResource._createBuild;
                        },
                        id: 'createBuild',
                        name: "Create build",
                        cls: 'ot-command-build-new',
                        action: function () {
                            otStructureService.createBuild(branchResource._createBuild).then(loadBuildView);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._templateDefinition;
                        },
                        id: 'templateDefinitionBranch',
                        name: "Template definition",
                        cls: 'ot-command-branch-template-definition',
                        action: function () {
                            otTemplateService.templateDefinition(branchResource._templateDefinition).then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._templateSync;
                        },
                        id: 'templateSyncBranch',
                        name: "Sync. template",
                        cls: 'ot-command-branch-template-sync',
                        action: function () {
                            otTemplateService.templateSync(branchResource._templateSync);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._templateInstanceCreate;
                        },
                        id: 'templateInstanceBranch',
                        name: "Create template instance",
                        cls: 'ot-command-branch-template-instance',
                        action: function () {
                            otTemplateService.createTemplateInstance(branchResource._templateInstanceCreate).then(
                                function (instance) {
                                    $state.go('branch', {branchId: instance.id});
                                }
                            );
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._templateInstanceDisconnect;
                        },
                        id: 'templateInstanceDisconnect',
                        name: "Disconnect from template",
                        cls: 'ot-command-branch-template-instance-disconnect',
                        action: function () {
                            otTemplateService.templateInstanceDisconnect(branchResource._templateInstanceDisconnect)
                                .then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._disable;
                        },
                        id: 'disableBranch',
                        name: "Disable branch",
                        cls: 'ot-command-branch-disable',
                        action: function () {
                            ot.pageCall($http.put(branchResource._disable)).then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._enable;
                        },
                        id: 'enableBranch',
                        name: "Enable branch",
                        cls: 'ot-command-branch-enable',
                        action: function () {
                            ot.pageCall($http.put(branchResource._enable)).then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return branchResource._update;
                        },
                        id: 'updateBranch',
                        name: "Update branch",
                        cls: 'ot-command-branch-update',
                        action: function () {
                            otStructureService.update(
                                branchResource._update,
                                "Update branch"
                            ).then(loadBranch);
                        }
                    },
                    {
                        condition: function () {
                            return $scope.branch._delete;
                        },
                        id: 'deleteBranch',
                        name: "Delete branch",
                        cls: 'ot-command-branch-delete',
                        action: function () {
                            otAlertService.confirm({
                                title: "Deleting a branch",
                                message: "Do you really want to delete the branch " + $scope.branch.name +
                                    " and all its associated data?"
                            }).then(function () {
                                return ot.call($http.delete($scope.branch._delete));
                            }).then(function () {
                                $state.go('project', {projectId: $scope.branch.project.id});
                            });
                        }
                    },
                    ot.viewApiCommand(branchResource._self),
                    ot.viewCloseCommand('/project/' + branchResource.project.id),
                    ot.viewActionsCommand(
                        $scope.branch._actions,
                        getTools($scope.branch)
                    )
                ];
                // Loads the build filters
                loadBuildFilters();
                // Loads the promotion levels
                loadPromotionLevels();
                // Loads the validation stamps
                loadValidationStamps();
                // Loads the other branches
                loadOtherBranches();
            });
        }

        // Initialization
        loadPermalink();
        loadBranch();

        // Reload callback available in the scope
        $scope.reloadBranch = loadBranch;

        // Gets the list of tools for a branch
        function getTools(branch) {
            var tools = [];
            // Clone into branch
            if (branch._clone) {
                tools.push({
                    id: 'branch-clone',
                    name: "Clone branch",
                    action: cloneBranch
                });
            }
            // Copy from branch
            if (branch._copy) {
                tools.push({
                    id: 'branch-copy',
                    name: "Copy config. from branch",
                    action: copyFromBranch
                });
            }
            // Bulk update
            if (branch._bulkUpdate) {
                tools.push({
                    id: 'branch-bulk-update',
                    name: "Bulk update",
                    action: bulkUpdateBranch
                });
            }
            // OK
            return tools;
        }

        // Bulk update of a branch
        function bulkUpdateBranch() {
            otCopyService.bulkUpdate($scope.branch).then(loadBranch);
        }

        // Cloning a branch
        function cloneBranch() {
            otCopyService.cloneBranch($scope.branch).then(function (newBranch) {
                $state.go('branch', {
                    branchId: newBranch.id
                });
            });
        }

        // Copy from a branch
        function copyFromBranch() {
            otCopyService.copyFrom($scope.branch).then(loadBranch);
        }

        // Creation of a promotion level
        $scope.createPromotionLevel = function () {
            otStructureService.create($scope.branch._createPromotionLevel, "New promotion level").then(loadBranch);
        };

        // Creation of a validation stamp
        $scope.createValidationStamp = function () {
            otStructureService.create($scope.branch._createValidationStamp, 'New validation stamp').then(loadBranch);
        };

        /**
         * Creating a validation run
         */
        $scope.createValidationRun = function (buildView, validationStampRunView) {
            otStructureService.create(
                buildView.build._validate,
                'Validation for the build',
                {
                    postForm: function (form) {
                        return otFormService.updateFieldValue(form, 'validationStamp', validationStampRunView.validationStamp.id);
                    }
                }
            ).then(loadBuildView);
        };

        /**
         * Displaying the promotion runs
         */
        $scope.displayPromotionRuns = function (buildView, promotionRun) {
            $modal.open({
                templateUrl: 'app/dialog/dialog.promotionRuns.tpl.html',
                controller: 'otDialogPromotionRuns',
                resolve: {
                    config: function () {
                        return {
                            build: buildView.build,
                            promotionLevel: promotionRun.promotionLevel,
                            uri: promotionRun._all
                        };
                    }
                }
            }).result.then(loadBuildView, loadBuildView);
        };

        /**
         * Displaying the validation runs
         */
        $scope.displayValidationRuns = function (buildView, validationStampRunView) {
            $modal.open({
                templateUrl: 'app/dialog/dialog.validationStampRunView.tpl.html',
                controller: 'otDialogValidationStampRunView',
                resolve: {
                    config: function () {
                        return {
                            buildView: buildView,
                            validationStampRunView: validationStampRunView
                        };
                    }
                }
            });
        };

        /**
         * Build diff action
         */
        $scope.buildDiff = function (action) {
            var selectedBuild = $scope.selectedBuild;
            if (selectedBuild.from && selectedBuild.to && selectedBuild.from != selectedBuild.to) {
                $state.go(action.id, {
                    branch: branchId,
                    from: selectedBuild.from,
                    to: selectedBuild.to
                });
            }
        };

        /**
         * Build filter: new one
         */
        $scope.buildFilterNew = function (buildFilterForm) {
            otBuildFilterService.createBuildFilter({
                branchId: branchId,
                buildFilterForm: buildFilterForm
            }).then(function () {
                // Reloads the filters
                loadBuildFilters();
            });
        };

        /**
         * Editing a filter
         */
        $scope.buildFilterEdit = function (buildFilterResource) {
            otBuildFilterService.editBuildFilter({
                branch: $scope.branch,
                buildFilterResource: buildFilterResource,
                buildFilterForms: $scope.buildFilterForms
            }).then(function () {
                // Reloads the filters
                loadBuildFilters();
            });
        };

        /**
         * Applying a filter
         */
        $scope.buildFilterApply = function (buildFilterResource) {
            if (!buildFilterResource.removing) {
                otBuildFilterService.storeCurrent(branchId, buildFilterResource);
                loadBuildView();
            }
        };

        /**
         * Removing the current filter
         */
        $scope.buildFilterErase = function () {
            otBuildFilterService.eraseCurrent(branchId);
            loadBuildView();
        };

        /**
         * Removing an existing filter
         */
        $scope.buildFilterRemove = function (buildFilterResource) {
            buildFilterResource.removing = true;
            otBuildFilterService.removeFilter($scope.branch, buildFilterResource).then(loadBuildFilters);
        };

        /**
         * Saving a local filter
         */
        $scope.buildFilterSave = function (buildFilterResource) {
            otBuildFilterService.saveFilter($scope.branch, buildFilterResource).then(loadBuildFilters);
        };

        /**
         * Sharing a saved filter
         */
        $scope.buildFilterShare = function (buildFilterResource) {
            otBuildFilterService.shareFilter($scope.branch, buildFilterResource).then(loadBuildFilters);
        };

        /**
         * Permalink to the current filter
         */
        $scope.buildFilterLink = function () {
            var currentFilter = otBuildFilterService.getCurrentFilter(branchId);
            if (currentFilter) {
                var jsonFilter = JSON.stringify(currentFilter);
                $location.hash(jsonFilter);
            }
        };

        /**
         * Loading the permalink at startup
         */
        function loadPermalink() {
            var jsonFilter = $location.hash();
            if (jsonFilter) {
                // Parsing the JSON
                try {
                    var json = JSON.parse(jsonFilter);
                    // Applies the filter
                    otBuildFilterService.storeCurrent(branchId, json);
                    // Removes the hash after use
                    $location.hash('');
                } catch (e) {
                    otNotificationService.error("Cannot get the filter from the permalink.");
                }
            }
        }

    })
;<|endoftext|>


<commit_before>"use strict";
/*
 * ooiui/static/js/views/common/TOCView.js
 * View definitions to build the table of contents
 *
 * Dependencies
 * Libs
 * - ooiui/static/lib/underscore/underscore.js
 * - ooiui/static/lib/backbone/backbone.js
 * - ooiui/static/js/ooi.js
 */

var TOCView = Backbone.View.extend({
    id: 'assetBrowser',
    events: {
        'keyup #search-filter' : 'filterToc'
    },
    initialize: function(options){
        _.bindAll(this, "render", "derender", "renderArrays", "renderAssets", "renderStreams");
        this.arrayCollection = options.arrayCollection;
        this.assetCollection = options.assetCollection;
        this.streamCollection = options.streamCollection;
        this.listenTo(vent, 'toc:derenderItems', function() {
            this.derender();
        });
    },
    template: JST['ooiui/static/js/partials/TOC.html'],
    renderArrays: function(){
        var arrayContainerView = this.arrayCollection.map(function(model) {
            return (new ArrayContainerView({ model:model })).render().el;
        });
        this.$el.find('ul.nav-list').append(arrayContainerView);
    },
    renderAssets: function(){
        // create a model for each item in the collection, and based on it's class,
        // render it in the browser as a platform or instrument.
        var filteredPlatforms = this.assetCollection.byClass('.AssetRecord');
        var filteredInstruments = this.assetCollection.byClass('.InstrumentAssetRecord');

        filteredPlatforms.map(function(model) {
            // get the array code from the reference designator
            var arrayCode = model.get('ref_des').substr(0,2);
            var assCode = model.get('ref_des').substr(0,8);

            // set the target to where this item will be inserted.
            var arrayTarget = '#array_'+ arrayCode;
            if ( document.getElementById( model.get('ref_des').substring(0,14)) == null ) {

                var assetItemView = new AssetItemView({ model:model });

                $( arrayTarget ).append( assetItemView.render().el );
            }

        });

        filteredInstruments.map(function(model) {
            var coord = model.get('coordinates');

            var platformCode = model.get('ref_des').substr(0,8);

            // set the target to where this item will be inserted.
            var platformTarget = 'ul#'+platformCode;
            if ( document.getElementById( model.get('ref_des')) == null ) {
                var assetItemView = new AssetItemView({ model:model });

                $( platformTarget ).append( assetItemView.render().el );
            }
        });
    },
    renderStreams: function() {
        if ( this.streamCollection != undefined ) {
            this.streamCollection.map( function(model) {
                var instrumentCode = model.get('reference_designator');
                var instrumentTarget = 'ul#'+instrumentCode;
                var streamItemView = new StreamItemView({ model:model });
                $( instrumentTarget ).append( streamItemView.render().el );
            });
        }
    },
    render: function(){
        this.$el.html(this.template());
        this.renderArrays();
        this.$el.find('[data-toggle="tooltip"]').tooltip();
        return this;
    },
    derender: function() {
        this.remove();
        this.unbind();
    },
});

var SearchResultView = Backbone.View.extend({
    tagName: 'ul',
    initialize: function() {
        _.bindAll(this, 'render', 'derender', 'onClick');
        this.listenTo(vent, 'toc:derenderItems', function() {
            this.derender();
        });

    },
    onClick: function() {
        ooi.trigger('toc:selectItem', this.model);
    },
    render: function(){
        var assetItemView = this.collection.map(function(model) {
            var coord = model.get('coordinates');
            if (coord) {
                return(new AssetItemView({ model:model }).render().el);
            }
        });
        this.$el.html(assetItemView);
        return this;
    },
    derender: function() {
        this.remove();
        this.unbind();
    },
});

var ArrayContainerView = Backbone.View.extend({
    tagName: 'li',
    attributes: function(){
        return {
            'style': 'width:100%'
        };
    },
    events:{
        'click .nav-header' : 'onClick',
        'click label.tree-toggler': 'collapse'
    },
    initialize: function(options) {
        _.bindAll(this, 'render', 'onClick', 'collapse');
        this.listenTo(vent, 'toc:derenderItems', function() {
            this.derender();
        });
    },
    collapse: function(e) {
        e.stopImmediatePropagation();
        this.$el.children('ul.tree').toggle(300);
    },
    onClick: function(e) {
                 ooi.trigger('toc:selectArray', this.model);
             },
    template: JST['ooiui/static/js/partials/ArrayItem.html'],
    render: function(){
        this.$el.html( this.template(this.model.toJSON()) );
        this.$el.append('

');
        return this;
    },
    derender: function() {
        this.remove();
        this.unbind();
        this.model.off;
    },
})

var AssetItemView = Backbone.View.extend({
    tagName: 'li',
    events: {
        'click label.platform': 'onClickPlatform',
        'click label.instrument': 'onClickInstrument',
        'click label.tree-toggler': 'collapse'
    },
    initialize: function(options) {
        _.bindAll(this,'render', 'onClickPlatform', 'onClickInstrument', 'collapse');
        this.listenTo(vent, 'toc:derenderItems', function() {
            this.derender();
        });
        this.listenTo(vent, 'toc:cleanUp', function() {
            if ( this.$el.find('ul.tree').children().length == 0 ) {
                this.$el.attr('style', 'color:grey');
            }
        });
    },
    onClickPlatform: function() {
        ooi.trigger('toc:selectPlatform', this.model);
    },
    onClickInstrument: function() {
        ooi.trigger('toc:selectInstrument', this.model);
    },
    collapse: function(e) {
        e.stopImmediatePropagation();
        this.$el.children('ul.tree').toggle(300);
    },
    template: _.template('<%= assetInfo.name %>'),
    derender: function() {
        this.remove();
        this.unbind();
        this.model.off;
    },
    render: function() {
        // If the asset class is an AssetRecord, give the view an ID of the
        // first 8 characters of the Reference Designator
        if (this.model.get('asset_class') == '.AssetRecord') {
            var platformName = this.model.get('assetInfo').name;
            var platformId = this.model.get('ref_des').substr(0,8);
            var assName = this.model.get('ref_des').substr(10,14);
            this.$el.attr('id', platformId);
            this.$el.attr('class', 'platform');
            this.$el.html( this.template(this.model.toJSON()) );
            // since this is an AssetRecord (platform / glider) lets assume
            // it'll need to have instruments attached to it...so create a container!
            var label = (platformName == undefined) ? platformId : '' + platformName + ' | ' + platformId + "-" + assName +'';
            this.$el.append(''+ label + '

');
        } else if(this.model.get('asset_class') == '.InstrumentAssetRecord') {
            // otherwise, if it's an InstrumentAssetRecord then give the view an ID
            // of the entire Reference Designator
            var instrumentName = this.model.get('assetInfo').name;
            var instrumentId = this.model.get('ref_des');
            this.$el.attr('id', instrumentId);
            this.$el.attr('class', 'instrument');
            this.$el.html( this.template(this.model.toJSON()) );
            var label = (instrumentName == undefined) ? instrumentId : '' + instrumentName + '' + instrumentId.substr(9,27) + '';
            this.$el.append(''+ label + '

');
        }
        return this;
    }
});

var StreamItemView = Backbone.View.extend({
    tagName: 'li',
    events: {
        'click': 'onClick'
    },
    initialize: function(options) {
        _.bindAll(this, 'render', 'derender', 'onClick');
        this.listenTo(vent, 'toc:denrenderItems', function() {
            this.derender();
        });
    },
    onClick: function(e) {
        $(".active-toc-item").removeClass("active-toc-item");
        e.stopImmediatePropagation();
        e.preventDefault();
        $(e.target).addClass("active-toc-item");

        var param_list = []
        var parameterhtml = "";
        for (var i = 0; i < this.model.get('variables').length; i++) {
            if (param_list.indexOf(this.model.get('variables')) == -1){
                var parameterId = this.model.get('parameter_id')[i];
                var units = this.model.get('units')[i];
                var variable = this.model.get('variables')[i];
                parameterhtml+= "<option pid='"+ parameterId +"' data-subtext='"+ units +"' >"+ variable +"</option>";
                param_list.push(variable);
            }
        }
        $.when( ooi.trigger('toc:selectStream', { model: this.model }) ).done(function() {
            $("div#yvar0-selection-default > div.form-group > select").append(parameterhtml);
            $("div#yvar1-selection > div.form-group > select").append(parameterhtml);
            $("div#yvar2-selection > div.form-group > select").append(parameterhtml);
            $("div#yvar3-selection > div.form-group > select").append(parameterhtml);
            $('#parameters_id').removeAttr('disabled');
            $('.selectpicker').selectpicker('refresh');
        });

    },
    template: _.template('<%= stream_name %>'),
    derender: function() {
        this.remove();
        this.unbind();
        this.model.off;
    },
    render: function() {
        this.$el.attr('id', this.model.get('reference_designator') + '-' + this.model.get('stream_name'));
        this.$el.html( this.template(this.model.toJSON()) );
        return this;
    }
});
<commit_msg>This was premature, but this needs to be addressed soon<commit_after>"use strict";
/*
 * ooiui/static/js/views/common/TOCView.js
 * View definitions to build the table of contents
 *
 * Dependencies
 * Libs
 * - ooiui/static/lib/underscore/underscore.js
 * - ooiui/static/lib/backbone/backbone.js
 * - ooiui/static/js/ooi.js
 */

var TOCView = Backbone.View.extend({
    id: 'assetBrowser',
    events: {
        'keyup #search-filter' : 'filterToc'
    },
    initialize: function(options){
        _.bindAll(this, "render", "derender", "renderArrays", "renderAssets", "renderStreams");
        this.arrayCollection = options.arrayCollection;
        this.assetCollection = options.assetCollection;
        this.streamCollection = options.streamCollection;
        this.listenTo(vent, 'toc:derenderItems', function() {
            this.derender();
        });
    },
    template: JST['ooiui/static/js/partials/TOC.html'],
    renderArrays: function(){
        var arrayContainerView = this.arrayCollection.map(function(model) {
            return (new ArrayContainerView({ model:model })).render().el;
        });
        this.$el.find('ul.nav-list').append(arrayContainerView);
    },
    renderAssets: function(){
        // create a model for each item in the collection, and based on it's class,
        // render it in the browser as a platform or instrument.
        var filteredPlatforms = this.assetCollection.byClass('.AssetRecord');
        var filteredInstruments = this.assetCollection.byClass('.InstrumentAssetRecord');

        filteredPlatforms.map(function(model) {
            // get the array code from the reference designator
            var arrayCode = model.get('ref_des').substr(0,2);
            var assCode = model.get('ref_des').substr(0,8);

            // set the target to where this item will be inserted.
            var arrayTarget = '#array_'+ arrayCode;
            if ( document.getElementById( model.get('ref_des').substring(0,8)) == null ) {

                var assetItemView = new AssetItemView({ model:model });

                $( arrayTarget ).append( assetItemView.render().el );
            }

        });

        filteredInstruments.map(function(model) {
            var coord = model.get('coordinates');

            var platformCode = model.get('ref_des').substr(0,8);

            // set the target to where this item will be inserted.
            var platformTarget = 'ul#'+platformCode;
            if ( document.getElementById( model.get('ref_des')) == null ) {
                var assetItemView = new AssetItemView({ model:model });

                $( platformTarget ).append( assetItemView.render().el );
            }
        });
    },
    renderStreams: function() {
        if ( this.streamCollection != undefined ) {
            this.streamCollection.map( function(model) {
                var instrumentCode = model.get('reference_designator');
                var instrumentTarget = 'ul#'+instrumentCode;
                var streamItemView = new StreamItemView({ model:model });
                $( instrumentTarget ).append( streamItemView.render().el );
            });
        }
    },
    render: function(){
        this.$el.html(this.template());
        this.renderArrays();
        this.$el.find('[data-toggle="tooltip"]').tooltip();
        return this;
    },
    derender: function() {
        this.remove();
        this.unbind();
    },
});

var SearchResultView = Backbone.View.extend({
    tagName: 'ul',
    initialize: function() {
        _.bindAll(this, 'render', 'derender', 'onClick');
        this.listenTo(vent, 'toc:derenderItems', function() {
            this.derender();
        });

    },
    onClick: function() {
        ooi.trigger('toc:selectItem', this.model);
    },
    render: function(){
        var assetItemView = this.collection.map(function(model) {
            var coord = model.get('coordinates');
            if (coord) {
                return(new AssetItemView({ model:model }).render().el);
            }
        });
        this.$el.html(assetItemView);
        return this;
    },
    derender: function() {
        this.remove();
        this.unbind();
    },
});

var ArrayContainerView = Backbone.View.extend({
    tagName: 'li',
    attributes: function(){
        return {
            'style': 'width:100%'
        };
    },
    events:{
        'click .nav-header' : 'onClick',
        'click label.tree-toggler': 'collapse'
    },
    initialize: function(options) {
        _.bindAll(this, 'render', 'onClick', 'collapse');
        this.listenTo(vent, 'toc:derenderItems', function() {
            this.derender();
        });
    },
    collapse: function(e) {
        e.stopImmediatePropagation();
        this.$el.children('ul.tree').toggle(300);
    },
    onClick: function(e) {
                 ooi.trigger('toc:selectArray', this.model);
             },
    template: JST['ooiui/static/js/partials/ArrayItem.html'],
    render: function(){
        this.$el.html( this.template(this.model.toJSON()) );
        this.$el.append('

');
        return this;
    },
    derender: function() {
        this.remove();
        this.unbind();
        this.model.off;
    },
})

var AssetItemView = Backbone.View.extend({
    tagName: 'li',
    events: {
        'click label.platform': 'onClickPlatform',
        'click label.instrument': 'onClickInstrument',
        'click label.tree-toggler': 'collapse'
    },
    initialize: function(options) {
        _.bindAll(this,'render', 'onClickPlatform', 'onClickInstrument', 'collapse');
        this.listenTo(vent, 'toc:derenderItems', function() {
            this.derender();
        });
        this.listenTo(vent, 'toc:cleanUp', function() {
            if ( this.$el.find('ul.tree').children().length == 0 ) {
                this.$el.attr('style', 'color:grey');
            }
        });
    },
    onClickPlatform: function() {
        ooi.trigger('toc:selectPlatform', this.model);
    },
    onClickInstrument: function() {
        ooi.trigger('toc:selectInstrument', this.model);
    },
    collapse: function(e) {
        e.stopImmediatePropagation();
        this.$el.children('ul.tree').toggle(300);
    },
    template: _.template('<%= assetInfo.name %>'),
    derender: function() {
        this.remove();
        this.unbind();
        this.model.off;
    },
    render: function() {
        // If the asset class is an AssetRecord, give the view an ID of the
        // first 8 characters of the Reference Designator
        if (this.model.get('asset_class') == '.AssetRecord') {
            var platformName = this.model.get('assetInfo').name;
            var platformId = this.model.get('ref_des').substr(0,8);
            var assName = this.model.get('ref_des').substr(10,14);
            this.$el.attr('id', platformId);
            this.$el.attr('class', 'platform');
            this.$el.html( this.template(this.model.toJSON()) );
            // since this is an AssetRecord (platform / glider) lets assume
            // it'll need to have instruments attached to it...so create a container!
            var label = (platformName == undefined) ? platformId : '' + platformName + ' | ' + platformId + "-" + assName +'';
            this.$el.append(''+ label + '

');
        } else if(this.model.get('asset_class') == '.InstrumentAssetRecord') {
            // otherwise, if it's an InstrumentAssetRecord then give the view an ID
            // of the entire Reference Designator
            var instrumentName = this.model.get('assetInfo').name;
            var instrumentId = this.model.get('ref_des');
            this.$el.attr('id', instrumentId);
            this.$el.attr('class', 'instrument');
            this.$el.html( this.template(this.model.toJSON()) );
            var label = (instrumentName == undefined) ? instrumentId : '' + instrumentName + '' + instrumentId.substr(9,27) + '';
            this.$el.append(''+ label + '

');
        }
        return this;
    }
});

var StreamItemView = Backbone.View.extend({
    tagName: 'li',
    events: {
        'click': 'onClick'
    },
    initialize: function(options) {
        _.bindAll(this, 'render', 'derender', 'onClick');
        this.listenTo(vent, 'toc:denrenderItems', function() {
            this.derender();
        });
    },
    onClick: function(e) {
        $(".active-toc-item").removeClass("active-toc-item");
        e.stopImmediatePropagation();
        e.preventDefault();
        $(e.target).addClass("active-toc-item");

        var param_list = []
        var parameterhtml = "";
        for (var i = 0; i < this.model.get('variables').length; i++) {
            if (param_list.indexOf(this.model.get('variables')) == -1){
                var parameterId = this.model.get('parameter_id')[i];
                var units = this.model.get('units')[i];
                var variable = this.model.get('variables')[i];
                parameterhtml+= "<option pid='"+ parameterId +"' data-subtext='"+ units +"' >"+ variable +"</option>";
                param_list.push(variable);
            }
        }
        $.when( ooi.trigger('toc:selectStream', { model: this.model }) ).done(function() {
            $("div#yvar0-selection-default > div.form-group > select").append(parameterhtml);
            $("div#yvar1-selection > div.form-group > select").append(parameterhtml);
            $("div#yvar2-selection > div.form-group > select").append(parameterhtml);
            $("div#yvar3-selection > div.form-group > select").append(parameterhtml);
            $('#parameters_id').removeAttr('disabled');
            $('.selectpicker').selectpicker('refresh');
        });

    },
    template: _.template('<%= stream_name %>'),
    derender: function() {
        this.remove();
        this.unbind();
        this.model.off;
    },
    render: function() {
        this.$el.attr('id', this.model.get('reference_designator') + '-' + this.model.get('stream_name'));
        this.$el.html( this.template(this.model.toJSON()) );
        return this;
    }
});
<|endoftext|>


<commit_before>/*
 Copyright (c) 2015, GEM Foundation.

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <https://www.gnu.org/licenses/agpl.html>.
 */

(function($, Backbone, _) {
    var progressHandlingFunction = function(progress) {
        var percent = progress.loaded / progress.total * 100;
        $('.bar').css('width', percent + '%');
        if (percent == 100) {
            dialog.hidePleaseWait();
        }
    };

    var dialog = (function ()
                  {
                      var pleaseWaitDiv = $('

Processing...

');
                      return {
                          showPleaseWait: function(msg, progress) {
                          $('h1', pleaseWaitDiv).text(msg);
                          if (progress) {
                          progressHandlingFunction({loaded: 0, total: 1});
                          } else {
                          progressHandlingFunction({loaded: 1, total: 1});
                      }
                              pleaseWaitDiv.modal();
                          },
                          hidePleaseWait: function () {
                              pleaseWaitDiv.modal('hide');
                          }
                      };
                  })();

    var diaerror = (function ()
                  {
                      var errorDiv = $('
\

\

\

\

Calculation not accepted: traceback
\

\

\

\

\
                      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\

\

\

\

');

//

Error

Close
');
//                      errorDiv.on("click", function(e) {
//                          this.hideDiaError();
//                      })
                      return {
                          showDiaError: function(title, msg) {
                              if (title != null) {
                                  $('.modal-title', errorDiv).html(title);
                              }
                              if (msg != null) {
                                  $('.modal-body-pre', errorDiv).html(msg);
                              }
                              errorDiv.modal();
                          },
                          hideDiaError: function () {
                              errorDiv.modal('hide');
                          }
                      };
                  })();

    var CalculationTable = Backbone.View.extend(
        {
            /* the html element where the table is rendered */
            el: $('#my-calculations'),

            initialize: function(options) {

                /* whatever happens to any calculation, re-render the table */
                _.bindAll(this, 'render');
                this.calculations = options.calculations;
                this.calculations.bind('reset', this.render);
                this.calculations.bind('add', this.render);
                this.calculations.bind('remove', this.render);

                /* if false, it prevents the table to be refreshed */
                this.can_be_rendered = true;

                this.render();
            },

            events: {
                "click .btn-danger": "remove_calculation",
                "click .btn-traceback": "show_traceback",
                "click .btn-file": "on_run_risk_clicked",
                "change .btn-file input": "on_run_risk_queued"
            },

            /* When an input dialog is opened, it is very important to not re-render the table */
            on_run_risk_clicked: function(e) {
                /* if a file input dialog has been opened do not refresh the calc table */
                this.can_be_rendered = false;
            },

            on_run_risk_queued: function(e) {
                this.can_be_rendered = true;
            },

            remove_calculation: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');
                var view = this;
                diaerror.showDiaError("Removing calculation  " + calc_id + ".", "...");
                $.post(gem_oq_server_url + "/v1/calc/" + calc_id + "/remove"
                     ).success(
                         function(data, textStatus, jqXHR)
                         {
                             diaerror.showDiaError("Remove calculation  " + calc_id + ".", "done");
                             view.calculations.remove([view.calculations.get(calc_id)]);
                         }
                     ).error(
                         function(jqXHR, textStatus, errorThrown)
                         {
                             if (jqXHR.status == 404) {
                                 diaerror.showDiaError("Remove calculation  " + calc_id + ".", "Failed: calculation " + calc_id + " not found.");
                             }
                             else {
                                 diaerror.showDiaError("Remove calculation  " + calc_id + ".", "Failed: " + textStatus);
                             }
                         }
                     );
            },

            show_traceback: function(e) {
                var calc_id = $(e.target).attr('data-calc-id');

                var myXhr = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/traceback",
                                    error: function (jqXHR, textStatus, errorThrown) {
                                        if (jqXHR.status == 404) {
                                            diaerror.showDiaError("Calculation " + calc_id + " not found.");
                                        }
                                        else {
                                            diaerror.showDiaError("Error retrieving traceback for calculation " + calc_id + ".", textStatus);
                                        }
                                        // alert("Error: " + textStatus);
                                    },
                                    success: function (data, textStatus, jqXHR) {
                                        if (data.length == 0) {
                                            diaerror.showDiaError("Traceback not found for calculation " + calc_id + ".", []);
                                        }
                                        else {
                                            out = ""
                                            for (s in data) {
                                                if (data[s] == "")
                                                    continue;
                                                out += data[s] + '\n';
                                            }
                                            diaerror.showDiaError("Traceback of calculation " + calc_id + ".", out);
                                        }
                                        // alert("Success: " + textStatus);
                                    }});
            },

            render: function() {
                if (!this.can_be_rendered) {
                    return;
                };
                this.$el.html(_.template($('#calculation-table-template').html(),
                                         { calculations: this.calculations.models }));
            }
        });

    var Calculation = Backbone.Model.extend({
        defaults: {
            map: null,
            layers: []
        }
    });

    var Calculations = Backbone.Collection.extend(
        {
            model: Calculation,
            url: gem_oq_server_url + "/v1/calc/list?relevant=true"
        });
    var calculations = new Calculations();

    var refresh_calcs;

    function setTimer() {
        refresh_calcs = setInterval(function() { calculations.fetch({reset: true}) }, 1000);
    }

    /* classic event management */
    $(document).ready(
        function() {
            var calculation_table = new CalculationTable({ calculations: calculations });
            calculations.fetch({reset: true});
            setTimer();

            /* XXX. Reset the input file value to ensure the change event
               will be always triggered */
            $(document).on("click", 'input[name=archive]',
                           function(e) { this.value = null; });
            $(document).on("change", 'input[name=archive]',
                           function(e) {
                               dialog.showPleaseWait('Uploading calculation', true);
                               var input = $(e.target);
                               var form = input.parents('form')[0];

                               $(form).ajaxSubmit(
                                   {
                                    xhr: function() {  // custom xhr to add progress bar management
                                        var myXhr = $.ajaxSettings.xhr();
                                        if(myXhr.upload){ // if upload property exists
                                            myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
                                        }
                                        return myXhr;
                                    },
                                    success: function(data) {
                                        calculations.add(new Calculation(data));
                                    },
                                    error: function(xhr) {
                                        dialog.hidePleaseWait();
                                        var s, out, ret = $.parseJSON(xhr.responseText);
                                        out = ""
                                        for (s in ret) {
                                            if (ret[s] == "")
                                                continue;
                                            out += ret[s] + '\n';
                                        }
                                        diaerror.showDiaError("Calculation not accepted: traceback", out);
                                    }});
                           });

            $(document).on('hidden.bs.modal', 'div[id^=traceback-]',
                           function(e) {
                               setTimer();
                           });

        });
})($, Backbone, _, gem_oq_server_url);
<commit_msg>Allow modal to be closed with 'esc' key<commit_after>/*
 Copyright (c) 2015, GEM Foundation.

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
 published by the Free Software Foundation, either version 3 of the
 License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <https://www.gnu.org/licenses/agpl.html>.
 */

(function($, Backbone, _) {
    var progressHandlingFunction = function(progress) {
        var percent = progress.loaded / progress.total * 100;
        $('.bar').css('width', percent + '%');
        if (percent == 100) {
            dialog.hidePleaseWait();
        }
    };

    var dialog = (function ()
                  {
                      var pleaseWaitDiv = $('

Processing...

');
                      return {
                          showPleaseWait: function(msg, progress) {
                          $('h1', pleaseWaitDiv).text(msg);
                          if (progress) {
                          progressHandlingFunction({loaded: 0, total: 1});
                          } else {
                          progressHandlingFunction({loaded: 1, total: 1});
                      }
                              pleaseWaitDiv.modal();
                          },
                          hidePleaseWait: function () {
                              pleaseWaitDiv.modal('hide');
                          }
                      };
                  })();

    var diaerror = (function ()
                  {
                      var errorDiv = $('
\

\

\

\

Calculation not accepted: traceback
\

\

\

\

\
                      <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>\

\

\

\

');

//

Error

Close
');
//                      errorDiv.on("click", function(e) {
//                          this.hideDiaError();
//                      })
                      return {
                          showDiaError: function(title, msg) {
                              if (title != null) {
                                  $('.modal-title', errorDiv).html(title);
                              }
                              if (msg != null) {
                                  $('.modal-body-pre', errorDiv).html(msg);
                              }
                              errorDiv.modal();
                          },
                          hideDiaError: function () {
                              errorDiv.modal('hide');
                          }
                      };
                  })();

    var CalculationTable = Backbone.View.extend(
        {
            /* the html element where the table is rendered */
            el: $('#my-calculations'),

            initialize: function(options) {

                /* whatever happens to any calculation, re-render the table */
                _.bindAll(this, 'render');
                this.calculations = options.calculations;
                this.calculations.bind('reset', this.render);
                this.calculations.bind('add', this.render);
                this.calculations.bind('remove', this.render);

                /* if false, it prevents the table to be refreshed */
                this.can_be_rendered = true;

                this.render();
            },

            events: {
                "click .btn-danger": "remove_calculation",
                "click .btn-traceback": "show_traceback",
                "click .btn-file": "on_run_risk_clicked",
                "change .btn-file input": "on_run_risk_queued"
            },

            /* When an input dialog is opened, it is very important to not re-render the table */
            on_run_risk_clicked: function(e) {
                /* if a file input dialog has been opened do not refresh the calc table */
                this.can_be_rendered = false;
            },

            on_run_risk_queued: function(e) {
                this.can_be_rendered = true;
            },

            remove_calculation: function(e) {
                e.preventDefault();
                var calc_id = $(e.target).attr('data-calc-id');
                var view = this;
                diaerror.showDiaError("Removing calculation  " + calc_id + ".", "...");
                $.post(gem_oq_server_url + "/v1/calc/" + calc_id + "/remove"
                     ).success(
                         function(data, textStatus, jqXHR)
                         {
                             diaerror.showDiaError("Remove calculation  " + calc_id + ".", "done");
                             view.calculations.remove([view.calculations.get(calc_id)]);
                         }
                     ).error(
                         function(jqXHR, textStatus, errorThrown)
                         {
                             if (jqXHR.status == 404) {
                                 diaerror.showDiaError("Remove calculation  " + calc_id + ".", "Failed: calculation " + calc_id + " not found.");
                             }
                             else {
                                 diaerror.showDiaError("Remove calculation  " + calc_id + ".", "Failed: " + textStatus);
                             }
                         }
                     );
            },

            show_traceback: function(e) {
                var calc_id = $(e.target).attr('data-calc-id');

                var myXhr = $.ajax({url: gem_oq_server_url + "/v1/calc/" + calc_id + "/traceback",
                                    error: function (jqXHR, textStatus, errorThrown) {
                                        if (jqXHR.status == 404) {
                                            diaerror.showDiaError("Calculation " + calc_id + " not found.");
                                        }
                                        else {
                                            diaerror.showDiaError("Error retrieving traceback for calculation " + calc_id + ".", textStatus);
                                        }
                                        // alert("Error: " + textStatus);
                                    },
                                    success: function (data, textStatus, jqXHR) {
                                        if (data.length == 0) {
                                            diaerror.showDiaError("Traceback not found for calculation " + calc_id + ".", []);
                                        }
                                        else {
                                            out = ""
                                            for (s in data) {
                                                if (data[s] == "")
                                                    continue;
                                                out += data[s] + '\n';
                                            }
                                            diaerror.showDiaError("Traceback of calculation " + calc_id + ".", out);
                                        }
                                        // alert("Success: " + textStatus);
                                    }});
            },

            render: function() {
                if (!this.can_be_rendered) {
                    return;
                };
                this.$el.html(_.template($('#calculation-table-template').html(),
                                         { calculations: this.calculations.models }));
            }
        });

    var Calculation = Backbone.Model.extend({
        defaults: {
            map: null,
            layers: []
        }
    });

    var Calculations = Backbone.Collection.extend(
        {
            model: Calculation,
            url: gem_oq_server_url + "/v1/calc/list?relevant=true"
        });
    var calculations = new Calculations();

    var refresh_calcs;

    function setTimer() {
        refresh_calcs = setInterval(function() { calculations.fetch({reset: true}) }, 1000);
    }

    /* classic event management */
    $(document).ready(
        function() {
            var calculation_table = new CalculationTable({ calculations: calculations });
            calculations.fetch({reset: true});
            setTimer();

            /* XXX. Reset the input file value to ensure the change event
               will be always triggered */
            $(document).on("click", 'input[name=archive]',
                           function(e) { this.value = null; });
            $(document).on("change", 'input[name=archive]',
                           function(e) {
                               dialog.showPleaseWait('Uploading calculation', true);
                               var input = $(e.target);
                               var form = input.parents('form')[0];

                               $(form).ajaxSubmit(
                                   {
                                    xhr: function() {  // custom xhr to add progress bar management
                                        var myXhr = $.ajaxSettings.xhr();
                                        if(myXhr.upload){ // if upload property exists
                                            myXhr.upload.addEventListener('progress', progressHandlingFunction, false);
                                        }
                                        return myXhr;
                                    },
                                    success: function(data) {
                                        calculations.add(new Calculation(data));
                                    },
                                    error: function(xhr) {
                                        dialog.hidePleaseWait();
                                        var s, out, ret = $.parseJSON(xhr.responseText);
                                        out = ""
                                        for (s in ret) {
                                            if (ret[s] == "")
                                                continue;
                                            out += ret[s] + '\n';
                                        }
                                        diaerror.showDiaError("Calculation not accepted: traceback", out);
                                    }});
                           });

            $(document).on('hidden.bs.modal', 'div[id^=traceback-]',
                           function(e) {
                               setTimer();
                           });

        });
})($, Backbone, _, gem_oq_server_url);
<|endoftext|>


<commit_before>vue_utils.push_component('app', {
    data: function () {
        return {
            feature_requests: null,
            edit_mode: false
        }
    },
    methods: {
        add: function () {
            this.edit_mode = true;
        },
        close_edit: function () {
            this.edit_mode = false;
            this.load();
        },
        load: function () {
            fetch($SCRIPT_ROOT + 'feature_request')
            .then(r => r.json())
            .then(r => {
                this.feature_requests = r;
            });
        }
    },
    created: function () {
        this.load();
    }
});

function start() {
    Vue.component('flat-pickr', VueFlatpickr.default);

    new Vue({
        el: '#Root'
    });
}

window.addEventListener('load', function () {
    vue_utils.register_components(start);
})<commit_msg>fix api urls in js<commit_after>vue_utils.push_component('app', {
    data: function () {
        return {
            feature_requests: null,
            edit_mode: false
        }
    },
    methods: {
        add: function () {
            this.edit_mode = true;
        },
        close_edit: function () {
            this.edit_mode = false;
            this.load();
        },
        load: function () {
            fetch($SCRIPT_ROOT + 'feature_request/')
            .then(r => r.json())
            .then(r => {
                this.feature_requests = r;
            });
        }
    },
    created: function () {
        this.load();
    }
});

function start() {
    Vue.component('flat-pickr', VueFlatpickr.default);

    new Vue({
        el: '#Root'
    });
}

window.addEventListener('load', function () {
    vue_utils.register_components(start);
})
<|endoftext|>


<commit_before>'use strict';

var includes       = require('es5-ext/array/#/contains')
  , identity       = require('es5-ext/function/identity')
  , toArray        = require('es5-ext/object/to-array')
  , ensureObject   = require('es5-ext/object/valid-object')
  , ensureCallable = require('es5-ext/object/valid-callable')
  , deferred       = require('deferred')
  , ensureDriver   = require('dbjs-persistence/ensure-driver')
  , getData        = require('../get-data');

/**
	*
	* @param data
	* driver                  - Database driver
	* processingStepsMeta     - map of processing steps
	* db                      - dbjs database
	* query (optional)        - query past from controller
	* customFilter (optional) - function used to filter by system specific parameters
	* @returns {Object}
*/
module.exports = function (data) {
	var driver = ensureDriver(ensureObject(data).driver)
	  , processingStepsMeta = ensureObject(data.processingStepsMeta)
	  , query = data.query || {}
	  , customFilter = data.customFilter ? ensureCallable(data.customFilter) : null;

	var result = {};

	// 1. Get data for all processing steps from all services
	return getData(driver, processingStepsMeta)(function (businessProcessesByStepsMap) {
		return deferred.map(Object.keys(businessProcessesByStepsMap), function (stepShortPath) {
			var entries = toArray(businessProcessesByStepsMap[stepShortPath], identity);

			// 2. Filter by step
			if (query.step && query.step !== stepShortPath) return;

			// 3. Filter by service
			if (query.service) {
				if (!includes.call(processingStepsMeta[stepShortPath]._services, query.service)) {
					return;
				}
				if (processingStepsMeta[stepShortPath]._services.length > 1) {
					entries = businessProcessesByStepsMap[stepShortPath].filter(function (entry) {
						return entry.serviceName === query.service;
					});
				}
			}
			if (!entries.length) return;

			// 4. Filter by date range
			if (query.dateFrom) {
				entries = entries.filter(function (data) {
					return data.processingDate >= query.dateFrom;
				});
			}
			if (query.dateTo) {
				entries = entries.filter(function (data) {
					return data.processingDate <= query.dateTo;
				});
			}

			// 5. Custom filter
			if (customFilter) {
				entries = deferred.map(entries, function (entry) {
					return customFilter(entry, query)(function (isOK) { return isOK ? entry : null; });
				}).invoke('filter', Boolean);
			}
			return deferred(entries)(function (filteredEntries) {
				result[stepShortPath] = filteredEntries;
			});
		});
	})(result);
};
<commit_msg>-- cleanup<commit_after>'use strict';

var includes       = require('es5-ext/array/#/contains')
  , identity       = require('es5-ext/function/identity')
  , toArray        = require('es5-ext/object/to-array')
  , ensureObject   = require('es5-ext/object/valid-object')
  , ensureCallable = require('es5-ext/object/valid-callable')
  , deferred       = require('deferred')
  , ensureDriver   = require('dbjs-persistence/ensure-driver')
  , getData        = require('../get-data');

/**
	*
	* @param data
	* driver                  - Database driver
	* processingStepsMeta     - map of processing steps
	* db                      - dbjs database
	* query (optional)        - query past from controller
	* customFilter (optional) - function used to filter by system specific parameters
	* @returns {Object}
*/
module.exports = function (data) {
	var driver = ensureDriver(ensureObject(data).driver)
	  , processingStepsMeta = ensureObject(data.processingStepsMeta)
	  , query = data.query || {}
	  , customFilter = data.customFilter ? ensureCallable(data.customFilter) : null;

	var result = {};

	return getData(driver, processingStepsMeta)(function (businessProcessesByStepsMap) {
		return deferred.map(Object.keys(businessProcessesByStepsMap), function (stepShortPath) {
			var entries = toArray(businessProcessesByStepsMap[stepShortPath], identity);

			// 1. Filter by service
			if (query.service) {
				if (!includes.call(processingStepsMeta[stepShortPath]._services, query.service)) {
					return;
				}
				if (processingStepsMeta[stepShortPath]._services.length > 1) {
					entries = businessProcessesByStepsMap[stepShortPath].filter(function (entry) {
						return entry.serviceName === query.service;
					});
					if (!entries.length) return;
				}
			}

			// 2. Filter by step
			if (query.step && query.step !== stepShortPath) return;

			// 3. Filter by date range
			if (query.dateFrom) {
				entries = entries.filter(function (data) {
					return data.processingDate >= query.dateFrom;
				});
			}
			if (query.dateTo) {
				entries = entries.filter(function (data) {
					return data.processingDate <= query.dateTo;
				});
			}

			// 4. Custom filter
			if (customFilter) {
				entries = deferred.map(entries, function (entry) {
					return customFilter(entry, query)(function (isOK) { return isOK ? entry : null; });
				}).invoke('filter', Boolean);
			}
			return deferred(entries)(function (filteredEntries) {
				result[stepShortPath] = filteredEntries;
			});
		});
	})(result);
};
<|endoftext|>


<commit_before>// @flow

const { logger } = require('@lagoon/commons/src/local-logging');
const { sendToLagoonLogs } = require('@lagoon/commons/src/logs');
const { createRemoveTask } = require('@lagoon/commons/src/tasks');

import type { WebhookRequestData, removeData, ChannelWrapper, Project  } from '../types';

async function bitbucketPullRequestClosed(webhook: WebhookRequestData, project: Project) {

    const {
      webhooktype,
      event,
      giturl,
      uuid,
      body,
    } = webhook;

    const meta = {
      pullrequestNumber: body.pullrequest.id
    }

    const data: removeData = {
      projectName: project.name,
      pullrequestNumber: body.pullrequest.id,
      pullrequestTitle: body.pullrequest.title,
      type: 'pullrequest'
    }

    try {
      const taskResult = await createRemoveTask(data);
      sendToLagoonLogs('info', project.name, uuid, `${webhooktype}:${event}:handled`, meta,
        `*[${project.name}]* \`${meta.branch}\` deleted in <${body.pullrequest.destination.repository.links.html.href}|${body.pullrequest.destination.branch.name}>`
      )
      return;
    } catch (error) {
      switch (error.name) {
        case "ProjectNotFound":
        case "NoActiveSystemsDefined":
        case "UnknownActiveSystem":
          // These are not real errors and also they will happen many times. We just log them locally but not throw an error
          sendToLagoonLogs('info', project.name, uuid, `${webhooktype}:${event}:handledButNoTask`, meta,
            `*[${project.name}]* \`${meta.branch}\` deleted. No remove task created, reason: ${error}`
          )
          return;

        case "CannotDeleteProductionEnvironment":
          // These are not real errors and also they will happen many times. We just log them locally but not throw an error
          sendToLagoonLogs('warning', project.name, uuid, `${webhooktype}:${event}:CannotDeleteProductionEnvironment`, meta,
            `*[${project.name}]* \`${meta.branch}\` not deleted. ${error}`
          )
          return;

        default:
          // Other messages are real errors and should reschedule the message in RabbitMQ in order to try again
          throw error
      }
    }
}

module.exports = bitbucketPullRequestClosed;
<commit_msg>update logs with more fields that exist.<commit_after>// @flow

const { logger } = require('@lagoon/commons/src/local-logging');
const { sendToLagoonLogs } = require('@lagoon/commons/src/logs');
const { createRemoveTask } = require('@lagoon/commons/src/tasks');

import type { WebhookRequestData, removeData, ChannelWrapper, Project  } from '../types';

async function bitbucketPullRequestClosed(webhook: WebhookRequestData, project: Project) {

    const {
      webhooktype,
      event,
      giturl,
      uuid,
      body,
    } = webhook;

    const meta = {
      pullrequestNumber: body.pullrequest.id
    }

    const data: removeData = {
      projectName: project.name,
      pullrequestNumber: body.pullrequest.id,
      pullrequestTitle: body.pullrequest.title,
      type: 'pullrequest'
    }

    try {
      const taskResult = await createRemoveTask(data);
      sendToLagoonLogs('info', project.name, uuid, `${webhooktype}:${event}:handled`, meta,
        `*[${project.name}]* PR \`${body.pullrequest.id}\` deleted in <${body.pullrequest.destination.repository.links.html.href}|${body.pullrequest.destination.branch.name}>`
      )
      return;
    } catch (error) {
      switch (error.name) {
        case "ProjectNotFound":
        case "NoActiveSystemsDefined":
        case "UnknownActiveSystem":
          // These are not real errors and also they will happen many times. We just log them locally but not throw an error
          sendToLagoonLogs('info', project.name, uuid, `${webhooktype}:${event}:handledButNoTask`, meta,
            `*[${project.name}]* \`${body.pullrequest.id}\` deleted. No remove task created, reason: ${error}`
          )
          return;

        case "CannotDeleteProductionEnvironment":
          // These are not real errors and also they will happen many times. We just log them locally but not throw an error
          sendToLagoonLogs('warning', project.name, uuid, `${webhooktype}:${event}:CannotDeleteProductionEnvironment`, meta,
            `*[${project.name}]* \`${meta.branch}\` not deleted. ${error}`
          )
          return;

        default:
          // Other messages are real errors and should reschedule the message in RabbitMQ in order to try again
          throw error
      }
    }
}

module.exports = bitbucketPullRequestClosed;
<|endoftext|>