1
- import { onChildEvent } from '../services/dom.ts ' ;
1
+ import { onChildEvent } from '../services/dom' ;
2
2
import { Component } from './component' ;
3
3
4
- /**
5
- * @typedef EntitySelectorSearchOptions
6
- * @property entityTypes string
7
- * @property entityPermission string
8
- * @property searchEndpoint string
9
- * @property initialValue string
10
- */
11
-
12
- /**
13
- * Entity Selector
14
- */
4
+ export interface EntitySelectorSearchOptions {
5
+ entityTypes : string ;
6
+ entityPermission : string ;
7
+ searchEndpoint : string ;
8
+ initialValue : string ;
9
+ }
10
+
11
+ export type EntitySelectorEntity = {
12
+ id : number ,
13
+ name : string ,
14
+ link : string ,
15
+ } ;
16
+
15
17
export class EntitySelector extends Component {
18
+ protected elem ! : HTMLElement ;
19
+ protected input ! : HTMLInputElement ;
20
+ protected searchInput ! : HTMLInputElement ;
21
+ protected loading ! : HTMLElement ;
22
+ protected resultsContainer ! : HTMLElement ;
23
+
24
+ protected searchOptions ! : EntitySelectorSearchOptions ;
25
+
26
+ protected search = '' ;
27
+ protected lastClick = 0 ;
16
28
17
29
setup ( ) {
18
30
this . elem = this . $el ;
19
31
20
- this . input = this . $refs . input ;
21
- this . searchInput = this . $refs . search ;
32
+ this . input = this . $refs . input as HTMLInputElement ;
33
+ this . searchInput = this . $refs . search as HTMLInputElement ;
22
34
this . loading = this . $refs . loading ;
23
35
this . resultsContainer = this . $refs . results ;
24
36
@@ -29,9 +41,6 @@ export class EntitySelector extends Component {
29
41
initialValue : this . searchInput . value || '' ,
30
42
} ;
31
43
32
- this . search = '' ;
33
- this . lastClick = 0 ;
34
-
35
44
this . setupListeners ( ) ;
36
45
this . showLoading ( ) ;
37
46
@@ -40,16 +49,13 @@ export class EntitySelector extends Component {
40
49
}
41
50
}
42
51
43
- /**
44
- * @param {EntitySelectorSearchOptions } options
45
- */
46
- configureSearchOptions ( options ) {
52
+ configureSearchOptions ( options : Partial < EntitySelectorSearchOptions > ) : void {
47
53
Object . assign ( this . searchOptions , options ) ;
48
54
this . reset ( ) ;
49
55
this . searchInput . value = this . searchOptions . initialValue ;
50
56
}
51
57
52
- setupListeners ( ) {
58
+ setupListeners ( ) : void {
53
59
this . elem . addEventListener ( 'click' , this . onClick . bind ( this ) ) ;
54
60
55
61
let lastSearch = 0 ;
@@ -67,7 +73,7 @@ export class EntitySelector extends Component {
67
73
} ) ;
68
74
69
75
// Keyboard navigation
70
- onChildEvent ( this . $el , '[data-entity-type]' , 'keydown' , event => {
76
+ onChildEvent ( this . $el , '[data-entity-type]' , 'keydown' , ( ( event : KeyboardEvent ) => {
71
77
if ( event . ctrlKey && event . code === 'Enter' ) {
72
78
const form = this . $el . closest ( 'form' ) ;
73
79
if ( form ) {
@@ -83,7 +89,7 @@ export class EntitySelector extends Component {
83
89
if ( event . code === 'ArrowUp' ) {
84
90
this . focusAdjacent ( false ) ;
85
91
}
86
- } ) ;
92
+ } ) as ( event : Event ) => void ) ;
87
93
88
94
this . searchInput . addEventListener ( 'keydown' , event => {
89
95
if ( event . code === 'ArrowDown' ) {
@@ -93,10 +99,10 @@ export class EntitySelector extends Component {
93
99
}
94
100
95
101
focusAdjacent ( forward = true ) {
96
- const items = Array . from ( this . resultsContainer . querySelectorAll ( '[data-entity-type]' ) ) ;
102
+ const items : ( Element | null ) [ ] = Array . from ( this . resultsContainer . querySelectorAll ( '[data-entity-type]' ) ) ;
97
103
const selectedIndex = items . indexOf ( document . activeElement ) ;
98
104
const newItem = items [ selectedIndex + ( forward ? 1 : - 1 ) ] || items [ 0 ] ;
99
- if ( newItem ) {
105
+ if ( newItem instanceof HTMLElement ) {
100
106
newItem . focus ( ) ;
101
107
}
102
108
}
@@ -132,7 +138,7 @@ export class EntitySelector extends Component {
132
138
}
133
139
134
140
window . $http . get ( this . searchUrl ( ) ) . then ( resp => {
135
- this . resultsContainer . innerHTML = resp . data ;
141
+ this . resultsContainer . innerHTML = resp . data as string ;
136
142
this . hideLoading ( ) ;
137
143
} ) ;
138
144
}
@@ -142,15 +148,15 @@ export class EntitySelector extends Component {
142
148
return `${ this . searchOptions . searchEndpoint } ?${ query } ` ;
143
149
}
144
150
145
- searchEntities ( searchTerm ) {
151
+ searchEntities ( searchTerm : string ) {
146
152
if ( ! this . searchOptions . searchEndpoint ) {
147
153
throw new Error ( 'Search endpoint not set for entity-selector load' ) ;
148
154
}
149
155
150
156
this . input . value = '' ;
151
157
const url = `${ this . searchUrl ( ) } &term=${ encodeURIComponent ( searchTerm ) } ` ;
152
158
window . $http . get ( url ) . then ( resp => {
153
- this . resultsContainer . innerHTML = resp . data ;
159
+ this . resultsContainer . innerHTML = resp . data as string ;
154
160
this . hideLoading ( ) ;
155
161
} ) ;
156
162
}
@@ -162,16 +168,16 @@ export class EntitySelector extends Component {
162
168
return answer ;
163
169
}
164
170
165
- onClick ( event ) {
166
- const listItem = event . target . closest ( '[data-entity-type]' ) ;
167
- if ( listItem ) {
171
+ onClick ( event : MouseEvent ) {
172
+ const listItem = ( event . target as HTMLElement ) . closest ( '[data-entity-type]' ) ;
173
+ if ( listItem instanceof HTMLElement ) {
168
174
event . preventDefault ( ) ;
169
175
event . stopPropagation ( ) ;
170
176
this . selectItem ( listItem ) ;
171
177
}
172
178
}
173
179
174
- selectItem ( item ) {
180
+ selectItem ( item : HTMLElement ) : void {
175
181
const isDblClick = this . isDoubleClick ( ) ;
176
182
const type = item . getAttribute ( 'data-entity-type' ) ;
177
183
const id = item . getAttribute ( 'data-entity-id' ) ;
@@ -180,14 +186,14 @@ export class EntitySelector extends Component {
180
186
this . unselectAll ( ) ;
181
187
this . input . value = isSelected ? `${ type } :${ id } ` : '' ;
182
188
183
- const link = item . getAttribute ( 'href' ) ;
184
- const name = item . querySelector ( '.entity-list-item-name' ) . textContent ;
185
- const data = { id : Number ( id ) , name, link} ;
189
+ const link = item . getAttribute ( 'href' ) || '' ;
190
+ const name = item . querySelector ( '.entity-list-item-name' ) ? .textContent || '' ;
191
+ const data : EntitySelectorEntity = { id : Number ( id ) , name, link} ;
186
192
187
193
if ( isSelected ) {
188
194
item . classList . add ( 'selected' ) ;
189
195
} else {
190
- window . $events . emit ( 'entity-select-change' , null ) ;
196
+ window . $events . emit ( 'entity-select-change' ) ;
191
197
}
192
198
193
199
if ( ! isDblClick && ! isSelected ) return ;
@@ -200,7 +206,7 @@ export class EntitySelector extends Component {
200
206
}
201
207
}
202
208
203
- confirmSelection ( data ) {
209
+ confirmSelection ( data : EntitySelectorEntity ) {
204
210
window . $events . emit ( 'entity-select-confirm' , data ) ;
205
211
}
206
212
0 commit comments