@@ -172,6 +172,7 @@ const addPermissions = z.object({
172172 accessedEnvironments : z . array ( z . string ( ) ) . optional ( ) ,
173173 accessedServices : z . array ( z . string ( ) ) . optional ( ) ,
174174 accessedGitProviders : z . array ( z . string ( ) ) . optional ( ) ,
175+ accessedServers : z . array ( z . string ( ) ) . optional ( ) ,
175176 canCreateProjects : z . boolean ( ) . optional ( ) . default ( false ) ,
176177 canCreateServices : z . boolean ( ) . optional ( ) . default ( false ) ,
177178 canDeleteProjects : z . boolean ( ) . optional ( ) . default ( false ) ,
@@ -208,6 +209,10 @@ export const AddUserPermissions = ({ userId, role }: Props) => {
208209 } ,
209210 ) ;
210211
212+ const { data : servers } = api . server . allForPermissions . useQuery ( undefined , {
213+ enabled : isOpen && ! ! haveValidLicense ,
214+ } ) ;
215+
211216 const { data, refetch } = api . user . one . useQuery (
212217 {
213218 userId,
@@ -226,6 +231,7 @@ export const AddUserPermissions = ({ userId, role }: Props) => {
226231 accessedEnvironments : [ ] ,
227232 accessedServices : [ ] ,
228233 accessedGitProviders : [ ] ,
234+ accessedServers : [ ] ,
229235 canDeleteEnvironments : false ,
230236 canCreateProjects : false ,
231237 canCreateServices : false ,
@@ -248,6 +254,7 @@ export const AddUserPermissions = ({ userId, role }: Props) => {
248254 accessedEnvironments : data . accessedEnvironments || [ ] ,
249255 accessedServices : data . accessedServices || [ ] ,
250256 accessedGitProviders : data . accessedGitProviders || [ ] ,
257+ accessedServers : data . accessedServers || [ ] ,
251258 canCreateProjects : data . canCreateProjects ,
252259 canCreateServices : data . canCreateServices ,
253260 canDeleteProjects : data . canDeleteProjects ,
@@ -276,6 +283,7 @@ export const AddUserPermissions = ({ userId, role }: Props) => {
276283 accessedEnvironments : data . accessedEnvironments || [ ] ,
277284 accessedServices : data . accessedServices || [ ] ,
278285 accessedGitProviders : data . accessedGitProviders || [ ] ,
286+ accessedServers : data . accessedServers || [ ] ,
279287 canAccessToDocker : data . canAccessToDocker ,
280288 canAccessToAPI : data . canAccessToAPI ,
281289 canAccessToSSHKeys : data . canAccessToSSHKeys ,
@@ -956,6 +964,79 @@ export const AddUserPermissions = ({ userId, role }: Props) => {
956964 />
957965 </ div >
958966 ) }
967+ { haveValidLicense ? (
968+ < FormField
969+ control = { form . control }
970+ name = "accessedServers"
971+ render = { ( ) => (
972+ < FormItem className = "md:col-span-2" >
973+ < div className = "mb-4" >
974+ < FormLabel className = "text-base" > Servers</ FormLabel >
975+ < FormDescription >
976+ Select the Servers that the user can access
977+ </ FormDescription >
978+ </ div >
979+ { servers ?. length === 0 && (
980+ < p className = "text-sm text-muted-foreground" >
981+ No servers found
982+ </ p >
983+ ) }
984+ < div className = "grid md:grid-cols-1 gap-2" >
985+ { servers ?. map ( ( s ) => (
986+ < FormField
987+ key = { s . serverId }
988+ control = { form . control }
989+ name = "accessedServers"
990+ render = { ( { field } ) => (
991+ < FormItem className = "flex flex-row items-center space-x-3 space-y-0 rounded-lg border p-3" >
992+ < FormControl >
993+ < Checkbox
994+ checked = { field . value ?. includes ( s . serverId ) }
995+ onCheckedChange = { ( checked ) => {
996+ if ( checked ) {
997+ field . onChange ( [
998+ ...( field . value || [ ] ) ,
999+ s . serverId ,
1000+ ] ) ;
1001+ } else {
1002+ field . onChange (
1003+ field . value ?. filter (
1004+ ( v ) => v !== s . serverId ,
1005+ ) ,
1006+ ) ;
1007+ }
1008+ } }
1009+ />
1010+ </ FormControl >
1011+ < div className = "flex items-center gap-2" >
1012+ < FormLabel className = "text-sm cursor-pointer" >
1013+ { s . name }
1014+ </ FormLabel >
1015+ < span className = "text-xs text-muted-foreground" >
1016+ ({ s . ipAddress } )
1017+ </ span >
1018+ < span className = "text-xs text-muted-foreground capitalize" >
1019+ { s . serverType }
1020+ </ span >
1021+ </ div >
1022+ </ FormItem >
1023+ ) }
1024+ />
1025+ ) ) }
1026+ </ div >
1027+ < FormMessage />
1028+ </ FormItem >
1029+ ) }
1030+ />
1031+ ) : (
1032+ < div className = "md:col-span-2" >
1033+ < EnterpriseFeatureLocked
1034+ compact
1035+ title = "Server Assignment"
1036+ description = "Assign specific Servers to users with an Enterprise license."
1037+ />
1038+ </ div >
1039+ ) }
9591040 < DialogFooter className = "flex w-full flex-row justify-end md:col-span-2" >
9601041 < Button
9611042 isLoading = { isPending }
0 commit comments