<commit_before>/**
 * Created by Serhii Maksymchuk from Ubrainians for imCode
 * 16.08.17.
 */
Imcms.define("imcms-image-content-builder",
    [
        "imcms-image-files-rest-api", "imcms-image-folders-rest-api", "imcms-bem-builder", "imcms-components-builder",
        "imcms-primitives-builder", "imcms-controls-builder", "imcms-modal-window-builder", "jquery"
    ],
    function (imageFilesREST, imageFoldersREST, BEM, components, primitives, controlsBuilder, modalWindow, $) {
        var OPENED_FOLDER_BTN_CLASS = "imcms-folder-btn--open";
        var SUBFOLDER_CLASS = "imcms-folders__subfolder";
        var ACTIVE_FOLDER_CLASS = "imcms-folder--active";
        var FOLDER_CREATION_BLOCK_ID = "imcms-folder-create-block";
        var ROOT_FOLDER_LEVEL = 0;

        var $foldersContainer, $imagesContainer, selectedImage;

        var viewModel = {
            root: {},
            $folder: [],
            $images: []
        };

        var rootFolderBEM = new BEM({
            block: "imcms-left-side",
            elements: {
                "controls": "imcms-main-folders-controls",
                "folders": "imcms-folders"
            }
        });

        function onFolderRenamed(response) {
            var newName = this.$block.find(".imcms-panel-named__input").val();

            console.log("Renaming folder " + newName);
            console.log(response);

            this.$block.prev()
                .find(".imcms-folder__name")
                .text(newName);

            this.$block.detach();
        }

        function onFolderCreated(response) {
            console.log("Created folder: ");
            console.log(response);
            response.$images = [];
            response.$folder = buildSubFolder(response, this.parentLevel + 1)
                .addClass(SUBFOLDER_CLASS)
                .css("display", "block")
            ;

            this.$block.replaceWith(response.$folder);

            var $parent = response.$folder.prev();
            if ($parent.hasClass("imcms-folder") && !$parent.children(".imcms-folder__btn").length) {
                $("<div>", {
                        "class": "imcms-folder__btn imcms-folder-btn--open",
                        click: openSubFolders
                    }
                ).prependTo($parent);
            }
        }

        var folderControlsBuilder = {
            move: function (folder) {
                return controlsBuilder.move(moveFolder.bind(folder));
            },
            remove: function (folder) {
                return controlsBuilder.remove(removeFolder.bind(folder));
            },
            edit: function (folder, level) {
                return controlsBuilder.edit(setRenameFolder(folder, level));
            },
            create: function (folder, level) {
                return controlsBuilder.create(setCreateFolder(folder, level));
            }
        };

        function buildRootControls(rootFile) {
            return new BEM({
                block: "imcms-main-folders-controls",
                elements: {
                    "name": $("<div>", {
                        "class": "imcms-title",
                        text: rootFile.name,
                        click: onFolderClick.bindArgs(rootFile)
                    }),
                    "control": folderControlsBuilder.create(rootFile, ROOT_FOLDER_LEVEL)
                }
            }).buildBlockStructure("<div>");
        }

        function buildRootFolder(rootFile) {
            rootFile.$folder = $foldersContainer;
            var $rootControls = buildRootControls(rootFile);

            return rootFolderBEM.makeBlockElement("controls", $rootControls);
        }

        function moveFolder() {
            // todo: implement or delete it's control icon at all
        }

        function removeFolder() { // this == folder
            modalWindow.buildModalWindow("Do you want to remove folder \"" + this.name + "\"?", function (answer) {
                if (answer) {

                    imageFoldersREST.remove(this.path).done(onDoneRemoveFolder.bindArgs(this.$folder, this.path));

                    function onDoneRemoveFolder($folder, path) {
                        removeFolderFromEditor($folder);
                        removeParentBtnIfNoSubfolders(path);

                        function removeFolderFromEditor($folder) {
                            $folder.detach();
                        }

                        function removeParentBtnIfNoSubfolders(path) {
                            var parentFolderPath = path.substring(0, path.lastIndexOf('/'));
                            var noChildFoldersLeft = $("[data-folder-path^='" + parentFolderPath + "/'").length === 0;
                            if (noChildFoldersLeft) {
                                $("[data-folder-path^='" + parentFolderPath + "'")
                                    .find(".imcms-folder__btn")
                                    .detach();
                            }
                        }
                    }
                }
            }.bind(this));
        }

        function buildFolderRenamingBlock(folder, level) {
            var currentFolderName = folder.$folder.children(".imcms-folders__folder")
                .find(".imcms-folder__name")
                .text();

            return buildFolderManageBlock({
                    folder: folder,
                    level: level,
                    name: currentFolderName
                },
                imageFoldersREST.update,
                onFolderRenamed
            ).css({
                position: "absolute",
                top: "0px",
                left: "0px"
            });
        }

        function setRenameFolder(folder, level) {
            return function renameFolder() {
                var $folderRenamingBlock = buildFolderRenamingBlock(folder, level);
                folder.$folder.children(".imcms-folders__folder").after($folderRenamingBlock);
            };
        }

        function setCreateFolder(folder, level) {
            return function createFolder() {
                showFolderCreationBlock(folder, level);

                var $openFolderBtn = $(this).parent()
                    .parent()
                    .children(".imcms-folder__btn");

                if ($openFolderBtn.hasClass("imcms-folder-btn--open")) {
                    return;
                }

                openSubFolders.call($openFolderBtn[0]);
            }
        }

        function buildFolderManageBlock(opts, onConfirm, onSuccess) {
            $("#" + FOLDER_CREATION_BLOCK_ID).detach();

            var $folderNameInput = primitives.imcmsInput({
                "class": "imcms-input",
                value: opts.name,
                placeholder: "New folder name"
            });
            var $confirmBtn = components.buttons.neutralButton({
                "class": "imcms-button",
                text: "add+",
                click: function () {
                    var folderName = $folderNameInput.val();

                    if (!folderName) {
                        return;
                    }

                    onConfirm(opts.folder.path + "/" + folderName).done(onSuccess.bind({
                        parentLevel: opts.level,
                        $block: $folderCreationBlock
                    }));
                }
            });

            var $folderCreationBlock = new BEM({
                block: "imcms-panel-named",
                elements: {
                    "input": $folderNameInput,
                    "button": $confirmBtn
                }
            }).buildBlockStructure("<div>", {id: FOLDER_CREATION_BLOCK_ID});

            return $folderCreationBlock;
        }

        function buildFolderCreationBlock(parentFolder, level) {
            return buildFolderManageBlock({
                folder: parentFolder,
                level: level,
                name: ""
            }, imageFoldersREST.create, onFolderCreated);
        }

        function showFolderCreationBlock(parentFolder, level) {
            var $createFolderBlock = buildFolderCreationBlock(parentFolder, level);
            var $subFolders = parentFolder.$folder.find(".imcms-folders");

            if ($subFolders.length) {
                $subFolders.eq(0).before($createFolderBlock);
                return;
            }

            parentFolder.$folder.append($createFolderBlock);
        }

        function buildControls(subfolder, level) {
            var controlsElements = [
                folderControlsBuilder.move(subfolder),
                folderControlsBuilder.remove(subfolder),
                folderControlsBuilder.edit(subfolder, level),
                folderControlsBuilder.create(subfolder, level)
            ];

            return controlsBuilder.buildControlsBlock("<div>", controlsElements);
        }

        function openSubFolders() {
            var $button = $(this);
            var $subFolders = $button.toggleClass(OPENED_FOLDER_BTN_CLASS)
                .parent() // fixme: bad idea!
                .parent()
                .children("." + SUBFOLDER_CLASS);

            var isOpen = $button.hasClass(OPENED_FOLDER_BTN_CLASS);

            if ($subFolders.length) {
                $subFolders.css("display", isOpen ? "block" : "none");
            }
        }

        function onFolderClick(folder) {
            $("." + ACTIVE_FOLDER_CLASS).removeClass(ACTIVE_FOLDER_CLASS);
            $(this).addClass(ACTIVE_FOLDER_CLASS);

            viewModel.$images.forEach(function ($image) {
                $image.css("display", "none");
            });
            folder.$images.forEach(function ($image) {
                $image.css("display", "block");
            });
        }

        function buildFolder(subfolder, level) {
            var elements = {};

            if (subfolder.folders && subfolder.folders.length) {
                elements.btn = $("<div>", {click: openSubFolders});
            }

            elements.name = $("<div>", {
                "class": "imcms-title",
                text: subfolder.name
            });

            elements.controls = buildControls(subfolder, level);

            return new BEM(
                {
                    block: "imcms-folder",
                    elements: elements
                }
            ).buildBlockStructure("<div>", {
                "data-folder-path": subfolder.path,
                click: function () {
                    onFolderClick.call(this, subfolder);
                }
            });
        }

        function buildSubFolder(subfolder, level) {
            var isSubLevel = (level > 1);

            var elements = {
                "folder": buildFolder(subfolder, level)
            };

            if (subfolder.folders && subfolder.folders.length) {
                elements.subfolder = buildSubFolders(subfolder, level + 1).map(function ($subfolder) {
                    if (isSubLevel) {
                        $subfolder.modifiers = ["close"];
                    }

                    return $subfolder;
                });
            }

            return new BEM({
                block: "imcms-folders",
                elements: elements
            }).buildBlockStructure("<div>", {"data-folders-lvl": level});
        }

        function buildSubFolders(folder, level) {
            return folder.folders.map(function (subfolder) {
                return subfolder.$folder = buildSubFolder(subfolder, level);
            });
        }

        function onImageDelete(imageFile) {
            imageFilesREST.remove(imageFile.path).done(function () {
                $(this).parent().parent().detach();
            }.bind(this));
        }

        function buildImageDescription(imageFile) {
            return new BEM({
                block: "imcms-choose-img-description",
                elements: {
                    "date": $("<div>", {text: imageFile.uploaded}),
                    "button": components.buttons.closeButton({
                        click: function () {
                            onImageDelete.call(this, imageFile);
                        }
                    }),
                    "img-title": $("<div>", {
                            "class": "imcms-title",
                        text: imageFile.name
                        }
                    ),
                    "img-size": $("<div>", {text: imageFile.resolution + " " + imageFile.size})
                }
            }).buildBlockStructure("<div>");
        }

        function selectImage(imageFile) {
            $(".image-chosen").removeClass("image-chosen");
            $(this).addClass("image-chosen");
            selectedImage = imageFile;
        }

        function buildImage(imageFile) {
            return new BEM({
                block: "imcms-choose-img-wrap",
                elements: {
                    "img": $("<div>", {
                        "class": "imcms-choose-img",
                        style: "background-image: url(" + Imcms.contextPath + imageFile.path + ")"
                    }),
                    "description": buildImageDescription(imageFile)
                }
            }).buildBlockStructure("<div>", {
                style: "display: none",
                click: function () {
                    selectImage.call(this, imageFile);
                }
            });
        }

        function buildImages(folder) {
            folder.$images = folder.files.map(buildImage);
            viewModel.$images = viewModel.$images.concat(folder.$images);
            (folder.folders || []).forEach(buildImages);
        }

        function loadImageFoldersContent(imagesRootFolder) {
            viewModel.root = imagesRootFolder;
            buildImages(viewModel.root);
            viewModel.$folder.push(buildRootFolder(viewModel.root));

            var $subfolders = buildSubFolders(viewModel.root, ROOT_FOLDER_LEVEL + 1).map(function ($subfolder) {
                return rootFolderBEM.makeBlockElement("folders", $subfolder);
            });

            viewModel.$folder = viewModel.$folder.concat($subfolders);

            $foldersContainer.append(viewModel.$folder);
            $imagesContainer.append(viewModel.$images);
            viewModel.root.$images.forEach(function ($image) {
                $image.css("display", "block");
            });
        }

        return {
            getSelectedImage: function () {
                return selectedImage;
            },
            loadAndBuildContent: function (options) {
                $foldersContainer = options.foldersContainer;
                $imagesContainer = options.imagesContainer;

                imageFoldersREST.read().done(loadImageFoldersContent);
            },
            onImageUpload: function (files) {
                var saveImageRequestData = {
                    files: files
                };

                var $activeFolder = $("." + ACTIVE_FOLDER_CLASS);

                if ($activeFolder.length) {
                    saveImageRequestData.folder = $activeFolder.data("folderPath")
                }

                imageFilesREST.create(saveImageRequestData)
                    .done(function (response) {
                        console.log("success file create");
                    });
            },
            clearContent: function () {
                $imagesContainer.children().detach();
                $foldersContainer.children().not("#closeFolders").detach();
                viewModel = {
                    root: {},
                    $folder: [],
                    $images: []
                }
            }
        };
    }
);
<commit_msg>IMCMS-258 - Upgrade image functionality to work with new image editor API on client side: - Fixed new image folders creation on client side.<commit_after>/**
 * Created by Serhii Maksymchuk from Ubrainians for imCode
 * 16.08.17.
 */
Imcms.define("imcms-image-content-builder",
    [
        "imcms-image-files-rest-api", "imcms-image-folders-rest-api", "imcms-bem-builder", "imcms-components-builder",
        "imcms-primitives-builder", "imcms-controls-builder", "imcms-modal-window-builder", "jquery"
    ],
    function (imageFilesREST, imageFoldersREST, BEM, components, primitives, controlsBuilder, modalWindow, $) {
        var OPENED_FOLDER_BTN_CLASS = "imcms-folder-btn--open";
        var SUBFOLDER_CLASS = "imcms-folders__subfolder";
        var ACTIVE_FOLDER_CLASS = "imcms-folder--active";
        var FOLDER_CREATION_BLOCK_ID = "imcms-folder-create-block";
        var ROOT_FOLDER_LEVEL = 0;

        var $foldersContainer, $imagesContainer, selectedImage;

        var viewModel = {
            root: {},
            $folder: [],
            $images: []
        };

        var rootFolderBEM = new BEM({
            block: "imcms-left-side",
            elements: {
                "controls": "imcms-main-folders-controls",
                "folders": "imcms-folders"
            }
        });

        function onFolderRenamed(response) {
            if (response) {
                var newName = this.$block.find(".imcms-panel-named__input").val();

                this.$block.prev()
                    .find(".imcms-folder__name")
                    .text(newName);

                this.$block.detach();

            } else {
                console.error("Folder " + this.path + "/" + this.name + " not renamed!")
            }
        }

        function onFolderCreated(response) {
            if (response) {
                var newFolder = {
                    name: this.name,
                    path: this.path,
                    $images: []
                };

                newFolder.$folder = buildSubFolder(newFolder, this.parentLevel + 1)
                    .addClass(SUBFOLDER_CLASS)
                    .css("display", "block");

                this.$block.replaceWith(newFolder.$folder);

                var $parent = newFolder.$folder.prev();
                if ($parent.hasClass("imcms-folder") && !$parent.children(".imcms-folder__btn").length) {
                    $("<div>", {
                            "class": "imcms-folder__btn imcms-folder-btn--open",
                            click: openSubFolders
                        }
                    ).prependTo($parent);
                }
            } else {
                console.error("Folder " + this.path + "/" + this.name + " not created!")
            }
        }

        var folderControlsBuilder = {
            move: function (folder) {
                return controlsBuilder.move(moveFolder.bind(folder));
            },
            remove: function (folder) {
                return controlsBuilder.remove(removeFolder.bind(folder));
            },
            edit: function (folder, level) {
                return controlsBuilder.edit(setRenameFolder(folder, level));
            },
            create: function (folder, level) {
                return controlsBuilder.create(setCreateFolder(folder, level));
            }
        };

        function buildRootControls(rootFile) {
            return new BEM({
                block: "imcms-main-folders-controls",
                elements: {
                    "name": $("<div>", {
                        "class": "imcms-title",
                        text: rootFile.name,
                        click: onFolderClick.bindArgs(rootFile)
                    }),
                    "control": folderControlsBuilder.create(rootFile, ROOT_FOLDER_LEVEL)
                }
            }).buildBlockStructure("<div>");
        }

        function buildRootFolder(rootFile) {
            rootFile.$folder = $foldersContainer;
            var $rootControls = buildRootControls(rootFile);

            return rootFolderBEM.makeBlockElement("controls", $rootControls);
        }

        function moveFolder() {
            // todo: implement or delete it's control icon at all
        }

        function removeFolder() { // this == folder
            modalWindow.buildModalWindow("Do you want to remove folder \"" + this.name + "\"?", function (answer) {
                if (answer) {

                    imageFoldersREST.remove(this.path).done(onDoneRemoveFolder.bindArgs(this.$folder, this.path));

                    function onDoneRemoveFolder($folder, path) {
                        removeFolderFromEditor($folder);
                        removeParentBtnIfNoSubfolders(path);

                        function removeFolderFromEditor($folder) {
                            $folder.detach();
                        }

                        function removeParentBtnIfNoSubfolders(path) {
                            var parentFolderPath = path.substring(0, path.lastIndexOf('/'));
                            var noChildFoldersLeft = $("[data-folder-path^='" + parentFolderPath + "/'").length === 0;
                            if (noChildFoldersLeft) {
                                $("[data-folder-path^='" + parentFolderPath + "'")
                                    .find(".imcms-folder__btn")
                                    .detach();
                            }
                        }
                    }
                }
            }.bind(this));
        }

        function buildFolderRenamingBlock(folder, level) {
            var currentFolderName = folder.$folder.children(".imcms-folders__folder")
                .find(".imcms-folder__name")
                .text();

            return buildFolderManageBlock({
                    folder: folder,
                    level: level,
                    name: currentFolderName
                },
                imageFoldersREST.update,
                onFolderRenamed
            ).css({
                position: "absolute",
                top: "0px",
                left: "0px"
            });
        }

        function setRenameFolder(folder, level) {
            return function renameFolder() {
                var $folderRenamingBlock = buildFolderRenamingBlock(folder, level);
                folder.$folder.children(".imcms-folders__folder").after($folderRenamingBlock);
            };
        }

        function setCreateFolder(folder, level) {
            return function createFolder() {
                showFolderCreationBlock(folder, level);

                var $openFolderBtn = $(this).parent()
                    .parent()
                    .children(".imcms-folder__btn");

                if ($openFolderBtn.hasClass("imcms-folder-btn--open")) {
                    return;
                }

                openSubFolders.call($openFolderBtn[0]);
            }
        }

        function buildFolderManageBlock(opts, onConfirm, onSuccess) {
            $("#" + FOLDER_CREATION_BLOCK_ID).detach();

            var $folderNameInput = primitives.imcmsInput({
                "class": "imcms-input",
                value: opts.name,
                placeholder: "New folder name"
            });
            var $confirmBtn = components.buttons.neutralButton({
                "class": "imcms-button",
                text: "add+",
                click: function () {
                    var folderName = $folderNameInput.val();

                    if (!folderName) {
                        return;
                    }

                    onConfirm({
                        name: folderName,
                        path: opts.folder.path

                    }).done(onSuccess.bind({
                        name: folderName,
                        path: opts.folder.path + "/" + folderName,
                        parentLevel: opts.level,
                        $block: $folderCreationBlock
                    }));
                }
            });

            var $folderCreationBlock = new BEM({
                block: "imcms-panel-named",
                elements: {
                    "input": $folderNameInput,
                    "button": $confirmBtn
                }
            }).buildBlockStructure("<div>", {id: FOLDER_CREATION_BLOCK_ID});

            return $folderCreationBlock;
        }

        function buildFolderCreationBlock(parentFolder, level) {
            return buildFolderManageBlock({
                folder: parentFolder,
                level: level,
                name: ""
            }, imageFoldersREST.create, onFolderCreated);
        }

        function showFolderCreationBlock(parentFolder, level) {
            var $createFolderBlock = buildFolderCreationBlock(parentFolder, level);
            var $subFolders = parentFolder.$folder.find(".imcms-folders");

            if ($subFolders.length) {
                $subFolders.eq(0).before($createFolderBlock);
                return;
            }

            parentFolder.$folder.append($createFolderBlock);
        }

        function buildControls(subfolder, level) {
            var controlsElements = [
                folderControlsBuilder.move(subfolder),
                folderControlsBuilder.remove(subfolder),
                folderControlsBuilder.edit(subfolder, level),
                folderControlsBuilder.create(subfolder, level)
            ];

            return controlsBuilder.buildControlsBlock("<div>", controlsElements);
        }

        function openSubFolders() {
            var $button = $(this);
            var $subFolders = $button.toggleClass(OPENED_FOLDER_BTN_CLASS)
                .parent() // fixme: bad idea!
                .parent()
                .children("." + SUBFOLDER_CLASS);

            var isOpen = $button.hasClass(OPENED_FOLDER_BTN_CLASS);

            if ($subFolders.length) {
                $subFolders.css("display", isOpen ? "block" : "none");
            }
        }

        function onFolderClick(folder) {
            $("." + ACTIVE_FOLDER_CLASS).removeClass(ACTIVE_FOLDER_CLASS);
            $(this).addClass(ACTIVE_FOLDER_CLASS);

            viewModel.$images.forEach(function ($image) {
                $image.css("display", "none");
            });
            folder.$images.forEach(function ($image) {
                $image.css("display", "block");
            });
        }

        function buildFolder(subfolder, level) {
            var elements = {};

            if (subfolder.folders && subfolder.folders.length) {
                elements.btn = $("<div>", {click: openSubFolders});
            }

            elements.name = $("<div>", {
                "class": "imcms-title",
                text: subfolder.name
            });

            elements.controls = buildControls(subfolder, level);

            return new BEM(
                {
                    block: "imcms-folder",
                    elements: elements
                }
            ).buildBlockStructure("<div>", {
                "data-folder-path": subfolder.path,
                click: function () {
                    onFolderClick.call(this, subfolder);
                }
            });
        }

        function buildSubFolder(subfolder, level) {
            var isSubLevel = (level > 1);

            var elements = {
                "folder": buildFolder(subfolder, level)
            };

            if (subfolder.folders && subfolder.folders.length) {
                elements.subfolder = buildSubFolders(subfolder, level + 1).map(function ($subfolder) {
                    if (isSubLevel) {
                        $subfolder.modifiers = ["close"];
                    }

                    return $subfolder;
                });
            }

            return new BEM({
                block: "imcms-folders",
                elements: elements
            }).buildBlockStructure("<div>", {"data-folders-lvl": level});
        }

        function buildSubFolders(folder, level) {
            return folder.folders.map(function (subfolder) {
                return subfolder.$folder = buildSubFolder(subfolder, level);
            });
        }

        function onImageDelete(imageFile) {
            imageFilesREST.remove(imageFile.path).done(function () {
                $(this).parent().parent().detach();
            }.bind(this));
        }

        function buildImageDescription(imageFile) {
            return new BEM({
                block: "imcms-choose-img-description",
                elements: {
                    "date": $("<div>", {text: imageFile.uploaded}),
                    "button": components.buttons.closeButton({
                        click: function () {
                            onImageDelete.call(this, imageFile);
                        }
                    }),
                    "img-title": $("<div>", {
                            "class": "imcms-title",
                        text: imageFile.name
                        }
                    ),
                    "img-size": $("<div>", {text: imageFile.resolution + " " + imageFile.size})
                }
            }).buildBlockStructure("<div>");
        }

        function selectImage(imageFile) {
            $(".image-chosen").removeClass("image-chosen");
            $(this).addClass("image-chosen");
            selectedImage = imageFile;
        }

        function buildImage(imageFile) {
            return new BEM({
                block: "imcms-choose-img-wrap",
                elements: {
                    "img": $("<div>", {
                        "class": "imcms-choose-img",
                        style: "background-image: url(" + Imcms.contextPath + imageFile.path + ")"
                    }),
                    "description": buildImageDescription(imageFile)
                }
            }).buildBlockStructure("<div>", {
                style: "display: none",
                click: function () {
                    selectImage.call(this, imageFile);
                }
            });
        }

        function buildImages(folder) {
            folder.$images = folder.files.map(buildImage);
            viewModel.$images = viewModel.$images.concat(folder.$images);
            (folder.folders || []).forEach(buildImages);
        }

        function loadImageFoldersContent(imagesRootFolder) {
            viewModel.root = imagesRootFolder;
            buildImages(viewModel.root);
            viewModel.$folder.push(buildRootFolder(viewModel.root));

            var $subfolders = buildSubFolders(viewModel.root, ROOT_FOLDER_LEVEL + 1).map(function ($subfolder) {
                return rootFolderBEM.makeBlockElement("folders", $subfolder);
            });

            viewModel.$folder = viewModel.$folder.concat($subfolders);

            $foldersContainer.append(viewModel.$folder);
            $imagesContainer.append(viewModel.$images);
            viewModel.root.$images.forEach(function ($image) {
                $image.css("display", "block");
            });
        }

        return {
            getSelectedImage: function () {
                return selectedImage;
            },
            loadAndBuildContent: function (options) {
                $foldersContainer = options.foldersContainer;
                $imagesContainer = options.imagesContainer;

                imageFoldersREST.read().done(loadImageFoldersContent);
            },
            onImageUpload: function (files) {
                var saveImageRequestData = {
                    files: files
                };

                var $activeFolder = $("." + ACTIVE_FOLDER_CLASS);

                if ($activeFolder.length) {
                    saveImageRequestData.folder = $activeFolder.data("folderPath")
                }

                imageFilesREST.create(saveImageRequestData)
                    .done(function (response) {
                        console.log("success file create");
                    });
            },
            clearContent: function () {
                $imagesContainer.children().detach();
                $foldersContainer.children().not("#closeFolders").detach();
                viewModel = {
                    root: {},
                    $folder: [],
                    $images: []
                }
            }
        };
    }
);
<|endoftext|>


<commit_before>/* global _ */
(function() {

  'use strict';

  function RelatedObjectsController(
    $scope, $location, SearchDao, $timeout,
    SearchResultNavigatorService, CleanJSObjectService,
    SearchHelperService, $transitions, $rootScope
  ) {
    var $ctrl = this;
    $scope.bowser = $rootScope.bowser;
    $ctrl.computeSearchResultIndex = computeSearchResultIndex;
    $ctrl.onPageChanged = onPageChanged;
    $ctrl.onSelectedTabChanged = onSelectedTabChanged;
    $ctrl.setCurrentSearchParams = setCurrentSearchParams;
    $ctrl.search = search;
    $ctrl.$onInit = init;
    $ctrl.dataPackageFilter = {};

    $ctrl.options = {};
    $ctrl.searchResult = {};
    $ctrl.placeHolder = '';
    $ctrl.disabled = false;

    var queryChangedOnInit = false;
    var tabChangedOnInitFlag = false;
    var locationChanged = false;
    var selectedTabChangeIsBeingHandled = false;
    var queryChangeIsBeingHandled = false;
    var tabs = [{
      title: 'search-management.tabs.data-packages',
      inputLabel: 'search-management.input-label.data-packages',
      elasticSearchType: 'data_packages',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.data-packages',
      group: 'dataPackages'
    }, {
      title: 'search-management.tabs.surveys',
      inputLabel: 'search-management.input-label.surveys',
      elasticSearchType: 'surveys',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.surveys',
      group: 'surveys'
    }, {
      title: 'search-management.tabs.instruments',
      inputLabel: 'search-management.input-label.instruments',
      elasticSearchType: 'instruments',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.instruments',
      group: 'instruments'
    }, {
      title: 'search-management.tabs.questions',
      inputLabel: 'search-management.input-label.questions',
      elasticSearchType: 'questions',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.questions',
      group: 'questions'
    }, {
      title: 'search-management.tabs.data_sets',
      inputLabel: 'search-management.input-label.data-sets',
      elasticSearchType: 'data_sets',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.data-sets',
      group: 'dataSets'
    }, {
      title: 'search-management.tabs.variables',
      inputLabel: 'search-management.input-label.variables',
      elasticSearchType: 'variables',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.variables',
      group: 'variables'
    }, {
      title: 'search-management.tabs.related_publications',
      inputLabel: 'search-management.input-label.related-publications',
      elasticSearchType: 'related_publications',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.related-publications',
      group: 'publications'
    }, {
      title: 'search-management.tabs.concepts',
      inputLabel: 'search-management.input-label.concepts',
      elasticSearchType: 'concepts',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.concepts',
      group: 'concepts'
    }];

    function init() {
      tabChangedOnInitFlag = true;
      queryChangedOnInit = true;
      $ctrl.tabs = tabsFilter($ctrl.options);

      // fdz-paginator options object
      $ctrl.options = {
        sortObject: {
          selected: 'relevance',
          options: ['relevance']
        },
        pageObject: {
          options: [10, 20, 50],
          totalHits: 0,
          size: 10,
          page: 1
        }
      };
      $ctrl.searchParams = {
        query: '',
        size: $ctrl.options.pageObject.size,
        selectedTabIndex: 0,
        filter: {}
      };

      readSearchParamsFromLocation();
      writeSearchParamsToLocation();
      $ctrl.placeHolder = $ctrl.tabs[$ctrl.searchParams.selectedTabIndex].title;
      $ctrl.search();
    }

    function getCurrentObjectFilter() {
      var objMapper = {
        'data-packages': 'data-package',
        'surveys': 'survey',
        'instruments': 'instrument',
        'questions': 'question',
        'data-sets': 'data-set',
        'variables': 'variable',
        'publications': 'related-publication',
        'concepts': 'concept'
      };
      var obj = {};
      var urlPath = _.takeRight($location.path().split('/'), 2);

      if (objMapper.hasOwnProperty(urlPath[0])) {
        obj[objMapper[urlPath[0]]] = $ctrl.id;
      }
      return obj;
    }

    function tabsFilter(data) {
      var relatedObjects = [];
      tabs.forEach(function(tab, index) {
        var prop = tab.group + 'Count';
        if (data.hasOwnProperty(prop)) {
          // tabs[index].count = data[prop];
          relatedObjects.push(tabs[index]);
        }
      });
      return relatedObjects;
    }

    function getSelectedMetadataType() {
      return $ctrl.tabs[$ctrl.searchParams.selectedTabIndex]
        .elasticSearchType;
    }

    // write the searchParams object to the location with the correct types
    function writeSearchParamsToLocation() {
      var locationSearch = {};
      locationSearch.page = '' + $ctrl.options.pageObject.page;
      locationSearch.size = '' + $ctrl.options.pageObject.size;
      locationSearch.type = $ctrl.tabs[
        $ctrl.searchParams.selectedTabIndex].elasticSearchType;
      if ($ctrl.searchParams.query && $ctrl.searchParams.query !== '') {
        locationSearch.query = $ctrl.searchParams.query;
      }
      if ($ctrl.searchParams['access-way'] &&
        $ctrl.searchParams['access-way'] !== '') {
        locationSearch['access-way'] = $ctrl.searchParams['access-way'];
      }
      if ($ctrl.searchParams.version && $ctrl.searchParams.version !== '') {
        locationSearch.version = $ctrl.searchParams.version;
      }
      if ($ctrl.searchParams.sortBy && $ctrl.searchParams.sortBy !== '') {
        locationSearch['sort-by'] = $ctrl.searchParams.sortBy;
      } else {
        delete locationSearch['sort-by'];
      }
      _.assign(locationSearch, _.omit($ctrl.searchParams.filter,
        'data-package', 'survey', 'concept', 'data-set', 'instrument',
        'question', 'related-publication', 'variable'));
      locationChanged = !angular.equals($location.search(),
        locationSearch);
      $location.search(locationSearch).replace();
    }

    // read the searchParams object from the location with the correct types
    function readSearchParamsFromLocation() {
      var locationSearch = $location.search();
      if (CleanJSObjectService.isNullOrEmpty(locationSearch)) {
        $ctrl.options.pageObject.page = 1;
        $ctrl.options.pageObject.size = 10;
        $ctrl.searchParams = {
          query: '',
          size: $ctrl.options.pageObject.size,
          selectedTabIndex: 0
        };
      } else {
        if (locationSearch.page != null) {
          $ctrl.options.pageObject.page = parseInt(locationSearch.page);
        } else {
          $ctrl.options.pageObject.page = 1;
        }
        if (locationSearch.size != null) {
          $ctrl.options.pageObject.size = parseInt(locationSearch.size);
          $ctrl.searchParams.size = $ctrl.options.pageObject.size;
        } else {
          $ctrl.options.pageObject.size = 10;
          $ctrl.searchParams.size = $ctrl.options.pageObject.size;
        }
        if (locationSearch.query) {
          $ctrl.searchParams.query = locationSearch.query;
        } else {
          $ctrl.searchParams.query = '';
        }
        if (locationSearch['access-way']) {
          $ctrl.searchParams['access-way'] = locationSearch['access-way'];
        }
        if (locationSearch.version) {
          $ctrl.searchParams.version = locationSearch.version;
        } else {
          $ctrl.searchParams.version = '';
        }
        $ctrl.searchParams.filter = _.omit(locationSearch, ['page', 'size',
          'type', 'query', 'sort-by', 'version'
        ]);
        $ctrl.searchParams.sortBy = locationSearch['sort-by'];
        var indexToSelect = _.findIndex($ctrl.tabs,
          function(tab) {
            return tab.elasticSearchType === locationSearch.type;
          });
        if (indexToSelect < 0) {
          $ctrl.searchParams.selectedTabIndex = 0;
        } else {
          $ctrl.searchParams.selectedTabIndex = indexToSelect;
        }
      }
    }

    // Paginator method
    function computeSearchResultIndex($index) {
      return $index + 1 +
        (($ctrl.options.pageObject.page - 1) * $ctrl.options.pageObject.size);
    }

    function setCurrentSearchParams() {
      SearchResultNavigatorService.setCurrentSearchParams(
        $ctrl.searchParams, null,
        getSelectedMetadataType(),
        $ctrl.options.pageObject);
    }

    //Search function
    function search() {
      $ctrl.isSearching++;
      if (!$ctrl.searchParams.filter) {
        $ctrl.searchParams.filter = {};
      }
      var filter = getCurrentObjectFilter();
      _.assign($ctrl.searchParams.filter, filter);
      SearchDao.search($ctrl.searchParams.query,
        $ctrl.options.pageObject.page, null, $ctrl.searchParams.filter,
        getSelectedMetadataType(),
        $ctrl.options.pageObject.size, $ctrl.searchParams.sortBy)
        .then(function(data) {
          $ctrl.searchResult = data.hits.hits;
          $ctrl.options.pageObject.totalHits = data.hits.total.value;
          $ctrl.tabs.forEach(function(tab) {
            if ($ctrl.tabs[
                $ctrl.searchParams.selectedTabIndex].elasticSearchType ===
              undefined) {
              tab.count = 0;
              data.aggregations.countByType.buckets.forEach(
                function(bucket) {
                  if (bucket.key === tab.elasticSearchType) {
                    // jscs:disable
                    tab.count = bucket.doc_count;
                    // jscs:enable
                  }
                });
            } else {
              tab.count = null;
            }
          });
          $ctrl.tabs[$ctrl.searchParams.selectedTabIndex].count =
            data.hits.total.value;
          $ctrl.isSearching--;

          // Safari fix
          $timeout(function() {
            angular.element('body')
              .append('

');
            $timeout(function() {
              angular.element('#fdz-safari-fix').remove();
            });
          }, 100);
        }, function() {
          $ctrl.options.pageObject.totalHits = 0;
          $ctrl.searchResult = {};
          $ctrl.tabs.forEach(function(tab) {
            tab.count = null;
          });
          $ctrl.tabs[$ctrl.searchParams.selectedTabIndex].count = 0;
          $ctrl.isSearching--;
        });
    }

    function onSelectedTabChanged() {
      // var version = $ctrl.searchParams.filter.version;
      if (!selectedTabChangeIsBeingHandled && !queryChangeIsBeingHandled) {
        //prevent multiple tab change handlers caused by logout
        selectedTabChangeIsBeingHandled = true;
        $timeout(function() {
          if (!tabChangedOnInitFlag) {
            $ctrl.placeHolder = $ctrl.tabs[$ctrl.searchParams.selectedTabIndex]
              .title;
            $ctrl.searchParams.filter = SearchHelperService
              .removeIrrelevantFilters(
                $ctrl.tabs[$ctrl.searchParams.selectedTabIndex]
                  .elasticSearchType,
                $ctrl.searchParams.filter);
            $ctrl.searchParams.sortBy = undefined;
            $ctrl.options.pageObject.page = 1;
            // $ctrl.searchParams.filter.version = version;
            writeSearchParamsToLocation();
            $ctrl.search();
          }
          tabChangedOnInitFlag = false;
          selectedTabChangeIsBeingHandled = false;
        });
      }
    }

    function onPageChanged() {
      writeSearchParamsToLocation();
      $ctrl.search();
    }

    $scope.$watch('$ctrl.searchParams.query', function(newVal, oldVal) {

      if (queryChangedOnInit) {
        queryChangedOnInit = false;
        return;
      }
      if (selectedTabChangeIsBeingHandled) {
        return;
      }
      queryChangeIsBeingHandled = true;
      $timeout(function() {
        $ctrl.options.pageObject.page = 1;
        delete $ctrl.searchParams.sortBy;
        if (newVal !== oldVal) {
          writeSearchParamsToLocation();
          $ctrl.search();
          queryChangeIsBeingHandled = false;
        }
      });
    });

    // watch for location changes not triggered by our code
    $scope.$watchCollection(function() {
      return $location.search();
    }, function(newValue, oldValue) {
      if (newValue !== oldValue && !locationChanged) {
        readSearchParamsFromLocation();
        // type changes are already handled by $scope.onSelectedTabChanged
        if (newValue.type === oldValue.type) {
          $ctrl.search();
        }
      } else {
        locationChanged = false;
      }
    });

    var unregisterTransitionHook = $transitions.onStart({}, function(trans) {
      $ctrl.disabled = trans.$to().name === 'relatedPublicationDetail' ||
        trans.$to().name === 'conceptDetail';
    });

    $scope.$on('$destroy', unregisterTransitionHook);
  }

  angular
    .module('metadatamanagementApp')
    .controller('RelatedObjectsController', RelatedObjectsController);

})();
<commit_msg>#2632 fix broken translation<commit_after>/* global _ */
(function() {

  'use strict';

  function RelatedObjectsController(
    $scope, $location, SearchDao, $timeout,
    SearchResultNavigatorService, CleanJSObjectService,
    SearchHelperService, $transitions, $rootScope
  ) {
    var $ctrl = this;
    $scope.bowser = $rootScope.bowser;
    $ctrl.computeSearchResultIndex = computeSearchResultIndex;
    $ctrl.onPageChanged = onPageChanged;
    $ctrl.onSelectedTabChanged = onSelectedTabChanged;
    $ctrl.setCurrentSearchParams = setCurrentSearchParams;
    $ctrl.search = search;
    $ctrl.$onInit = init;
    $ctrl.dataPackageFilter = {};

    $ctrl.options = {};
    $ctrl.searchResult = {};
    $ctrl.placeHolder = '';
    $ctrl.disabled = false;

    var queryChangedOnInit = false;
    var tabChangedOnInitFlag = false;
    var locationChanged = false;
    var selectedTabChangeIsBeingHandled = false;
    var queryChangeIsBeingHandled = false;
    var tabs = [{
      title: 'search-management.tabs.data_packages',
      inputLabel: 'search-management.input-label.data-packages',
      elasticSearchType: 'data_packages',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.data-packages',
      group: 'dataPackages'
    }, {
      title: 'search-management.tabs.surveys',
      inputLabel: 'search-management.input-label.surveys',
      elasticSearchType: 'surveys',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.surveys',
      group: 'surveys'
    }, {
      title: 'search-management.tabs.instruments',
      inputLabel: 'search-management.input-label.instruments',
      elasticSearchType: 'instruments',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.instruments',
      group: 'instruments'
    }, {
      title: 'search-management.tabs.questions',
      inputLabel: 'search-management.input-label.questions',
      elasticSearchType: 'questions',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.questions',
      group: 'questions'
    }, {
      title: 'search-management.tabs.data_sets',
      inputLabel: 'search-management.input-label.data-sets',
      elasticSearchType: 'data_sets',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.data-sets',
      group: 'dataSets'
    }, {
      title: 'search-management.tabs.variables',
      inputLabel: 'search-management.input-label.variables',
      elasticSearchType: 'variables',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.variables',
      group: 'variables'
    }, {
      title: 'search-management.tabs.related_publications',
      inputLabel: 'search-management.input-label.related-publications',
      elasticSearchType: 'related_publications',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.related-publications',
      group: 'publications'
    }, {
      title: 'search-management.tabs.concepts',
      inputLabel: 'search-management.input-label.concepts',
      elasticSearchType: 'concepts',
      count: null,
      uploadFunction: null,
      disabled: false,
      visibleForPublicUser: true,
      noResultsText: 'search-management.no-results-text.concepts',
      group: 'concepts'
    }];

    function init() {
      tabChangedOnInitFlag = true;
      queryChangedOnInit = true;
      $ctrl.tabs = tabsFilter($ctrl.options);

      // fdz-paginator options object
      $ctrl.options = {
        sortObject: {
          selected: 'relevance',
          options: ['relevance']
        },
        pageObject: {
          options: [10, 20, 50],
          totalHits: 0,
          size: 10,
          page: 1
        }
      };
      $ctrl.searchParams = {
        query: '',
        size: $ctrl.options.pageObject.size,
        selectedTabIndex: 0,
        filter: {}
      };

      readSearchParamsFromLocation();
      writeSearchParamsToLocation();
      $ctrl.placeHolder = $ctrl.tabs[$ctrl.searchParams.selectedTabIndex].title;
      $ctrl.search();
    }

    function getCurrentObjectFilter() {
      var objMapper = {
        'data-packages': 'data-package',
        'surveys': 'survey',
        'instruments': 'instrument',
        'questions': 'question',
        'data-sets': 'data-set',
        'variables': 'variable',
        'publications': 'related-publication',
        'concepts': 'concept'
      };
      var obj = {};
      var urlPath = _.takeRight($location.path().split('/'), 2);

      if (objMapper.hasOwnProperty(urlPath[0])) {
        obj[objMapper[urlPath[0]]] = $ctrl.id;
      }
      return obj;
    }

    function tabsFilter(data) {
      var relatedObjects = [];
      tabs.forEach(function(tab, index) {
        var prop = tab.group + 'Count';
        if (data.hasOwnProperty(prop)) {
          // tabs[index].count = data[prop];
          relatedObjects.push(tabs[index]);
        }
      });
      return relatedObjects;
    }

    function getSelectedMetadataType() {
      return $ctrl.tabs[$ctrl.searchParams.selectedTabIndex]
        .elasticSearchType;
    }

    // write the searchParams object to the location with the correct types
    function writeSearchParamsToLocation() {
      var locationSearch = {};
      locationSearch.page = '' + $ctrl.options.pageObject.page;
      locationSearch.size = '' + $ctrl.options.pageObject.size;
      locationSearch.type = $ctrl.tabs[
        $ctrl.searchParams.selectedTabIndex].elasticSearchType;
      if ($ctrl.searchParams.query && $ctrl.searchParams.query !== '') {
        locationSearch.query = $ctrl.searchParams.query;
      }
      if ($ctrl.searchParams['access-way'] &&
        $ctrl.searchParams['access-way'] !== '') {
        locationSearch['access-way'] = $ctrl.searchParams['access-way'];
      }
      if ($ctrl.searchParams.version && $ctrl.searchParams.version !== '') {
        locationSearch.version = $ctrl.searchParams.version;
      }
      if ($ctrl.searchParams.sortBy && $ctrl.searchParams.sortBy !== '') {
        locationSearch['sort-by'] = $ctrl.searchParams.sortBy;
      } else {
        delete locationSearch['sort-by'];
      }
      _.assign(locationSearch, _.omit($ctrl.searchParams.filter,
        'data-package', 'survey', 'concept', 'data-set', 'instrument',
        'question', 'related-publication', 'variable'));
      locationChanged = !angular.equals($location.search(),
        locationSearch);
      $location.search(locationSearch).replace();
    }

    // read the searchParams object from the location with the correct types
    function readSearchParamsFromLocation() {
      var locationSearch = $location.search();
      if (CleanJSObjectService.isNullOrEmpty(locationSearch)) {
        $ctrl.options.pageObject.page = 1;
        $ctrl.options.pageObject.size = 10;
        $ctrl.searchParams = {
          query: '',
          size: $ctrl.options.pageObject.size,
          selectedTabIndex: 0
        };
      } else {
        if (locationSearch.page != null) {
          $ctrl.options.pageObject.page = parseInt(locationSearch.page);
        } else {
          $ctrl.options.pageObject.page = 1;
        }
        if (locationSearch.size != null) {
          $ctrl.options.pageObject.size = parseInt(locationSearch.size);
          $ctrl.searchParams.size = $ctrl.options.pageObject.size;
        } else {
          $ctrl.options.pageObject.size = 10;
          $ctrl.searchParams.size = $ctrl.options.pageObject.size;
        }
        if (locationSearch.query) {
          $ctrl.searchParams.query = locationSearch.query;
        } else {
          $ctrl.searchParams.query = '';
        }
        if (locationSearch['access-way']) {
          $ctrl.searchParams['access-way'] = locationSearch['access-way'];
        }
        if (locationSearch.version) {
          $ctrl.searchParams.version = locationSearch.version;
        } else {
          $ctrl.searchParams.version = '';
        }
        $ctrl.searchParams.filter = _.omit(locationSearch, ['page', 'size',
          'type', 'query', 'sort-by', 'version'
        ]);
        $ctrl.searchParams.sortBy = locationSearch['sort-by'];
        var indexToSelect = _.findIndex($ctrl.tabs,
          function(tab) {
            return tab.elasticSearchType === locationSearch.type;
          });
        if (indexToSelect < 0) {
          $ctrl.searchParams.selectedTabIndex = 0;
        } else {
          $ctrl.searchParams.selectedTabIndex = indexToSelect;
        }
      }
    }

    // Paginator method
    function computeSearchResultIndex($index) {
      return $index + 1 +
        (($ctrl.options.pageObject.page - 1) * $ctrl.options.pageObject.size);
    }

    function setCurrentSearchParams() {
      SearchResultNavigatorService.setCurrentSearchParams(
        $ctrl.searchParams, null,
        getSelectedMetadataType(),
        $ctrl.options.pageObject);
    }

    //Search function
    function search() {
      $ctrl.isSearching++;
      if (!$ctrl.searchParams.filter) {
        $ctrl.searchParams.filter = {};
      }
      var filter = getCurrentObjectFilter();
      _.assign($ctrl.searchParams.filter, filter);
      SearchDao.search($ctrl.searchParams.query,
        $ctrl.options.pageObject.page, null, $ctrl.searchParams.filter,
        getSelectedMetadataType(),
        $ctrl.options.pageObject.size, $ctrl.searchParams.sortBy)
        .then(function(data) {
          $ctrl.searchResult = data.hits.hits;
          $ctrl.options.pageObject.totalHits = data.hits.total.value;
          $ctrl.tabs.forEach(function(tab) {
            if ($ctrl.tabs[
                $ctrl.searchParams.selectedTabIndex].elasticSearchType ===
              undefined) {
              tab.count = 0;
              data.aggregations.countByType.buckets.forEach(
                function(bucket) {
                  if (bucket.key === tab.elasticSearchType) {
                    // jscs:disable
                    tab.count = bucket.doc_count;
                    // jscs:enable
                  }
                });
            } else {
              tab.count = null;
            }
          });
          $ctrl.tabs[$ctrl.searchParams.selectedTabIndex].count =
            data.hits.total.value;
          $ctrl.isSearching--;

          // Safari fix
          $timeout(function() {
            angular.element('body')
              .append('

');
            $timeout(function() {
              angular.element('#fdz-safari-fix').remove();
            });
          }, 100);
        }, function() {
          $ctrl.options.pageObject.totalHits = 0;
          $ctrl.searchResult = {};
          $ctrl.tabs.forEach(function(tab) {
            tab.count = null;
          });
          $ctrl.tabs[$ctrl.searchParams.selectedTabIndex].count = 0;
          $ctrl.isSearching--;
        });
    }

    function onSelectedTabChanged() {
      // var version = $ctrl.searchParams.filter.version;
      if (!selectedTabChangeIsBeingHandled && !queryChangeIsBeingHandled) {
        //prevent multiple tab change handlers caused by logout
        selectedTabChangeIsBeingHandled = true;
        $timeout(function() {
          if (!tabChangedOnInitFlag) {
            $ctrl.placeHolder = $ctrl.tabs[$ctrl.searchParams.selectedTabIndex]
              .title;
            $ctrl.searchParams.filter = SearchHelperService
              .removeIrrelevantFilters(
                $ctrl.tabs[$ctrl.searchParams.selectedTabIndex]
                  .elasticSearchType,
                $ctrl.searchParams.filter);
            $ctrl.searchParams.sortBy = undefined;
            $ctrl.options.pageObject.page = 1;
            // $ctrl.searchParams.filter.version = version;
            writeSearchParamsToLocation();
            $ctrl.search();
          }
          tabChangedOnInitFlag = false;
          selectedTabChangeIsBeingHandled = false;
        });
      }
    }

    function onPageChanged() {
      writeSearchParamsToLocation();
      $ctrl.search();
    }

    $scope.$watch('$ctrl.searchParams.query', function(newVal, oldVal) {

      if (queryChangedOnInit) {
        queryChangedOnInit = false;
        return;
      }
      if (selectedTabChangeIsBeingHandled) {
        return;
      }
      queryChangeIsBeingHandled = true;
      $timeout(function() {
        $ctrl.options.pageObject.page = 1;
        delete $ctrl.searchParams.sortBy;
        if (newVal !== oldVal) {
          writeSearchParamsToLocation();
          $ctrl.search();
          queryChangeIsBeingHandled = false;
        }
      });
    });

    // watch for location changes not triggered by our code
    $scope.$watchCollection(function() {
      return $location.search();
    }, function(newValue, oldValue) {
      if (newValue !== oldValue && !locationChanged) {
        readSearchParamsFromLocation();
        // type changes are already handled by $scope.onSelectedTabChanged
        if (newValue.type === oldValue.type) {
          $ctrl.search();
        }
      } else {
        locationChanged = false;
      }
    });

    var unregisterTransitionHook = $transitions.onStart({}, function(trans) {
      $ctrl.disabled = trans.$to().name === 'relatedPublicationDetail' ||
        trans.$to().name === 'conceptDetail';
    });

    $scope.$on('$destroy', unregisterTransitionHook);
  }

  angular
    .module('metadatamanagementApp')
    .controller('RelatedObjectsController', RelatedObjectsController);

})();
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012 Vanderbilt University, All rights reserved.
 *
 * Author: Tamas Kecskes
 */

define([ 'storage/mongo', 'storage/server', 'storage/cache', 'storage/log', 'storage/broadcaster'], function (Mongo,Server,Cache,Log,Broadcaster) {
    "use strict";
    function server(options){
        return new Server(new Log(new Cache/*(new Broadcaster*/(new Mongo(options)/*,options)*/,options),options),options);
    }

    return server;
});

<commit_msg>cacheSize===0 in config => dont use storage/cache at all<commit_after>/*
 * Copyright (C) 2012 Vanderbilt University, All rights reserved.
 *
 * Author: Tamas Kecskes
 */

define([ 'storage/mongo', 'storage/server', 'storage/cache', 'storage/log', 'storage/broadcaster'], function (Mongo,Server,Cache,Log,Broadcaster) {
    "use strict";
    function server(options){
        var server = /*new Broadcaster(*/new Mongo(options)/*,options)*/;
        if (options.cache !== 0) {
            server = new Cache(server, options);
        }
        return new Server(new Log(server, options), options);
    }

    return server;
});

<|endoftext|>


<commit_before>import Ember from 'ember';
import ENV from '../config/environment';
import baseConfig, { testConfig } from '../mirage/config';
import Server from 'ember-cli-mirage/server';
import readModules from 'ember-cli-mirage/utils/read-modules';

export default {
  name: 'ember-cli-mirage',
  initialize: function(container, application) {
    var env = ENV.environment;

    if (_shouldUseMirage(env, ENV['ember-cli-mirage'])) {
      var modulesMap = readModules(ENV.modulePrefix);
      var hasFactories = !Ember.isEmpty(modulesMap['factories']);
      var hasDefaultScenario = modulesMap['scenarios'].hasOwnProperty('default');
      var server = new Server({
        environment: env
      });

      server.loadConfig(baseConfig);

      if (env === 'test') {
        server.loadConfig(testConfig);
      }

      if (env === 'test' && hasFactories) {
        server.loadFactories(modulesMap['factories']);
      } else if (env !== 'test' && hasDefaultScenario && hasFactories) {
        server.loadFactories(modulesMap['factories']);
        modulesMap['scenarios']['default'](server);
      } else {
        server.db.loadData(modulesMap['fixtures']);
      }
    }
  }
};

function _shouldUseMirage(env, addonConfig) {
  var userDeclaredEnabled = typeof addonConfig.enabled !== 'undefined';
  var defaultEnabled = _defaultEnabled(env, addonConfig);

  return userDeclaredEnabled ? addonConfig.enabled : defaultEnabled;
}

/*
  Returns a boolean specifying the default behavior for whether
  to initialize Mirage.
*/
function _defaultEnabled(env, addonConfig) {
  var usingInDev = env === 'development' && !addonConfig.usingProxy;
  var usingInTest = env === 'test';

  return usingInDev || usingInTest;
}
<commit_msg>[closes #148] allow testconfig to be optional<commit_after>import Ember from 'ember';
import ENV from '../config/environment';
import baseConfig, { testConfig } from '../mirage/config';
import Server from 'ember-cli-mirage/server';
import readModules from 'ember-cli-mirage/utils/read-modules';

export default {
  name: 'ember-cli-mirage',
  initialize: function(container, application) {
    var env = ENV.environment;

    if (_shouldUseMirage(env, ENV['ember-cli-mirage'])) {
      var modulesMap = readModules(ENV.modulePrefix);
      var hasFactories = !Ember.isEmpty(modulesMap['factories']);
      var hasDefaultScenario = modulesMap['scenarios'].hasOwnProperty('default');
      var server = new Server({
        environment: env
      });

      server.loadConfig(baseConfig);

      if (env === 'test' && testConfig) {
        server.loadConfig(testConfig);
      }

      if (env === 'test' && hasFactories) {
        server.loadFactories(modulesMap['factories']);
      } else if (env !== 'test' && hasDefaultScenario && hasFactories) {
        server.loadFactories(modulesMap['factories']);
        modulesMap['scenarios']['default'](server);
      } else {
        server.db.loadData(modulesMap['fixtures']);
      }
    }
  }
};

function _shouldUseMirage(env, addonConfig) {
  var userDeclaredEnabled = typeof addonConfig.enabled !== 'undefined';
  var defaultEnabled = _defaultEnabled(env, addonConfig);

  return userDeclaredEnabled ? addonConfig.enabled : defaultEnabled;
}

/*
  Returns a boolean specifying the default behavior for whether
  to initialize Mirage.
*/
function _defaultEnabled(env, addonConfig) {
  var usingInDev = env === 'development' && !addonConfig.usingProxy;
  var usingInTest = env === 'test';

  return usingInDev || usingInTest;
}
<|endoftext|>


<commit_before>import React from 'react'

import {
  pictureCreate,
  pictureReset,
} from '../../action/picture-action.js'

let counter = 0
let rightIndex = 0
let leftIndex = 0
let centerIndex = 0
var currentImage = []

class PictureItem extends React.Component{
  constructor(props){
    super(props)

    this.state = {
      imagesArray: [
        'chrisH', 'zayn', 'lance' ,'zac', 'chrisPR', 'david',
        'taylor', 'kofi', 'ryanR', 'chrisP', 'charles', 'greyworm',
        'ryanG', 'jason', 'don', 'robert', 'jessie', 'richard',
        'jon', 'orlando', 'liam',
      ],
      urlImageArray: [],
      random: false,
    }

    // this.renderImage = this.renderImage.bind(this)
    this.getRandomNumber = this.getRandomNumber.bind(this)
    this.makeURLs = this.makeURLs.bind(this)
    this.randomlyShowImages = this.randomlyShowImages.bind(this)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick(e){
    // e.preventDefault()

    console.log('inside event handler')
    console.log('%%%%%%%%', counter)
    var imageDiv = document.getElementById('three-images')
    imageDiv.innerHTML = ''
    this.randomlyShowImages()
    console.log('outside of it')
    // this.state.imagesArray.map((imageName) => {
    //   if (e.target.src === imageName)
    // }
  }

  makeURLs(imageName){
    this.state.urlImageArray.push('../images/' + imageName + '.png')
    // console.log('MAKE URLS', this.state)
    counter++
    if (counter == this.state.imagesArray.length){
      console.log('hellllllllllo')
      this.randomlyShowImages()
    }
  }

  randomlyShowImages(imageName) {
    if(counter < 22) {
      console.log('inside if statement')
      this.makeURLs(imageName)
      console.log('outside if statement')
    } else if ( counter >= 22 ) {
      counter = 0
      this.state.imagesArray.map((imageName) =>
        this.makeURLs(imageName)
      )
    }

    console.log('#$#$#$#$#$', counter)
    console.log('!!!!!!', this.state.imagesArray.length)
    if (counter >= 22) {
      leftIndex = parseInt(this.getRandomNumber(0, 20))
      currentImage.push(leftIndex)
      // console.log(this.state.urlImageArray[leftIndex])

      centerIndex = parseInt(this.getRandomNumber(0, 20))
      currentImage.push(centerIndex)
      // console.log(this.state.urlImageArray[centerIndex])

      rightIndex = parseInt(this.getRandomNumber(0, 20))
      currentImage.push(rightIndex)
      // console.log(this.state.urlImageArray[rightIndex])

      // console.log('&&&&currentImage ARRAY: ', currentImage)
      console.log('checking this out:', this.state.imagesArray[leftIndex])

      return (

      )
    }
  }

  getRandomNumber(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min)
  }

  render() {
    console.log(this)
    return (

THESE IS THE IMAGES

            {counter=null}
            {this.state.imagesArray.map((imageName) => {
              return this.randomlyShowImages(imageName)
            })}

    )
  }
}

export default PictureItem
<commit_msg>considering using lodash<commit_after>import React from 'react'

// TODO: Consider using Lodash (3rd party module) to shuffle and chunk the array of images.
// NOTE: Make sure to understand the ins and outs of how it works.

import {
  pictureCreate,
  pictureReset,
} from '../../action/picture-action.js'

let counter = 0
let rightIndex = 0
let leftIndex = 0
let centerIndex = 0
var currentImage = []

class PictureItem extends React.Component{
  constructor(props){
    super(props)

    this.state = {
      imagesArray: [
        'chrisH', 'zayn', 'lance' ,'zac', 'chrisPR', 'david',
        'taylor', 'kofi', 'ryanR', 'chrisP', 'charles', 'greyworm',
        'ryanG', 'jason', 'don', 'robert', 'jessie', 'richard',
        'jon', 'orlando', 'liam',
      ],
      urlImageArray: [],
      random: false,
    }

    // this.renderImage = this.renderImage.bind(this)
    this.getRandomNumber = this.getRandomNumber.bind(this)
    this.makeURLs = this.makeURLs.bind(this)
    this.randomlyShowImages = this.randomlyShowImages.bind(this)
    this.handleClick = this.handleClick.bind(this)
  }

  handleClick(e){
    // e.preventDefault()

    console.log('inside event handler')
    console.log('%%%%%%%%', counter)
    var imageDiv = document.getElementById('three-images')
    imageDiv.innerHTML = ''
    this.randomlyShowImages()
    console.log('outside of it')
    // this.state.imagesArray.map((imageName) => {
    //   if (e.target.src === imageName)
    // }
  }

  makeURLs(imageName){
    this.state.urlImageArray.push('../images/' + imageName + '.png')
    // console.log('MAKE URLS', this.state)
    counter++
    if (counter == this.state.imagesArray.length){
      console.log('hellllllllllo')
      this.randomlyShowImages()
    }
  }

  randomlyShowImages(imageName) {
    if(counter < 22) {
      console.log('inside if statement')
      this.makeURLs(imageName)
      console.log('outside if statement')
    } else if ( counter >= 22 ) {
      counter = 0
      this.state.imagesArray.map((imageName) =>
        this.makeURLs(imageName)
      )
    }

    console.log('#$#$#$#$#$', counter)
    console.log('!!!!!!', this.state.imagesArray.length)
    if (counter >= 22) {
      leftIndex = parseInt(this.getRandomNumber(0, 20))
      currentImage.push(leftIndex)
      // console.log(this.state.urlImageArray[leftIndex])

      centerIndex = parseInt(this.getRandomNumber(0, 20))
      currentImage.push(centerIndex)
      // console.log(this.state.urlImageArray[centerIndex])

      rightIndex = parseInt(this.getRandomNumber(0, 20))
      currentImage.push(rightIndex)
      // console.log(this.state.urlImageArray[rightIndex])

      // console.log('&&&&currentImage ARRAY: ', currentImage)
      console.log('checking this out:', this.state.imagesArray[leftIndex])

      return (

      )
    }
  }

  getRandomNumber(min, max) {
    return Math.floor(Math.random() * (max - min + 1) + min)
  }

  render() {
    console.log(this)
    return (

THESE IS THE IMAGES

            {counter=null}
            {this.state.imagesArray.map((imageName) => {
              return this.randomlyShowImages(imageName)
            })}

    )
  }
}

export default PictureItem
<|endoftext|>


<commit_before>import flatten from 'flat';
import jsonexport from 'jsonexport';
import React, { Component } from 'react';
import { CSVLink } from 'react-csv';

class CSVExport extends Component {
	constructor(){
		super();

		this.exportFile = this.exportFile.bind(this);
	}

	convertFileType(data) {
		const options = {
			headers: this.props.columns.map((column) => (column.value)),
			rename: this.props.columns.map((column) => (column.label)),
		};

		jsonexport(data, options, (err,csv) => {
			if(err) {
				return console.log(err);
			}
			return csv;
		});
	}

	exportFile() {
		return this.reformatColumns(this.props.visibleItems);
	}

	reformatColumns(items) {
		const flatList = items.map((item) => flatten(item, { maxDepth: 2 }));

		// convert columns
    const reformattedList = flatList.map((item) => ({
      ...item,
      // Put the hours in the right column
      [item['budgetHours.column']]: item['budgetHours.value'],
      total: item['budgetHours.value'],
    }));

		let concatObj = {};

		// combine on feature
		reformattedList.map((item) => {
      // Feature isn't already in the object
			if (typeof concatObj[item.feature] === 'undefined') {
				concatObj[item.feature] = item;
			} else {
        // Add to existing feature
				for (const property in item) {
					if(Array.isArray(item[property])) {
            concatObj[item.feature][property] = [
              ...concatObj[item.feature][property],
              ...item[property],
            ];
					} else if(typeof item[property] === 'number') {
            // Sum the numbers
						concatObj[item.feature][property] = concatObj[item.feature][property] + item[property] || item[property];
					}
				}
			}
		});

		// convert concatObj from properties to array elements
		let concatList = [];
		for (const element in concatObj) {
			concatList = [...concatList, concatObj[element]];
		}

		return concatList;
	}

	render() {

		return (

				<CSVLink
					data={this.exportFile()}
					headers={this.props.columns}
					filename={'Budget.csv'}
					className="btn btn-primary">
					Export to CSV
				</CSVLink>

		);
	}
}

CSVExport.defaultProps = {
	columns: [{
		key:'feature',
		value:'feature',
		label:'Page/Feature',
	},{
		key:'t&m',
		value:'t&m',
		label:'T&M',
	},{
		key:'Discovery',
		value:'Discovery',
		label:'Disc',
	},{
		key:'Design',
		value:'Design',
		label:'Design',
	},{
		key:'Dev',
		value:'Dev',
		label:'Dev',
	},{
		key:'Testing',
		value:'Testing',
		label:'Testing',
	},{
		key:'Remediation',
		value:'Remediation',
		label:'Remediation',
	},{
		key:'Deploy',
		value:'Deploy',
		label:'Deploy',
	},{
		key:'PM',
		value:'PM',
		label:'PM',
	},{
		key:'total',
		value:'total',
		label:'Total',
	},{
		key:'descriptions.budget',
		value:'descriptions.budget',
		label:'Description',
	},{
		key:'descriptions.assumptions',
		value:'descriptions.assumptions',
		label:'Assumptions',
	},{
		key:'descriptions.clientResponsibilities',
		value:'descriptions.clientResponsibilities',
		label:'Client Responsibilities',
	},{
		key:'descriptions.exclusions',
		value:'descriptions.exclusions',
		label:'Exclusions',
	},
	]
}

export default CSVExport;
<commit_msg>Start to refactor formatting for export<commit_after>import flatten from 'flat';
import jsonexport from 'jsonexport';
import React, { Component } from 'react';
import { CSVLink } from 'react-csv';

class CSVExport extends Component {
	constructor(){
		super();

		this.exportFile = this.exportFile.bind(this);
	}

	convertFileType(data) {
		const options = {
			headers: this.props.columns.map((column) => (column.value)),
			rename: this.props.columns.map((column) => (column.label)),
		};

		jsonexport(data, options, (err,csv) => {
			if(err) {
				return console.log(err);
			}
			return csv;
		});
	}

	exportFile() {
		return this.reformatColumns(this.props.visibleItems);
	}

	reformatColumns(items) {
		const flatList = items.map((item) => flatten(item, { maxDepth: 2 }));

		// convert columns
    const reformattedList = flatList.map((item) => ({
      ...item,
      // Put the hours in the right column
      [item['budgetHours.column']]: item['budgetHours.value'],
      total: item['budgetHours.value'],
    }));

		let concatObj = {};

    const itemsByFeature = reformattedList.reduce((features, item) => {
      features[item.feature] = [
        ...features[item.feature] || [],
        item,
      ];

      return features;
    }, {});

    console.log({ itemsByFeature, reformattedList });

		// combine on feature
		reformattedList.map((item) => {
      // Feature isn't already in the object
			if (typeof concatObj[item.feature] === 'undefined') {
				concatObj[item.feature] = item;
			} else {
        // Add to existing feature
				for (const property in item) {
					if(Array.isArray(item[property])) {
            concatObj[item.feature][property] = [
              ...concatObj[item.feature][property],
              ...item[property],
            ];
					} else if(typeof item[property] === 'number') {
            // Sum the numbers
						concatObj[item.feature][property] = concatObj[item.feature][property] + item[property] || item[property];
					}
				}
			}
		});

		// convert concatObj from properties to array elements
		let concatList = [];
		for (const element in concatObj) {
			concatList = [...concatList, concatObj[element]];
		}

		return concatList;
	}

	render() {

		return (

				<CSVLink
					data={this.exportFile()}
					headers={this.props.columns}
					filename={'Budget.csv'}
					className="btn btn-primary">
					Export to CSV
				</CSVLink>

		);
	}
}

CSVExport.defaultProps = {
	columns: [{
		key:'feature',
		value:'feature',
		label:'Page/Feature',
	},{
		key:'t&m',
		value:'t&m',
		label:'T&M',
	},{
		key:'Discovery',
		value:'Discovery',
		label:'Disc',
	},{
		key:'Design',
		value:'Design',
		label:'Design',
	},{
		key:'Dev',
		value:'Dev',
		label:'Dev',
	},{
		key:'Testing',
		value:'Testing',
		label:'Testing',
	},{
		key:'Remediation',
		value:'Remediation',
		label:'Remediation',
	},{
		key:'Deploy',
		value:'Deploy',
		label:'Deploy',
	},{
		key:'PM',
		value:'PM',
		label:'PM',
	},{
		key:'total',
		value:'total',
		label:'Total',
	},{
		key:'descriptions.budget',
		value:'descriptions.budget',
		label:'Description',
	},{
		key:'descriptions.assumptions',
		value:'descriptions.assumptions',
		label:'Assumptions',
	},{
		key:'descriptions.clientResponsibilities',
		value:'descriptions.clientResponsibilities',
		label:'Client Responsibilities',
	},{
		key:'descriptions.exclusions',
		value:'descriptions.exclusions',
		label:'Exclusions',
	},
	]
}

export default CSVExport;
<|endoftext|>


<commit_before>import React from 'react'
import classes from './HeroPage.scss'
import { Col } from 'react-bootstrap'
import lightbulb from 'static/lightbulb2018.png'
// import gif from 'static/Ideate2k17.gif'

export const HeroPage = () => (

        <Col md={10}>

Ideate

            A student innovation & design conference

            April 14, 2018 @ Duke University

        </Col>
        <Col md={2}>

        </Col>

          <button className={classes.registerButton}> Register </button>

)

export default HeroPage
<commit_msg>Actually change background<commit_after>import React from 'react'
import classes from './HeroPage.scss'
import { Col } from 'react-bootstrap'
import lightbulb from 'static/lightbulb2018.png'
import gif from 'static/Ideate2k17.gif'

export const HeroPage = () => (

        <Col md={10}>

Ideate

            A student innovation & design conference

            April 14, 2018 @ Duke University

        </Col>
        <Col md={2}>

        </Col>

          <button className={classes.registerButton}> Register </button>

)

export default HeroPage
<|endoftext|>


<commit_before>// source: https://github.com/murb/zxing-demo/blob/master/zxing_helper.js

// <!-- UTILS START

// https://gist.github.com/jonleighton/958841
// bytes: Uint8Array

var ZXing;

if (typeof require !== "undefined") {
  ZXing = require('zxing/zxing_reader');
}

function uint8ArrayToBase64(bytes) {
  var base64    = ''
  var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  var byteLength    = bytes.byteLength
  var byteRemainder = byteLength % 3
  var mainLength    = byteLength - byteRemainder
  var a, b, c, d
  var chunk
  for (var i = 0; i < mainLength; i = i + 3) {
    chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
    a = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18
    b = (chunk & 258048)   >> 12 // 258048   = (2^6 - 1) << 12
    c = (chunk & 4032)     >>  6 // 4032     = (2^6 - 1) << 6
    d = chunk & 63               // 63       = 2^6 - 1
    base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]
  }
  if (byteRemainder == 1) {
    chunk = bytes[mainLength]
    a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2
    b = (chunk & 3)   << 4 // 3   = 2^2 - 1
    base64 += encodings[a] + encodings[b] + '=='
  } else if (byteRemainder == 2) {
    chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]
    a = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10
    b = (chunk & 1008)  >>  4 // 1008  = (2^6 - 1) << 4
    c = (chunk & 15)    <<  2 // 15    = 2^4 - 1
    base64 += encodings[a] + encodings[b] + encodings[c] + '='
  }
  return base64
}

// https://stackoverflow.com/a/21797381
// https://stackoverflow.com/a/7261048
function base64ToUint8Array(uri) { // i.e. base64.b64_decode() in python
    var binary_string =  window.atob(uri.split(",")[1]);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++) {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes;
}

// https://gist.github.com/murb/a8823e7a2d6fc9613b3c5c00a0225809
if (!Element.prototype.matches) {
  Element.prototype.matches = Element.prototype.msMatchesSelector;
}

// https://gist.github.com/murb/a8823e7a2d6fc9613b3c5c00a0225809
if (!HTMLDocument.prototype.addDelegatedEventListener) {
  HTMLDocument.prototype.addDelegatedEventListener = function(event, matcher, cb) {
    var newCB;
    newCB = function(event) {
      if (event.target.matches && event.target.matches(matcher)) {
        return cb(event);
      }
    };
    return this.addEventListener(event, newCB);
  };
}

// play a simple beep
let gain;

const prepareAudioContext = function() {
  const AudioContext = window.AudioContext || window.webkitAudioContext;
  if (typeof AudioContext !== "undefined") {
    var audioContext = new AudioContext();
    // create empty buffer
    let buffer = audioContext.createBuffer(1, 1, 22050);
    let source = audioContext.createBufferSource();
    source.buffer = buffer;

    // connect to output (your speakers)
    source.connect(audioContext.destination);

    audioContext.createOscillator();
    gain = audioContext.createGain();
    let oscillator = audioContext.createOscillator();

    oscillator.connect(gain);
    oscillator.frequency.value = 880;
    oscillator.type = 0; //sine
    gain.connect(audioContext.destination);
    gain.gain.value = 0;
    oscillator.start(audioContext.currentTime);
  }
}

function beep(vol, duration){
  gain.gain.value = vol;
  setTimeout(function() { gain.gain.value = 0 }, duration)
}

// --> UTILS END

var zxing;
var state = {
  scanActive: null,
  targetElement: null,
  codeCallback: renderCodeToTargetElement,
  values: []
}

function scanBarcode(canvasElement, format) {
    var imgWidth = canvasElement.width;
    var imgHeight = canvasElement.height;
    var imageData = canvasElement.getContext('2d').getImageData(0, 0, imgWidth, imgHeight);
    var sourceBuffer = imageData.data;
    if (sourceBuffer.byteLength <= imgWidth*imgHeight*4) {
      var buffer = zxing._malloc(sourceBuffer.byteLength * 2);
      zxing.HEAPU8.set(sourceBuffer, buffer);
      var result = zxing.readBarcodeFromPixmap(buffer, imgWidth, imgHeight, true, format);
      zxing._free(buffer);
      return result;
    } else {
      console.log(sourceBuffer.byteLength)
    }
}

function flashBorder() {
  document.querySelector(".zxing-canvas-container").classList.add("flash");
  setTimeout(function() {
    document.querySelector(".zxing-canvas-container").classList.remove("flash")
  }, 500)
}

function renderCodeInOutputMessage(code) {
  var outputContainer = document.getElementById("output");
  var outputMessage = document.getElementById("outputMessage");
  var outputData = document.getElementById("outputData");

  outputContainer.hidden = false;

  if (code.error) {
    outputMessage.hidden = true;
    outputData.parentElement.hidden = false;
    outputData.innerText = code.error;
  } else if(code.format) {
    outputMessage.hidden = true;
    outputData.parentElement.hidden = false;
    outputData.innerText = code.text;
  } else {
    outputMessage.hidden = false;
    outputData.parentElement.hidden = true;
  }
}

function renderCodeToTargetTextArea(code) {
  if (code.format) {
    var currentValue = state.targetElement.value.trim();
    if (!currentValue.match(code.text)) { // tried escapeProblemFreeMatch() but too slow for Safari atm, out of scope anyhow
      currentValue = code.text + "\n" + currentValue;
      flashBorder();
      beep(0.1, 200);
    }
    state.targetElement.value = currentValue
  }
}

function renderCodeToTargetElement(code) {
  if (state.targetElement.localName == "textarea") {
    renderCodeToTargetTextArea(code);
  }
}

// too slow for safari (was a workaround for bad QR codes, but out of scope for now anyhow)
function escapeProblemFreeMatch(text, target) {
  return text.replaceAll(/[\"\:\?\.\/]/g,"").match(target.replaceAll(/[\"\:\?\.\/]/g,""))
}

function initializeScanner() {
  var video = document.createElement("video");

  zxing = ZXing();
  video.width = 800;
  video.height = 800;

  var canvasElement = document.getElementById("zxing-canvas");
  var canvas = canvasElement.getContext("2d");
  var loadingMessage = document.getElementById("loadingMessage");

  function scanFrame() {
    if (video.readyState === video.HAVE_ENOUGH_DATA) {
      canvasElement.hidden = false;

      canvasElement.height = video.videoHeight;
      canvasElement.width = video.videoWidth;
      canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);

      var format = "";
      try {
        if (state.scanActive) {
          var code = scanBarcode(canvasElement, format);
          setTimeout(function(){
            state.codeCallback(code)
          }, 1);
        }
      }
      catch (error) {
      }
    }
    requestAnimationFrame(scanFrame);
  }

  // Use facingMode: environment to attemt to get the front camera on phones
  navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } }).then(function(stream) {
    video.srcObject = stream;
    video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
    video.play();
    requestAnimationFrame(scanFrame);
  });
}

let startScan = function(event) {
  prepareAudioContext();

  state.scanActive = true;
  state.targetElement = document.querySelector("*[data-zxing-output-target]");
  document.querySelector(".zxing-canvas-container").classList.add("active");
  initializeScanner();
}
let stopScan = function(event) {
  document.querySelector(".zxing-canvas-container").classList.remove("active")
  document.querySelector(".zxing-canvas-container").classList.remove("flash")
  state.scanActive = false;
}

document.addDelegatedEventListener("touchstart", "#zxing-canvas", startScan)
document.addDelegatedEventListener("touchend", "#zxing-canvas", stopScan)
document.addDelegatedEventListener("mousedown", "#zxing-canvas", startScan)
document.addDelegatedEventListener("mouseup", "#zxing-canvas", stopScan)

<commit_msg>more parsing in main thread<commit_after>// source: https://github.com/murb/zxing-demo/blob/master/zxing_helper.js

// <!-- UTILS START

// https://gist.github.com/jonleighton/958841
// bytes: Uint8Array

var ZXing;

if (typeof require !== "undefined") {
  ZXing = require('zxing/zxing_reader');
}

function uint8ArrayToBase64(bytes) {
  var base64    = ''
  var encodings = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  var byteLength    = bytes.byteLength
  var byteRemainder = byteLength % 3
  var mainLength    = byteLength - byteRemainder
  var a, b, c, d
  var chunk
  for (var i = 0; i < mainLength; i = i + 3) {
    chunk = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2]
    a = (chunk & 16515072) >> 18 // 16515072 = (2^6 - 1) << 18
    b = (chunk & 258048)   >> 12 // 258048   = (2^6 - 1) << 12
    c = (chunk & 4032)     >>  6 // 4032     = (2^6 - 1) << 6
    d = chunk & 63               // 63       = 2^6 - 1
    base64 += encodings[a] + encodings[b] + encodings[c] + encodings[d]
  }
  if (byteRemainder == 1) {
    chunk = bytes[mainLength]
    a = (chunk & 252) >> 2 // 252 = (2^6 - 1) << 2
    b = (chunk & 3)   << 4 // 3   = 2^2 - 1
    base64 += encodings[a] + encodings[b] + '=='
  } else if (byteRemainder == 2) {
    chunk = (bytes[mainLength] << 8) | bytes[mainLength + 1]
    a = (chunk & 64512) >> 10 // 64512 = (2^6 - 1) << 10
    b = (chunk & 1008)  >>  4 // 1008  = (2^6 - 1) << 4
    c = (chunk & 15)    <<  2 // 15    = 2^4 - 1
    base64 += encodings[a] + encodings[b] + encodings[c] + '='
  }
  return base64
}

// https://stackoverflow.com/a/21797381
// https://stackoverflow.com/a/7261048
function base64ToUint8Array(uri) { // i.e. base64.b64_decode() in python
    var binary_string =  window.atob(uri.split(",")[1]);
    var len = binary_string.length;
    var bytes = new Uint8Array( len );
    for (var i = 0; i < len; i++) {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes;
}

// https://gist.github.com/murb/a8823e7a2d6fc9613b3c5c00a0225809
if (!Element.prototype.matches) {
  Element.prototype.matches = Element.prototype.msMatchesSelector;
}

// https://gist.github.com/murb/a8823e7a2d6fc9613b3c5c00a0225809
if (!HTMLDocument.prototype.addDelegatedEventListener) {
  HTMLDocument.prototype.addDelegatedEventListener = function(event, matcher, cb) {
    var newCB;
    newCB = function(event) {
      if (event.target.matches && event.target.matches(matcher)) {
        return cb(event);
      }
    };
    return this.addEventListener(event, newCB);
  };
}

// play a simple beep
let gain;

const prepareAudioContext = function() {
  const AudioContext = window.AudioContext || window.webkitAudioContext;
  if (typeof AudioContext !== "undefined") {
    var audioContext = new AudioContext();
    // create empty buffer
    let buffer = audioContext.createBuffer(1, 1, 22050);
    let source = audioContext.createBufferSource();
    source.buffer = buffer;

    // connect to output (your speakers)
    source.connect(audioContext.destination);

    audioContext.createOscillator();
    gain = audioContext.createGain();
    let oscillator = audioContext.createOscillator();

    oscillator.connect(gain);
    oscillator.frequency.value = 880;
    oscillator.type = 0; //sine
    gain.connect(audioContext.destination);
    gain.gain.value = 0;
    oscillator.start(audioContext.currentTime);
  }
}

function beep(vol, duration){
  gain.gain.value = vol;
  setTimeout(function() { gain.gain.value = 0 }, duration)
}

// --> UTILS END

var zxing = ZXing();
var state = {
  scanActive: null,
  targetElement: null,
  codeCallback: renderCodeToTargetElement,
  values: []
}

function scanBarcode(canvasElement, format) {
    var imgWidth = canvasElement.width;
    var imgHeight = canvasElement.height;
    var imageData = canvasElement.getContext('2d').getImageData(0, 0, imgWidth, imgHeight);
    var sourceBuffer = imageData.data;
    if (sourceBuffer.byteLength <= imgWidth*imgHeight*4) {
      var buffer = zxing._malloc(sourceBuffer.byteLength);
      zxing.HEAPU8.set(sourceBuffer, buffer);
      var result = zxing.readBarcodeFromPixmap(buffer, imgWidth, imgHeight, true, format);
      zxing._free(buffer);
      return result;
    } else {
      console.log(sourceBuffer.byteLength)
    }
}

function flashBorder() {
  document.querySelector(".zxing-canvas-container").classList.add("flash");
  setTimeout(function() {
    document.querySelector(".zxing-canvas-container").classList.remove("flash")
  }, 500)
}

function renderCodeInOutputMessage(code) {
  var outputContainer = document.getElementById("output");
  var outputMessage = document.getElementById("outputMessage");
  var outputData = document.getElementById("outputData");

  outputContainer.hidden = false;

  if (code.error) {
    outputMessage.hidden = true;
    outputData.parentElement.hidden = false;
    outputData.innerText = code.error;
  } else if(code.format) {
    outputMessage.hidden = true;
    outputData.parentElement.hidden = false;
    outputData.innerText = code.text;
  } else {
    outputMessage.hidden = false;
    outputData.parentElement.hidden = true;
  }
}

function renderCodeToTargetTextArea(code) {
  if (code.format) {
    var currentValue = state.targetElement.value.trim();
    if (!currentValue.match(code.text)) { // tried escapeProblemFreeMatch() but too slow for Safari atm, out of scope anyhow
      currentValue = code.text + "\n" + currentValue;
      flashBorder();
      beep(0.1, 200);
    }
    state.targetElement.value = currentValue
  }
}

function renderCodeToTargetElement(code) {
  if (state.targetElement.localName == "textarea") {
    renderCodeToTargetTextArea(code);
  }
}

// too slow for safari (was a workaround for bad QR codes, but out of scope for now anyhow)
function escapeProblemFreeMatch(text, target) {
  return text.replaceAll(/[\"\:\?\.\/]/g,"").match(target.replaceAll(/[\"\:\?\.\/]/g,""))
}

function initializeScanner() {
  var video = document.createElement("video");

  video.width = 800;
  video.height = 800;

  var canvasElement = document.getElementById("zxing-canvas");
  var canvas = canvasElement.getContext("2d");
  var loadingMessage = document.getElementById("loadingMessage");

  function scanFrame() {
    if (video.readyState === video.HAVE_ENOUGH_DATA) {
      canvasElement.hidden = false;

      canvasElement.height = video.videoHeight;
      canvasElement.width = video.videoWidth;
      canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);

      var format = "";
      try {
        if (state.scanActive) {
          var code = scanBarcode(canvasElement, format);
          state.codeCallback(code)
        }
      }
      catch (error) {
      }
    }
    requestAnimationFrame(scanFrame);
  }

  // Use facingMode: environment to attemt to get the front camera on phones
  navigator.mediaDevices.getUserMedia({ video: { facingMode: "environment" } }).then(function(stream) {
    video.srcObject = stream;
    video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
    video.play();
    requestAnimationFrame(scanFrame);
  });
}

let startScan = function(event) {
  prepareAudioContext();

  state.scanActive = true;
  state.targetElement = document.querySelector("*[data-zxing-output-target]");
  document.querySelector(".zxing-canvas-container").classList.add("active");
  initializeScanner();
}
let stopScan = function(event) {
  document.querySelector(".zxing-canvas-container").classList.remove("active")
  document.querySelector(".zxing-canvas-container").classList.remove("flash")
  state.scanActive = false;
}

document.addDelegatedEventListener("touchstart", "#zxing-canvas", startScan)
document.addDelegatedEventListener("touchend", "#zxing-canvas", stopScan)
document.addDelegatedEventListener("mousedown", "#zxing-canvas", startScan)
document.addDelegatedEventListener("mouseup", "#zxing-canvas", stopScan)

<|endoftext|>


<commit_before>// the eslint "no-unused-expressions" rule is triggered by the `expect`
// assertions in the tests. So, in order to avoid problems with eslint, I'm
// disabling that rule in this file
//
/* eslint-disable no-unused-expressions */

import React from 'react';
import { shallow } from 'enzyme';
import chai from 'chai';
import NumericInput from './NumericInput';

const expect = chai.expect;

/* *****************************************************************************
in terms of basic markup, the NumericInput component
    should be a div.form-group
    should include an input[type="text"]
    should include an input.form-control
    should include a label with the appropriate text if a label is specified
    should include a placeholder if a placeholder is specified
*/
describe('in terms of basic markup, the NumericInput component', () => {

    it('should be a div.form-group', () => {
        const component = shallow(<NumericInput />);

        expect(component.is('div.form-group')).to.equal(true);
    });

    // it('should include an input[type="text"]', () => {});

    // it('should include an input.form-control', () => {});

    // it('should include a label with the appropriate text if a label is specified', () => {});

    // it('should include a placeholder if a placeholder is specified', () => {});

});
<commit_msg>added test for input element<commit_after>// the eslint "no-unused-expressions" rule is triggered by the `expect`
// assertions in the tests. So, in order to avoid problems with eslint, I'm
// disabling that rule in this file
//
/* eslint-disable no-unused-expressions */

import React from 'react';
import { shallow, render } from 'enzyme';
import chai from 'chai';
import NumericInput from './NumericInput';

const expect = chai.expect;

/* *****************************************************************************
in terms of basic markup, the NumericInput component
    should be a div.form-group
    should include an input[type="text"]
    should include an input.form-control
    should include a label with the appropriate text if a label is specified
    should include a placeholder if a placeholder is specified
*/
describe('in terms of basic markup, the NumericInput component', () => {

    it('should be a div.form-group', () => {
        const component = shallow(<NumericInput />);

        expect(component.is('div.form-group')).to.equal(true);
    });

    it('should include an input[type="text"]', () => {
        const component = render(<NumericInput />);

        expect(component.find('input[type="text"]').length).to.equal(1);
    });

    // it('should include an input.form-control', () => {});

    // it('should include a label with the appropriate text if a label is specified', () => {});

    // it('should include a placeholder if a placeholder is specified', () => {});

});
<|endoftext|>