88
99import { useEffect , useReducer } from 'react'
1010import { useNavigate , useParams } from 'react-router-dom'
11- import { useServices } from '@kernel/common'
11+ import { useServices , AutocompleteInput } from '@kernel/common'
1212
1313import AppConfig from 'App.config'
1414
1515const MODES = { create : 'create' , update : 'update' }
16- const KEYS = [ 'name' , 'memberIdsText' ]
17- const STATE_KEYS = [ 'group' , 'groups' , 'member' , 'members' , 'error' , 'status' , 'taskService' ]
16+ const KEYS = [ 'name' , 'memberIdsText' , 'groupMembers' ]
17+ const STATE_KEYS = [ 'group' , 'groups' , 'member' , 'members' , 'profiles' , ' error', 'status' , 'taskService' ]
1818const INITIAL_STATE = STATE_KEYS . concat ( KEYS )
1919 . reduce ( ( acc , k ) => Object . assign ( acc , { [ k ] : '' } ) , { } )
2020
@@ -23,6 +23,8 @@ Object.keys(INITIAL_STATE)
2323 . forEach ( ( k ) => {
2424 actions [ k ] = ( state , e ) => Object . assign ( { } , state , { [ k ] : e } )
2525 } )
26+ INITIAL_STATE . groupMembers = [ ]
27+ INITIAL_STATE . profiles = [ ]
2628
2729const reducer = ( state , action ) => {
2830 try {
@@ -36,6 +38,8 @@ const reducer = (state, action) => {
3638}
3739
3840const change = ( dispatch , type , e ) => {
41+ console . log ( 'in change' )
42+ console . log ( e )
3943 try {
4044 e . preventDefault ( )
4145 const payload = e . target . value
@@ -50,8 +54,14 @@ const value = (state, type) => {
5054}
5155
5256// dedupe, sort
53- const textToArray = ( s ) => [ ...new Set ( s . split ( ',' ) . map ( ( e ) => e . trim ( ) ) ) ] . sort ( )
54- const arrayToText = ( arr ) => arr . join ( ', ' )
57+ const getMemberIds = ( groupMembers ) => groupMembers . map ( groupMember => groupMember . id )
58+ const transformProfiles = ( profiles ) => {
59+ const out = [ ]
60+ for ( const [ , v ] of Object . entries ( profiles ) ) {
61+ out . push ( { id : v . data . memberId , name : v . data . name } )
62+ }
63+ return out
64+ }
5565const resetAlerts = ( dispatch ) => {
5666 dispatch ( { type : 'error' , payload : '' } )
5767 dispatch ( { type : 'status' , payload : 'submitting' } )
@@ -60,15 +70,17 @@ const resetAlerts = (dispatch) => {
6070const create = async ( state , dispatch , e ) => {
6171 e . preventDefault ( )
6272 resetAlerts ( dispatch )
63- const { groups, memberIdsText , name, taskService } = state
64- const memberIds = textToArray ( memberIdsText )
65- if ( ! name . length || ! memberIdsText . length ) {
73+ const { groups, groupMembers , name, taskService } = state
74+ const memberIds = getMemberIds ( groupMembers )
75+ if ( ! name . length || ! groupMembers . length ) {
6676 dispatch ( { type : 'error' , payload : 'name and member ids are required' } )
6777 return
6878 }
6979 try {
7080 const group = await groups . create ( { name } )
7181 const groupId = group . id
82+ console . log ( 'groupid' )
83+ console . log ( group . id )
7284 await groups . updateMeta ( groupId , { owner : groupId } )
7385 await taskService . syncGroupMembers ( { groupId, memberIds } )
7486 dispatch ( { type : 'status' , payload : 'Group creation submitted' } )
@@ -80,9 +92,9 @@ const create = async (state, dispatch, e) => {
8092const update = async ( state , dispatch , e ) => {
8193 e . preventDefault ( )
8294 resetAlerts ( dispatch )
83- const { group, groups, memberIdsText , name, taskService } = state
95+ const { group, groups, groupMembers , name, taskService } = state
8496 const groupId = group . id
85- const memberIds = textToArray ( memberIdsText )
97+ const memberIds = getMemberIds ( groupMembers )
8698 try {
8799 if ( group . data . name !== name ) {
88100 await groups . patch ( groupId , { name } )
@@ -117,14 +129,17 @@ const Form = () => {
117129 useEffect ( ( ) => {
118130 ( async ( ) => {
119131 dispatch ( { type : 'status' , payload : 'Loading' } )
120- const { entityFactory, taskService } = await services ( )
132+ const { entityFactory, taskService, queryService } = await services ( )
121133 dispatch ( { type : 'taskService' , payload : taskService } )
122134 const members = await entityFactory ( { resource : 'member' } )
123135 const member = await members . get ( user . iss )
124136 const groups = await entityFactory ( { resource : 'group' } )
137+ const { profiles } = await queryService . recommend ( )
138+ const transformedProfiles = transformProfiles ( profiles )
125139 dispatch ( { type : 'members' , payload : members } )
126140 dispatch ( { type : 'member' , payload : member } )
127141 dispatch ( { type : 'groups' , payload : groups } )
142+ dispatch ( { type : 'profiles' , payload : transformedProfiles } )
128143 if ( mode === MODES . update ) {
129144 const entity = await groups . get ( group )
130145 dispatch ( { type : 'group' , payload : entity } )
@@ -133,10 +148,9 @@ const Form = () => {
133148 . forEach ( ( [ k , v ] ) => {
134149 let type = k
135150 let payload = v
136- // TODO: more ergonomic way to select group memebers
137151 if ( k === 'memberIds' ) {
138- type = 'memberIdsText '
139- payload = arrayToText ( v )
152+ type = 'groupMembers '
153+ payload = transformedProfiles . filter ( item => v . includes ( item . id ) )
140154 }
141155 dispatch ( { type, payload } )
142156 } )
@@ -155,10 +169,11 @@ const Form = () => {
155169 />
156170 </ label >
157171 < label className = 'block' >
158- < span className = 'text-gray-700' > Member Ids (comma separated)</ span >
159- < input
160- type = 'text' multiple className = { formClass }
161- value = { value ( state , 'memberIdsText' ) } onChange = { change . bind ( null , dispatch , 'memberIdsText' ) }
172+ < span className = 'text-gray-700' > Member Names</ span >
173+ < AutocompleteInput
174+ items = { value ( state , 'profiles' ) }
175+ selectedItems = { value ( state , 'groupMembers' ) }
176+ setSelectedItems = { items => dispatch ( { type : 'groupMembers' , payload : items } ) }
162177 />
163178 </ label >
164179 < label className = 'block' >
0 commit comments