class CardCollectionView extends View { constructor(element) { super(element); //Measure a dummy card. var measurementCard = new CardView(); measurementCard.element.style.left = "-100vw"; measurementCard.element.style.top = "-100vh"; measurementCard.element.style.position = "absolute"; document.body.appendChild(measurementCard.element); this.cardWidth = measurementCard.element.clientWidth; this.cardHeight = measurementCard.element.clientHeight; var style = window.getComputedStyle(measurementCard.element); var margin = parseInt(style.margin.replace("px", "")) * 2 * 2; this.cardWidth += margin; this.cardHeight += margin; document.body.removeChild(measurementCard.element); //Build the filter bar. this.filterBar = document.createElement("div"); this.filterBar.className = "filter-bar"; element.appendChild(this.filterBar); var projectLabel = document.createElement("label"); projectLabel.setAttribute("for", "project-select"); projectLabel.innerText = "Project:"; //TODO: Localize this. this.filterBar.appendChild(projectLabel); this.projectSelect = document.createElement("select"); this.projectSelect.id = "project-select"; this.projectSelect.addEventListener("change", this.applyFilters.bind(this)); this.filterBar.appendChild(this.projectSelect); var allProjects = document.createElement("option"); allProjects.value = ""; allProjects.innerText = "(All)"; this.projectSelect.appendChild(allProjects); var searchLabel = document.createElement("label"); searchLabel.setAttribute("for", "search-field"); searchLabel.innerText = "Search Cards:"; //TODO: Localize this. searchLabel.style.marginLeft = "0.8em"; this.filterBar.appendChild(searchLabel); this.searchField = document.createElement("input"); this.searchField.type = "text"; this.searchField.placeholder = "Card, Project or Category"; //TODO: Localize this. this.searchField.addEventListener("input", this.applyFilters.bind(this)); this.searchField.maxLength = 1000; this.filterBar.appendChild(this.searchField); //Add category button. this.addCategoryButton = document.createElement("button"); this.addCategoryButton.className = "add-category-button require_w__card_category"; this.addCategoryButton.innerText = "Add Category ..."; //TODO: Localize this. this.addCategoryButton.addEventListener("click", this.onAddCategoryButtonPressed.bind(this)); this.filterBar.appendChild(this.addCategoryButton); //Add the listeners. TimeCards.dataManager.addDataListener("project", null, this.onProjectUpdate.bind(this)); TimeCards.dataManager.addDataListener("card_category", null, this.onCategoryUpdate.bind(this)); this.categoryViews = { }; this.projectOptions = { }; } onProjectUpdate(projectId, project, sortedBefore) { if (!project) { //Handle the deleted project. var option = this.projectOptions[projectId]; this.projectSelect.removeChild(option); delete this.projectOptions[projectId]; this.applyFilters(); } else if (!(projectId in this.projectOptions)) { //Handle the added project. var newProjectOption = document.createElement("OPTION"); newProjectOption.value = project.project_id; newProjectOption.innerText = project.name; if (project.description) { newProjectOption.title = project.description; } this.projectSelect.insertBefore(newProjectOption, this.projectOptions[sortedBefore]); this.projectOptions[projectId] = newProjectOption; } else { //Handle the changed project. var option = this.projectOptions[projectId]; option.innerText = project.name; option.title = project.description; } } onCategoryUpdate(categoryId, category, sortedBefore) { if (!category) { //Handle the deleted category. if (!(categoryId in this.categoryViews)) { console.warn("A category removed event was called, but there is no category view with this category ID. This should not have happened."); return; } var viewToRemove = this.categoryViews[categoryId]; this.element.removeChild(viewToRemove.element); delete this.categoryViews[categoryId]; } else if (!(categoryId in this.categoryViews)) { //Handle the added category. var cardCategoryView = new CardCategoryView(); cardCategoryView.setCategoryData(category); cardCategoryView.collectionView = this; cardCategoryView.viewController = this.viewController; this.element.insertBefore(cardCategoryView.element, sortedBefore && (sortedBefore in this.categoryViews) ? this.categoryViews[sortedBefore].element : null); this.viewController.allSubviews.push(cardCategoryView); this.categoryViews[categoryId] = cardCategoryView; } else { //Handle the changed category. var changedCategoryView = this.categoryViews[categoryId]; changedCategoryView.setCategoryData(category); //Re-add the category view to maintain the sort order in case of a name change. this.element.insertBefore(changedCategoryView.element, sortedBefore && (sortedBefore in this.categoryViews) ? this.categoryViews[sortedBefore].element : null); this.applyFilters(); } } applyFilters() { var filterOptions = { }; if (this.projectSelect.value) { filterOptions["id_project"] = this.projectSelect.value; } if (this.searchField.value) { filterOptions["search_query"] = this.searchField.value; if (this.element.className.indexOf("search-query-active") == -1) { this.element.classList.add("search-query-active"); } } else { this.element.classList.remove("search-query-active"); } for (var categoryId in this.categoryViews) { this.categoryViews[categoryId].setFilter(filterOptions); } } onAddCategoryButtonPressed(event) { UIKit.getPopoverById("add-category-popover").showForElement(event.currentTarget, "bottom"); event.stopPropagation(); } } UIKit.registerViewType(CardCollectionView);