mirror of
https://github.com/snowball-tools/snowballtools-base.git
synced 2024-12-23 00:57:44 +00:00
Use branches from GitHub API in edit domain dialog (#74)
* Use branches from GitHub API * Disable git branch input if repo not found * Disable git branch if branches is empty * Use async select for accounts dropdown * Log actual HTTP error in console --------- Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
parent
ce55fe62d8
commit
c3d1b4f3eb
@ -3,11 +3,12 @@ import { Octokit } from 'octokit';
|
||||
import assert from 'assert';
|
||||
import { useDebounce } from 'usehooks-ts';
|
||||
|
||||
import { Button, Typography, Option, Select } from '@material-tailwind/react';
|
||||
import { Button, Typography, Option } from '@material-tailwind/react';
|
||||
|
||||
import SearchBar from '../../SearchBar';
|
||||
import ProjectRepoCard from './ProjectRepoCard';
|
||||
import { GitOrgDetails, GitRepositoryDetails } from '../../../types';
|
||||
import AsyncSelect from '../../shared/AsyncSelect';
|
||||
|
||||
const DEFAULT_SEARCHED_REPO = '';
|
||||
const REPOS_PER_PAGE = 5;
|
||||
@ -109,8 +110,7 @@ const RepositoryList = ({ octokit }: RepositoryListProps) => {
|
||||
<div className="p-4">
|
||||
<div className="flex gap-2 mb-2">
|
||||
<div className="basis-1/3">
|
||||
{/* TODO: Fix selection of Git user at start */}
|
||||
<Select
|
||||
<AsyncSelect
|
||||
value={selectedAccount}
|
||||
onChange={(value) => setSelectedAccount(value!)}
|
||||
>
|
||||
@ -119,7 +119,7 @@ const RepositoryList = ({ octokit }: RepositoryListProps) => {
|
||||
^ {account.login}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</AsyncSelect>
|
||||
</div>
|
||||
<div className="basis-2/3">
|
||||
<SearchBar
|
||||
|
@ -12,7 +12,6 @@ import {
|
||||
Card,
|
||||
} from '@material-tailwind/react';
|
||||
|
||||
import { RepositoryDetails } from '../../../../types';
|
||||
import ConfirmDialog from '../../../shared/ConfirmDialog';
|
||||
import EditDomainDialog from './EditDomainDialog';
|
||||
import { useGQLClient } from '../../../../context/GQLClientContext';
|
||||
@ -27,7 +26,7 @@ enum RefreshStatus {
|
||||
interface DomainCardProps {
|
||||
domains: Domain[];
|
||||
domain: Domain;
|
||||
repo: RepositoryDetails;
|
||||
branches: string[];
|
||||
project: Project;
|
||||
onUpdate: () => Promise<void>;
|
||||
}
|
||||
@ -44,7 +43,7 @@ const DOMAIN_RECORD = {
|
||||
const DomainCard = ({
|
||||
domains,
|
||||
domain,
|
||||
repo,
|
||||
branches,
|
||||
project,
|
||||
onUpdate,
|
||||
}: DomainCardProps) => {
|
||||
@ -188,7 +187,7 @@ const DomainCard = ({
|
||||
domains={domains}
|
||||
open={editDialogOpen}
|
||||
domain={domain}
|
||||
repo={repo}
|
||||
branches={branches}
|
||||
onUpdate={onUpdate}
|
||||
/>
|
||||
</>
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
Option,
|
||||
} from '@material-tailwind/react';
|
||||
|
||||
import { RepositoryDetails } from '../../../../types';
|
||||
import { useGQLClient } from '../../../../context/GQLClientContext';
|
||||
|
||||
const DEFAULT_REDIRECT_OPTIONS = ['none'];
|
||||
@ -25,7 +24,7 @@ interface EditDomainDialogProp {
|
||||
open: boolean;
|
||||
handleOpen: () => void;
|
||||
domain: Domain;
|
||||
repo: RepositoryDetails;
|
||||
branches: string[];
|
||||
onUpdate: () => Promise<void>;
|
||||
}
|
||||
|
||||
@ -40,7 +39,7 @@ const EditDomainDialog = ({
|
||||
open,
|
||||
handleOpen,
|
||||
domain,
|
||||
repo,
|
||||
branches,
|
||||
onUpdate,
|
||||
}: EditDomainDialogProp) => {
|
||||
const client = useGQLClient();
|
||||
@ -120,7 +119,7 @@ const EditDomainDialog = ({
|
||||
branch: domain.branch,
|
||||
redirectedTo: getRedirectUrl(domain),
|
||||
});
|
||||
}, [domain, repo]);
|
||||
}, [domain]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} handler={handleOpen}>
|
||||
@ -166,9 +165,13 @@ const EditDomainDialog = ({
|
||||
<Input
|
||||
crossOrigin={undefined}
|
||||
{...register('branch', {
|
||||
validate: (value) => repo.branch.includes(value),
|
||||
validate: (value) =>
|
||||
Boolean(branches.length) ? branches.includes(value) : true,
|
||||
})}
|
||||
disabled={watch('redirectedTo') !== DEFAULT_REDIRECT_OPTIONS[0]}
|
||||
disabled={
|
||||
!Boolean(branches.length) ||
|
||||
watch('redirectedTo') !== DEFAULT_REDIRECT_OPTIONS[0]
|
||||
}
|
||||
/>
|
||||
{!isValid && (
|
||||
<Typography variant="small" className="text-red-500">
|
||||
|
@ -14,13 +14,13 @@ import { useGQLClient } from './GQLClientContext';
|
||||
const UNAUTHORIZED_ERROR_CODE = 401;
|
||||
|
||||
interface ContextValue {
|
||||
octokit: Octokit | null;
|
||||
octokit: Octokit;
|
||||
isAuth: boolean;
|
||||
updateAuth: () => void;
|
||||
}
|
||||
|
||||
const OctokitContext = createContext<ContextValue>({
|
||||
octokit: null,
|
||||
octokit: new Octokit(),
|
||||
isAuth: false,
|
||||
updateAuth: () => {},
|
||||
});
|
||||
|
@ -24,7 +24,7 @@ const NewProject = () => {
|
||||
})}
|
||||
</div>
|
||||
<h5 className="mt-4 ml-4">Import a repository</h5>
|
||||
<RepositoryList octokit={octokit!} />
|
||||
<RepositoryList octokit={octokit} />
|
||||
</>
|
||||
) : (
|
||||
<ConnectAccount onAuth={updateAuth} />
|
||||
|
@ -24,10 +24,6 @@ const OverviewTabPanel = () => {
|
||||
const { project } = useOutletContext<OutletContextType>();
|
||||
|
||||
useEffect(() => {
|
||||
if (!octokit) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Save repo commits in DB and avoid using GitHub API in frontend
|
||||
// TODO: Figure out fetching latest commits for all branches
|
||||
const fetchRepoActivity = async () => {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { RequestError } from 'octokit';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Link, useOutletContext } from 'react-router-dom';
|
||||
import { Domain } from 'gql-client';
|
||||
|
||||
@ -6,14 +7,41 @@ import { Button, Typography } from '@material-tailwind/react';
|
||||
|
||||
import DomainCard from '../../../../../components/projects/project/settings/DomainCard';
|
||||
import { useGQLClient } from '../../../../../context/GQLClientContext';
|
||||
import repositories from '../../../../../assets/repositories.json';
|
||||
import { OutletContextType } from '../../../../../types';
|
||||
import { useOctokit } from '../../../../../context/OctokitContext';
|
||||
|
||||
const Domains = () => {
|
||||
const client = useGQLClient();
|
||||
const { octokit } = useOctokit();
|
||||
const { project } = useOutletContext<OutletContextType>();
|
||||
|
||||
const [domains, setDomains] = useState<Domain[]>([]);
|
||||
const [branches, setBranches] = useState<string[]>([]);
|
||||
|
||||
const fetchBranches = useCallback(async () => {
|
||||
const [owner, repo] = project.repository.split('/');
|
||||
|
||||
try {
|
||||
const result = await octokit.rest.repos.listBranches({
|
||||
owner,
|
||||
repo,
|
||||
});
|
||||
|
||||
const branches = result.data.map((repo) => repo.name);
|
||||
|
||||
setBranches(branches);
|
||||
} catch (err) {
|
||||
if (!(err instanceof RequestError && err.status === 404)) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
console.error(err);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
fetchBranches();
|
||||
}, []);
|
||||
|
||||
const fetchDomains = async () => {
|
||||
if (project === undefined) {
|
||||
@ -46,7 +74,7 @@ const Domains = () => {
|
||||
domain={domain}
|
||||
key={domain.id}
|
||||
// TODO: Use github API for getting linked repository
|
||||
repo={repositories[0]!}
|
||||
branches={branches}
|
||||
project={project}
|
||||
onUpdate={fetchDomains}
|
||||
/>
|
||||
|
@ -6,15 +6,6 @@ export interface GitOrgDetails {
|
||||
avatar_url: string;
|
||||
}
|
||||
|
||||
// TODO: Use GitRepositoryDetails
|
||||
export interface RepositoryDetails {
|
||||
title: string;
|
||||
updatedAt: string;
|
||||
user: string;
|
||||
private: boolean;
|
||||
branch: string[];
|
||||
}
|
||||
|
||||
export interface GitRepositoryDetails {
|
||||
id: number;
|
||||
name: string;
|
||||
|
Loading…
Reference in New Issue
Block a user