diff --git a/src/components/FindProject.vue b/src/components/FindProject.vue index 2cea7bd..3ee1eb4 100644 --- a/src/components/FindProject.vue +++ b/src/components/FindProject.vue @@ -48,10 +48,12 @@ export default defineComponent({ }, data() { return { - aspectRatio: 1, columnIndex: 0, + containerWidth: 1, endReached: false, + maxTileSize: 1, overlay: true, + page: [], results: {}, selectedTaskIds: [], selectOverlay: true, @@ -88,12 +90,10 @@ export default defineComponent({ return this.columnIndex <= 0 }, columnsPerPage() { - // set columns of tiles per page based on window aspect ratio - let possibleColumnsPerPage = [1, 2, 3, 4, 6, 12] - let columnsRatio = this.rowsPerPage * this.aspectRatio * 1.33 - const columnsPerPage = possibleColumnsPerPage.reduce((a, b) => { - return Math.abs(b - columnsRatio) < Math.abs(a - columnsRatio) ? b : a - }) + const remainder = this.containerWidth % this.maxTileSize + const ratio = this.containerWidth / this.maxTileSize + const rounded = remainder < 100 ? Math.floor(ratio) : Math.ceil(ratio) + const columnsPerPage = this.clamp(rounded, 1, this.totalColumns) return columnsPerPage }, instructionMessage() { @@ -109,28 +109,6 @@ export default defineComponent({ let lastPage = rightColumnIndex >= this.totalColumns return lastPage }, - /* eslint-disable vue/no-side-effects-in-computed-properties */ - page() { - this.columnIndex = Math.min(this.columnIndex, this.totalColumns - this.columnsPerPage) - let begin = Math.max(this.columnIndex * this.rowsPerPage, 0) - let end = begin + this.tasksPerPage - let pageTasks = this.processedTasks.slice(begin, end).map(this.appendColorAndLabel) - let uniqueY = [...new Set(pageTasks.map((task) => parseInt(task.taskY)))].sort() - let page = [] - for (let y of uniqueY) { - let row = pageTasks - .filter((task) => parseInt(task.taskY) === y) - .sort((a, b) => parseInt(a.taskX) > parseInt(b.taskX)) - page.push(row) - } - if (this.processedTasks.length <= this.tasksPerPage) { - this.endReached = true - this.taskIndex = this.processedTasks.length - } - this.taskIndex = (this.columnIndex + this.columnsPerPage) * this.rowsPerPage - return page - }, - /* eslint-enable vue/no-side-effects-in-computed-properties */ processedTasks() { const tasks = this.tasks.length ? this.tasks : buildTasks(this.project, this.group) const sorted = tasks.sort((a, b) => (a.taskId > b.taskId ? 1 : -1)) @@ -147,10 +125,18 @@ export default defineComponent({ tilesInSelection() { return this.selectedTaskIds.length > 0 }, + tileSize() { + const tileSize = Math.min(this.maxTileSize, this.containerWidth / this.columnsPerPage) + return tileSize + }, totalColumns() { let totalColumns = Math.ceil(this.processedTasks.length / this.rowsPerPage) return totalColumns }, + iconSize() { + const size = this.tileSize < 256 ? 'x-small' : 'small' + return size + }, }, methods: { appendColorAndLabel(task) { @@ -166,6 +152,7 @@ export default defineComponent({ if (!this.backDisabled) { this.removeFromSelection(this.page.map((row) => row.pop()).map((t) => t.taskId)) this.columnIndex-- + this.updatePage() } }, bumpResult(taskId, currentOptionIndex) { @@ -175,6 +162,10 @@ export default defineComponent({ this.results[taskId] = this.options[0].value } }, + clamp(value: number, min: number, max: number) { + const clamp = Math.min(Math.max(value, min), max) + return clamp + }, getCheckboxIcon(taskId) { const selected = this.isTaskSelected(taskId) const icon = selected ? 'mdi-checkbox-marked-circle' : 'mdi-checkbox-blank-circle-outline' @@ -197,6 +188,7 @@ export default defineComponent({ } else if (this.selectedTaskIds.includes(taskId)) { this.selectedTaskIds.map((t) => this.bumpResult(t, currentOptionIndex)) } + this.updatePage() }, handleTileSelected(e, taskId) { e.preventDefault() @@ -211,6 +203,7 @@ export default defineComponent({ this.removeFromSelection(this.page.flat().map((t) => t.taskId)) let target = this.columnIndex - this.columnsPerPage this.columnIndex = Math.max(target, 0) + this.updatePage() } }, fastBackColumns() { @@ -222,6 +215,7 @@ export default defineComponent({ let target = this.columnIndex + this.columnsPerPage let max = this.totalColumns - this.columnsPerPage this.columnIndex = Math.min(target, max) + this.updatePage() if (this.isLastPage) this.endReached = true } }, @@ -233,6 +227,7 @@ export default defineComponent({ if (!this.forwardDisabled) { this.removeFromSelection(this.page.map((row) => row[0]).map((t) => t.taskId)) this.columnIndex++ + this.updatePage() if (this.isLastPage) this.endReached = true } }, @@ -241,7 +236,11 @@ export default defineComponent({ return selected }, onResize() { - this.aspectRatio = window.innerWidth / window.innerHeight + const container = this.$refs.container.$el as HTMLElement + this.containerWidth = container.clientWidth + const maxTileHeight = this.clamp((window.innerHeight - 300) / this.rowsPerPage, 128, 512) + this.maxTileSize = maxTileHeight + this.updatePage() }, removeFromSelection(taskIds: Array) { const newSelection = this.selectedTaskIds.filter((t) => !taskIds.includes(t)) @@ -252,6 +251,25 @@ export default defineComponent({ } this.selectedTaskIds = newSelection }, + updatePage() { + this.columnIndex = Math.min(this.columnIndex, this.totalColumns - this.columnsPerPage) + let begin = Math.max(this.columnIndex * this.rowsPerPage, 0) + let end = begin + this.tasksPerPage + let pageTasks = this.processedTasks.slice(begin, end).map(this.appendColorAndLabel) + let uniqueY = [...new Set(pageTasks.map((task) => parseInt(task.taskY)))].sort() + this.page = [] + for (let y of uniqueY) { + let row = pageTasks + .filter((task) => parseInt(task.taskY) === y) + .sort((a, b) => parseInt(a.taskX) > parseInt(b.taskX)) + this.page.push(row) + } + if (this.processedTasks.length <= this.tasksPerPage) { + this.endReached = true + this.taskIndex = this.processedTasks.length + } + this.taskIndex = (this.columnIndex + this.columnsPerPage) * this.rowsPerPage + }, }, mounted() { this.onResize() @@ -277,7 +295,7 @@ export default defineComponent({ color="primary" /> - - - + +
- - +
- + diff --git a/src/components/ProjectHeader.vue b/src/components/ProjectHeader.vue index f01e223..99cf259 100644 --- a/src/components/ProjectHeader.vue +++ b/src/components/ProjectHeader.vue @@ -16,7 +16,7 @@ export default defineComponent({