mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Fix: handle overflowing dropdowns on mobile (#7758)
See https://github.com/ng-bootstrap/ng-bootstrap/pull/4760
This commit is contained in:
		| @@ -1,4 +1,4 @@ | |||||||
| <div class="btn-group w-100" ngbDropdown role="group"> | <div class="btn-group w-100" ngbDropdown role="group" [popperOptions]="popperOptions"> | ||||||
|   <button class="btn btn-sm" id="dropdown{{title}}" ngbDropdownToggle [ngClass]="createdDateBefore || createdDateAfter ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled"> |   <button class="btn btn-sm" id="dropdown{{title}}" ngbDropdownToggle [ngClass]="createdDateBefore || createdDateAfter ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled"> | ||||||
|     <i-bs width="1em" height="1em" name="calendar-event-fill"></i-bs> |     <i-bs width="1em" height="1em" name="calendar-event-fill"></i-bs> | ||||||
|     <div class="d-none d-sm-inline"> {{title}}</div> |     <div class="d-none d-sm-inline"> {{title}}</div> | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ import { Subject, Subscription } from 'rxjs' | |||||||
| import { debounceTime } from 'rxjs/operators' | import { debounceTime } from 'rxjs/operators' | ||||||
| import { SettingsService } from 'src/app/services/settings.service' | import { SettingsService } from 'src/app/services/settings.service' | ||||||
| import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter' | import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter' | ||||||
|  | import { popperOptionsReenablePreventOverflow } from 'src/app/utils/popper-options' | ||||||
|  |  | ||||||
| export interface DateSelection { | export interface DateSelection { | ||||||
|   createdBefore?: string |   createdBefore?: string | ||||||
| @@ -35,6 +36,8 @@ export enum RelativeDate { | |||||||
|   providers: [{ provide: NgbDateAdapter, useClass: ISODateAdapter }], |   providers: [{ provide: NgbDateAdapter, useClass: ISODateAdapter }], | ||||||
| }) | }) | ||||||
| export class DatesDropdownComponent implements OnInit, OnDestroy { | export class DatesDropdownComponent implements OnInit, OnDestroy { | ||||||
|  |   public popperOptions = popperOptionsReenablePreventOverflow | ||||||
|  |  | ||||||
|   constructor(settings: SettingsService) { |   constructor(settings: SettingsService) { | ||||||
|     this.datePlaceHolder = settings.getLocalizedDateInputFormat() |     this.datePlaceHolder = settings.getLocalizedDateInputFormat() | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| <div class="btn-group w-100" ngbDropdown role="group" (openChange)="dropdownOpenChange($event)" #dropdown="ngbDropdown" (keydown)="listKeyDown($event)"> | <div class="btn-group w-100" ngbDropdown role="group" (openChange)="dropdownOpenChange($event)" #dropdown="ngbDropdown" (keydown)="listKeyDown($event)" [popperOptions]="popperOptions"> | ||||||
|   <button class="btn btn-sm" id="dropdown_{{name}}" ngbDropdownToggle [ngClass]="!editing && selectionModel.selectionSize() > 0 ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled"> |   <button class="btn btn-sm" id="dropdown_{{name}}" ngbDropdownToggle [ngClass]="!editing && selectionModel.selectionSize() > 0 ? 'btn-primary' : 'btn-outline-primary'" [disabled]="disabled"> | ||||||
|     <i-bs name="{{icon}}"></i-bs> |     <i-bs name="{{icon}}"></i-bs> | ||||||
|     <div class="d-none d-sm-inline"> {{title}}</div> |     <div class="d-none d-sm-inline"> {{title}}</div> | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import { Subject, filter, take, takeUntil } from 'rxjs' | |||||||
| import { SelectionDataItem } from 'src/app/services/rest/document.service' | import { SelectionDataItem } from 'src/app/services/rest/document.service' | ||||||
| import { ObjectWithPermissions } from 'src/app/data/object-with-permissions' | import { ObjectWithPermissions } from 'src/app/data/object-with-permissions' | ||||||
| import { HotKeyService } from 'src/app/services/hot-key.service' | import { HotKeyService } from 'src/app/services/hot-key.service' | ||||||
|  | import { popperOptionsReenablePreventOverflow } from 'src/app/utils/popper-options' | ||||||
|  |  | ||||||
| export interface ChangedItems { | export interface ChangedItems { | ||||||
|   itemsToAdd: MatchingModel[] |   itemsToAdd: MatchingModel[] | ||||||
| @@ -330,6 +331,8 @@ export class FilterableDropdownComponent implements OnDestroy, OnInit { | |||||||
|   @ViewChild('dropdown') dropdown: NgbDropdown |   @ViewChild('dropdown') dropdown: NgbDropdown | ||||||
|   @ViewChild('buttonItems') buttonItems: ElementRef |   @ViewChild('buttonItems') buttonItems: ElementRef | ||||||
|  |  | ||||||
|  |   public popperOptions = popperOptionsReenablePreventOverflow | ||||||
|  |  | ||||||
|   filterText: string |   filterText: string | ||||||
|  |  | ||||||
|   @Input() |   @Input() | ||||||
|   | |||||||
							
								
								
									
										24
									
								
								src-ui/src/app/utils/popper-options.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src-ui/src/app/utils/popper-options.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | import { popperOptionsReenablePreventOverflow } from './popper-options' | ||||||
|  | import { Options } from '@popperjs/core' | ||||||
|  |  | ||||||
|  | describe('popperOptionsReenablePreventOverflow', () => { | ||||||
|  |   it('should return the config without the empty fun preventOverflow, add padding to other', () => { | ||||||
|  |     const config: Partial<Options> = { | ||||||
|  |       modifiers: [ | ||||||
|  |         { name: 'preventOverflow', fn: function () {} }, | ||||||
|  |         { | ||||||
|  |           name: 'preventOverflow', | ||||||
|  |           fn: function () { | ||||||
|  |             return | ||||||
|  |           }, | ||||||
|  |         }, | ||||||
|  |       ], | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     const result = popperOptionsReenablePreventOverflow(config) | ||||||
|  |  | ||||||
|  |     expect(result.modifiers.length).toBe(1) | ||||||
|  |     expect(result.modifiers[0].name).toBe('preventOverflow') | ||||||
|  |     expect(result.modifiers[0].options).toEqual({ padding: 10 }) | ||||||
|  |   }) | ||||||
|  | }) | ||||||
							
								
								
									
										24
									
								
								src-ui/src/app/utils/popper-options.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src-ui/src/app/utils/popper-options.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | import { Options } from '@popperjs/core' | ||||||
|  |  | ||||||
|  | export function popperOptionsReenablePreventOverflow( | ||||||
|  |   config: Partial<Options> | ||||||
|  | ): Partial<Options> { | ||||||
|  |   const preventOverflowModifier = config.modifiers?.find( | ||||||
|  |     (m) => m.name === 'preventOverflow' && m.fn?.length === 0 | ||||||
|  |   ) | ||||||
|  |   if (preventOverflowModifier) { | ||||||
|  |     config.modifiers.splice( | ||||||
|  |       config.modifiers.indexOf(preventOverflowModifier), | ||||||
|  |       1 | ||||||
|  |     ) | ||||||
|  |   } | ||||||
|  |   const ogPreventOverflowModifier = config.modifiers.find( | ||||||
|  |     (m) => m.name === 'preventOverflow' | ||||||
|  |   ) | ||||||
|  |   if (ogPreventOverflowModifier) { | ||||||
|  |     ogPreventOverflowModifier.options = { | ||||||
|  |       padding: 10, | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return config | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user
	 shamoon
					shamoon