BranchDifferences

git4refactor
filip mertens 7 months ago
parent b3252a04a6
commit 02e1d29084
  1. 30
      libs/remix-ui/git/src/components/buttons/sourcecontrolbuttons.tsx
  2. 6
      libs/remix-ui/git/src/components/gitui.tsx
  3. 3
      libs/remix-ui/git/src/components/navigation/commits.tsx
  4. 13
      libs/remix-ui/git/src/components/navigation/remotesdetails.tsx
  5. 17
      libs/remix-ui/git/src/components/navigation/sourcecontrol.tsx
  6. 31
      libs/remix-ui/git/src/components/panels/branches/branchdifferencedetails.tsx
  7. 23
      libs/remix-ui/git/src/components/panels/branches/branchdifferences.tsx
  8. 16
      libs/remix-ui/git/src/components/panels/commits.tsx
  9. 7
      libs/remix-ui/git/src/components/panels/remotes.tsx
  10. 5
      libs/remix-ui/git/src/components/panels/remotesimport.tsx
  11. 20
      libs/remix-ui/git/src/lib/gitactions.ts
  12. 2
      libs/remix-ui/git/src/state/context.tsx
  13. 2
      libs/remix-ui/git/src/state/gitreducer.tsx
  14. 1
      libs/remix-ui/git/src/types/index.ts

@ -0,0 +1,30 @@
import { faArrowDown, faArrowUp, faArrowsUpDown, faArrowRotateRight } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { CustomTooltip } from "@remix-ui/helper"
import React, { useState } from "react"
import { FormattedMessage } from "react-intl"
import { branch, remote } from "../../types"
interface SourceControlButtonsProps {
remote?: remote,
branch?: branch
}
export const SourceControlButtons = (props: SourceControlButtonsProps) => {
const { remote, branch } = props
return (<span className='d-flex justify-content-end align-items-center w-25'>
<CustomTooltip tooltipText={<FormattedMessage id="git.pull" />}>
<button onClick={async () => { }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowDown} className="" /></button>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.push" />}>
<button onClick={async () => { }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowUp} className="" /></button>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.sync" />}>
<button onClick={async () => { }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowsUpDown} className="" /></button>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.refresh" />}>
<button onClick={async () => { }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowRotateRight} className="" /></button>
</CustomTooltip>
</span>)
}

@ -1,5 +1,5 @@
import React, { useEffect, useReducer, useState } from 'react'
import { add, addall, checkout, checkoutfile, clone, commit, createBranch, remoteBranches, repositories, rm, getCommitChanges, diff, resolveRef, getBranchCommits, setUpstreamRemote, getGitHubUser, getBranches, getRemotes, remoteCommits, saveGitHubCredentials, getGitHubCredentials, fetch, pull, push, setDefaultRemote } from '../lib/gitactions'
import { add, addall, checkout, checkoutfile, clone, commit, createBranch, remoteBranches, repositories, rm, getCommitChanges, diff, resolveRef, getBranchCommits, setUpstreamRemote, getGitHubUser, getBranches, getRemotes, remoteCommits, saveGitHubCredentials, getGitHubCredentials, fetch, pull, push, setDefaultRemote, addRemote, removeRemote } from '../lib/gitactions'
import { loadFiles, setCallBacks } from '../lib/listeners'
import { openDiff, openFile, saveToken, setModifiedDecorator, setPlugin, setUntrackedDecorator, statusChanged } from '../lib/pluginActions'
import { gitActionsContext, pluginActionsContext } from '../state/context'
@ -111,7 +111,9 @@ export const GitUI = (props: IGitUi) => {
fetch,
pull,
push,
setDefaultRemote
setDefaultRemote,
addRemote,
removeRemote
}
const pluginActionsProviderValue = {

@ -4,6 +4,7 @@ import { CustomTooltip } from "@remix-ui/helper";
import React, { useEffect } from "react";
import { FormattedMessage } from "react-intl";
import { pluginActionsContext } from "../../state/context";
import { branch } from "../../types";
import { gitPluginContext } from "../gitui";
export interface CommitsNavigationProps {
@ -11,6 +12,7 @@ export interface CommitsNavigationProps {
eventKey: string,
activePanel: string,
callback: (eventKey: string) => void
branch?: branch,
}
export const CommitsNavigation = ({ eventKey, activePanel, callback, title }: CommitsNavigationProps) => {
@ -41,6 +43,7 @@ export const CommitsNavigation = ({ eventKey, activePanel, callback, title }: Co
</span>
{
activePanel === eventKey ?
<span className='d-flex justify-content-end align-items-center w-25'>

@ -1,4 +1,4 @@
import { faCaretDown, faCaretRight, faArrowRightArrowLeft, faGlobe, faToggleOff, faToggleOn } from "@fortawesome/free-solid-svg-icons";
import { faCaretDown, faCaretRight, faArrowRightArrowLeft, faGlobe, faToggleOff, faToggleOn, faTrash, faCheck } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React, { useContext, useEffect } from "react";
import { gitActionsContext } from "../../state/context";
@ -16,7 +16,7 @@ export const RemotesDetailsNavigation = (props: RemotesDetailsNavigationProps) =
const { eventKey, activePanel, callback, remote } = props;
const context = React.useContext(gitPluginContext)
const actions = React.useContext(gitActionsContext)
const handleClick = () => {
if (!callback) return
if (activePanel === eventKey) {
@ -37,20 +37,21 @@ export const RemotesDetailsNavigation = (props: RemotesDetailsNavigationProps) =
return (
<>
<div className="d-flex flex-row w-100 mb-2 mt-2">
<div onClick={() => handleClick()} role={'button'} className='pointer d-flex flex-row w-100 commit-navigation'>
<div onClick={() => handleClick()} role={'button'} className='pointer long-and-truncated d-flex flex-row commit-navigation'>
{
activePanel === eventKey ? <FontAwesomeIcon className='' icon={faCaretDown}></FontAwesomeIcon> : <FontAwesomeIcon className='' icon={faCaretRight}></FontAwesomeIcon>
}
<div className="long-and-truncated pl-1">
{remote.remote} <FontAwesomeIcon className='' icon={faArrowRightArrowLeft}></FontAwesomeIcon> {remote.url}
<div className={`long-and-truncated ml-1 ${context.defaultRemote && context.defaultRemote?.url === remote.url ? 'text-success' : ''}`}>
{remote.remote} <FontAwesomeIcon className='' icon={faArrowRightArrowLeft}></FontAwesomeIcon> {remote.url}
</div>
</div>
{context.defaultRemote && context.defaultRemote?.url === remote.url ?
<FontAwesomeIcon className='ml-auto mr-1 pointer text-success' icon={faToggleOff} ></FontAwesomeIcon>
<FontAwesomeIcon className='ml-auto mr-1 pointer text-success' icon={faCheck} ></FontAwesomeIcon>
:
<FontAwesomeIcon className='ml-auto mr-1 pointer' icon={faToggleOn} onClick={setAsDefault} ></FontAwesomeIcon>
}
<FontAwesomeIcon className='ml-auto mr-1 pointer' icon={faTrash} onClick={() => actions.removeRemote(remote)}></FontAwesomeIcon>
{remote?.url && <FontAwesomeIcon className='ml-2 pointer' icon={faGlobe} onClick={() => openRemote()}></FontAwesomeIcon>}
</div>
</>

@ -4,6 +4,7 @@ import { CustomTooltip } from "@remix-ui/helper";
import React, { useContext, useEffect } from "react";
import { FormattedMessage } from "react-intl";
import { pluginActionsContext } from "../../state/context";
import { SourceControlButtons } from "../buttons/sourcecontrolbuttons";
import { SourceControlMenu } from "./menu/sourcecontrolmenu";
export const SourceControlNavigation = ({ eventKey, activePanel, callback }) => {
@ -31,21 +32,7 @@ export const SourceControlNavigation = ({ eventKey, activePanel, callback }) =>
</span>
{
activePanel === eventKey ?
<span className='d-flex justify-content-end align-items-center w-25'>
<CustomTooltip tooltipText={<FormattedMessage id="git.pull" />}>
<button onClick={async () => { await pluginactions.loadFiles() }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowDown} className="" /></button>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.push" />}>
<button onClick={async () => { await pluginactions.loadFiles() }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowUp} className="" /></button>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.sync" />}>
<button onClick={async () => { await pluginactions.loadFiles() }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowsUpDown} className="" /></button>
</CustomTooltip>
<CustomTooltip tooltipText={<FormattedMessage id="git.refresh" />}>
<button onClick={async () => { await pluginactions.loadFiles() }} className='btn btn-sm'><FontAwesomeIcon icon={faArrowRotateRight} className="" /></button>
</CustomTooltip>
</span> : null
<SourceControlButtons/> : null
}
</div>

@ -0,0 +1,31 @@
import { ReadCommitResult } from "isomorphic-git";
import { Accordion } from "react-bootstrap";
import React, { useEffect, useState } from "react";
import { CommitDetails } from "../commits/commitdetails";
import { CommitsNavigation } from "../../navigation/commits";
export interface BrancheDifferenceProps {
commits: ReadCommitResult[];
title: string
}
export const BranchDifferenceDetails = (props: BrancheDifferenceProps) => {
const { commits, title } = props;
const [activePanel, setActivePanel] = useState<string>("");
if (commits.length === 0) return null
return (
<Accordion activeKey={activePanel} defaultActiveKey="">
<CommitsNavigation title={title} eventKey="0" activePanel={activePanel} callback={setActivePanel} />
<Accordion.Collapse className="pl-2 border-left ml-1" eventKey="0">
<div className="ml-1">
{commits && commits.map((commit, index) => {
return (
<CommitDetails key={index} checkout={()=>{}} commit={commit}></CommitDetails>
);
})}
</div>
</Accordion.Collapse>
</Accordion>)
}

@ -2,13 +2,16 @@ import { branch, remote } from "../../../types";
import React, { useEffect, useState } from "react";
import { gitPluginContext } from "../../gitui";
import { CommitDetails } from "../commits/commitdetails";
import { BranchDifferenceDetails } from "./branchdifferencedetails";
export interface BrancheDetailsProps {
branch: branch;
showSummary?: boolean;
remote?: remote;
}
export const BranchDifferences = (props: BrancheDetailsProps) => {
const { branch } = props;
const { branch, showSummary, remote } = props;
const context = React.useContext(gitPluginContext)
useEffect(() => {
@ -28,20 +31,18 @@ export const BranchDifferences = (props: BrancheDetailsProps) => {
}
return (
<div>
<div>
{context.remotes.map((remote, index) => {
<>
{!showSummary && context.remotes.map((remote, index) => {
return (
<div key={index}>
<h5>{remote.remote}</h5>
<ul>
<li>ahead by {commitsAhead(remote).length} commit(s)</li>
<li>behind by {commitsBehind(remote).length} commits(s)</li>
</ul>
<BranchDifferenceDetails title={`ahead of ${remote.remote} by ${commitsAhead(remote).length} commit(s)`} commits={commitsAhead(remote)}></BranchDifferenceDetails>
<BranchDifferenceDetails title={`behind ${remote.remote} by ${commitsBehind(remote).length} commit(s)`} commits={commitsBehind(remote)}></BranchDifferenceDetails>
{commitsAhead(remote).length === 0 && commitsBehind(remote).length === 0? null: <hr></hr>}
</div>
);
})}
</div>
</div>
{showSummary && <div>summary</div>}
</>
);
}

@ -2,6 +2,7 @@ import { checkout, ReadCommitResult } from "isomorphic-git";
import React from "react";
import { gitActionsContext } from "../../state/context";
import { gitPluginContext } from "../gitui";
import { BranchDifferences } from "./branches/branchdifferences";
import { CommitDetails } from "./commits/commitdetails";
import { CommitSummary } from "./commits/commitsummary";
@ -24,26 +25,15 @@ export const Commits = () => {
return (
<>
{context.commits && context.commits.length ?
<div>
<><BranchDifferences branch={context.currentBranch}></BranchDifferences><div>
<div className="pt-1">
{context.commits && context.commits.map((commit, index) => {
return (
<CommitDetails key={index} checkout={checkout} commit={commit}></CommitDetails>
);
})}
<div
onClick={async () => await checkout("main")}
className="btn btn-primary btn-sm checkout-btn mt-2 d-none"
data-oid="main"
>
git checkout main
</div>
</div>
</div>
</div></>
: <div className="text-muted">No commits</div>}
</>
)

@ -18,9 +18,10 @@ export const Remotes = () => {
}
const addRemote = async () => {
//await gitservice.addRemote(remoteName, url)
//setCurrentRemote(remoteName)
//await gitservice.getRemotes()
actions.addRemote({
remote: remoteName,
url: url
})
}

@ -59,7 +59,10 @@ export const RemotesImport = () => {
const addRemote = async () => {
try {
actions.addRemote({
remote: remoteName,
url: repo.html_url
})
} catch (e) {
// do nothing
}

@ -88,7 +88,7 @@ export const getBranches = async () => {
}
export const getRemotes = async () => {
console.log('getRemotes')
const remotes = await plugin.call("dGitProvider", "remotes" as any);
const remotes: remote[] = await plugin.call("dGitProvider", "remotes" as any);
console.log('remotes :>>', remotes)
dispatch(setRemotes(remotes));
}
@ -801,3 +801,21 @@ export const getBranchCommits = async (branch: branch, page: number) => {
export const setDefaultRemote = async (remote: remote) => {
dispatch(setRemoteAsDefault(remote))
}
export const addRemote = async (remote: remote) => {
try {
await plugin.call('dGitProvider', 'addremote', remote)
await getRemotes()
} catch (e) {
console.log(e)
}
}
export const removeRemote = async (remote: remote) => {
try {
await plugin.call('dGitProvider', 'delremote', remote)
await getRemotes()
} catch (e) {
console.log(e)
}
}

@ -3,6 +3,7 @@ import React from "react"
import { branch, commitChange, remote } from "../types"
export interface gitActions {
removeRemote(remote: remote): void
clone(url: string, path: string, depth: number, singleBranch: boolean): Promise<void>
add(path: string): Promise<void>
rm(path: string): Promise<void>
@ -25,6 +26,7 @@ export interface gitActions {
getBranches: () => Promise<void>
getRemotes: () => Promise<void>
setDefaultRemote: (remote: remote) => Promise<void>
addRemote: (remote: remote) => Promise<void>
}
export const gitActionsContext = React.createContext<gitActions>(null)

@ -1,6 +1,6 @@
import { ReadCommitResult } from "isomorphic-git"
import { allChangedButNotStagedFiles, getFilesByStatus, getFilesWithNotModifiedStatus } from "../lib/fileHelpers"
import { branch, commitChange, defaultGitState, fileStatusResult, gitState, setRemoteBranchCommitsAction, setLocalBranchCommitsAction, setBranchDifferencesAction, setDefaultRemoteAction } from "../types"
import { branch, commitChange, defaultGitState, fileStatusResult, gitState, setRemoteBranchCommitsAction, setLocalBranchCommitsAction, setBranchDifferencesAction, setDefaultRemoteAction, setRemotesAction } from "../types"
interface Action {
type: string

@ -95,6 +95,7 @@ export type repository = {
full_name: string
default_branch: string
id: number
url: string
}
export type branch = {

Loading…
Cancel
Save