mirror of
				https://github.com/simon987/sist2.git
				synced 2025-10-31 16:06:53 +00:00 
			
		
		
		
	Shift click & select all/none in index picker
This commit is contained in:
		
							parent
							
								
									030643cee0
								
							
						
					
					
						commit
						e3f78fb693
					
				| @ -7,11 +7,28 @@ | |||||||
|         value-field="id"></b-form-select> |         value-field="id"></b-form-select> | ||||||
|   </div> |   </div> | ||||||
|   <div v-else> |   <div v-else> | ||||||
|     <b-list-group id="index-picker-desktop"> | 
 | ||||||
|  | 
 | ||||||
|  |     <div class="d-flex justify-content-between align-content-center"> | ||||||
|  |       <span> | ||||||
|  |         {{ selectedIndices.length }} | ||||||
|  |         {{ selectedIndices.length === 1 ? $t("indexPicker.selectedIndex") : $t("indexPicker.selectedIndices") }} | ||||||
|  |       </span> | ||||||
|  | 
 | ||||||
|  |       <div> | ||||||
|  |         <b-button variant="link" @click="selectAll()"> {{ $t("indexPicker.selectAll") }}</b-button> | ||||||
|  |         <b-button variant="link" @click="selectNone()"> {{ $t("indexPicker.selectNone") }}</b-button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |     <b-list-group id="index-picker-desktop" class="unselectable"> | ||||||
|       <b-list-group-item |       <b-list-group-item | ||||||
|           v-for="idx in indices" |           v-for="idx in indices" | ||||||
|           @click="toggleIndex(idx)" |           @click="toggleIndex(idx, $event)" | ||||||
|           class="d-flex justify-content-between align-items-center list-group-item-action pointer"> |           @click.shift="shiftClick(idx, $event)" | ||||||
|  |           class="d-flex justify-content-between align-items-center list-group-item-action pointer" | ||||||
|  |           :class="{active: lastClickIndex === idx}" | ||||||
|  |       > | ||||||
|         <div class="d-flex"> |         <div class="d-flex"> | ||||||
|           <b-checkbox @change="toggleIndex(idx)" :checked="isSelected(idx)"></b-checkbox> |           <b-checkbox @change="toggleIndex(idx)" :checked="isSelected(idx)"></b-checkbox> | ||||||
|           {{ idx.name }} |           {{ idx.name }} | ||||||
| @ -36,6 +53,7 @@ export default Vue.extend({ | |||||||
|   data() { |   data() { | ||||||
|     return { |     return { | ||||||
|       loading: true, |       loading: true, | ||||||
|  |       lastClickIndex: null | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
| @ -53,13 +71,50 @@ export default Vue.extend({ | |||||||
|     ...mapActions({ |     ...mapActions({ | ||||||
|       setSelectedIndices: "setSelectedIndices" |       setSelectedIndices: "setSelectedIndices" | ||||||
|     }), |     }), | ||||||
|  |     shiftClick(index, e) { | ||||||
|  |       if (this.lastClickIndex === null) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       const select = this.isSelected(this.lastClickIndex); | ||||||
|  | 
 | ||||||
|  |       let leftBoundary = this.indices.indexOf(this.lastClickIndex); | ||||||
|  |       let rightBoundary = this.indices.indexOf(index); | ||||||
|  | 
 | ||||||
|  |       if (rightBoundary < leftBoundary) { | ||||||
|  |         let tmp = leftBoundary; | ||||||
|  |         leftBoundary = rightBoundary; | ||||||
|  |         rightBoundary = tmp; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       for (let i = leftBoundary; i <= rightBoundary; i++) { | ||||||
|  |         if (select) { | ||||||
|  |           if (!this.isSelected(this.indices[i])) { | ||||||
|  |             this.setSelectedIndices([this.indices[i], ...this.selectedIndices]); | ||||||
|  |           } | ||||||
|  |         } else { | ||||||
|  |           this.setSelectedIndices(this.selectedIndices.filter(idx => idx !== this.indices[i])); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     selectAll() { | ||||||
|  |       this.setSelectedIndices(this.indices); | ||||||
|  |     }, | ||||||
|  |     selectNone() { | ||||||
|  |       this.setSelectedIndices([]); | ||||||
|  |     }, | ||||||
|     onSelect(value) { |     onSelect(value) { | ||||||
|       this.setSelectedIndices(this.indices.filter(idx => value.includes(idx.id))); |       this.setSelectedIndices(this.indices.filter(idx => value.includes(idx.id))); | ||||||
|     }, |     }, | ||||||
|     formatIdxDate(timestamp: number): string { |     formatIdxDate(timestamp: number): string { | ||||||
|       return format(new Date(timestamp * 1000), "yyyy-MM-dd"); |       return format(new Date(timestamp * 1000), "yyyy-MM-dd"); | ||||||
|     }, |     }, | ||||||
|     toggleIndex(index) { |     toggleIndex(index, e) { | ||||||
|  |       if (e.shiftKey) { | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       this.lastClickIndex = index; | ||||||
|       if (this.isSelected(index)) { |       if (this.isSelected(index)) { | ||||||
|         this.setSelectedIndices(this.selectedIndices.filter(idx => idx.id != index.id)); |         this.setSelectedIndices(this.selectedIndices.filter(idx => idx.id != index.id)); | ||||||
|       } else { |       } else { | ||||||
| @ -92,4 +147,21 @@ export default Vue.extend({ | |||||||
|   overflow-y: auto; |   overflow-y: auto; | ||||||
|   max-height: 132px; |   max-height: 132px; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | .btn-link:focus { | ||||||
|  |   box-shadow: none; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .unselectable { | ||||||
|  |   user-select: none; | ||||||
|  |   -ms-user-select: none; | ||||||
|  |   -moz-user-select: none; | ||||||
|  |   -webkit-user-select: none; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .list-group-item.active { | ||||||
|  |   z-index: 2; | ||||||
|  |   background-color: inherit; | ||||||
|  |   color: inherit; | ||||||
|  | } | ||||||
| </style> | </style> | ||||||
| @ -23,7 +23,7 @@ | |||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import {EsResult} from "@/Sist2Api"; | import {EsResult} from "@/Sist2Api"; | ||||||
| import Vue from "vue"; | import Vue from "vue"; | ||||||
| import {humanFileSize, humanTime} from "@/util"; | import {humanFileSize} from "@/util"; | ||||||
| import DisplayModeToggle from "@/components/DisplayModeToggle.vue"; | import DisplayModeToggle from "@/components/DisplayModeToggle.vue"; | ||||||
| import SortSelect from "@/components/SortSelect.vue"; | import SortSelect from "@/components/SortSelect.vue"; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -131,7 +131,6 @@ export default { | |||||||
|         saveTagModalTitle: "Add tag", |         saveTagModalTitle: "Add tag", | ||||||
|         saveTagPlaceholder: "Tag name", |         saveTagPlaceholder: "Tag name", | ||||||
|         confirm: "Confirm", |         confirm: "Confirm", | ||||||
|         indexPickerPlaceholder: "Select indices", |  | ||||||
|         sort: { |         sort: { | ||||||
|             relevance: "Relevance", |             relevance: "Relevance", | ||||||
|             dateAsc: "Date (Older first)", |             dateAsc: "Date (Older first)", | ||||||
| @ -145,7 +144,13 @@ export default { | |||||||
|             mimeSize: "Size distribution by media type", |             mimeSize: "Size distribution by media type", | ||||||
|             dateHistogram: "File modification time distribution", |             dateHistogram: "File modification time distribution", | ||||||
|             sizeHistogram: "File size distribution", |             sizeHistogram: "File size distribution", | ||||||
|         } |         }, | ||||||
|  |         indexPicker: { | ||||||
|  |             selectNone: "Select None", | ||||||
|  |             selectAll: "Select All", | ||||||
|  |             selectedIndex: "selected index", | ||||||
|  |             selectedIndices: "selected indices", | ||||||
|  |         }, | ||||||
|     }, |     }, | ||||||
|     fr: { |     fr: { | ||||||
|         searchBar: { |         searchBar: { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user