Merge branch 'master' into statusbar-updates

pull/5370/head
Joseph Izang 7 months ago committed by GitHub
commit fdedbe1da9
  1. 4
      apps/remix-ide/src/app/plugins/git.tsx
  2. 77
      libs/remix-ui/git/src/components/branchHeader.tsx
  3. 4
      libs/remix-ui/git/src/components/buttons/commitmessage.tsx
  4. 6
      libs/remix-ui/git/src/components/github/devicecode.tsx
  5. 4
      libs/remix-ui/git/src/components/github/repositoryselect.tsx
  6. 8
      libs/remix-ui/git/src/components/github/selectandclonerepositories.tsx
  7. 43
      libs/remix-ui/git/src/components/gitui.tsx
  8. 4
      libs/remix-ui/git/src/components/navigation/branches.tsx
  9. 4
      libs/remix-ui/git/src/components/navigation/clone.tsx
  10. 9
      libs/remix-ui/git/src/components/navigation/commands.tsx
  11. 5
      libs/remix-ui/git/src/components/navigation/commits.tsx
  12. 14
      libs/remix-ui/git/src/components/navigation/github.tsx
  13. 4
      libs/remix-ui/git/src/components/navigation/log.tsx
  14. 4
      libs/remix-ui/git/src/components/navigation/remotes.tsx
  15. 4
      libs/remix-ui/git/src/components/navigation/settings.tsx
  16. 9
      libs/remix-ui/git/src/components/navigation/sourcecontrol.tsx
  17. 6
      libs/remix-ui/git/src/components/navigation/sourcecontrolgroup.tsx
  18. 10
      libs/remix-ui/git/src/components/panels/branches.tsx
  19. 32
      libs/remix-ui/git/src/components/panels/clone.tsx
  20. 6
      libs/remix-ui/git/src/components/panels/commands.tsx
  21. 6
      libs/remix-ui/git/src/components/panels/commands/fetch.tsx
  22. 14
      libs/remix-ui/git/src/components/panels/commands/pushpull.tsx
  23. 8
      libs/remix-ui/git/src/components/panels/githubcredentials.tsx
  24. 31
      libs/remix-ui/git/src/components/panels/remotes.tsx
  25. 19
      libs/remix-ui/git/src/components/panels/remotesimport.tsx
  26. 2
      libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolgroup.tsx
  27. 12
      libs/remix-ui/git/src/components/panels/sourcecontrol/sourcecontrolitem.tsx
  28. 4
      libs/remix-ui/git/src/components/panels/sourcontrol.tsx
  29. 11
      libs/remix-ui/git/src/components/panels/tokenWarning.tsx
  30. 11
      libs/remix-ui/git/src/lib/gitactions.ts
  31. 53
      libs/remix-ui/git/src/lib/listeners.ts
  32. 3
      libs/remix-ui/git/src/state/actions.ts
  33. 9
      libs/remix-ui/git/src/state/gitpayload.ts
  34. 8
      libs/remix-ui/git/src/state/gitreducer.tsx
  35. 10
      libs/remix-ui/git/src/style/index.css
  36. 18
      libs/remix-ui/git/src/types/index.ts
  37. 1
      libs/remix-ui/plugin-manager/src/lib/reducers/pluginManagerReducer.ts

@ -1,7 +1,7 @@
'use strict'
import { ViewPlugin } from '@remixproject/engine-web';
import { ViewPlugin } from '@remixproject/engine-web'
import React from 'react' // eslint-disable-line
import { gitState, GitUI } from '@remix-ui/git';
import { gitState, GitUI } from '@remix-ui/git'
import * as packageJson from '../../../../../package.json'
const profile = {

@ -43,6 +43,14 @@ export const BranchHeader = () => {
}
}, [context.fileStatusResult, context.modified, context.allchangesnotstaged, context.untracked, context.deleted])
const getName = () => {
const url = context.currentBranch?.remote?.url
if (!url) return
const regex = /https:\/\/github\.com\/[^/]+\/([^/]+)\.git/
const match = url.match(regex)
return match ? match[1] : 'Couldn\'t get repo name!'
}
const showDetachedWarningText = async () => {
await pluginActions.showAlert({
message: `You are in 'detached HEAD' state. This means you are not on a branch because you checkout a tag or a specific commit. If you want to commit changes, you will need to create a new branch.`,
@ -50,21 +58,64 @@ export const BranchHeader = () => {
})
}
const Heading = () => {
return (
<div className="container-fluid px-3">
<div className="d-flex flex-column pt-1 mb-1">
<div className="d-flex flex-column justify-content-start align-items-start">
{getName() !== "Couldn't get repo name!" ? (
<div className="pr-1 m-0">
<span className="col-4 px-0">Repository Name:</span>
<span className="" style={{ width: '15rem' }}>
<span className={`${ changed ? 'text-danger pl-2 text-truncate overflow-hidden whitespace-nowrap ml-4' : "text-secondary pl-2 text-truncate overflow-hidden whitespace-nowrap ml-4" }`}>
{getName() ?? ''}
</span>
</span>
</div>
) : null
}
<div className="pr-1 m-0">
<span className="col-4 px-0">Branch Name:</span>
<span className="pl-2 text-secondary text-truncate overflow-hidden whitespace-nowrap ml-4">
<span className={`${changed ? 'text-danger pl-2' : "pl-2"}`}>
<i className="fa fa-code-branch mr-1 pl-2"></i>
{context.currentBranch && context.currentBranch.name}
</span>
</span>
</div>
{context.storage.enabled ?
<div className="d-flex">
<span className="d-flex justify-between align-items-center" style={{ width: '15rem' }}>
<span className="col-4 px-0">Storage :</span>
<span className="text-secondary text-sm text-truncate overflow-hidden whitespace-nowrap ml-4">
{context.storage.used} MB used
({context.storage.percentUsed} %)
</span>
</span>
</div> : null}
<div className="d-flex flex-row">
<span className="d-flex justify-between align-items-center" style={{ width: '15rem' }}>
<span className="col-4 px-0">Messages :</span>
<span className="text-truncate overflow-hidden" >
<span className="text-secondary text-truncate overflow-hidden whitespace-nowrap ml-4">
{latestCommit ?
latestCommit.commit && latestCommit.commit.message ? latestCommit.commit.message : '' : null}
{isDetached ?
<>You are in a detached state<i onClick={showDetachedWarningText} className="btn fa fa-info-circle mr-1 pl-2"></i></>: null}
</span>
</span>
</span>
</div>
</div>
</div>
</div>
)
}
return (<>
<div className='text-sm w-100'>
<div className='text-secondary long-and-truncated'>
<i className="fa fa-code-branch mr-1 pl-2"></i>
{changed ? '*' : ''}{context.currentBranch && context.currentBranch.name}
</div>
{latestCommit ?
<div className='text-secondary long-and-truncated'>
{latestCommit.commit && latestCommit.commit.message ? latestCommit.commit.message : ''}
</div> : null}
{isDetached ?
<div className='text-warning long-and-truncated'>
You are in a detached state<i onClick={showDetachedWarningText} className="btn fa fa-info-circle mr-1 pl-2"></i>
</div> : null}
<Heading />
</div>
<hr></hr>
</>)
}
}

@ -126,7 +126,7 @@ export const CommitMessage = () => {
return (
<>
<div className="form-group">
<div className="form-group pt-3">
<input placeholder={commitMessagePlaceholder()} data-id='commitMessage' disabled={!messageEnabled()} className="form-control" type="text" onChange={handleChange} value={message.value} />
</div>
<button data-id='commitButton' className={`btn btn-primary w-100 ${buttonState === buttonStateValues.Commit ? '' : 'd-none'}`} disabled={commitNotAllowed()} onClick={async () => await commit()} >
@ -144,4 +144,4 @@ export const CommitMessage = () => {
<hr></hr>
</>
);
}
}

@ -72,8 +72,8 @@ export const GetDeviceCode = () => {
return (
<>
{(context.gitHubUser && context.gitHubUser.login) ? null :
<button className='btn btn-primary mt-1 w-100' onClick={async () => {
getDeviceCodeFromGitHub();
<button className='btn btn-secondary mt-1 w-100' onClick={async () => {
await getDeviceCodeFromGitHub()
}}><i className="fab fa-github mr-1"></i>Login in with github</button>
}
{gitHubResponse && !authorized &&
@ -124,4 +124,4 @@ export const GetDeviceCode = () => {
}
</>)
}
}

@ -64,9 +64,9 @@ const RepositorySelect = (props: RepositorySelectProps) => {
};
return (
<><Button data-id='fetch-repositories' onClick={fetchRepositories} className="w-100 mt-1">
<><button data-id='fetch-repositories' onClick={fetchRepositories} className="w-100 mt-1 btn btn-secondary mb-2">
<i className="fab fa-github mr-1"></i>Fetch Repositories from GitHub
</Button>
</button>
{
show ?
<Select

@ -43,15 +43,15 @@ export const SelectAndCloneRepositories = (props: RepositoriesProps) => {
return (
<>
<TokenWarning />
<RepositorySelect select={selectRepo} />
<TokenWarning />
{repo &&<BranchSelect select={selectRemoteBranch} />}
{ repo && <BranchSelect select={selectRemoteBranch} /> }
{repo && branch && branch.name && branch.name !== '0' ?
{ repo && branch && branch.name && branch.name !== '0' ?
<button data-id={`clonebtn-${repo.full_name}-${branch.name}`} className='btn btn-primary mt-1 w-100' onClick={async () => {
await clone()
}}>clone {repo.full_name}:{branch.name}</button> : null}
}}>clone {repo.full_name}:{branch.name}</button> : null }
</>
)

@ -31,8 +31,8 @@ import { SourceControl } from './panels/sourcontrol'
import { GitHubCredentials } from './panels/githubcredentials'
import { Setup } from './panels/setup'
import { Init } from './panels/init'
import { CustomRemixApi } from "@remix-api";
import { Plugin } from "@remixproject/engine";
import { CustomRemixApi } from "@remix-api"
import { Plugin } from "@remixproject/engine"
import { Disabled } from './disabled'
export const gitPluginContext = React.createContext<gitState>(defaultGitState)
@ -174,63 +174,64 @@ export const GitUI = (props: IGitUi) => {
{setup && !needsInit ? <Setup></Setup> : null}
{needsInit ? <Init></Init> : null}
{!setup && !needsInit ?
<Accordion activeKey={activePanel} defaultActiveKey="0">
<Accordion activeKey={activePanel} defaultActiveKey="0" className="">
<SourceControlNavigation eventKey="0" activePanel={activePanel} callback={setActivePanel} />
<Accordion.Collapse className='bg-light' eventKey="0">
<>
<div className="px-2 py-2">
<SourceControlBase><CommitMessage /></SourceControlBase>
<SourceControl />
</>
</div>
</Accordion.Collapse>
<hr></hr>
<CommandsNavigation eventKey="1" activePanel={activePanel} callback={setActivePanel} />
<Accordion.Collapse className='bg-light' eventKey="1">
<>
<Accordion.Collapse className="bg-light" eventKey="1">
<div className="px-2 py-2">
<Commands></Commands>
</>
</div>
</Accordion.Collapse>
<hr></hr>
<CommitsNavigation title={`COMMITS`} eventKey="3" activePanel={activePanel} callback={setActivePanel} showButtons={true} />
<Accordion.Collapse className='bg-light' eventKey="3">
<>
<div className="px-2 py-2">
<Commits />
</>
</div>
</Accordion.Collapse>
<hr></hr>
<BranchesNavigation eventKey="2" activePanel={activePanel} callback={setActivePanel} />
<Accordion.Collapse className='bg-light' eventKey="2">
<>
<Branches /></>
<div className="px-2 py-2">
<Branches />
</div>
</Accordion.Collapse>
<hr></hr>
<RemotesNavigation eventKey="5" activePanel={activePanel} callback={setActivePanel} />
<Accordion.Collapse className='bg-light' eventKey="5">
<>
<div className="px-2 py-2">
<Remotes></Remotes>
</>
</div>
</Accordion.Collapse>
<hr></hr>
<CloneNavigation eventKey="4" activePanel={activePanel} callback={setActivePanel} />
<Accordion.Collapse className='bg-light' eventKey="4">
<>
<Clone /></>
<div className="px-2 py-2">
<Clone /></div>
</Accordion.Collapse>
<hr></hr>
<GitHubNavigation eventKey="7" activePanel={activePanel} callback={setActivePanel} />
<Accordion.Collapse className='bg-light' eventKey="7">
<>
<div className="px-2 py-2">
<GetDeviceCode></GetDeviceCode>
<hr></hr>
<GitHubCredentials></GitHubCredentials>
</>
</div>
</Accordion.Collapse>
<hr></hr>
<LogNavigation eventKey="6" activePanel={activePanel} callback={setActivePanel} />
<Accordion.Collapse className='bg-light' eventKey="6">
<>
<div className="px-2 py-2">
<LogViewer />
</>
</div>
</Accordion.Collapse>
</Accordion>
@ -242,4 +243,4 @@ export const GitUI = (props: IGitUi) => {
</div>}
</>
)
}
}

@ -23,10 +23,10 @@ export const BranchesNavigation = ({ eventKey, activePanel, callback }) => {
{
activePanel === eventKey ? <FontAwesomeIcon className='' icon={faCaretDown}></FontAwesomeIcon> : <FontAwesomeIcon className='' icon={faCaretRight}></FontAwesomeIcon>
}
<label className="pl-1 nav form-check-label">BRANCHES</label>
<label className="pl-2 nav form-check-label">BRANCHES</label>
<LoaderIndicator></LoaderIndicator>
</span>
</div>
</>
);
}
}

@ -20,10 +20,10 @@ export const CloneNavigation = ({ eventKey, activePanel, callback }) => {
{
activePanel === eventKey ? <FontAwesomeIcon className='' icon={faCaretDown}></FontAwesomeIcon> : <FontAwesomeIcon className='' icon={faCaretRight}></FontAwesomeIcon>
}
<label className="pl-1 nav form-check-label">CLONE</label>
<label className="pl-2 nav form-check-label ">CLONE</label>
<LoaderIndicator></LoaderIndicator>
</span>
</div>
</>
);
}
}

@ -21,15 +21,14 @@ export const CommandsNavigation = ({ eventKey, activePanel, callback }) => {
return (
<>
<div className={'d-flex justify-content-between ' + (activePanel === eventKey ? 'bg-light' : '')}>
<span data-id='commands-panel' onClick={() => handleClick()} role={'button'} className='nav d-flex justify-content-start align-items-center w-75'>
<span data-id='commands-panel' onClick={() => handleClick()} role={'button'} className="nav d-flex justify-content-start align-items-center w-75">
{
activePanel === eventKey ? <FontAwesomeIcon className='' icon={faCaretDown}></FontAwesomeIcon> : <FontAwesomeIcon className='' icon={faCaretRight}></FontAwesomeIcon>
}
<label className="pl-1 nav form-check-label">COMMANDS</label>
<LoaderIndicator></LoaderIndicator>
<label className="pl-2 nav form-check-label">COMMANDS</label>
</span>
<LoaderIndicator></LoaderIndicator>
</div>
</>
);
}
}

@ -48,9 +48,8 @@ export const CommitsNavigation = ({ eventKey, activePanel, callback, title, bran
}
{ahead? <FontAwesomeIcon className='ml-1' icon={faCloudArrowUp}></FontAwesomeIcon> : null}
{behind? <FontAwesomeIcon className='ml-1' icon={faCloudArrowDown}></FontAwesomeIcon> : null}
<label className={`pl-1 nav form-check-label ${ahead || behind? 'text-success':''}`}>{title}</label>
<label className={`pl-2 nav form-check-label ${ahead || behind? 'text-success':''}`}>{title}</label>
<LoaderIndicator></LoaderIndicator>
</span>
{showButtons ?
<SourceControlBase branch={branch} remote={remote}>
@ -60,4 +59,4 @@ export const CommitsNavigation = ({ eventKey, activePanel, callback, title, bran
</div>
</>
);
}
}

@ -1,7 +1,7 @@
import { faCaretDown, faCaretRight } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { } from "react";
import { pluginActionsContext } from "../../state/context";
import { faCaretDown, faCaretRight } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import React, { } from "react"
import { pluginActionsContext } from "../../state/context"
export const GitHubNavigation = ({ eventKey, activePanel, callback }) => {
const pluginactions = React.useContext(pluginActionsContext)
@ -21,9 +21,9 @@ export const GitHubNavigation = ({ eventKey, activePanel, callback }) => {
{
activePanel === eventKey ? <FontAwesomeIcon className='' icon={faCaretDown}></FontAwesomeIcon> : <FontAwesomeIcon className='' icon={faCaretRight}></FontAwesomeIcon>
}
<label className="pl-1 nav form-check-label">GITHUB SETUP</label>
<label className="pl-2 nav form-check-label">GITHUB SETUP</label>
</span>
</div>
</>
);
}
)
}

@ -50,7 +50,7 @@ export const LogNavigation = ({ eventKey, activePanel, callback }) => {
{
activePanel === eventKey ? <FontAwesomeIcon className='' icon={faCaretDown}></FontAwesomeIcon> : <FontAwesomeIcon className='' icon={faCaretRight}></FontAwesomeIcon>
}
<label className="pl-1 nav form-check-label mr-2">LOG</label>
<label className="pl-2 nav form-check-label mr-2">LOG</label>
{logState.errorCount > 0 && (
<div className="text-danger mr-1">
{logState.errorCount}
@ -84,4 +84,4 @@ export const LogNavigation = ({ eventKey, activePanel, callback }) => {
</div>
</>
);
}
}

@ -23,10 +23,10 @@ export const RemotesNavigation = ({ eventKey, activePanel, callback }) => {
{
activePanel === eventKey ? <FontAwesomeIcon className='' icon={faCaretDown}></FontAwesomeIcon> : <FontAwesomeIcon className='' icon={faCaretRight}></FontAwesomeIcon>
}
<label className="pl-1 nav form-check-label">REMOTES</label>
<label className="pl-2 nav form-check-label">REMOTES</label>
<LoaderIndicator></LoaderIndicator>
</span>
</div>
</>
);
}
}

@ -24,7 +24,7 @@ export const SettingsNavigation = ({ eventKey, activePanel, callback }) => {
{
activePanel === eventKey ? <FontAwesomeIcon className='' icon={faCaretDown}></FontAwesomeIcon> : <FontAwesomeIcon className='' icon={faCaretRight}></FontAwesomeIcon>
}
<label className="nav pl-1 form-check-label">SETTINGS</label>
<label className="nav pl-2 form-check-label">SETTINGS</label>
</span>
@ -38,4 +38,4 @@ export const SettingsNavigation = ({ eventKey, activePanel, callback }) => {
</div>
</>
);
}
}

@ -24,12 +24,13 @@ export const SourceControlNavigation = ({ eventKey, activePanel, callback }) =>
return (
<>
<div className={'d-flex justify-content-between ' + (activePanel === eventKey ? 'bg-light' : '')}>
<span data-id='sourcecontrol-panel' onClick={() => handleClick()} role={'button'} className='nav d-flex justify-content-start align-items-center w-75'>
<div className={'d-flex align-items-center justify-content-between ' + (activePanel === eventKey ? 'bg-light' : '')}>
<span data-id='sourcecontrol-panel' onClick={() => handleClick()} role={'button'} className='nav d-flex justify-content-start align-items-center w-75'
>
{
activePanel === eventKey ? <FontAwesomeIcon className='' icon={faCaretDown}></FontAwesomeIcon> : <FontAwesomeIcon className='' icon={faCaretRight}></FontAwesomeIcon>
}
<label className="nav pl-1 form-check-label">SOURCE CONTROL</label>
<label className="nav pl-2 form-check-label">SOURCE CONTROL</label>
<LoaderIndicator></LoaderIndicator>
</span>
@ -39,4 +40,4 @@ export const SourceControlNavigation = ({ eventKey, activePanel, callback }) =>
</div>
</>
);
}
}

@ -38,10 +38,10 @@ export const SourceControlGroupNavigation = (props: SourceControlGroupNavigation
</span>
{
activePanel === eventKey ?
<span className='d-flex justify-content-end align-items-center w-25'>
<span className='d-flex justify-content-end align-items-center w-25 py-2'>
{group.name === 'Changes' ?
<CustomTooltip tooltipText={<FormattedMessage id="git.stageall" />}>
<button data-id='sourcecontrol-add-all' onClick={async () => { await actions.addall(context.allchangesnotstaged) }} className='btn btn-sm'><FontAwesomeIcon icon={faPlus} className="" /></button>
<button data-id='sourcecontrol-add-all' onClick={async () => { await actions.addall(context.allchangesnotstaged) }} className='btn btn-sm' style={{ marginLeft: '1rem', marginRight: '1.3rem' }}><FontAwesomeIcon icon={faPlus} className="" /></button>
</CustomTooltip>: null}
</span> : null
@ -49,4 +49,4 @@ export const SourceControlGroupNavigation = (props: SourceControlGroupNavigation
</div>
</>
);
}
}

@ -18,7 +18,7 @@ export const Branches = () => {
return (
<>
<div data-id='branches-panel-content' className="pt-1">
<div data-id='branches-panel-content' className="pt-2">
{context.branches && context.branches.length ?
<div>
{context.branches && context.branches.filter((branch, index) => !branch.remote).map((branch, index) => {
@ -32,9 +32,9 @@ export const Branches = () => {
{context.currentBranch
&& context.currentBranch.name !== ''
&& (!context.branches || context.branches.length === 0) ?
<div className="text-muted">Current branch is `{context.currentBranch.name}` but you have no commits.<hr /></div>
<div className="text-muted">Current branch is <strong className="text-dark">{`${context.currentBranch.name}`}</strong> but you have no commits.</div>
: null}
<label>create branch</label>
<label className="text-uppercase pt-2 pb-1">Create branch</label>
<div className="form-group">
<input
@ -49,7 +49,7 @@ export const Branches = () => {
<GitUIButton
data-id="sourcecontrol-create-branch"
onClick={async () => actions.createBranch(newBranch.value)}
className="btn w-md-25 w-100 btn-primary"
className="btn w-md-25 w-100 btn-primary mb-3"
id="createbranch-btn"
>
create new branch
@ -57,4 +57,4 @@ export const Branches = () => {
</div>
</>
);
}
}

@ -1,12 +1,12 @@
import React, { useState } from "react";
import { Alert, Form, FormControl, InputGroup } from "react-bootstrap";
import { useLocalStorage } from "../../hooks/useLocalStorage";
import { gitActionsContext } from "../../state/context";
import { gitPluginContext } from "../gitui";
import { SelectAndCloneRepositories } from "../github/selectandclonerepositories";
import { RemixUiCheckbox } from "@remix-ui/checkbox";
import GitUIButton from "../buttons/gituibutton";
import React, { useState } from "react"
import { Alert, Form, FormControl, InputGroup } from "react-bootstrap"
import { useLocalStorage } from "../../hooks/useLocalStorage"
import { gitActionsContext } from "../../state/context"
import { gitPluginContext } from "../gitui"
import { SelectAndCloneRepositories } from "../github/selectandclonerepositories"
import { RemixUiCheckbox } from "@remix-ui/checkbox"
import GitUIButton from "../buttons/gituibutton"
export const Clone = () => {
const context = React.useContext(gitPluginContext)
@ -64,21 +64,21 @@ export const Clone = () => {
return (
<>
<div data-id="clone-panel-content">
<InputGroup className="mb-1">
<SelectAndCloneRepositories cloneAllBranches={cloneAllBranches} cloneDepth={cloneDepth} />
<hr />
<InputGroup className="mb-2 pb-1">
<FormControl data-id="clone-url" id="cloneulr" placeholder="url" name='cloneurl' value={cloneUrl} onChange={e => onGitHubCloneUrlChange(e.target.value)} aria-describedby="urlprepend" />
</InputGroup>
<input name='clonebranch' onChange={e => onCloneBranchChange(e.target.value)} value={cloneBranch} className="form-control mb-1 mt-2" placeholder="branch" type="text" id="clonebranch" />
<input name='clonebranch' onChange={e => onCloneBranchChange(e.target.value)} value={cloneBranch} className="form-control mb-2 mt-2" placeholder="branch" type="text" id="clonebranch" />
<GitUIButton disabledCondition={!cloneUrl} data-id='clone-btn' className='btn btn-primary mt-1 w-100' onClick={async () => {
clone()
}}>clone</GitUIButton>
<hr />
<SelectAndCloneRepositories cloneAllBranches={cloneAllBranches} cloneDepth={cloneDepth} />
<hr />
<label>options</label>
<label className="text-uppercase">Options</label>
<InputGroup className="mt-1 mb-1">
<InputGroup.Prepend>
<InputGroup.Text id="clonedepthprepend">
<InputGroup.Prepend className="bg-secondary">
<InputGroup.Text id="clonedepthprepend" className="text-dark">
--depth
</InputGroup.Text>
</InputGroup.Prepend>
@ -98,4 +98,4 @@ export const Clone = () => {
<hr></hr>
</div>
</>)
}
}

@ -6,9 +6,9 @@ import { Merge } from "./commands/merge";
export const Commands = () => {
return (
<>
<div>
<PushPull></PushPull>
<hr></hr>
<Fetch></Fetch>
</>)
}
</div>)
}

@ -15,11 +15,11 @@ export const Fetch = () => {
<div className="btn-group w-100" role="group">
<GitUIButton data-id='sourcecontrol-fetch-remote' disabledCondition={fetchIsDisabled()} type="button" onClick={async () => actions.fetch({
remote: context.upstream,
})} className="btn btn-primary mr-1 w-50"><div>Fetch {context.upstream && context.upstream.name}</div></GitUIButton>
})} className="btn btn-secondary mr-1 w-50"><div>Fetch {context.upstream && context.upstream.name}</div></GitUIButton>
<GitUIButton data-id='sourcecontrol-fetch-branch' disabledCondition={fetchIsDisabled()} type="button" onClick={async () => actions.fetch({
remote: context.upstream,
ref: context.currentBranch
})} className="btn btn-primary w-50 long-and-truncated">Fetch {context.currentBranch.name}</GitUIButton>
})} className="btn btn-secondary w-50 long-and-truncated">Fetch {context.currentBranch.name}</GitUIButton>
</div>
</>)
}
}

@ -148,7 +148,7 @@ export const PushPull = () => {
<GitUIButton data-id='sourcecontrol-push' disabledCondition={pushPullIsDisabled()} type="button" onClick={async () => push()} className="btn btn-primary">Push</GitUIButton>
</div>
<label>Local Branch</label>
<label className="pt-3 text-uppercase">Local Branch</label>
<Select
id='commands-local-branch-select'
options={localBranchOptions}
@ -161,7 +161,7 @@ export const PushPull = () => {
placeholder="Type to search for a branch..."
/>
<label>Remote Branch</label>
<label className="pt-3 text-uppercase">Remote Branch</label>
<Select
id='commands-remote-branch-select'
options={remoteBranchOptions}
@ -174,7 +174,7 @@ export const PushPull = () => {
placeholder="Type to search for a branch..."
/>
<label>Remote</label>
<label className="pt-3 text-uppercase">Remote</label>
<Select
id='commands-remote-origin-select'
options={localRemotesOptions}
@ -187,10 +187,10 @@ export const PushPull = () => {
placeholder="Type to search for a branch..."
/>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<input checked={force} onChange={e => onForceChange(e)} className="remixui_autocompile custom-control-input" type="checkbox" data-id="compilerContainerAutoCompile" id="forcepush" title="Force Push" />
<label className="form-check-label custom-control-label" htmlFor="forcepush">Force push</label>
<div className="pt-3 d-flex align-items-center remixui_compilerConfig custom-control custom-checkbox">
<input checked={force} onChange={e => onForceChange(e)} className="remixui_autocompile form-check-input custom-control-input" type="checkbox" data-id="compilerContainerAutoCompile" id="forcepush" title="Force Push" />
<label className="form-check-label custom-control-label " htmlFor="forcepush">Force push</label>
</div>
</>)
}
}

@ -67,14 +67,14 @@ export const GitHubCredentials = () => {
return (
<>
<div className="input-group text-secondary mb-1 h6">
<div className="input-group text-secondary mb-3 h6">
<input data-id='githubToken' type="password" value={githubToken} placeholder="GitHub token" className="form-control" name='githubToken' onChange={e => handleChangeTokenState(e.target.value)} />
<div className="input-group-append">
<CopyToClipboard content={githubToken} data-id='copyToClipboardCopyIcon' className='far fa-copy ml-1 p-2 mt-1' direction={"top"} />
</div>
</div>
<input data-id='gitubUsername' name='githubUsername' onChange={e => handleChangeUserNameState(e.target.value)} value={githubUsername} className="form-control mb-1" placeholder="Git username" type="text" id="githubUsername" />
<input data-id='githubEmail' name='githubEmail' onChange={e => handleChangeEmailState(e.target.value)} value={githubEmail} className="form-control mb-1" placeholder="Git email" type="text" id="githubEmail" />
<input data-id='gitubUsername' name='githubUsername' onChange={e => handleChangeUserNameState(e.target.value)} value={githubUsername} className="form-control mb-3" placeholder="Git username" type="text" id="githubUsername" />
<input data-id='githubEmail' name='githubEmail' onChange={e => handleChangeEmailState(e.target.value)} value={githubEmail} className="form-control mb-3" placeholder="Git email" type="text" id="githubEmail" />
<div className="d-flex justify-content-between">
<button data-id='saveGitHubCredentials' className="btn btn-primary w-100" onClick={saveGithubToken}>
<FormattedMessage id="save" defaultMessage="Save" />
@ -87,4 +87,4 @@ export const GitHubCredentials = () => {
<hr />
</>
);
}
}

@ -1,8 +1,8 @@
import React, { useEffect } from "react";
import { gitActionsContext } from "../../state/context";
import { gitPluginContext } from "../gitui";
import { Remoteselect } from "./remoteselect";
import { RemotesImport } from "./remotesimport";
import React, { useEffect } from "react"
import { gitActionsContext } from "../../state/context"
import { gitPluginContext } from "../gitui"
import { Remoteselect } from "./remoteselect"
import { RemotesImport } from "./remotesimport"
export const Remotes = () => {
const context = React.useContext(gitPluginContext)
@ -26,9 +26,11 @@ export const Remotes = () => {
return (
<>
<div data-id="remotes-panel-content">
<div data-id="remotes-panel-content" className="d-flex flex-column">
<RemotesImport />
<hr className="mt-0 border border-2" />
{context.remotes && context.remotes.length ?
<>
<div>
{context.remotes && context.remotes.map((remote, index) => {
@ -36,18 +38,17 @@ export const Remotes = () => {
<Remoteselect key={index} remote={remote}></Remoteselect>
);
})}
</> : <>No remotes</>}
<hr></hr>
</div> : <div>
<label className="text-uppercase">No remotes</label>
</div>}
<input placeholder="remote name" name='remotename' onChange={e => onRemoteNameChange(e.target.value)} value={remoteName} className="form-control mb-2" type="text" id="remotename" />
<input placeholder="remote url" name='remoteurl' onChange={e => onUrlChange(e.target.value)} value={url} className="form-control" type="text" id="remoteurl" />
<input placeholder="remote name" name='remotename' onChange={e => onRemoteNameChange(e.target.value)} value={remoteName} className="form-control mb-3" type="text" id="remotename" />
<input placeholder="remote url" name='remoteurl' onChange={e => onUrlChange(e.target.value)} value={url} className="form-control mb-3" type="text" id="remoteurl" />
<button disabled={(remoteName && url) ? false : true} className='btn btn-primary mt-1 w-100' onClick={async () => {
addRemote();
}}>add remote</button>
<hr />
<RemotesImport />
<hr />
<hr className="mt-0 border border-2" />
</div>
</>)
}
}

@ -1,12 +1,12 @@
import React, { useEffect, useState } from "react";
import { Alert, Button } from "react-bootstrap";
import { gitActionsContext } from "../../state/context";
import { repository } from "../../types";
import { gitPluginContext } from "../gitui";
import React, { useEffect, useState } from "react"
import { Alert, Button } from "react-bootstrap"
import { gitActionsContext } from "../../state/context"
import { repository } from "../../types"
import { gitPluginContext } from "../gitui"
import Select from 'react-select'
import { selectStyles, selectTheme } from "../../types/styles";
import { TokenWarning } from "./tokenWarning";
import RepositorySelect from "../github/repositoryselect";
import { selectStyles, selectTheme } from "../../types/styles"
import { TokenWarning } from "./tokenWarning"
import RepositorySelect from "../github/repositoryselect"
export const RemotesImport = () => {
const context = React.useContext(gitPluginContext)
@ -64,9 +64,8 @@ export const RemotesImport = () => {
return (
<>
<TokenWarning />
<RepositorySelect select={selectRepo} />
<TokenWarning />
{repo ?
<input data-id='remote-panel-remotename' placeholder="remote name" name='remotename' onChange={e => onRemoteNameChange(e.target.value)} value={remoteName} className="form-control mb-2" type="text" id="remotename" />
: null}

@ -35,4 +35,4 @@ export const SourceControGroup = (props: SourceControGroupProps) => {
</Accordion.Collapse>
</Accordion> : <></>}
</>)
}
}

@ -41,10 +41,10 @@ export const SourceControlItem = (props: SourceControlItemProps) => {
return (<>
{status && status.indexOf("modified") === -1 ? <></> : <div>M</div>}
{status && status.indexOf("deleted") === -1 ? <></> : <span>D</span>}
{status && status.indexOf("added") === -1 ? <></> : <span>A</span>}
{status && status.indexOf("untracked") === -1 ? <></> : <span>U</span>}
{status && status.indexOf("modified") === -1 ? <></> : <span className="pl-2">M</span>}
{status && status.indexOf("deleted") === -1 ? <></> : <span className="pl-2">D</span>}
{status && status.indexOf("added") === -1 ? <></> : <span className="pl-2">A</span>}
{status && status.indexOf("untracked") === -1 ? <></> : <span className="pl-2">U</span>}
</>)
}
@ -56,10 +56,10 @@ export const SourceControlItem = (props: SourceControlItemProps) => {
<span className='font-weight-bold long-and-truncated'>{path.basename(file.filename)}</span>
<div className='text-secondary long-and-truncated'> {file.filename}</div>
</div>
<div className="d-flex align-items-center ml-1">
<div className="d-flex align-items-center ml-1 px-2">
<SourceControlItemButtons group={group} file={file}></SourceControlItemButtons>
<FunctionStatusIcons></FunctionStatusIcons>
</div>
</div>
</>)
}
}

@ -37,7 +37,7 @@ export const SourceControl = () => {
<>
{show ?
<>
<div>
<div className="mb-2">
<RenderGroups></RenderGroups>
</div></>
: <>
@ -46,4 +46,4 @@ export const SourceControl = () => {
</>
);
}
}

@ -1,12 +1,15 @@
import { gitPluginContext } from "../gitui"
import React, { useEffect, useState } from "react";
import React, { useEffect, useState } from "react"
export const TokenWarning = () => {
const context = React.useContext(gitPluginContext)
return (<>
{(context.gitHubUser && context.gitHubUser.login) ? null :
<li className="text-warning list-group-item d-flex justify-content-between align-items-center">
To use add a GitHub token to the settings.</li>
<span className="text-warning text-left">
<span>Generate and add a Git token to use this plugin. Tokens are added in </span><span className=" text-decoration-line-through messageTip" onClick={async () => {
}}>settings.</span>
</span>
}
</>
)
}
}

@ -1,7 +1,7 @@
import { ReadBlobResult, ReadCommitResult } from "isomorphic-git";
import React from "react";
import { fileStatus, fileStatusMerge, setRemoteBranchCommits, resetRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences, setRemoteAsDefault, setScopes, setLog, clearLog, setUserEmails, setCurrenHead } from "../state/gitpayload";
import { GitHubUser, branch, commitChange, gitActionDispatch, statusMatrixType, gitState, branchDifference, remote, gitLog, fileStatusResult, customGitApi, IGitApi, cloneInputType, fetchInputType, pullInputType, pushInputType, checkoutInput, rmInput, addInput, repository, userEmails } from '../types';
import { fileStatus, fileStatusMerge, setRemoteBranchCommits, resetRemoteBranchCommits, setBranches, setCanCommit, setCommitChanges, setCommits, setCurrentBranch, setGitHubUser, setLoading, setRemoteBranches, setRemotes, setRepos, setUpstream, setLocalBranchCommits, setBranchDifferences, setRemoteAsDefault, setScopes, setLog, clearLog, setUserEmails, setCurrenHead, setStoragePayload } from "../state/gitpayload";
import { GitHubUser, branch, commitChange, gitActionDispatch, statusMatrixType, gitState, branchDifference, remote, gitLog, fileStatusResult, customGitApi, IGitApi, cloneInputType, fetchInputType, pullInputType, pushInputType, checkoutInput, rmInput, addInput, repository, userEmails, storage } from '../types';
import { removeSlash } from "../utils";
import { disableCallBacks, enableCallBacks } from "./listeners";
import { ModalTypes } from "@remix-ui/app";
@ -849,4 +849,9 @@ export const sendToGitLog = async (message: gitLog) => {
export const clearGitLog = async () => {
dispatch(clearLog())
}
}
export const setStorage = async (storage: storage) => {
console.log(storage)
dispatch(setStoragePayload(storage))
}

@ -1,9 +1,9 @@
import React from "react";
import { setCanUseApp, setLoading, setRepoName, setGItHubToken, setLog, setGitHubUser, setUserEmails } from "../state/gitpayload";
import { gitActionDispatch } from "../types";
import { gitActionDispatch, storage } from "../types";
import { Plugin } from "@remixproject/engine";
import { getBranches, getFileStatusMatrix, loadGitHubUserFromToken, getRemotes, gitlog, setPlugin } from "./gitactions";
import { getBranches, getFileStatusMatrix, loadGitHubUserFromToken, getRemotes, gitlog, setPlugin, setStorage } from "./gitactions";
import { Profile } from "@remixproject/plugin-utils";
import { CustomRemixApi } from "@remix-api";
import { statusChanged } from "./pluginActions";
@ -20,7 +20,7 @@ class AsyncDebouncedQueue {
this.queues = new Map();
}
enqueue(callback: AsyncCallback, customDelay?:number): void {
enqueue(callback: AsyncCallback, customDelay?: number): void {
if (this.queues.has(callback)) {
clearTimeout(this.queues.get(callback)!.timer);
}
@ -180,6 +180,7 @@ export const getGitConfig = async () => {
export const loadFiles = async (filepaths: string[] = null) => {
try {
await calculateLocalStorage()
const branch = await plugin.call('dgitApi', "currentbranch")
if (branch) {
await getFileStatusMatrix(filepaths);
@ -199,3 +200,49 @@ export const enableCallBacks = async () => {
callBackEnabled = true;
}
const calculateLocalStorage = async () => {
function bytesToMB(bytes) {
return parseFloat((bytes / (1024 * 1024)).toFixed(2));
}
function calculatePercentage(used, quota) {
return parseFloat(((used / quota) * 100).toFixed(2));
}
let storage: storage = {
used: 0,
total: 0,
available: 0,
percentUsed: 0,
enabled: false
}
if ('storage' in navigator && 'estimate' in navigator.storage) {
navigator.storage.estimate().then(estimate => {
const usedMB = bytesToMB(estimate.usage);
const quotaMB = bytesToMB(estimate.quota);
const availableMB = bytesToMB(estimate.quota - estimate.usage);
const percentageUsed = calculatePercentage(estimate.usage, estimate.quota);
console.log(`Used storage: ${usedMB} MB`);
console.log(`Total quota: ${quotaMB} MB`);
console.log(`Available storage: ${availableMB} MB`);
console.log(`Percentage used: ${percentageUsed}%`);
storage = {
used: usedMB,
total: quotaMB,
available: availableMB,
percentUsed: percentageUsed,
enabled: true
}
setStorage(storage);
});
} else {
console.log('Storage API not supported in this browser.');
setStorage(storage);
}
}

@ -1,5 +1,5 @@
import { ReadCommitResult } from "isomorphic-git"
import { branch, branchDifference, commitChange, fileStatusResult, GitHubUser, gitLog, pagedCommits, remote, remoteBranch, repository, userEmails } from "../types"
import { branch, branchDifference, commitChange, fileStatusResult, GitHubUser, gitLog, pagedCommits, remote, remoteBranch, repository, storage, userEmails } from "../types"
export interface ActionPayloadTypes {
FILE_STATUS: fileStatusResult[],
@ -42,6 +42,7 @@ export interface ActionPayloadTypes {
SET_LOG: gitLog
CLEAR_LOG: void
SET_USER_EMAILS: userEmails
SET_STORAGE: storage
}
export interface Action<T extends keyof ActionPayloadTypes> {

@ -1,5 +1,5 @@
import { ReadCommitResult } from "isomorphic-git"
import { GitHubUser, branch, commitChange, fileStatusResult, remote, pagedCommits, branchDifference, gitLog, repository, userEmails } from "../types"
import { GitHubUser, branch, commitChange, fileStatusResult, remote, pagedCommits, branchDifference, gitLog, repository, userEmails, storage } from "../types"
import { Endpoints } from "@octokit/types"
export const fileStatus = (files: fileStatusResult[]) => {
@ -218,3 +218,10 @@ export const clearLog = () => {
type: 'CLEAR_LOG'
}
}
export const setStoragePayload = (storage: storage) => {
return {
type: 'SET_STORAGE',
payload: storage
}
}

@ -204,5 +204,11 @@ export const gitReducer = (state: gitState = defaultGitState, action: Actions):
log: []
}
case 'SET_STORAGE':
return {
...state,
storage: action.payload
}
}
}
}

@ -28,9 +28,17 @@
.gitfile:hover {
background-color : var(--custom-select);
}
hr {
background-color: var(--custom-select);
}
.messageTip {
}
.messageTip:hover {
cursor: pointer;
text-decoration: underline;
}

@ -163,7 +163,7 @@ export type gitState = {
fileStatusResult: fileStatusResult[]
canUseApp: boolean
loading: boolean
storageUsed: any
storage: storage
reponame: string
staged: fileStatusResult[]
untracked: fileStatusResult[]
@ -282,7 +282,13 @@ export const defaultGitState: gitState = {
allchangesnotstaged: [],
canUseApp: true,
loading: false,
storageUsed: {},
storage: {
used: 0,
total: 0,
available: 0,
percentUsed: 0,
enabled: false
},
reponame: "",
repositories: [],
remoteBranches: [],
@ -324,6 +330,14 @@ export type sourceControlGroup = {
name: string
}
export type storage = {
used: number,
total: number
available: number
percentUsed: number
enabled: boolean
}
export interface fileStatusAction {
type: string,
payload: fileStatusResult[]

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
export type localPluginReducerActionType = {
type: 'show' | 'close',

Loading…
Cancel
Save