1+ /**
2+ * Functions for handling group management
3+ *
4+ * @todo move fetch() functionality to api functions
5+ *
6+ * This Source Code Form is subject to the terms of the Mozilla Public License,
7+ * v. 2.0. If a copy of the MPL was not distributed with this file, You can
8+ * obtain one at https://mozilla.org/MPL/2.0/.
9+ *
10+ * @package phpMyFAQ
11+ * @author Thorsten Rinne <[email protected] > 12+ * @copyright 2023-2025 phpMyFAQ Team
13+ * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
14+ * @link https://www.phpmyfaq.de
15+ * @since 2023-01-04
16+ */
17+
118import { fetchAllGroups , fetchAllMembers , fetchAllUsersForGroups , fetchGroup , fetchGroupRights } from '../api' ;
219import { selectAll , unSelectAll } from '../utils' ;
320
4- export const handleGroups = async ( ) => {
21+ interface Group {
22+ group_id : string ;
23+ name : string ;
24+ description ?: string ;
25+ auto_join ?: string ;
26+ }
27+
28+ interface User {
29+ user_id : string ;
30+ login : string ;
31+ }
32+
33+ interface Member {
34+ user_id : string ;
35+ login : string ;
36+ }
37+
38+ export const handleGroups = async ( ) : Promise < void > => {
539 clearGroupList ( ) ;
640
7- const groupListSelect = document . querySelector ( '#group_list_select' ) ;
41+ const groupListSelect = document . querySelector < HTMLSelectElement > ( '#group_list_select' ) ;
842 if ( ! groupListSelect ) {
943 return ;
1044 }
1145
12- const addMember = document . querySelector ( '.pmf-add-member' ) ;
13- const removeMember = document . querySelector ( '.pmf-remove-member' ) ;
14- const selectAllUsers = document . getElementById ( 'select_all_group_user_list' ) ;
15- const unSelectAllUsers = document . getElementById ( 'unselect_all_group_user_list' ) ;
16- const selectAllMembers = document . getElementById ( 'select_all_members' ) ;
17- const unSelectAllMembers = document . getElementById ( 'unselect_all_members' ) ;
18- const groups = await fetchAllGroups ( ) ;
46+ const addMember = document . querySelector < HTMLButtonElement > ( '.pmf-add-member' ) as HTMLButtonElement ;
47+ const removeMember = document . querySelector < HTMLButtonElement > ( '.pmf-remove-member' ) as HTMLButtonElement ;
48+ const selectAllUsers = document . getElementById ( 'select_all_group_user_list' ) as HTMLButtonElement ;
49+ const unSelectAllUsers = document . getElementById ( 'unselect_all_group_user_list' ) as HTMLButtonElement ;
50+ const selectAllMembers = document . getElementById ( 'select_all_members' ) as HTMLButtonElement ;
51+ const unSelectAllMembers = document . getElementById ( 'unselect_all_members' ) as HTMLButtonElement ;
52+ const groups : Group [ ] = await fetchAllGroups ( ) ;
1953
2054 groups . forEach ( ( group ) => {
2155 const option = document . createElement ( 'option' ) ;
@@ -27,7 +61,7 @@ export const handleGroups = async () => {
2761 await processGroupList ( ) ;
2862
2963 // Events
30- groupListSelect . addEventListener ( 'change' , ( event ) => {
64+ groupListSelect . addEventListener ( 'change' , ( event : Event ) => {
3165 handleGroupSelect ( event ) ;
3266 } ) ;
3367
@@ -58,8 +92,8 @@ export const handleGroups = async () => {
5892 } ) ;
5993} ;
6094
61- const handleGroupSelect = async ( event ) => {
62- const groupId = event . target ?. value ;
95+ const handleGroupSelect = async ( event : Event ) : Promise < void > => {
96+ const groupId = ( event . target as HTMLSelectElement ) ?. value ;
6397
6498 if ( groupId ) {
6599 clearGroupData ( ) ;
@@ -72,12 +106,12 @@ const handleGroupSelect = async (event) => {
72106 await getMemberList ( groupId ) ;
73107
74108 // Activate user inputs
75- const saveGroupDetails = document . getElementById ( 'saveGroupDetails' ) ;
76- const saveMembersList = document . getElementById ( 'saveMembersList' ) ;
77- const saveGroupRights = document . getElementById ( 'saveGroupRights' ) ;
78- const deleteGroup = document . getElementById ( 'deleteGroup' ) ;
79- const groupAddMember = document . getElementById ( 'groupAddMember' ) ;
80- const groupRemoveMember = document . getElementById ( 'groupRemoveMember' ) ;
109+ const saveGroupDetails = document . getElementById ( 'saveGroupDetails' ) as HTMLButtonElement ;
110+ const saveMembersList = document . getElementById ( 'saveMembersList' ) as HTMLButtonElement ;
111+ const saveGroupRights = document . getElementById ( 'saveGroupRights' ) as HTMLButtonElement ;
112+ const deleteGroup = document . getElementById ( 'deleteGroup' ) as HTMLButtonElement ;
113+ const groupAddMember = document . getElementById ( 'groupAddMember' ) as HTMLButtonElement ;
114+ const groupRemoveMember = document . getElementById ( 'groupRemoveMember' ) as HTMLButtonElement ;
81115
82116 saveGroupDetails . disabled = false ;
83117 saveMembersList . disabled = false ;
@@ -86,89 +120,89 @@ const handleGroupSelect = async (event) => {
86120 groupAddMember . disabled = false ;
87121 groupRemoveMember . disabled = false ;
88122
89- const rightCheckboxes = document . querySelectorAll ( '.permission' ) . forEach ( ( item ) => {
123+ document . querySelectorAll < HTMLInputElement > ( '.permission' ) . forEach ( ( item ) => {
90124 item . disabled = false ;
91125 } ) ;
92126 }
93127} ;
94128
95- const getGroupData = async ( groupId ) => {
96- const groupData = await fetchGroup ( groupId ) ;
129+ const getGroupData = async ( groupId : string ) : Promise < void > => {
130+ const groupData : Group = await fetchGroup ( groupId ) ;
97131
98- document . getElementById ( 'update_group_id' ) . value = groupData . group_id ;
99- document . getElementById ( 'update_group_name' ) . value = groupData . name ;
100- document . getElementById ( 'update_group_description' ) . value = groupData . description ;
132+ ( document . getElementById ( 'update_group_id' ) as HTMLInputElement ) . value = groupData . group_id ;
133+ ( document . getElementById ( 'update_group_name' ) as HTMLInputElement ) . value = groupData . name ;
134+ ( document . getElementById ( 'update_group_description' ) as HTMLInputElement ) . value = groupData . description || '' ;
101135
102- const autoJoinCheckbox = document . getElementById ( 'update_group_auto_join' ) ;
103- autoJoinCheckbox . checked = 1 === parseInt ( groupData . auto_join ) ;
136+ const autoJoinCheckbox = document . getElementById ( 'update_group_auto_join' ) as HTMLInputElement ;
137+ autoJoinCheckbox . checked = 1 === parseInt ( groupData . auto_join || '0' ) ;
104138} ;
105139
106- const clearGroupList = ( ) => {
107- const groupList = document . getElementById ( 'group_list_select' ) ;
140+ const clearGroupList = ( ) : void => {
141+ const groupList = document . getElementById ( 'group_list_select' ) as HTMLSelectElement ;
108142 if ( groupList ) {
109143 groupList . textContent = '' ;
110144 }
111145} ;
112146
113- const processGroupList = async ( ) => {
147+ const processGroupList = async ( ) : Promise < void > => {
114148 clearGroupData ( ) ;
115149 clearGroupRights ( ) ;
116150 clearUserList ( ) ;
117151 await getUserList ( ) ;
118152 clearMemberList ( ) ;
119153} ;
120154
121- const clearGroupData = ( ) => {
122- const updateGroupAutoJoin = document . getElementById ( 'update_group_auto_join' ) ;
123- const updateGroupId = document . getElementById ( '# update_group_id' ) ;
155+ const clearGroupData = ( ) : void => {
156+ const updateGroupAutoJoin = document . getElementById ( 'update_group_auto_join' ) as HTMLInputElement ;
157+ const updateGroupId = document . getElementById ( 'update_group_id' ) as HTMLInputElement ;
124158 if ( updateGroupId ) {
125159 updateGroupId . value = '' ;
126160 }
127- const updateGroupName = document . getElementById ( '# update_group_name' ) ;
161+ const updateGroupName = document . getElementById ( 'update_group_name' ) as HTMLInputElement ;
128162 if ( updateGroupName ) {
129163 updateGroupName . value = '' ;
130164 }
131- const updateGroupDescription = document . getElementById ( '# update_group_description' ) ;
165+ const updateGroupDescription = document . getElementById ( 'update_group_description' ) as HTMLInputElement ;
132166 if ( updateGroupDescription ) {
133167 updateGroupDescription . value = '' ;
134168 }
135- if ( 'checked' === updateGroupAutoJoin . getAttribute ( ' checked' ) ) {
136- updateGroupAutoJoin . setAttribute ( ' checked' , '' ) ;
169+ if ( updateGroupAutoJoin . checked ) {
170+ updateGroupAutoJoin . checked = false ;
137171 }
138172} ;
139173
140- const clearGroupRights = ( ) => {
141- const groupRightsCheckboxes = document . querySelectorAll ( '#groupRights input[type=checkbox]' ) ;
174+ const clearGroupRights = ( ) : void => {
175+ const groupRightsCheckboxes = document . querySelectorAll < HTMLInputElement > ( '#groupRights input[type=checkbox]' ) ;
142176 if ( groupRightsCheckboxes ) {
143177 groupRightsCheckboxes . forEach ( ( checkbox ) => {
144178 checkbox . checked = false ;
145179 } ) ;
146180 }
147181} ;
148182
149- const getGroupRights = async ( groupId ) => {
150- const groupRights = await fetchGroupRights ( groupId ) ;
183+ const getGroupRights = async ( groupId : string ) : Promise < void > => {
184+ const groupRights : string [ ] = await fetchGroupRights ( groupId ) ;
151185
152186 if ( groupRights ) {
153- document . getElementById ( 'rights_group_id' ) . value = groupId ;
187+ ( document . getElementById ( 'rights_group_id' ) as HTMLInputElement ) . value = groupId ;
154188 groupRights . forEach ( ( right ) => {
155- document . getElementById ( `group_right_${ right } ` ) . checked = true ;
189+ ( document . getElementById ( `group_right_${ right } ` ) as HTMLInputElement ) . checked = true ;
156190 } ) ;
157191 }
158192} ;
159193
160- const clearUserList = ( ) => {
161- const groupUserListOptions = document . querySelectorAll ( '#group_user_list option' ) ;
194+ const clearUserList = ( ) : void => {
195+ const groupUserListOptions = document . querySelectorAll < HTMLSelectElement > ( '#group_user_list option' ) ;
162196 if ( groupUserListOptions ) {
163197 groupUserListOptions . forEach ( ( option ) => {
164198 option . value = '' ;
165199 } ) ;
166200 }
167201} ;
168202
169- const getUserList = async ( ) => {
170- const groupUserList = document . querySelector ( '#group_user_list' ) ;
171- const allUsers = await fetchAllUsersForGroups ( ) ;
203+ const getUserList = async ( ) : Promise < void > => {
204+ const groupUserList = document . querySelector < HTMLSelectElement > ( '#group_user_list' ) ;
205+ const allUsers : User [ ] = await fetchAllUsersForGroups ( ) ;
172206
173207 groupUserList . textContent = '' ;
174208 allUsers . forEach ( ( user ) => {
@@ -179,14 +213,14 @@ const getUserList = async () => {
179213 } ) ;
180214} ;
181215
182- const clearMemberList = ( ) => {
183- const groupMemberList = document . querySelector ( '#group_member_list' ) ;
216+ const clearMemberList = ( ) : void => {
217+ const groupMemberList = document . querySelector < HTMLSelectElement > ( '#group_member_list' ) ;
184218 groupMemberList . textContent = '' ;
185219} ;
186220
187- const getMemberList = async ( groupId ) => {
188- const groupMemberList = document . querySelector ( '#group_member_list' ) ;
189- const members = await fetchAllMembers ( groupId ) ;
221+ const getMemberList = async ( groupId : string ) : Promise < void > => {
222+ const groupMemberList = document . querySelector < HTMLSelectElement > ( '#group_member_list' ) ;
223+ const members : Member [ ] = await fetchAllMembers ( groupId ) ;
190224
191225 groupMemberList . textContent = '' ;
192226 members . forEach ( ( member ) => {
@@ -196,24 +230,25 @@ const getMemberList = async (groupId) => {
196230 option . selected = true ;
197231 groupMemberList . appendChild ( option ) ;
198232 } ) ;
199- document . getElementById ( 'update_member_group_id' ) . value = groupId ;
233+ ( document . getElementById ( 'update_member_group_id' ) as HTMLInputElement ) . value = groupId ;
200234} ;
201235
202- const addGroupMembers = ( ) => {
236+ const addGroupMembers = ( ) : void => {
203237 // make sure that a group is selected
204- const selectedGroup = document . querySelector ( '#group_list_select option:checked' ) ;
238+ const selectedGroup = document . querySelector < HTMLSelectElement > ( '#group_list_select option:checked' ) ;
205239 if ( selectedGroup === null ) {
206240 // @todo refactor alert() to something more beautiful.
207241 alert ( 'Please choose a group.' ) ;
242+ return ;
208243 }
209244
210- const allUsers = document . getElementById ( 'group_user_list' ) ;
245+ const allUsers = document . getElementById ( 'group_user_list' ) as HTMLSelectElement ;
211246 const selectedUsers = [ ...allUsers . options ]
212247 . filter ( ( option ) => option . selected )
213248 . map ( ( option ) => {
214249 return { value : option . value , login : option . innerText } ;
215250 } ) ;
216- const allMembers = document . getElementById ( 'group_member_list' ) ;
251+ const allMembers = document . getElementById ( 'group_member_list' ) as HTMLSelectElement ;
217252 const members = [ ...allMembers . options ] . map ( ( option ) => {
218253 return { value : option . value , login : option . innerText } ;
219254 } ) ;
@@ -227,7 +262,7 @@ const addGroupMembers = () => {
227262 } ) ;
228263
229264 if ( isMember === false ) {
230- const groupMemberList = document . getElementById ( 'group_member_list' ) ;
265+ const groupMemberList = document . getElementById ( 'group_member_list' ) as HTMLSelectElement ;
231266 const option = document . createElement ( 'option' ) ;
232267 option . value = user . value ;
233268 option . textContent = user . login ;
@@ -238,19 +273,17 @@ const addGroupMembers = () => {
238273 }
239274} ;
240275
241- const removeGroupMembers = ( ) => {
242- console . log ( 'removeGroupMembers' ) ;
243-
244- const memberList = document . getElementById ( 'group_member_list' ) ;
245- const allMembers = [ ...memberList . options ] . map ( ( option ) => option . value ) ;
276+ const removeGroupMembers = ( ) : void => {
277+ const memberList = document . getElementById ( 'group_member_list' ) as HTMLSelectElement ;
246278 const selectedMembers = [ ...memberList . options ] . filter ( ( option ) => option . selected ) . map ( ( option ) => option . value ) ;
247279
248280 if ( selectedMembers . length === 0 ) {
249281 // @todo refactor alert() to something more beautiful.
250282 alert ( 'Please choose a member.' ) ;
283+ return ;
251284 }
252285
253- for ( const member of [ ...document . querySelector ( '#group_member_list' ) . options ] ) {
286+ for ( const member of [ ...document . querySelectorAll < HTMLSelectElement > ( '#group_member_list option' ) ] ) {
254287 if ( selectedMembers . includes ( member . value ) ) {
255288 member . remove ( ) ;
256289 }
0 commit comments