Browse Source

feat(AdvancedTable): Improved resizable columns logic and usability

Owen Diffey 3 years ago
parent
commit
2bf8307628
2 changed files with 58 additions and 23 deletions
  1. 32 7
      frontend/src/components/AdvancedTable.vue
  2. 26 16
      frontend/src/pages/Admin/tabs/Test.vue

+ 32 - 7
frontend/src/components/AdvancedTable.vue

@@ -152,9 +152,9 @@
 									'item-draggable': column.draggable
 								}"
 								:style="{
-									minWidth: column.minWidth,
-									width: column.width,
-									maxWidth: column.maxWidth
+									minWidth: `${column.minWidth}px`,
+									width: `${column.width}px`,
+									maxWidth: `${column.maxWidth}px`
 								}"
 								v-if="shownColumns.indexOf(column.name) !== -1"
 							>
@@ -584,8 +584,30 @@ export default {
 				}
 				this.resizing.width -= this.resizing.lastX - event.x;
 				this.resizing.lastX = event.x;
-				this.resizing.resizingColumn.minWidth = `${this.resizing.width}px`;
-				this.resizing.resizingColumn.maxWidth = `${this.resizing.width}px`;
+				if (
+					this.resizing.resizingColumn.minWidth &&
+					this.resizing.resizingColumn.maxWidth
+				) {
+					this.resizing.resizingColumn.width = Math.max(
+						Math.min(
+							this.resizing.resizingColumn.maxWidth,
+							this.resizing.width
+						),
+						this.resizing.resizingColumn.minWidth
+					);
+				} else if (this.resizing.resizingColumn.minWidth) {
+					this.resizing.resizingColumn.width = Math.max(
+						this.resizing.width,
+						this.resizing.resizingColumn.minWidth
+					);
+				} else if (this.resizing.resizingColumn.maxWidth) {
+					this.resizing.resizingColumn.width = Math.min(
+						this.resizing.resizingColumn.maxWidth,
+						this.resizing.width
+					);
+				} else {
+					this.resizing.resizingColumn.width = this.resizing.width;
+				}
 				console.log(`New width: ${this.resizing.width}px`);
 			}
 		},
@@ -645,6 +667,7 @@ export default {
 
 		table {
 			border-collapse: separate;
+			table-layout: fixed;
 
 			thead {
 				tr {
@@ -735,22 +758,24 @@ export default {
 			position: relative;
 			white-space: nowrap;
 			text-overflow: ellipsis;
+			overflow: hidden;
 
 			&:first-child {
 				position: sticky;
 				left: 0;
 				z-index: 2;
+				width: 5px;
 				padding: 0;
 				padding-left: 5px;
 			}
 
 			.resizer {
 				height: 100%;
-				width: 4px;
+				width: 5px;
 				background-color: transparent;
 				cursor: col-resize;
 				position: absolute;
-				right: -2px;
+				right: 0;
 				top: 0;
 			}
 		}

+ 26 - 16
frontend/src/pages/Admin/tabs/Test.vue

@@ -22,7 +22,9 @@
 					</a>
 				</template>
 				<template #column-_id="slotProps">
-					{{ slotProps.item._id }}
+					<span :title="slotProps.item._id">{{
+						slotProps.item._id
+					}}</span>
 				</template>
 				<template #column-youtubeId="slotProps">
 					<a
@@ -36,13 +38,19 @@
 					</a>
 				</template>
 				<template #column-title="slotProps">
-					{{ slotProps.item.title }}
+					<span :title="slotProps.item.title">{{
+						slotProps.item.title
+					}}</span>
 				</template>
 				<template #column-artists="slotProps">
-					{{ slotProps.item.artists.join(", ") }}
+					<span :title="slotProps.item.artists.join(', ')">{{
+						slotProps.item.artists.join(", ")
+					}}</span>
 				</template>
 				<template #column-genres="slotProps">
-					{{ slotProps.item.genres.join(", ") }}
+					<span :title="slotProps.item.genres.join(', ')">{{
+						slotProps.item.genres.join(", ")
+					}}</span>
 				</template>
 				<template #column-requestedBy="slotProps">
 					<user-id-to-username
@@ -71,14 +79,18 @@ export default {
 				hidable: true,
 				defaultVisibility: "shown",
 				draggable: true,
-				resizable: true
+				resizable: true,
+				minWidth: 200,
+				maxWidth: 600
 			},
 			columns: [
 				{
 					name: "thumbnailImage",
 					displayName: "Thumb",
 					properties: ["thumbnail"],
-					width: "150px",
+					minWidth: 120,
+					width: 120,
+					maxWidth: 120,
 					resizable: false
 				},
 				{
@@ -86,15 +98,15 @@ export default {
 					displayName: "Musare ID",
 					properties: ["_id"],
 					sortProperty: "_id",
-					width: "220px"
+					width: 220
 				},
 				{
 					name: "youtubeId",
 					displayName: "YouTube ID",
 					properties: ["youtubeId"],
 					sortProperty: "youtubeId",
-					minWidth: "155px",
-					width: "155px"
+					minWidth: 155,
+					width: 155
 				},
 				{
 					name: "title",
@@ -106,29 +118,27 @@ export default {
 					name: "artists",
 					displayName: "Artists",
 					properties: ["artists"],
-					sortable: false,
-					width: "300px"
+					sortable: false
 				},
 				{
 					name: "genres",
 					displayName: "Genres",
 					properties: ["genres"],
-					sortable: false,
-					width: "300px"
+					sortable: false
 				},
 				{
 					name: "thumbnailUrl",
 					displayName: "Thumbnail (URL)",
 					properties: ["thumbnail"],
 					sortProperty: "thumbnail",
-					defaultVisibility: "hidden",
-					width: "300px"
+					defaultVisibility: "hidden"
 				},
 				{
 					name: "requestedBy",
 					displayName: "Requested By",
 					properties: ["requestedBy"],
-					sortProperty: "requestedBy"
+					sortProperty: "requestedBy",
+					width: 200
 				}
 			],
 			filters: [