parent
777f635f75
commit
c4dce2d804
@ -1,30 +1,144 @@ |
|||||||
import React, { useState } from 'react'; |
import React, { useEffect } from "react"; |
||||||
|
import { gitActionsContext, pluginActionsContext } from "../../state/context"; |
||||||
|
import { gitPluginContext } from "../gitui"; |
||||||
|
import axios from "axios"; |
||||||
|
import { CopyToClipboard } from "@remix-ui/clipboard"; |
||||||
|
import { Card } from "react-bootstrap"; |
||||||
|
|
||||||
const GetDeviceCode = () => { |
|
||||||
const [userCode, setUserCode] = useState(null); |
|
||||||
|
|
||||||
const requestDeviceCode = async () => { |
export const GetDeviceCode = () => { |
||||||
const response = await fetch('http://localhost:3000/github.com/login/device/code', { |
const context = React.useContext(gitPluginContext) |
||||||
method: 'POST', |
const actions = React.useContext(gitActionsContext) |
||||||
|
const pluginActions = React.useContext(pluginActionsContext) |
||||||
|
const [gitHubResponse, setGitHubResponse] = React.useState<any>(null) |
||||||
|
const [authorized, setAuthorized] = React.useState<boolean>(false) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const getDeviceCodeFromGitHub = async () => { |
||||||
|
|
||||||
|
setAuthorized(false) |
||||||
|
// Send a POST request
|
||||||
|
const response = await axios({ |
||||||
|
method: 'post', |
||||||
|
url: 'http://0.0.0.0:3000/github.com/login/device/code', |
||||||
|
data: { |
||||||
|
client_id: 'dccbc48453f7afa34fad', |
||||||
|
scope: 'repo' |
||||||
|
}, |
||||||
headers: { |
headers: { |
||||||
'Content-Type': 'application/json', |
'Content-Type': 'application/json', |
||||||
|
'Accept': 'application/json' |
||||||
}, |
}, |
||||||
body: JSON.stringify({ |
}); |
||||||
|
|
||||||
|
// convert response to json
|
||||||
|
const githubrespone = await response.data; |
||||||
|
console.log('json', githubrespone) |
||||||
|
|
||||||
|
setGitHubResponse(githubrespone) |
||||||
|
} |
||||||
|
|
||||||
|
const connectApp = async () => { |
||||||
|
// poll https://github.com/login/oauth/access_token
|
||||||
|
const accestokenresponse = await axios({ |
||||||
|
method: 'post', |
||||||
|
url: 'http://0.0.0.0:3000/github.com/login/oauth/access_token', |
||||||
|
data: { |
||||||
client_id: 'dccbc48453f7afa34fad', |
client_id: 'dccbc48453f7afa34fad', |
||||||
scope: 'repo', // or another appropriate scope
|
device_code: gitHubResponse.device_code, |
||||||
}), |
grant_type: 'urn:ietf:params:oauth:grant-type:device_code' |
||||||
|
}, |
||||||
|
headers: { |
||||||
|
'Content-Type': 'application/json', |
||||||
|
'Accept': 'application/json' |
||||||
|
}, |
||||||
}); |
}); |
||||||
|
|
||||||
const data = await response.json(); |
// convert response to json
|
||||||
setUserCode(data.user_code); // Store user code to show to the user
|
const response = await accestokenresponse.data; |
||||||
}; |
console.log('json2', response) |
||||||
|
|
||||||
|
if (response.error) { |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if (response.access_token) { |
||||||
|
setAuthorized(true) |
||||||
|
await pluginActions.saveToken(response.access_token) |
||||||
|
await actions.getGitHubUser() |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
const disconnect = async () => { |
||||||
|
setAuthorized(false) |
||||||
|
setGitHubResponse(null) |
||||||
|
} |
||||||
|
|
||||||
|
const checkConnection = async () => { |
||||||
|
//await actions.getGitHubUser()
|
||||||
|
} |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
|
||||||
|
},[]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log('context.rateLimit', context.rateLimit) |
||||||
|
}, [context.rateLimit]) |
||||||
|
|
||||||
|
|
||||||
return ( |
return ( |
||||||
<div> |
<> |
||||||
<button onClick={requestDeviceCode}>Get Device Code</button> |
{(context.gitHubUser && context.gitHubUser.login) ? null : |
||||||
{userCode && <div>User Code: {userCode}</div>} |
<button className='btn btn-primary mt-1 w-100' onClick={async () => { |
||||||
</div> |
getDeviceCodeFromGitHub(); |
||||||
); |
}}>Login in with github</button> |
||||||
}; |
} |
||||||
|
{gitHubResponse && !authorized && |
||||||
export default GetDeviceCode; |
<div className="pt-2"> |
||||||
|
|
||||||
|
Step 1: Copy this code: |
||||||
|
<div className="input-group text-secondary mb-0 h6"> |
||||||
|
<input disabled type="text" className="form-control" value={gitHubResponse.user_code} /> |
||||||
|
<div className="input-group-append"> |
||||||
|
<CopyToClipboard content={gitHubResponse.user_code} data-id='copyToClipboardCopyIcon' className='far fa-copy ml-1 p-2 mt-1' direction={"top"} /> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<br></br> |
||||||
|
Step 2: Authorize the app here |
||||||
|
<br></br><a target="_blank" href={gitHubResponse.verification_uri}>{gitHubResponse.verification_uri}</a> |
||||||
|
<br /><br></br> |
||||||
|
Step 3: When you are done, click on the button below: |
||||||
|
<button className='btn btn-primary mt-1 w-100' onClick={async () => { |
||||||
|
connectApp() |
||||||
|
}}>Connect</button> |
||||||
|
</div> |
||||||
|
} |
||||||
|
{ |
||||||
|
(context.gitHubUser && context.gitHubUser.login) ? |
||||||
|
<div className="pt-2"> |
||||||
|
<button className='btn btn-primary mt-1 w-100' onClick={async () => { |
||||||
|
disconnect() |
||||||
|
}}>Disconnect</button> |
||||||
|
</div>: null |
||||||
|
} |
||||||
|
{ |
||||||
|
(context.gitHubUser && context.gitHubUser.login) ? |
||||||
|
<div className="pt-2"> |
||||||
|
<Card> |
||||||
|
<Card.Body> |
||||||
|
<Card.Title>Connected as {context.gitHubUser.login}</Card.Title> |
||||||
|
<Card.Text> |
||||||
|
<img src={context.gitHubUser.avatar_url} className="w-100" /> |
||||||
|
<a target="_blank" href={context.gitHubUser.html_url}>{context.gitHubUser.html_url}</a> |
||||||
|
</Card.Text> |
||||||
|
</Card.Body> |
||||||
|
</Card> |
||||||
|
</div>: null |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
</>) |
||||||
|
} |
@ -0,0 +1,88 @@ |
|||||||
|
import { clearInstances } from 'libs/remix-ui/run-tab/src/lib/actions/actions'; |
||||||
|
import React, { useState, useCallback, useEffect } from 'react'; |
||||||
|
import { Button } from 'react-bootstrap'; |
||||||
|
import { OptionsOrGroups, GroupBase } from 'react-select'; |
||||||
|
import Select from 'react-select/async'; |
||||||
|
import { gitActionsContext } from '../../state/context'; |
||||||
|
import { selectStyles, selectTheme } from '../../types/styles'; |
||||||
|
import { gitPluginContext } from '../gitui'; |
||||||
|
import { TokenWarning } from '../panels/tokenWarning'; |
||||||
|
|
||||||
|
const RepositorySelect = () => { |
||||||
|
const [page, setPage] = useState(1); |
||||||
|
const [repoOtions, setRepoOptions] = useState<any>([]); |
||||||
|
const context = React.useContext(gitPluginContext) |
||||||
|
const actions = React.useContext(gitActionsContext) |
||||||
|
const [loading, setLoading] = useState(false) |
||||||
|
const [show, setShow] = useState(false) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log('context', context.repositories) |
||||||
|
if (context.repositories && context.repositories.length > 0) { |
||||||
|
// map context.repositories to options
|
||||||
|
const options = context.repositories && context.repositories.length > 0 && context.repositories.map(repo => { |
||||||
|
return { value: repo.id, label: repo.full_name } |
||||||
|
}) |
||||||
|
console.log('options', options) |
||||||
|
setRepoOptions(options) |
||||||
|
} else { |
||||||
|
setRepoOptions(null) |
||||||
|
setShow(false) |
||||||
|
} |
||||||
|
setLoading(false) |
||||||
|
|
||||||
|
}, [context.repositories]) |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
console.log('OTIONS', repoOtions) |
||||||
|
},[repoOtions]) |
||||||
|
|
||||||
|
const selectRepo = async (value: number | string) => { |
||||||
|
// find repo
|
||||||
|
console.log('setRepo', value, context.repositories) |
||||||
|
|
||||||
|
const repo = context.repositories.find(repo => { |
||||||
|
return repo.id.toString() === value.toString() |
||||||
|
}) |
||||||
|
console.log('repo', repo) |
||||||
|
if (repo) { |
||||||
|
//setBranchOptions([])
|
||||||
|
//setBranch({ name: "" })
|
||||||
|
//setRepo(repo)
|
||||||
|
await actions.remoteBranches(repo.owner.login, repo.name) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const fetchRepositories = async () => { |
||||||
|
try { |
||||||
|
setShow(true) |
||||||
|
setLoading(true) |
||||||
|
//setRepoOptions([])
|
||||||
|
//setBranchOptions([])
|
||||||
|
console.log(await actions.repositories()) |
||||||
|
} catch (e) { |
||||||
|
// do nothing
|
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<><TokenWarning /><Button onClick={fetchRepositories} className="w-100 mt-1"> |
||||||
|
<i className="fab fa-github mr-1"></i>Fetch Repositories from GitHub |
||||||
|
</Button> |
||||||
|
{ |
||||||
|
show ? |
||||||
|
<Select |
||||||
|
options={repoOtions} |
||||||
|
className="mt-1" |
||||||
|
onChange={(e: any) => e && selectRepo(e.value)} |
||||||
|
theme={selectTheme} |
||||||
|
styles={selectStyles} |
||||||
|
isClearable={true} |
||||||
|
placeholder="Type to search for a repository..." |
||||||
|
isLoading={loading} |
||||||
|
/> : null |
||||||
|
}</> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export default RepositorySelect; |
Loading…
Reference in new issue