11/** @jsxImportSource @emotion /react */
2+ import { useState } from "react" ;
23import Button , { LoadingButton } from "@atlaskit/button" ;
34import { GitHubInstallationType } from "../../../../../src/rest-interfaces" ;
45import { css } from "@emotion/react" ;
56import { token } from "@atlaskit/tokens" ;
6- import { useState } from "react" ;
77import WarningIcon from "@atlaskit/icon/glyph/warning" ;
88import OauthManager from "../../../services/oauth-manager" ;
9- import { ErrorForIPBlocked , ErrorForNonAdmins , ErrorForSSO } from "../../../components/Error/KnownErrors" ;
9+ import {
10+ ErrorForIPBlocked ,
11+ ErrorForNonAdmins ,
12+ ErrorForSSO ,
13+ } from "../../../components/Error/KnownErrors" ;
14+ import useOrgListScroll from "../../../helper/useOrgListScroll" ;
1015
1116const orgsWrapperStyle = css `
1217 max-height : 250px ;
1318 overflow-y : auto;
14- padding-right : 80px ;
15- margin-right : -80px ;
19+ width : 100% ;
1620` ;
1721const orgDivStyle = css `
1822 display : flex;
@@ -34,6 +38,14 @@ const iconWrapperStyle = css`
3438 padding-top : ${ token ( "space.150" ) } ;
3539` ;
3640
41+ const gradientStyle = css `
42+ background : linear-gradient (rgba (255 , 255 , 255 , 0 ), rgb (255 , 255 , 255 ));
43+ height : 70px ;
44+ margin-top : -70px ;
45+ position : relative;
46+ width : 100% ;
47+ display : block;
48+ ` ;
3749
3850const OrganizationsList = ( {
3951 organizations,
@@ -49,8 +61,18 @@ const OrganizationsList = ({
4961 resetCallback : ( args : boolean ) => void ;
5062 connectingOrg : ( org : GitHubInstallationType ) => void ;
5163} ) => {
52- const [ clickedOrg , setClickedOrg ] = useState < GitHubInstallationType | undefined > ( undefined ) ;
53- const canConnect = ( org : GitHubInstallationType ) => ! org . requiresSsoLogin && ! org . isIPBlocked && org . isAdmin ;
64+ const {
65+ isScrolledToBottom,
66+ isListScrollable,
67+ containerRef,
68+ hasUserScrolledRef,
69+ } = useOrgListScroll ( ) ;
70+ const [ clickedOrg , setClickedOrg ] = useState <
71+ GitHubInstallationType | undefined
72+ > ( undefined ) ;
73+
74+ const canConnect = ( org : GitHubInstallationType ) =>
75+ ! org . requiresSsoLogin && ! org . isIPBlocked && org . isAdmin ;
5476
5577 // This method clears the tokens and then re-authenticates
5678 const resetToken = async ( ) => {
@@ -81,60 +103,66 @@ const OrganizationsList = ({
81103 }
82104 } ;
83105 return (
84- < div css = { orgsWrapperStyle } >
85- { organizations . map ( ( org ) => {
86- const hasError = ! canConnect ( org ) ;
87- const orgDivStyles = hasError
88- ? [ orgDivStyle , orgDivWithErrorStyle ]
89- : [ orgDivStyle ] ;
90- return (
91- < div key = { org . id } css = { orgDivStyles } >
92- { canConnect ( org ) ? (
93- < >
94- < span css = { orgNameStyle } > { org . account . login } </ span >
95- { loaderForOrgClicked && clickedOrg ?. id === org . id ? (
96- < LoadingButton style = { { width : 80 } } isLoading >
97- Loading button
98- </ LoadingButton >
99- ) : (
100- < Button
101- isDisabled = {
102- loaderForOrgClicked && clickedOrg ?. id !== org . id
103- }
104- onClick = { async ( ) => {
105- setLoaderForOrgClicked ( true ) ;
106- setClickedOrg ( org ) ;
107- try {
108- // Calling the create connection function that is passed from the parent
109- await connectingOrg ( org ) ;
110- } finally {
111- setLoaderForOrgClicked ( false ) ;
112- }
113- } }
114- >
115- Connect
116- </ Button >
117- ) }
118- </ >
119- ) : (
120- < >
121- < div >
106+ < >
107+ < div css = { orgsWrapperStyle } ref = { containerRef } >
108+ { organizations . map ( ( org ) => {
109+ const hasError = ! canConnect ( org ) ;
110+ const orgDivStyles = hasError
111+ ? [ orgDivStyle , orgDivWithErrorStyle ]
112+ : [ orgDivStyle ] ;
113+ return (
114+ < div key = { org . id } css = { orgDivStyles } >
115+ { canConnect ( org ) ? (
116+ < >
122117 < span css = { orgNameStyle } > { org . account . login } </ span >
123- < div > { errorMessage ( org ) } </ div >
124- </ div >
125- < div css = { iconWrapperStyle } >
126- < WarningIcon
127- label = "warning"
128- primaryColor = { token ( "color.background.warning.bold" ) }
129- size = "medium"
130- />
131- </ div >
132- </ >
133- ) }
134- </ div >
135- ) ;
136- } ) }
137- </ div >
118+ { loaderForOrgClicked && clickedOrg ?. id === org . id ? (
119+ < LoadingButton style = { { width : 80 } } isLoading >
120+ Loading button
121+ </ LoadingButton >
122+ ) : (
123+ < Button
124+ isDisabled = {
125+ loaderForOrgClicked && clickedOrg ?. id !== org . id
126+ }
127+ onClick = { async ( ) => {
128+ setLoaderForOrgClicked ( true ) ;
129+ setClickedOrg ( org ) ;
130+ try {
131+ // Calling the create connection function that is passed from the parent
132+ await connectingOrg ( org ) ;
133+ } finally {
134+ setLoaderForOrgClicked ( false ) ;
135+ }
136+ } }
137+ >
138+ Connect
139+ </ Button >
140+ ) }
141+ </ >
142+ ) : (
143+ < >
144+ < div >
145+ < span css = { orgNameStyle } > { org . account . login } </ span >
146+ < div > { errorMessage ( org ) } </ div >
147+ </ div >
148+ < div css = { iconWrapperStyle } >
149+ < WarningIcon
150+ label = "warning"
151+ primaryColor = { token ( "color.background.warning.bold" ) }
152+ size = "medium"
153+ />
154+ </ div >
155+ </ >
156+ ) }
157+ </ div >
158+ ) ;
159+ } ) }
160+ </ div >
161+ { isListScrollable &&
162+ ( hasUserScrolledRef . current ? ! isScrolledToBottom : true ) && (
163+ < div css = { gradientStyle } />
164+ ) }
165+ </ >
138166 ) ;
139167} ;
140168
0 commit comments