<commit_before>angular.module('ot.view.home', [
    'ui.router',
    'ot.service.structure',
    'ot.service.core',
    'ot.service.user',
    'ot.service.graphql',
    'ot.service.label'
])
    .config(function ($stateProvider) {
        $stateProvider.state('home', {
            url: '/home',
            templateUrl: 'app/view/view.home.tpl.html',
            controller: 'HomeCtrl'
        });
    })
    .controller('HomeCtrl', function ($rootScope, $location, $log, $scope, $http, ot, otGraphqlService, otStructureService, otNotificationService, otUserService, otLabelService) {
        const search = $location.search();
        const code = search.code;
        const url = search.url;
        $rootScope.view = {
            // Title
            title: 'Home',
            // Commands
            commands: []
        };

        // Preloading filter mode
        $scope.preloadingLabelFilter = true;

        // No initial filter
        $scope.projectFilter = {
            name: '',
            label: undefined
        };

        // GraphQL fragment for the decorations
        const decorationFragment = `
            fragment decorationContent on Decoration {
              decorationType
              error
              data
              feature {
                id
              }
            }
        `;

        // GraphQL fragment for the displayed projects
        const projectFragment = `
            fragment projectContent on Project {
                id
                name
                labels {
                  id
                  category
                  name
                  description
                  color
                  foregroundColor
                  computedBy {
                    id
                    name
                  }
                }
                links {
                  _favourite
                  _unfavourite
                }
                decorations {
                  ...decorationContent
                }
            }
        `;

        // Full GraphQL query
        const fullQuery = ` query HomePage(
                    $includeProjects: Boolean!,
                    $maxBranches: Int!
                ) {
                  userRootActions {
                    projectCreate
                  }
                  labels {
                    id
                    category
                    name
                    description
                    color
                    foregroundColor
                    computedBy {
                        id
                        name
                    }
                    links {
                        _update
                        _delete
                    }
                  }
                  favouriteBranches: branches(favourite: true) {
                    project {
                      name
                      links {
                        _page
                      }
                    }
                    id
                    name
                    disabled
                    type
                    decorations {
                      ...decorationContent
                    }
                    creation {
                      time
                    }
                    links {
                      _page
                      _enable
                      _disable
                      _delete
                      _unfavourite
                      _favourite
                    }
                    latestBuild: builds(count: 1) {
                      id
                      name
                      creation {
                          time
                      }
                    }
                    promotionLevels {
                      id
                      name
                      image
                      _image
                      promotionRuns(first: 1) {
                        build {
                          id
                          name
                        }
                      }
                    }
                  }
                  projects @include(if: $includeProjects) {
                    ...projectContent
                  }
                  projectFavourites: projects(favourites: true) {
                    id
                    name
                    disabled
                    decorations {
                      ...decorationContent
                    }
                    links {
                      _unfavourite
                    }
                    branches(useModel: true, count: $maxBranches) {
                      id
                      name
                      type
                      disabled
                      decorations {
                        ...decorationContent
                      }
                      latestPromotions: builds(lastPromotions: true, count: 1) {
                        id
                        name
                        promotionRuns {
                          promotionLevel {
                            id
                            name
                            image
                            _image
                          }
                        }
                      }
                      latestBuild: builds(count: 1) {
                        id
                        name
                      }
                    }
                  }
                }

                ${projectFragment}

                ${decorationFragment}
                `;

        // Projects by name
        const projectQuery = `
            query ProjectQuery(pattern: String!) {
                projects(pattern: $pattern) {
                    ...projectContent
                }
            }

            ${projectFragment}

            ${decorationFragment}
        `;

        // Loading the project list
        function loadProjects() {
            $scope.loadingProjects = true;
            // We start collecting some global settings
            otGraphqlService.pageGraphQLCall(`{
                settings {
                    homePage {
                        maxBranches
                        maxProjects
                    }
                }
                entityCounts {
                    projects
                }
            }`).then(global => {
                // Storing the data
                $scope.maxBranches = global.settings.homePage.maxBranches;
                $scope.maxProjects = global.settings.homePage.maxProjects;
                $scope.projectCount = global.entityCounts.projects;
                // Must the projects be included?
                $scope.includeProjects = $scope.projectCount <= $scope.maxProjects;
                // Actual call
                return otGraphqlService.pageGraphQLCall(fullQuery, {
                    includeProjects: $scope.includeProjects,
                    maxBranches: $scope.maxBranches
                });
            }).then(function (data) {

                $scope.projectsData = data;
                $scope.projectFavourites = data.projectFavourites;
                $scope.favouriteBranches = data.favouriteBranches;

                if ($scope.includeProjects) {
                    preloadLabelFilter();
                }

                // All branches disabled status computation
                $scope.projectFavourites.forEach(function (projectFavourite) {
                    projectFavourite.allBranchesDisabled = projectFavourite.branches.length > 0 &&
                        projectFavourite.branches.every(function (branch) {
                            return branch.disabled || branch.type === 'TEMPLATE_DEFINITION';
                        });
                });

                // Commands
                $rootScope.view.commands = [
                    {
                        id: 'createProject',
                        name: 'Create project',
                        cls: 'ot-command-project-new',
                        condition: function () {
                            return data.userRootActions.projectCreate;
                        },
                        action: $scope.createProject
                    }, {
                        id: 'showDisabled',
                        name: "Show all hidden items",
                        cls: 'ot-command-show-disabled',
                        condition: function () {
                            return !$scope.showDisabled;
                        },
                        action: function () {
                            $scope.showDisabled = true;
                        }
                    }, {
                        id: 'hideDisabled',
                        name: "Hide disabled items",
                        cls: 'ot-command-hide-disabled',
                        condition: function () {
                            return $scope.showDisabled;
                        },
                        action: function () {
                            $scope.showDisabled = false;
                        }
                    }, {
                        name: "API",
                        cls: 'ot-command-api',
                        link: '/api-doc'
                    }, {
                        name: "GraphiQL",
                        cls: 'ot-command-api',
                        absoluteLink: "graphiql.html"
                    }
                ];
            }).finally(function () {
                $scope.loadingProjects = false;
            });

        }

        // Search for the projects by name
        // TODO Fuzzy search is needed (name part only)
        $scope.onProjectSearch = () => {
            if ($scope.projectFilter.name) {
                $scope.searchingProjects = true;
                otGraphqlService.pageGraphQLCall(projectQuery, { pattern: $scope.projectFilter.name}).then(data => {
                    $scope.projectsData.projects = data.projects;
                    $scope.searchingReturnsNoResult = (data.projects.length === 0);
                }).finally(() => {
                    $scope.searchingProjects = false;
                });
            }
        };

        // Creating a project
        $scope.createProject = function () {
            otStructureService.createProject($scope.projectsData.userRootActions.projectCreate).then(loadProjects);
        };

        // Sets a project as favourite
        $scope.projectFavourite = function (project) {
            if (project.links._favourite) {
                ot.pageCall($http.put(project.links._favourite)).then(loadProjects);
            }
        };

        // Unsets a project as favourite
        $scope.projectUnfavourite = function (project) {
            if (project.links._unfavourite) {
                ot.pageCall($http.put(project.links._unfavourite)).then(loadProjects);
            }
        };

        // Sets a branch as favourite
        $scope.branchFavourite = function (branch) {
            if (branch.links._favourite) {
                ot.pageCall($http.put(branch.links._favourite)).then(loadProjects);
            }
        };

        // Unsets a branch as favourite
        $scope.branchUnfavourite = function (branch) {
            if (branch.links._unfavourite) {
                ot.pageCall($http.put(branch.links._unfavourite)).then(loadProjects);
            }
        };

        // Selecting a label
        $scope.projectFilterSelectLabel = (label) => {
            $scope.projectFilter.label = label;
        };

        // Clearing the label selection
        $scope.projectFilterClearLabel = () => {
            $scope.projectFilter.label = undefined;
        };

        const LOCATION_KEY = "label";
        const STORAGE_KEY = "home.label";

        // Management of the location search component in case of label change
        $scope.$watch('projectFilter.label', function () {
            if (!$scope.preloadingLabelFilter) {
                if ($scope.projectFilter.label) {
                    let labelKey = $scope.formatLabel($scope.projectFilter.label);
                    $location.search(LOCATION_KEY, labelKey);
                    localStorage.setItem(STORAGE_KEY, labelKey);
                } else {
                    $location.search(LOCATION_KEY, undefined);
                    localStorage.removeItem(STORAGE_KEY);
                }
            }
        });

        // Preloading of the label filter
        function preloadLabelFilter() {
            // Gets the label key
            let labelKey = getLabelKeyFromBrowser();
            // If defined, identifies and sets the filter
            let label = $scope.projectsData.labels.find(it => {
                return $scope.formatLabel(it) === labelKey;
            });
            if (label) {
                $scope.projectFilter.label = label;
            }
            // Done
            $scope.preloadingLabelFilter = false;
        }

        function getLabelKeyFromBrowser() {
            let key = $location.search().label;
            if (key) {
                return key;
            } else {
                return localStorage.getItem(STORAGE_KEY);
            }
        }

        // Filtering the labels for a token
        $scope.typeAheadFilterLabels = (token) => {
            return $scope.projectsData.labels.filter(label => {
                return !token || ($scope.formatLabel(label).toLowerCase().indexOf(token.toLowerCase()) >= 0);
            });
        };

        // Formatting a label for a type-ahead
        $scope.formatLabel = otLabelService.formatLabel;

        // Project filter function
        $scope.projectFilterFn = (project) => {
            return projectFilterNameFn(project) && projectFilterLabelFn(project);
        };

        const projectFilterNameFn = project => {
            return !$scope.projectFilter.name || project.name.toLowerCase().indexOf($scope.projectFilter.name.toLowerCase()) >= 0;
        };

        const projectFilterLabelFn = project => {
            return !$scope.projectFilter.label || project.labels.some(it => it.id === $scope.projectFilter.label.id);
        };

        // Login procedure
        $scope.accessStatus = 'undefined';
        if (code && Number(code) === 403) {
            $log.debug('[403] received');
            if (otUserService.logged()) {
                $scope.accessStatus = 'unauthorised';
                $log.debug('[403] user already logged - error notification');
            } else {
                $scope.accessStatus = 'login-requested';
                $log.debug('[403] user not logged - login redirection - callback URL = ' + url);
                otUserService.login().then(function () {
                    $scope.accessStatus = 'ok';
                    if (url) {
                        // Callback URL
                        $log.debug('[403] reloading ' + url + 'after signing in.');
                        location.href = url;
                        location.reload();
                    } else {
                        // Reloads current page
                        $log.debug('[403] reloading after signing in.');
                        location.reload();
                    }
                }, function () {
                    $scope.accessStatus = 'login-failed';
                    $log.debug('[403] user cannot be logged - error notification');
                });
            }
        } else if ($rootScope.user && $rootScope.user.authenticationRequired && !$rootScope.user.logged) {
            $scope.accessStatus = 'login-requested';
            $log.debug('user not logged and authentication is required');
            otUserService.login().then(function () {
                $scope.accessStatus = 'ok';
                $log.debug('[403] reloading after signing in.');
                location.reload();
            }, function () {
                $scope.accessStatus = 'login-failed';
                $log.debug('[403] user cannot be logged - error notification');
            });
        } else {
            $scope.accessStatus = 'ok';
            // Loading the list of projects
            loadProjects();
        }

    })
;<commit_msg>#859 Query correction<commit_after>angular.module('ot.view.home', [
    'ui.router',
    'ot.service.structure',
    'ot.service.core',
    'ot.service.user',
    'ot.service.graphql',
    'ot.service.label'
])
    .config(function ($stateProvider) {
        $stateProvider.state('home', {
            url: '/home',
            templateUrl: 'app/view/view.home.tpl.html',
            controller: 'HomeCtrl'
        });
    })
    .controller('HomeCtrl', function ($rootScope, $location, $log, $scope, $http, ot, otGraphqlService, otStructureService, otNotificationService, otUserService, otLabelService) {
        const search = $location.search();
        const code = search.code;
        const url = search.url;
        $rootScope.view = {
            // Title
            title: 'Home',
            // Commands
            commands: []
        };

        // Preloading filter mode
        $scope.preloadingLabelFilter = true;

        // No initial filter
        $scope.projectFilter = {
            name: '',
            label: undefined
        };

        // GraphQL fragment for the decorations
        const decorationFragment = `
            fragment decorationContent on Decoration {
              decorationType
              error
              data
              feature {
                id
              }
            }
        `;

        // GraphQL fragment for the displayed projects
        const projectFragment = `
            fragment projectContent on Project {
                id
                name
                labels {
                  id
                  category
                  name
                  description
                  color
                  foregroundColor
                  computedBy {
                    id
                    name
                  }
                }
                links {
                  _favourite
                  _unfavourite
                }
                decorations {
                  ...decorationContent
                }
            }
        `;

        // Full GraphQL query
        const fullQuery = ` query HomePage(
                    $includeProjects: Boolean!,
                    $maxBranches: Int!
                ) {
                  userRootActions {
                    projectCreate
                  }
                  labels {
                    id
                    category
                    name
                    description
                    color
                    foregroundColor
                    computedBy {
                        id
                        name
                    }
                    links {
                        _update
                        _delete
                    }
                  }
                  favouriteBranches: branches(favourite: true) {
                    project {
                      name
                      links {
                        _page
                      }
                    }
                    id
                    name
                    disabled
                    type
                    decorations {
                      ...decorationContent
                    }
                    creation {
                      time
                    }
                    links {
                      _page
                      _enable
                      _disable
                      _delete
                      _unfavourite
                      _favourite
                    }
                    latestBuild: builds(count: 1) {
                      id
                      name
                      creation {
                          time
                      }
                    }
                    promotionLevels {
                      id
                      name
                      image
                      _image
                      promotionRuns(first: 1) {
                        build {
                          id
                          name
                        }
                      }
                    }
                  }
                  projects @include(if: $includeProjects) {
                    ...projectContent
                  }
                  projectFavourites: projects(favourites: true) {
                    id
                    name
                    disabled
                    decorations {
                      ...decorationContent
                    }
                    links {
                      _unfavourite
                    }
                    branches(useModel: true, count: $maxBranches) {
                      id
                      name
                      type
                      disabled
                      decorations {
                        ...decorationContent
                      }
                      latestPromotions: builds(lastPromotions: true, count: 1) {
                        id
                        name
                        promotionRuns {
                          promotionLevel {
                            id
                            name
                            image
                            _image
                          }
                        }
                      }
                      latestBuild: builds(count: 1) {
                        id
                        name
                      }
                    }
                  }
                }

                ${projectFragment}

                ${decorationFragment}
                `;

        // Projects by name
        const projectQuery = `
            query ProjectQuery($pattern: String!) {
                projects(pattern: $pattern) {
                    ...projectContent
                }
            }

            ${projectFragment}

            ${decorationFragment}
        `;

        // Loading the project list
        function loadProjects() {
            $scope.loadingProjects = true;
            // We start collecting some global settings
            otGraphqlService.pageGraphQLCall(`{
                settings {
                    homePage {
                        maxBranches
                        maxProjects
                    }
                }
                entityCounts {
                    projects
                }
            }`).then(global => {
                // Storing the data
                $scope.maxBranches = global.settings.homePage.maxBranches;
                $scope.maxProjects = global.settings.homePage.maxProjects;
                $scope.projectCount = global.entityCounts.projects;
                // Must the projects be included?
                $scope.includeProjects = $scope.projectCount <= $scope.maxProjects;
                // Actual call
                return otGraphqlService.pageGraphQLCall(fullQuery, {
                    includeProjects: $scope.includeProjects,
                    maxBranches: $scope.maxBranches
                });
            }).then(function (data) {

                $scope.projectsData = data;
                $scope.projectFavourites = data.projectFavourites;
                $scope.favouriteBranches = data.favouriteBranches;

                if ($scope.includeProjects) {
                    preloadLabelFilter();
                }

                // All branches disabled status computation
                $scope.projectFavourites.forEach(function (projectFavourite) {
                    projectFavourite.allBranchesDisabled = projectFavourite.branches.length > 0 &&
                        projectFavourite.branches.every(function (branch) {
                            return branch.disabled || branch.type === 'TEMPLATE_DEFINITION';
                        });
                });

                // Commands
                $rootScope.view.commands = [
                    {
                        id: 'createProject',
                        name: 'Create project',
                        cls: 'ot-command-project-new',
                        condition: function () {
                            return data.userRootActions.projectCreate;
                        },
                        action: $scope.createProject
                    }, {
                        id: 'showDisabled',
                        name: "Show all hidden items",
                        cls: 'ot-command-show-disabled',
                        condition: function () {
                            return !$scope.showDisabled;
                        },
                        action: function () {
                            $scope.showDisabled = true;
                        }
                    }, {
                        id: 'hideDisabled',
                        name: "Hide disabled items",
                        cls: 'ot-command-hide-disabled',
                        condition: function () {
                            return $scope.showDisabled;
                        },
                        action: function () {
                            $scope.showDisabled = false;
                        }
                    }, {
                        name: "API",
                        cls: 'ot-command-api',
                        link: '/api-doc'
                    }, {
                        name: "GraphiQL",
                        cls: 'ot-command-api',
                        absoluteLink: "graphiql.html"
                    }
                ];
            }).finally(function () {
                $scope.loadingProjects = false;
            });

        }

        // Search for the projects by name
        // TODO Fuzzy search is needed (name part only)
        $scope.onProjectSearch = () => {
            if ($scope.projectFilter.name) {
                $scope.searchingProjects = true;
                otGraphqlService.pageGraphQLCall(projectQuery, { pattern: $scope.projectFilter.name}).then(data => {
                    $scope.projectsData.projects = data.projects;
                    $scope.searchingReturnsNoResult = (data.projects.length === 0);
                }).finally(() => {
                    $scope.searchingProjects = false;
                });
            }
        };

        // Creating a project
        $scope.createProject = function () {
            otStructureService.createProject($scope.projectsData.userRootActions.projectCreate).then(loadProjects);
        };

        // Sets a project as favourite
        $scope.projectFavourite = function (project) {
            if (project.links._favourite) {
                ot.pageCall($http.put(project.links._favourite)).then(loadProjects);
            }
        };

        // Unsets a project as favourite
        $scope.projectUnfavourite = function (project) {
            if (project.links._unfavourite) {
                ot.pageCall($http.put(project.links._unfavourite)).then(loadProjects);
            }
        };

        // Sets a branch as favourite
        $scope.branchFavourite = function (branch) {
            if (branch.links._favourite) {
                ot.pageCall($http.put(branch.links._favourite)).then(loadProjects);
            }
        };

        // Unsets a branch as favourite
        $scope.branchUnfavourite = function (branch) {
            if (branch.links._unfavourite) {
                ot.pageCall($http.put(branch.links._unfavourite)).then(loadProjects);
            }
        };

        // Selecting a label
        $scope.projectFilterSelectLabel = (label) => {
            $scope.projectFilter.label = label;
        };

        // Clearing the label selection
        $scope.projectFilterClearLabel = () => {
            $scope.projectFilter.label = undefined;
        };

        const LOCATION_KEY = "label";
        const STORAGE_KEY = "home.label";

        // Management of the location search component in case of label change
        $scope.$watch('projectFilter.label', function () {
            if (!$scope.preloadingLabelFilter) {
                if ($scope.projectFilter.label) {
                    let labelKey = $scope.formatLabel($scope.projectFilter.label);
                    $location.search(LOCATION_KEY, labelKey);
                    localStorage.setItem(STORAGE_KEY, labelKey);
                } else {
                    $location.search(LOCATION_KEY, undefined);
                    localStorage.removeItem(STORAGE_KEY);
                }
            }
        });

        // Preloading of the label filter
        function preloadLabelFilter() {
            // Gets the label key
            let labelKey = getLabelKeyFromBrowser();
            // If defined, identifies and sets the filter
            let label = $scope.projectsData.labels.find(it => {
                return $scope.formatLabel(it) === labelKey;
            });
            if (label) {
                $scope.projectFilter.label = label;
            }
            // Done
            $scope.preloadingLabelFilter = false;
        }

        function getLabelKeyFromBrowser() {
            let key = $location.search().label;
            if (key) {
                return key;
            } else {
                return localStorage.getItem(STORAGE_KEY);
            }
        }

        // Filtering the labels for a token
        $scope.typeAheadFilterLabels = (token) => {
            return $scope.projectsData.labels.filter(label => {
                return !token || ($scope.formatLabel(label).toLowerCase().indexOf(token.toLowerCase()) >= 0);
            });
        };

        // Formatting a label for a type-ahead
        $scope.formatLabel = otLabelService.formatLabel;

        // Project filter function
        $scope.projectFilterFn = (project) => {
            return projectFilterNameFn(project) && projectFilterLabelFn(project);
        };

        const projectFilterNameFn = project => {
            return !$scope.projectFilter.name || project.name.toLowerCase().indexOf($scope.projectFilter.name.toLowerCase()) >= 0;
        };

        const projectFilterLabelFn = project => {
            return !$scope.projectFilter.label || project.labels.some(it => it.id === $scope.projectFilter.label.id);
        };

        // Login procedure
        $scope.accessStatus = 'undefined';
        if (code && Number(code) === 403) {
            $log.debug('[403] received');
            if (otUserService.logged()) {
                $scope.accessStatus = 'unauthorised';
                $log.debug('[403] user already logged - error notification');
            } else {
                $scope.accessStatus = 'login-requested';
                $log.debug('[403] user not logged - login redirection - callback URL = ' + url);
                otUserService.login().then(function () {
                    $scope.accessStatus = 'ok';
                    if (url) {
                        // Callback URL
                        $log.debug('[403] reloading ' + url + 'after signing in.');
                        location.href = url;
                        location.reload();
                    } else {
                        // Reloads current page
                        $log.debug('[403] reloading after signing in.');
                        location.reload();
                    }
                }, function () {
                    $scope.accessStatus = 'login-failed';
                    $log.debug('[403] user cannot be logged - error notification');
                });
            }
        } else if ($rootScope.user && $rootScope.user.authenticationRequired && !$rootScope.user.logged) {
            $scope.accessStatus = 'login-requested';
            $log.debug('user not logged and authentication is required');
            otUserService.login().then(function () {
                $scope.accessStatus = 'ok';
                $log.debug('[403] reloading after signing in.');
                location.reload();
            }, function () {
                $scope.accessStatus = 'login-failed';
                $log.debug('[403] user cannot be logged - error notification');
            });
        } else {
            $scope.accessStatus = 'ok';
            // Loading the list of projects
            loadProjects();
        }

    })
;<|endoftext|>


<commit_before>angular.module('ot.view.home', [
    'ui.router',
    'ot.service.structure',
    'ot.service.core',
    'ot.service.user',
    'ot.service.graphql',
    'ot.service.label'
])
    .config(function ($stateProvider) {
        $stateProvider.state('home', {
            url: '/home',
            templateUrl: 'app/view/view.home.tpl.html',
            controller: 'HomeCtrl'
        });
    })
    .controller('HomeCtrl', function ($rootScope, $location, $log, $scope, $http, ot, otGraphqlService, otStructureService, otNotificationService, otUserService, otLabelService) {
        const search = $location.search();
        const code = search.code;
        const url = search.url;
        $rootScope.view = {
            // Title
            title: 'Home',
            // Commands
            commands: []
        };

        // Preloading filter mode
        $scope.preloadingLabelFilter = true;

        // No initial filter
        $scope.projectFilter = {
            name: '',
            label: undefined
        };

        // Loading the project list
        function loadProjects() {
            $scope.loadingProjects = true;
            // We start collecting some global settings
            otGraphqlService.pageGraphQLCall(`{
                settings {
                    homePage {
                        maxBranches
                        maxProjects
                    }
                }
                entityCounts {
                    projects
                }
            }`).then(global => {
                // Storing the data
                $scope.maxBranches = global.settings.homePage.maxBranches;
                $scope.maxProjects = global.settings.homePage.maxProjects;
                $scope.projectCount = global.entityCounts.projects;
                // Must the projects be included?
                $scope.includeProjects = $scope.projectCount <= $scope.maxProjects;
                // Actual call
                return otGraphqlService.pageGraphQLCall(` query HomePage(
                    $includeProjects: Boolean!
                ) {
                  userRootActions {
                    projectCreate
                  }
                  labels {
                    id
                    category
                    name
                    description
                    color
                    foregroundColor
                    computedBy {
                        id
                        name
                    }
                    links {
                        _update
                        _delete
                    }
                  }
                  favouriteBranches: branches(favourite: true) {
                    project {
                      name
                      links {
                        _page
                      }
                    }
                    id
                    name
                    disabled
                    type
                    decorations {
                      ...decorationContent
                    }
                    creation {
                      time
                    }
                    links {
                      _page
                      _enable
                      _disable
                      _delete
                      _unfavourite
                      _favourite
                    }
                    latestBuild: builds(count: 1) {
                      id
                      name
                      creation {
                          time
                      }
                    }
                    promotionLevels {
                      id
                      name
                      image
                      _image
                      promotionRuns(first: 1) {
                        build {
                          id
                          name
                        }
                      }
                    }
                  }
                  projects @include(if: $includeProjects) {
                    id
                    name
                    labels {
                      id
                      category
                      name
                      description
                      color
                      foregroundColor
                      computedBy {
                        id
                        name
                      }
                    }
                    links {
                      _favourite
                      _unfavourite
                    }
                    decorations {
                      ...decorationContent
                    }
                  }
                  projectFavourites: projects(favourites: true) {
                    id
                    name
                    disabled
                    decorations {
                      ...decorationContent
                    }
                    links {
                      _unfavourite
                    }
                    branches(useModel: true, count: ${$scope.maxBranches}) {
                      id
                      name
                      type
                      disabled
                      decorations {
                        ...decorationContent
                      }
                      latestPromotions: builds(lastPromotions: true, count: 1) {
                        id
                        name
                        promotionRuns {
                          promotionLevel {
                            id
                            name
                            image
                            _image
                          }
                        }
                      }
                      latestBuild: builds(count: 1) {
                        id
                        name
                      }
                    }
                  }
                }

                fragment decorationContent on Decoration {
                  decorationType
                  error
                  data
                  feature {
                    id
                  }
                }
                `, {
                    includeProjects: $scope.includeProjects
                });
            }).then(function (data) {

                $scope.projectsData = data;
                $scope.projectFavourites = data.projectFavourites;
                $scope.favouriteBranches = data.favouriteBranches;

                if ($scope.includeProjects) {
                    preloadLabelFilter();
                }

                // All branches disabled status computation
                $scope.projectFavourites.forEach(function (projectFavourite) {
                    projectFavourite.allBranchesDisabled = projectFavourite.branches.length > 0 &&
                        projectFavourite.branches.every(function (branch) {
                            return branch.disabled || branch.type === 'TEMPLATE_DEFINITION';
                        });
                });

                // Commands
                $rootScope.view.commands = [
                    {
                        id: 'createProject',
                        name: 'Create project',
                        cls: 'ot-command-project-new',
                        condition: function () {
                            return data.userRootActions.projectCreate;
                        },
                        action: $scope.createProject
                    }, {
                        id: 'showDisabled',
                        name: "Show all hidden items",
                        cls: 'ot-command-show-disabled',
                        condition: function () {
                            return !$scope.showDisabled;
                        },
                        action: function () {
                            $scope.showDisabled = true;
                        }
                    }, {
                        id: 'hideDisabled',
                        name: "Hide disabled items",
                        cls: 'ot-command-hide-disabled',
                        condition: function () {
                            return $scope.showDisabled;
                        },
                        action: function () {
                            $scope.showDisabled = false;
                        }
                    }, {
                        name: "API",
                        cls: 'ot-command-api',
                        link: '/api-doc'
                    }, {
                        name: "GraphiQL",
                        cls: 'ot-command-api',
                        absoluteLink: "graphiql.html"
                    }
                ];
            }).finally(function () {
                $scope.loadingProjects = false;
            });

        }

        // Creating a project
        $scope.createProject = function () {
            otStructureService.createProject($scope.projectsData.userRootActions.projectCreate).then(loadProjects);
        };

        // Sets a project as favourite
        $scope.projectFavourite = function (project) {
            if (project.links._favourite) {
                ot.pageCall($http.put(project.links._favourite)).then(loadProjects);
            }
        };

        // Unsets a project as favourite
        $scope.projectUnfavourite = function (project) {
            if (project.links._unfavourite) {
                ot.pageCall($http.put(project.links._unfavourite)).then(loadProjects);
            }
        };

        // Sets a branch as favourite
        $scope.branchFavourite = function (branch) {
            if (branch.links._favourite) {
                ot.pageCall($http.put(branch.links._favourite)).then(loadProjects);
            }
        };

        // Unsets a branch as favourite
        $scope.branchUnfavourite = function (branch) {
            if (branch.links._unfavourite) {
                ot.pageCall($http.put(branch.links._unfavourite)).then(loadProjects);
            }
        };

        // Selecting a label
        $scope.projectFilterSelectLabel = (label) => {
            $scope.projectFilter.label = label;
        };

        // Clearing the label selection
        $scope.projectFilterClearLabel = () => {
            $scope.projectFilter.label = undefined;
        };

        const LOCATION_KEY = "label";
        const STORAGE_KEY = "home.label";

        // Management of the location search component in case of label change
        $scope.$watch('projectFilter.label', function () {
            if (!$scope.preloadingLabelFilter) {
                if ($scope.projectFilter.label) {
                    let labelKey = $scope.formatLabel($scope.projectFilter.label);
                    $location.search(LOCATION_KEY, labelKey);
                    localStorage.setItem(STORAGE_KEY, labelKey);
                } else {
                    $location.search(LOCATION_KEY, undefined);
                    localStorage.removeItem(STORAGE_KEY);
                }
            }
        });

        // Preloading of the label filter
        function preloadLabelFilter() {
            // Gets the label key
            let labelKey = getLabelKeyFromBrowser();
            // If defined, identifies and sets the filter
            let label = $scope.projectsData.labels.find(it => {
                return $scope.formatLabel(it) === labelKey;
            });
            if (label) {
                $scope.projectFilter.label = label;
            }
            // Done
            $scope.preloadingLabelFilter = false;
        }

        function getLabelKeyFromBrowser() {
            let key = $location.search().label;
            if (key) {
                return key;
            } else {
                return localStorage.getItem(STORAGE_KEY);
            }
        }

        // Filtering the labels for a token
        $scope.typeAheadFilterLabels = (token) => {
            return $scope.projectsData.labels.filter(label => {
                return !token || ($scope.formatLabel(label).toLowerCase().indexOf(token.toLowerCase()) >= 0);
            });
        };

        // Formatting a label for a type-ahead
        $scope.formatLabel = otLabelService.formatLabel;

        // Project filter function
        $scope.projectFilterFn = (project) => {
            return projectFilterNameFn(project) && projectFilterLabelFn(project);
        };

        const projectFilterNameFn = project => {
            return !$scope.projectFilter.name || project.name.toLowerCase().indexOf($scope.projectFilter.name.toLowerCase()) >= 0;
        };

        const projectFilterLabelFn = project => {
            return !$scope.projectFilter.label || project.labels.some(it => it.id === $scope.projectFilter.label.id);
        };

        // Login procedure
        $scope.accessStatus = 'undefined';
        if (code && Number(code) === 403) {
            $log.debug('[403] received');
            if (otUserService.logged()) {
                $scope.accessStatus = 'unauthorised';
                $log.debug('[403] user already logged - error notification');
            } else {
                $scope.accessStatus = 'login-requested';
                $log.debug('[403] user not logged - login redirection - callback URL = ' + url);
                otUserService.login().then(function () {
                    $scope.accessStatus = 'ok';
                    if (url) {
                        // Callback URL
                        $log.debug('[403] reloading ' + url + 'after signing in.');
                        location.href = url;
                        location.reload();
                    } else {
                        // Reloads current page
                        $log.debug('[403] reloading after signing in.');
                        location.reload();
                    }
                }, function () {
                    $scope.accessStatus = 'login-failed';
                    $log.debug('[403] user cannot be logged - error notification');
                });
            }
        } else if ($rootScope.user && $rootScope.user.authenticationRequired && !$rootScope.user.logged) {
            $scope.accessStatus = 'login-requested';
            $log.debug('user not logged and authentication is required');
            otUserService.login().then(function () {
                $scope.accessStatus = 'ok';
                $log.debug('[403] reloading after signing in.');
                location.reload();
            }, function () {
                $scope.accessStatus = 'login-failed';
                $log.debug('[403] user cannot be logged - error notification');
            });
        } else {
            $scope.accessStatus = 'ok';
            // Loading the list of projects
            loadProjects();
        }

    })
;<commit_msg>#859 Looking for the projects<commit_after>angular.module('ot.view.home', [
    'ui.router',
    'ot.service.structure',
    'ot.service.core',
    'ot.service.user',
    'ot.service.graphql',
    'ot.service.label'
])
    .config(function ($stateProvider) {
        $stateProvider.state('home', {
            url: '/home',
            templateUrl: 'app/view/view.home.tpl.html',
            controller: 'HomeCtrl'
        });
    })
    .controller('HomeCtrl', function ($rootScope, $location, $log, $scope, $http, ot, otGraphqlService, otStructureService, otNotificationService, otUserService, otLabelService) {
        const search = $location.search();
        const code = search.code;
        const url = search.url;
        $rootScope.view = {
            // Title
            title: 'Home',
            // Commands
            commands: []
        };

        // Preloading filter mode
        $scope.preloadingLabelFilter = true;

        // No initial filter
        $scope.projectFilter = {
            name: '',
            label: undefined
        };

        // GraphQL fragment for the decorations
        const decorationFragment = `
            fragment decorationContent on Decoration {
              decorationType
              error
              data
              feature {
                id
              }
            }
        `;

        // GraphQL fragment for the displayed projects
        const projectFragment = `
            fragment projectContent on Project {
                id
                name
                labels {
                  id
                  category
                  name
                  description
                  color
                  foregroundColor
                  computedBy {
                    id
                    name
                  }
                }
                links {
                  _favourite
                  _unfavourite
                }
                decorations {
                  ...decorationContent
                }
            }
        `;

        // Full GraphQL query
        const fullQuery = ` query HomePage(
                    $includeProjects: Boolean!,
                    $maxBranches: Int!
                ) {
                  userRootActions {
                    projectCreate
                  }
                  labels {
                    id
                    category
                    name
                    description
                    color
                    foregroundColor
                    computedBy {
                        id
                        name
                    }
                    links {
                        _update
                        _delete
                    }
                  }
                  favouriteBranches: branches(favourite: true) {
                    project {
                      name
                      links {
                        _page
                      }
                    }
                    id
                    name
                    disabled
                    type
                    decorations {
                      ...decorationContent
                    }
                    creation {
                      time
                    }
                    links {
                      _page
                      _enable
                      _disable
                      _delete
                      _unfavourite
                      _favourite
                    }
                    latestBuild: builds(count: 1) {
                      id
                      name
                      creation {
                          time
                      }
                    }
                    promotionLevels {
                      id
                      name
                      image
                      _image
                      promotionRuns(first: 1) {
                        build {
                          id
                          name
                        }
                      }
                    }
                  }
                  projects @include(if: $includeProjects) {
                    ...projectContent
                  }
                  projectFavourites: projects(favourites: true) {
                    id
                    name
                    disabled
                    decorations {
                      ...decorationContent
                    }
                    links {
                      _unfavourite
                    }
                    branches(useModel: true, count: $maxBranches) {
                      id
                      name
                      type
                      disabled
                      decorations {
                        ...decorationContent
                      }
                      latestPromotions: builds(lastPromotions: true, count: 1) {
                        id
                        name
                        promotionRuns {
                          promotionLevel {
                            id
                            name
                            image
                            _image
                          }
                        }
                      }
                      latestBuild: builds(count: 1) {
                        id
                        name
                      }
                    }
                  }
                }

                ${projectFragment}

                ${decorationFragment}
                `;

        // Projects by name
        const projectQuery = `
            query ProjectQuery($name: String!) {
                projects(name: $name) {
                    ...projectContent
                }
            }

            ${projectFragment}

            ${decorationFragment}
        `;

        // Loading the project list
        function loadProjects() {
            $scope.loadingProjects = true;
            // We start collecting some global settings
            otGraphqlService.pageGraphQLCall(`{
                settings {
                    homePage {
                        maxBranches
                        maxProjects
                    }
                }
                entityCounts {
                    projects
                }
            }`).then(global => {
                // Storing the data
                $scope.maxBranches = global.settings.homePage.maxBranches;
                $scope.maxProjects = global.settings.homePage.maxProjects;
                $scope.projectCount = global.entityCounts.projects;
                // Must the projects be included?
                $scope.includeProjects = $scope.projectCount <= $scope.maxProjects;
                // Actual call
                return otGraphqlService.pageGraphQLCall(fullQuery, {
                    includeProjects: $scope.includeProjects,
                    maxBranches: $scope.maxBranches
                });
            }).then(function (data) {

                $scope.projectsData = data;
                $scope.projectFavourites = data.projectFavourites;
                $scope.favouriteBranches = data.favouriteBranches;

                if ($scope.includeProjects) {
                    preloadLabelFilter();
                }

                // All branches disabled status computation
                $scope.projectFavourites.forEach(function (projectFavourite) {
                    projectFavourite.allBranchesDisabled = projectFavourite.branches.length > 0 &&
                        projectFavourite.branches.every(function (branch) {
                            return branch.disabled || branch.type === 'TEMPLATE_DEFINITION';
                        });
                });

                // Commands
                $rootScope.view.commands = [
                    {
                        id: 'createProject',
                        name: 'Create project',
                        cls: 'ot-command-project-new',
                        condition: function () {
                            return data.userRootActions.projectCreate;
                        },
                        action: $scope.createProject
                    }, {
                        id: 'showDisabled',
                        name: "Show all hidden items",
                        cls: 'ot-command-show-disabled',
                        condition: function () {
                            return !$scope.showDisabled;
                        },
                        action: function () {
                            $scope.showDisabled = true;
                        }
                    }, {
                        id: 'hideDisabled',
                        name: "Hide disabled items",
                        cls: 'ot-command-hide-disabled',
                        condition: function () {
                            return $scope.showDisabled;
                        },
                        action: function () {
                            $scope.showDisabled = false;
                        }
                    }, {
                        name: "API",
                        cls: 'ot-command-api',
                        link: '/api-doc'
                    }, {
                        name: "GraphiQL",
                        cls: 'ot-command-api',
                        absoluteLink: "graphiql.html"
                    }
                ];
            }).finally(function () {
                $scope.loadingProjects = false;
            });

        }

        // Search for the projects by name
        $scope.onProjectSearch = () => {
            if ($scope.projectFilter.name) {
                $scope.loadingProjects = true;
                otGraphqlService.pageGraphQLCall(projectQuery, { name: $scope.projectFilter.name}).then(data => {
                    $scope.projectsData.projects = data.projects;
                }).finally(() => {
                    $scope.loadingProjects = false;
                });
            }
        };

        // Creating a project
        $scope.createProject = function () {
            otStructureService.createProject($scope.projectsData.userRootActions.projectCreate).then(loadProjects);
        };

        // Sets a project as favourite
        $scope.projectFavourite = function (project) {
            if (project.links._favourite) {
                ot.pageCall($http.put(project.links._favourite)).then(loadProjects);
            }
        };

        // Unsets a project as favourite
        $scope.projectUnfavourite = function (project) {
            if (project.links._unfavourite) {
                ot.pageCall($http.put(project.links._unfavourite)).then(loadProjects);
            }
        };

        // Sets a branch as favourite
        $scope.branchFavourite = function (branch) {
            if (branch.links._favourite) {
                ot.pageCall($http.put(branch.links._favourite)).then(loadProjects);
            }
        };

        // Unsets a branch as favourite
        $scope.branchUnfavourite = function (branch) {
            if (branch.links._unfavourite) {
                ot.pageCall($http.put(branch.links._unfavourite)).then(loadProjects);
            }
        };

        // Selecting a label
        $scope.projectFilterSelectLabel = (label) => {
            $scope.projectFilter.label = label;
        };

        // Clearing the label selection
        $scope.projectFilterClearLabel = () => {
            $scope.projectFilter.label = undefined;
        };

        const LOCATION_KEY = "label";
        const STORAGE_KEY = "home.label";

        // Management of the location search component in case of label change
        $scope.$watch('projectFilter.label', function () {
            if (!$scope.preloadingLabelFilter) {
                if ($scope.projectFilter.label) {
                    let labelKey = $scope.formatLabel($scope.projectFilter.label);
                    $location.search(LOCATION_KEY, labelKey);
                    localStorage.setItem(STORAGE_KEY, labelKey);
                } else {
                    $location.search(LOCATION_KEY, undefined);
                    localStorage.removeItem(STORAGE_KEY);
                }
            }
        });

        // Preloading of the label filter
        function preloadLabelFilter() {
            // Gets the label key
            let labelKey = getLabelKeyFromBrowser();
            // If defined, identifies and sets the filter
            let label = $scope.projectsData.labels.find(it => {
                return $scope.formatLabel(it) === labelKey;
            });
            if (label) {
                $scope.projectFilter.label = label;
            }
            // Done
            $scope.preloadingLabelFilter = false;
        }

        function getLabelKeyFromBrowser() {
            let key = $location.search().label;
            if (key) {
                return key;
            } else {
                return localStorage.getItem(STORAGE_KEY);
            }
        }

        // Filtering the labels for a token
        $scope.typeAheadFilterLabels = (token) => {
            return $scope.projectsData.labels.filter(label => {
                return !token || ($scope.formatLabel(label).toLowerCase().indexOf(token.toLowerCase()) >= 0);
            });
        };

        // Formatting a label for a type-ahead
        $scope.formatLabel = otLabelService.formatLabel;

        // Project filter function
        $scope.projectFilterFn = (project) => {
            return projectFilterNameFn(project) && projectFilterLabelFn(project);
        };

        const projectFilterNameFn = project => {
            return !$scope.projectFilter.name || project.name.toLowerCase().indexOf($scope.projectFilter.name.toLowerCase()) >= 0;
        };

        const projectFilterLabelFn = project => {
            return !$scope.projectFilter.label || project.labels.some(it => it.id === $scope.projectFilter.label.id);
        };

        // Login procedure
        $scope.accessStatus = 'undefined';
        if (code && Number(code) === 403) {
            $log.debug('[403] received');
            if (otUserService.logged()) {
                $scope.accessStatus = 'unauthorised';
                $log.debug('[403] user already logged - error notification');
            } else {
                $scope.accessStatus = 'login-requested';
                $log.debug('[403] user not logged - login redirection - callback URL = ' + url);
                otUserService.login().then(function () {
                    $scope.accessStatus = 'ok';
                    if (url) {
                        // Callback URL
                        $log.debug('[403] reloading ' + url + 'after signing in.');
                        location.href = url;
                        location.reload();
                    } else {
                        // Reloads current page
                        $log.debug('[403] reloading after signing in.');
                        location.reload();
                    }
                }, function () {
                    $scope.accessStatus = 'login-failed';
                    $log.debug('[403] user cannot be logged - error notification');
                });
            }
        } else if ($rootScope.user && $rootScope.user.authenticationRequired && !$rootScope.user.logged) {
            $scope.accessStatus = 'login-requested';
            $log.debug('user not logged and authentication is required');
            otUserService.login().then(function () {
                $scope.accessStatus = 'ok';
                $log.debug('[403] reloading after signing in.');
                location.reload();
            }, function () {
                $scope.accessStatus = 'login-failed';
                $log.debug('[403] user cannot be logged - error notification');
            });
        } else {
            $scope.accessStatus = 'ok';
            // Loading the list of projects
            loadProjects();
        }

    })
;<|endoftext|>


<commit_before>$(document).ready(function() {

   $('.reloadDiv').click(function()
   {
      var link_name = $(this).attr('id');
      $("#mainSection").load(link_name+".php");
    });

   // when the textboxes change value run this function
	$(".addToBasket").change(function()
	{

  	// keep track of number of item
  	var itemCount = itemCounter();

  	if(itemCount > 0)
  	{
  		$("#noItems").hide();
  		$("#storeBasket").show();

  		// store the values we need for later purposes
  		var nameOfItem = $(this).attr("name");

  		// replace the -'s with spaces throughout the name
  		nameOfItem = nameOfItem.replace(/-/g, ' ');

  		var itemID = $(this).attr('id');
  		var money = itemID.substring(8);
  		var quantity = $(this).val();
  		var total =  (parseFloat(money) * parseFloat(quantity)).toFixed(2);
  		var found = false;

  		// if the item we just changed was set to zero
  		if(quantity === "0")
  		{
  			// cycle through all the item in the shopping cart to find the correct item to remove
  			$('#storeBasket .removable').each(function()
				{
					if($(this).children(":first-child").html() === nameOfItem)
					{
						$(this).remove();
					}
				});
  		}
			else //otherwise we want to add the item to the shopping cart
			{
				// check to see wheather the item is already in the shopping cart
				// if so then increment quantity and total otherwise add whole row
				$('#storeBasket .itemname').each(function()
				{
				 	if(($(this).html()) === nameOfItem)
				 	{
				 		$(this).next().next().html(quantity);
				 		$(this).next().next().next().html("$" + total);
				 		found = true;
				 	}
				});

				if(found != true)
				{
					var htmltoadd = "
" + nameOfItem + "	$" + money +
					 "	" + quantity + "	$" + total + "
";

	  			$("#storeBasket tbody").prepend(htmltoadd);
				}
			}

  		// update the total
  		var subtotal = calctotal();
 			$("#totalPrice").html("$" + subtotal);

 		}
		else // no fish in cart
  	{
			$("#noItems").show();

			$('#storeBasket .removable').each(function()
			{
				$(this).remove();
			});

  		$("#storeBasket").hide();
  	}

	});

});

// function for getting number of item in quantity boxes
function itemCounter()
{
	var count = 0;
	$('.addToBasket').each(function()
	{
	  count = count + parseInt($(this).val(), 10);
	});

	return count;
};

// function for getting the cumulative total of all item in cart
function calctotal()
{
	var total = 0;
	$('.itemincart').each(function()
	{
	  total = total + parseFloat($(this).html().substring(1));
	});

	total = total.toFixed(2);
	return total;
};

function goToStore()
{
	$("#mainSection").load("purchase.php");
};<commit_msg>fixed javascript to add adopted to basket<commit_after>$(document).ready(function() {

   $('.reloadDiv').click(function()
   {
      var link_name = $(this).attr('id');
      $("#mainSection").load(link_name+".php");
    });

   // when the textboxes change value run this function
	$(".addToBasket").change(function()
	{

  	// keep track of number of item
  	var itemCount = itemCounter();

  	if(itemCount > 0)
  	{
  		$("#noItems").hide();
  		$("#storeBasket").show();

  		// store the values we need for later purposes
  		var nameOfItem = $(this).attr("name");

  		// replace the -'s with spaces throughout the name
  		nameOfItem = nameOfItem.replace(/-/g, ' ');

  		var itemID = $(this).attr('id');
		if (itemID.substring(0,8) == "adoption")
		{
			var money = itemID.substring(9);
		}
		else
		{
			var money = itemID.substring(8);
		}
  		var quantity = $(this).val();
  		var total =  (parseFloat(money) * parseFloat(quantity)).toFixed(2);
  		var found = false;

  		// if the item we just changed was set to zero
  		if(quantity === "0")
  		{
  			// cycle through all the item in the shopping cart to find the correct item to remove
  			$('#storeBasket .removable').each(function()
				{
					if($(this).children(":first-child").html() === nameOfItem)
					{
						$(this).remove();
					}
				});
  		}
			else //otherwise we want to add the item to the shopping cart
			{
				// check to see wheather the item is already in the shopping cart
				// if so then increment quantity and total otherwise add whole row
				$('#storeBasket .itemname').each(function()
				{
				 	if(($(this).html()) === nameOfItem)
				 	{
				 		$(this).next().next().html(quantity);
				 		$(this).next().next().next().html("$" + total);
				 		found = true;
				 	}
				});

				if(found != true)
				{
					var htmltoadd = "
" + nameOfItem + "	$" + money +
					 "	" + quantity + "	$" + total + "
";

	  			$("#storeBasket tbody").prepend(htmltoadd);
				}
			}

  		// update the total
  		var subtotal = calctotal();
 			$("#totalPrice").html("$" + subtotal);

 		}
		else // no fish in cart
  	{
			$("#noItems").show();

			$('#storeBasket .removable').each(function()
			{
				$(this).remove();
			});

  		$("#storeBasket").hide();
  	}

	});

});

// function for getting number of item in quantity boxes
function itemCounter()
{
	var count = 0;
	$('.addToBasket').each(function()
	{
	  count = count + parseInt($(this).val(), 10);
	});

	return count;
};

// function for getting the cumulative total of all item in cart
function calctotal()
{
	var total = 0;
	$('.itemincart').each(function()
	{
	  total = total + parseFloat($(this).html().substring(1));
	});

	total = total.toFixed(2);
	return total;
};

function goToStore()
{
	$("#mainSection").load("purchase.php");
};<|endoftext|>


<commit_before>import { isArray } from './is';

export function addToArray ( array, value ) {
    const index = array.indexOf( value );

    if ( index === -1 ) {
        array.push( value );
    }
}

export function arrayContains ( array, value ) {
    for ( let i = 0, c = array.length; i < c; i++ ) {
        if ( array[i] == value ) {
            return true;
        }
    }

    return false;
}

export function arrayContentsMatch ( a, b ) {
    let i;

    if ( !isArray( a ) || !isArray( b ) ) {
        return false;
    }

    if ( a.length !== b.length ) {
        return false;
    }

    i = a.length;
    while ( i-- ) {
        if ( a[i] !== b[i] ) {
            return false;
        }
    }

    return true;
}

export function ensureArray ( x ) {
    if ( typeof x === 'string' ) {
        return [ x ];
    }

    if ( x === undefined ) {
        return [];
    }

    return x;
}

export function lastItem ( array ) {
    return array[ array.length - 1 ];
}

export function removeFromArray ( array, member ) {
    if ( !array ) {
        return;
    }

    const index = array.indexOf( member );

    if ( index !== -1 ) {
        array.splice( index, 1 );
    }
}

export function toArray ( arrayLike ) {
    const array = [];
    let i = arrayLike.length;
    while ( i-- ) {
        array[i] = arrayLike[i];
    }

    return array;
}

export function findByKeyValue( array, key, value ) {
    return array.filter(function( obj ) {
        return obj[key] === value;
    });
}
<commit_msg>Added array cloning to utils<commit_after>import { isArray } from './is';

export function addToArray ( array, value ) {
    const index = array.indexOf( value );

    if ( index === -1 ) {
        array.push( value );
    }
}

export function arrayContains ( array, value ) {
    for ( let i = 0, c = array.length; i < c; i++ ) {
        if ( array[i] == value ) {
            return true;
        }
    }

    return false;
}

export function arrayContentsMatch ( a, b ) {
    let i;

    if ( !isArray( a ) || !isArray( b ) ) {
        return false;
    }

    if ( a.length !== b.length ) {
        return false;
    }

    i = a.length;
    while ( i-- ) {
        if ( a[i] !== b[i] ) {
            return false;
        }
    }

    return true;
}

export function ensureArray ( x ) {
    if ( typeof x === 'string' ) {
        return [ x ];
    }

    if ( x === undefined ) {
        return [];
    }

    return x;
}

export function lastItem ( array ) {
    return array[ array.length - 1 ];
}

export function removeFromArray ( array, member ) {
    if ( !array ) {
        return;
    }

    const index = array.indexOf( member );

    if ( index !== -1 ) {
        array.splice( index, 1 );
    }
}

export function toArray ( arrayLike ) {
    const array = [];
    let i = arrayLike.length;
    while ( i-- ) {
        array[i] = arrayLike[i];
    }

    return array;
}

export function findByKeyValue( array, key, value ) {
    return array.filter(function( obj ) {
        return obj[key] === value;
    });
}

export function cloneArray( array ) {
    return JSON.parse(JSON.stringify(array));
}
<|endoftext|>


<commit_before>const serialize = require('serialize-javascript');

function createPreloadTag(href, as, extra) {
  return `<link rel="preload" href="${href}"${extra ? ' ' + extra : ''} as="${as}" />`;
}

function createStyleTag(href) {
  return `<link rel="stylesheet" href="${href}" />`;
}

function createScriptTag(src, extra) {
  return `<script src="${src}"${extra ? ' ' + extra : ''} /></script>`;
}

module.exports = function generateHtmlSnippets(meta, reactContent, assets, data, useDll) {
  const preloads = [];

  // generate styles html
  const styles = [];
  if (process.env.APP_MODE === 'development') {
    styles.push('<!-- styles are injected via hot loading in development -->');
  } else {
    if (assets['desktop.css'] && meta.device === 'desktop') {
      preloads.push(createPreloadTag(assets['desktop.css'], 'style'));
      styles.push(createStyleTag(assets['desktop.css']));
    }
    if (assets['mobile.css'] && meta.device === 'mobile') {
      preloads.push(createPreloadTag(assets['mobile.css'], 'style'));
      styles.push(createStyleTag(assets['mobile.css']));
    }
    if (assets['main.css']) {
      preloads.push(createPreloadTag(assets['desktop.css'], 'style'));
      styles.push(createStyleTag(assets['main.css']));
    }
  }

  // generate content html
  const content = `<div id="content">${reactContent}</div>`;

  // generate javascript html
  const scripts = [];
  scripts.push(`<script>window.__DATA__=${serialize(data)};</script>`);
  scripts.push(`<script>window.__METADATA__=${serialize(meta)};</script>`);

  if (useDll && process.env.APP_MODE === 'development') {
    preloads.push(createPreloadTag('/dll/dll__vendor.js', 'script'));
    scripts.push(createScriptTag('/dll/dll__vendor.js', 'key="dll__vendor"'));
  }

  const crossOrigin = process.env.APP_MODE === 'development' ? 'crossorigin' : null;
  preloads.push(createPreloadTag(assets['main.js'], 'script', crossOrigin));
  scripts.push(createScriptTag(assets['main.js'], crossOrigin));

  // bundle html snippets
  return {
    preloads,
    styles,
    content,
    scripts,
  };
};
<commit_msg>Fix prefer-template eslint errors<commit_after>const serialize = require('serialize-javascript');

function createPreloadTag(href, as, extra) {
  return `<link rel="preload" href="${href}"${extra ? ` ${extra}` : ''} as="${as}" />`;
}

function createStyleTag(href) {
  return `<link rel="stylesheet" href="${href}" />`;
}

function createScriptTag(src, extra) {
  return `<script src="${src}"${extra ? ` ${extra}` : ''} /></script>`;
}

module.exports = function generateHtmlSnippets(meta, reactContent, assets, data, useDll) {
  const preloads = [];

  // generate styles html
  const styles = [];
  if (process.env.APP_MODE === 'development') {
    styles.push('<!-- styles are injected via hot loading in development -->');
  } else {
    if (assets['desktop.css'] && meta.device === 'desktop') {
      preloads.push(createPreloadTag(assets['desktop.css'], 'style'));
      styles.push(createStyleTag(assets['desktop.css']));
    }
    if (assets['mobile.css'] && meta.device === 'mobile') {
      preloads.push(createPreloadTag(assets['mobile.css'], 'style'));
      styles.push(createStyleTag(assets['mobile.css']));
    }
    if (assets['main.css']) {
      preloads.push(createPreloadTag(assets['desktop.css'], 'style'));
      styles.push(createStyleTag(assets['main.css']));
    }
  }

  // generate content html
  const content = `<div id="content">${reactContent}</div>`;

  // generate javascript html
  const scripts = [];
  scripts.push(`<script>window.__DATA__=${serialize(data)};</script>`);
  scripts.push(`<script>window.__METADATA__=${serialize(meta)};</script>`);

  if (useDll && process.env.APP_MODE === 'development') {
    preloads.push(createPreloadTag('/dll/dll__vendor.js', 'script'));
    scripts.push(createScriptTag('/dll/dll__vendor.js', 'key="dll__vendor"'));
  }

  const crossOrigin = process.env.APP_MODE === 'development' ? 'crossorigin' : null;
  preloads.push(createPreloadTag(assets['main.js'], 'script', crossOrigin));
  scripts.push(createScriptTag(assets['main.js'], crossOrigin));

  // bundle html snippets
  return {
    preloads,
    styles,
    content,
    scripts,
  };
};
<|endoftext|>


<commit_before>"use strict";
//-----------------------------------------------------------------------------------
// Global counters
//-----------------------------------------------------------------------------------

/**
 *
 * @constructor
 * @extends {CCollaborativeEditingBase}
 */
function CCollaborativeEditing()
{
    CCollaborativeEditing.superclass.constructor.call(this);
}

Asc.extendClass(CCollaborativeEditing, CCollaborativeEditingBase);

CCollaborativeEditing.prototype.Have_OtherChanges = function()
{
    return false;
};

CCollaborativeEditing.prototype.Start_CollaborationEditing = function()
{
};

CCollaborativeEditing.prototype.Add_User = function(UserId)
{
};

CCollaborativeEditing.prototype.Find_User = function(UserId)
{
};

CCollaborativeEditing.prototype.Remove_User = function(UserId)
{
};

CCollaborativeEditing.prototype.Add_Changes = function(Changes)
{
};

CCollaborativeEditing.prototype.Add_Unlock = function(LockClass)
{
};

CCollaborativeEditing.prototype.Add_Unlock2 = function(Lock)
{
};

CCollaborativeEditing.prototype.Apply_OtherChanges = function()
{
};

CCollaborativeEditing.prototype.Apply_Changes = function()
{
};

CCollaborativeEditing.prototype.Send_Changes = function()
{
};

CCollaborativeEditing.prototype.Release_Locks = function()
{
};

CCollaborativeEditing.prototype.OnStart_Load_Objects = function()
{
};

CCollaborativeEditing.prototype.OnEnd_Load_Objects = function()
{
};
//-----------------------------------------------------------------------------------
// Функции для работы с ссылками, у новых объектов
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Clear_LinkData = function()
{
    this.m_aLinkData.length = 0;
};

CCollaborativeEditing.prototype.Add_LinkData = function(Class, LinkData)
{
    this.m_aLinkData.push( { Class : Class, LinkData : LinkData } );
};

CCollaborativeEditing.prototype.Apply_LinkData = function()
{
    var Count = this.m_aLinkData.length;
    for ( var Index = 0; Index < Count; Index++ )
    {
        var Item = this.m_aLinkData[Index];
        Item.Class.Load_LinkData( Item.LinkData );
    }
    this.Clear_LinkData();

};
CCollaborativeEditing.prototype.Load_Images = function(){
    if(this.m_aNewImages.length > 0)
    {
        var old_val =  Asc["editor"].ImageLoader.bIsAsyncLoadDocumentImages;
        Asc["editor"].ImageLoader.bIsAsyncLoadDocumentImages = true;
        Asc["editor"].ImageLoader.LoadDocumentImages(this.m_aNewImages, null);
        CollaborativeEditing.m_aNewImages.length = 0;
        Asc["editor"].ImageLoader.bIsAsyncLoadDocumentImages = old_val;
    }
}
//-----------------------------------------------------------------------------------
// Функции для проверки корректности новых изменений
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Check_MergeData = function()
{
};
//-----------------------------------------------------------------------------------
// Функции для проверки залоченности объектов
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Get_GlobalLock = function()
{
};

CCollaborativeEditing.prototype.OnStart_CheckLock = function()
{
};

CCollaborativeEditing.prototype.Add_CheckLock = function(oItem)
{
};

CCollaborativeEditing.prototype.OnEnd_CheckLock = function()
{
};

CCollaborativeEditing.prototype.OnCallback_AskLock = function(result)
{
};
//-----------------------------------------------------------------------------------
// Функции для работы с залоченными объектами, которые еще не были добавлены
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Reset_NeedLock = function()
{
};

CCollaborativeEditing.prototype.Add_NeedLock = function(Id, sUser)
{
};

CCollaborativeEditing.prototype.Remove_NeedLock = function(Id)
{
};

CCollaborativeEditing.prototype.Lock_NeedLock = function()
{
};
//-----------------------------------------------------------------------------------
// Функции для работы с новыми объектами, созданными на других клиентах
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Clear_NewObjects = function()
{
};

CCollaborativeEditing.prototype.Add_NewObject = function(Class)
{
};

CCollaborativeEditing.prototype.OnEnd_ReadForeignChanges = function()
{
};

//-----------------------------------------------------------------------------------
// Функции для работы с массивом m_aDC
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Add_NewDC = function(Class)
{
};

CCollaborativeEditing.prototype.Clear_DCChanges = function()
{
};

CCollaborativeEditing.prototype.Refresh_DCChanges = function()
{
};
//-----------------------------------------------------------------------------------
// Функции для работы с отметками изменений
//-----------------------------------------------------------------------------------

CCollaborativeEditing.prototype.Clear_CollaborativeMarks = function()
{
    for ( var Id in this.m_aChangedClasses )
    {
        this.m_aChangedClasses[Id].Clear_CollaborativeMarks();
    }

    // Очищаем массив
    this.m_aChangedClasses = {};
};

var CollaborativeEditing = new CCollaborativeEditing();<commit_msg>баг с красными крестами после загрузки<commit_after>"use strict";
//-----------------------------------------------------------------------------------
// Global counters
//-----------------------------------------------------------------------------------

/**
 *
 * @constructor
 * @extends {CCollaborativeEditingBase}
 */
function CCollaborativeEditing()
{
    CCollaborativeEditing.superclass.constructor.call(this);
}

Asc.extendClass(CCollaborativeEditing, CCollaborativeEditingBase);

CCollaborativeEditing.prototype.Have_OtherChanges = function()
{
    return false;
};

CCollaborativeEditing.prototype.Start_CollaborationEditing = function()
{
};

CCollaborativeEditing.prototype.Add_User = function(UserId)
{
};

CCollaborativeEditing.prototype.Find_User = function(UserId)
{
};

CCollaborativeEditing.prototype.Remove_User = function(UserId)
{
};

CCollaborativeEditing.prototype.Add_Changes = function(Changes)
{
};

CCollaborativeEditing.prototype.Add_Unlock = function(LockClass)
{
};

CCollaborativeEditing.prototype.Add_Unlock2 = function(Lock)
{
};

CCollaborativeEditing.prototype.Apply_OtherChanges = function()
{
};

CCollaborativeEditing.prototype.Apply_Changes = function()
{
};

CCollaborativeEditing.prototype.Send_Changes = function()
{
};

CCollaborativeEditing.prototype.Release_Locks = function()
{
};

CCollaborativeEditing.prototype.OnStart_Load_Objects = function()
{
};

CCollaborativeEditing.prototype.OnEnd_Load_Objects = function()
{
};
//-----------------------------------------------------------------------------------
// Функции для работы с ссылками, у новых объектов
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Clear_LinkData = function()
{
    this.m_aLinkData.length = 0;
};

CCollaborativeEditing.prototype.Add_LinkData = function(Class, LinkData)
{
    this.m_aLinkData.push( { Class : Class, LinkData : LinkData } );
};

CCollaborativeEditing.prototype.Apply_LinkData = function()
{
    var Count = this.m_aLinkData.length;
    for ( var Index = 0; Index < Count; Index++ )
    {
        var Item = this.m_aLinkData[Index];
        Item.Class.Load_LinkData( Item.LinkData );
    }
    this.Clear_LinkData();
    this.Load_Images();
};
CCollaborativeEditing.prototype.Load_Images = function(){
    if(this.m_aNewImages.length > 0)
    {
        var old_val =  Asc["editor"].ImageLoader.bIsAsyncLoadDocumentImages;
        Asc["editor"].ImageLoader.bIsAsyncLoadDocumentImages = true;
        Asc["editor"].ImageLoader.LoadDocumentImages(this.m_aNewImages, null);
        CollaborativeEditing.m_aNewImages.length = 0;
        Asc["editor"].ImageLoader.bIsAsyncLoadDocumentImages = old_val;
    }
}
//-----------------------------------------------------------------------------------
// Функции для проверки корректности новых изменений
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Check_MergeData = function()
{
};
//-----------------------------------------------------------------------------------
// Функции для проверки залоченности объектов
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Get_GlobalLock = function()
{
};

CCollaborativeEditing.prototype.OnStart_CheckLock = function()
{
};

CCollaborativeEditing.prototype.Add_CheckLock = function(oItem)
{
};

CCollaborativeEditing.prototype.OnEnd_CheckLock = function()
{
};

CCollaborativeEditing.prototype.OnCallback_AskLock = function(result)
{
};
//-----------------------------------------------------------------------------------
// Функции для работы с залоченными объектами, которые еще не были добавлены
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Reset_NeedLock = function()
{
};

CCollaborativeEditing.prototype.Add_NeedLock = function(Id, sUser)
{
};

CCollaborativeEditing.prototype.Remove_NeedLock = function(Id)
{
};

CCollaborativeEditing.prototype.Lock_NeedLock = function()
{
};
//-----------------------------------------------------------------------------------
// Функции для работы с новыми объектами, созданными на других клиентах
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Clear_NewObjects = function()
{
};

CCollaborativeEditing.prototype.Add_NewObject = function(Class)
{
};

CCollaborativeEditing.prototype.OnEnd_ReadForeignChanges = function()
{
};

//-----------------------------------------------------------------------------------
// Функции для работы с массивом m_aDC
//-----------------------------------------------------------------------------------
CCollaborativeEditing.prototype.Add_NewDC = function(Class)
{
};

CCollaborativeEditing.prototype.Clear_DCChanges = function()
{
};

CCollaborativeEditing.prototype.Refresh_DCChanges = function()
{
};
//-----------------------------------------------------------------------------------
// Функции для работы с отметками изменений
//-----------------------------------------------------------------------------------

CCollaborativeEditing.prototype.Clear_CollaborativeMarks = function()
{
    for ( var Id in this.m_aChangedClasses )
    {
        this.m_aChangedClasses[Id].Clear_CollaborativeMarks();
    }

    // Очищаем массив
    this.m_aChangedClasses = {};
};

var CollaborativeEditing = new CCollaborativeEditing();<|endoftext|>