mirror of
https://github.com/Dictionarry-Hub/profilarr.git
synced 2026-01-22 10:51:02 +01:00
refactor: move branch functionality into repo container. Add some icons
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import React, {useState, useEffect, useRef} from 'react';
|
||||
import {
|
||||
getSettings,
|
||||
getGitStatus,
|
||||
@@ -8,15 +8,17 @@ import {
|
||||
pullBranch,
|
||||
checkDevMode
|
||||
} from '../../api/api';
|
||||
import {
|
||||
Loader,
|
||||
} from 'lucide-react';
|
||||
import {Loader} from 'lucide-react';
|
||||
import ViewBranches from './git/modal/ViewBranches';
|
||||
import Alert from '../ui/Alert';
|
||||
import ArrContainer from './arrs/ArrContainer';
|
||||
import RepoContainer from './git/RepoContainer';
|
||||
import StatusContainer from './git/StatusContainer';
|
||||
import { statusLoadingMessages, noChangesMessages, getRandomMessage } from '../../utils/messages';
|
||||
import {
|
||||
statusLoadingMessages,
|
||||
noChangesMessages,
|
||||
getRandomMessage
|
||||
} from '../../utils/messages';
|
||||
|
||||
const SettingsPage = () => {
|
||||
const [settings, setSettings] = useState(null);
|
||||
@@ -27,8 +29,8 @@ const SettingsPage = () => {
|
||||
const [statusLoading, setStatusLoading] = useState(true);
|
||||
const [statusLoadingMessage, setStatusLoadingMessage] = useState('');
|
||||
const [noChangesMessage, setNoChangesMessage] = useState('');
|
||||
const [activeTab, setActiveTab] = useState('git'); // New state for tab navigation
|
||||
const tabsRef = useRef({}); // Ref for tabs
|
||||
const [activeTab, setActiveTab] = useState('git'); // New state for tab navigation
|
||||
const tabsRef = useRef({}); // Ref for tabs
|
||||
|
||||
useEffect(() => {
|
||||
fetchSettings();
|
||||
@@ -66,10 +68,14 @@ const SettingsPage = () => {
|
||||
if (result.success) {
|
||||
setChanges({
|
||||
...result.data,
|
||||
outgoing_changes: Array.isArray(result.data.outgoing_changes)
|
||||
outgoing_changes: Array.isArray(
|
||||
result.data.outgoing_changes
|
||||
)
|
||||
? result.data.outgoing_changes
|
||||
: [],
|
||||
incoming_changes: Array.isArray(result.data.incoming_changes)
|
||||
incoming_changes: Array.isArray(
|
||||
result.data.incoming_changes
|
||||
)
|
||||
? result.data.incoming_changes
|
||||
: []
|
||||
});
|
||||
@@ -82,11 +88,11 @@ const SettingsPage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleTabChange = (tab) => {
|
||||
const handleTabChange = tab => {
|
||||
setActiveTab(tab);
|
||||
};
|
||||
|
||||
const handleStageSelectedChanges = async (selectedChanges) => {
|
||||
const handleStageSelectedChanges = async selectedChanges => {
|
||||
setLoadingAction('stage_selected');
|
||||
try {
|
||||
const response = await addFiles(selectedChanges);
|
||||
@@ -104,7 +110,10 @@ const SettingsPage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleCommitSelectedChanges = async (selectedChanges, commitMessage) => {
|
||||
const handleCommitSelectedChanges = async (
|
||||
selectedChanges,
|
||||
commitMessage
|
||||
) => {
|
||||
setLoadingAction('commit_selected');
|
||||
try {
|
||||
const response = await pushFiles(selectedChanges, commitMessage);
|
||||
@@ -115,33 +124,43 @@ const SettingsPage = () => {
|
||||
Alert.error(response.error);
|
||||
}
|
||||
} catch (error) {
|
||||
Alert.error('An unexpected error occurred while committing changes.');
|
||||
Alert.error(
|
||||
'An unexpected error occurred while committing changes.'
|
||||
);
|
||||
console.error('Error committing changes:', error);
|
||||
} finally {
|
||||
setLoadingAction('');
|
||||
}
|
||||
};
|
||||
|
||||
const handleRevertSelectedChanges = async (selectedChanges) => {
|
||||
const handleRevertSelectedChanges = async selectedChanges => {
|
||||
setLoadingAction('revert_selected');
|
||||
try {
|
||||
const response = await Promise.all(selectedChanges.map(filePath => revertFile(filePath)));
|
||||
const response = await Promise.all(
|
||||
selectedChanges.map(filePath => revertFile(filePath))
|
||||
);
|
||||
const allSuccessful = response.every(res => res.success);
|
||||
if (allSuccessful) {
|
||||
await fetchGitStatus();
|
||||
Alert.success('Selected changes have been reverted successfully.');
|
||||
Alert.success(
|
||||
'Selected changes have been reverted successfully.'
|
||||
);
|
||||
} else {
|
||||
Alert.error('Some changes could not be reverted. Please try again.');
|
||||
Alert.error(
|
||||
'Some changes could not be reverted. Please try again.'
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
Alert.error('An unexpected error occurred while reverting changes.');
|
||||
Alert.error(
|
||||
'An unexpected error occurred while reverting changes.'
|
||||
);
|
||||
console.error('Error reverting changes:', error);
|
||||
} finally {
|
||||
setLoadingAction('');
|
||||
}
|
||||
};
|
||||
|
||||
const handlePullSelectedChanges = async (selectedChanges) => {
|
||||
const handlePullSelectedChanges = async selectedChanges => {
|
||||
setLoadingAction('pull_changes');
|
||||
try {
|
||||
const response = await pullBranch(changes.branch, selectedChanges);
|
||||
@@ -161,51 +180,62 @@ const SettingsPage = () => {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<nav className="flex space-x-4">
|
||||
<nav className='flex space-x-4'>
|
||||
<div
|
||||
onClick={() => handleTabChange('git')}
|
||||
ref={(el) => (tabsRef.current['git'] = el)}
|
||||
ref={el => (tabsRef.current['git'] = el)}
|
||||
className={`cursor-pointer px-3 py-2 rounded-md text-sm font-medium mb-4 ${
|
||||
activeTab === 'git' ? 'text-white dark:bg-gray-600 border border-gray-200 dark:border-gray-600' : 'text-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700'
|
||||
}`}
|
||||
>
|
||||
activeTab === 'git'
|
||||
? 'text-white dark:bg-gray-600 border border-gray-200 dark:border-gray-600'
|
||||
: 'text-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700'
|
||||
}`}>
|
||||
Git Settings
|
||||
</div>
|
||||
<div
|
||||
onClick={() => handleTabChange('app')}
|
||||
ref={(el) => (tabsRef.current['app'] = el)}
|
||||
ref={el => (tabsRef.current['app'] = el)}
|
||||
className={`cursor-pointer px-3 py-2 rounded-md text-sm font-medium mb-4 ${
|
||||
activeTab === 'app' ? 'text-white dark:bg-gray-600 border border-gray-200 dark:border-gray-600' : 'text-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700'
|
||||
}`}
|
||||
>
|
||||
activeTab === 'app'
|
||||
? 'text-white dark:bg-gray-600 border border-gray-200 dark:border-gray-600'
|
||||
: 'text-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700'
|
||||
}`}>
|
||||
App Settings
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{activeTab === 'git' && (
|
||||
<>
|
||||
|
||||
<RepoContainer
|
||||
settings={settings}
|
||||
setSettings={setSettings}
|
||||
fetchGitStatus={fetchGitStatus}
|
||||
status={changes}
|
||||
isDevMode={isDevMode}
|
||||
/>
|
||||
|
||||
{settings && (
|
||||
<div className="space-y-4">
|
||||
<div className='space-y-4'>
|
||||
{statusLoading ? (
|
||||
<div className="flex items-left justify-left dark:bg-gray-800 p-4 rounded-md border border-gray-200 dark:border-gray-700 text-sm">
|
||||
<Loader className="animate-spin mr-2" size={16} />
|
||||
<span className="text-gray-300">{statusLoadingMessage}</span>
|
||||
<div className='flex items-left justify-left dark:bg-gray-800 p-4 rounded-md border border-gray-200 dark:border-gray-700 text-sm'>
|
||||
<Loader
|
||||
className='animate-spin mr-2'
|
||||
size={16}
|
||||
/>
|
||||
<span className='text-gray-300'>
|
||||
{statusLoadingMessage}
|
||||
</span>
|
||||
</div>
|
||||
) : (
|
||||
) : (
|
||||
<StatusContainer
|
||||
status={changes}
|
||||
isDevMode={isDevMode}
|
||||
onViewBranches={() => setShowBranchModal(true)}
|
||||
onStageSelected={handleStageSelectedChanges}
|
||||
onCommitSelected={handleCommitSelectedChanges}
|
||||
onRevertSelected={handleRevertSelectedChanges}
|
||||
onCommitSelected={
|
||||
handleCommitSelectedChanges
|
||||
}
|
||||
onRevertSelected={
|
||||
handleRevertSelectedChanges
|
||||
}
|
||||
onPullSelected={handlePullSelectedChanges}
|
||||
loadingAction={loadingAction}
|
||||
/>
|
||||
@@ -228,7 +258,7 @@ const SettingsPage = () => {
|
||||
|
||||
{activeTab === 'app' && (
|
||||
<>
|
||||
<h2 className="text-xl font-bold mb-4 text-gray-100 mt-3">
|
||||
<h2 className='text-xl font-bold mb-4 text-gray-100 mt-3'>
|
||||
App Settings
|
||||
</h2>
|
||||
<ArrContainer />
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Loader, Unlink, Link } from 'lucide-react';
|
||||
import React, {useState} from 'react';
|
||||
import {
|
||||
Loader,
|
||||
Unlink,
|
||||
Link,
|
||||
GitBranch,
|
||||
Eye,
|
||||
GitFork,
|
||||
GitCommit
|
||||
} from 'lucide-react';
|
||||
import Tooltip from '../../ui/Tooltip';
|
||||
import { unlinkRepo, getSettings } from '../../../api/api';
|
||||
import {unlinkRepo, getSettings} from '../../../api/api';
|
||||
import Alert from '../../ui/Alert';
|
||||
import LinkRepo from './modal/LinkRepo';
|
||||
import UnlinkRepo from './modal/UnlinkRepo';
|
||||
import ViewBranches from './modal/ViewBranches';
|
||||
|
||||
const RepoContainer = ({ settings, setSettings, fetchGitStatus }) => {
|
||||
const RepoContainer = ({
|
||||
settings,
|
||||
setSettings,
|
||||
fetchGitStatus,
|
||||
status,
|
||||
isDevMode
|
||||
}) => {
|
||||
const [loadingAction, setLoadingAction] = useState('');
|
||||
const [showLinkModal, setShowLinkModal] = useState(false);
|
||||
const [showUnlinkRepo, setShowUnlinkRepo] = useState(false);
|
||||
const [showBranchModal, setShowBranchModal] = useState(false);
|
||||
|
||||
const handleLinkRepo = () => {
|
||||
setLoadingAction('link_repo');
|
||||
setShowLinkModal(true);
|
||||
};
|
||||
|
||||
const handleUnlinkRepo = async (removeFiles) => {
|
||||
const handleUnlinkRepo = async removeFiles => {
|
||||
setLoadingAction('unlink_repo');
|
||||
try {
|
||||
const response = await unlinkRepo(removeFiles);
|
||||
@@ -64,25 +80,43 @@ const RepoContainer = ({ settings, setSettings, fetchGitStatus }) => {
|
||||
<div className='dark:bg-gray-800 border border-gray-200 dark:border-gray-700 p-5 rounded-lg shadow-md'>
|
||||
<div className='flex flex-col sm:flex-row items-start sm:items-center justify-between space-y-3 sm:space-y-0'>
|
||||
<div className='flex flex-col sm:flex-row sm:items-center'>
|
||||
<h3 className='text-sm font-semibold text-gray-100 mr-2 mb-1 sm:mb-0'>
|
||||
{settings ? 'Connected Repository:' : 'Repository:'}
|
||||
</h3>
|
||||
<div className='flex items-center'>
|
||||
<GitFork className='mr-2 text-blue-400' size={14} />
|
||||
<h3 className='text-m font-semibold text-gray-100 mr-2 mb-1 sm:mb-0'>
|
||||
{settings
|
||||
? 'Connected Repository:'
|
||||
: 'Repository:'}
|
||||
</h3>
|
||||
</div>
|
||||
{settings ? (
|
||||
<a
|
||||
href={settings.gitRepo}
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
className='text-blue-400 hover:text-blue-300 transition-colors text-sm font-medium truncate max-w-xs sm:max-w-md'>
|
||||
className='text-blue-400 hover:text-blue-300 transition-colors text-m font-medium truncate max-w-xs sm:max-w-md'>
|
||||
{settings.gitRepo}
|
||||
</a>
|
||||
) : (
|
||||
<span className='text-gray-400 text-sm'>No repository linked</span>
|
||||
<span className='text-gray-400 text-sm'>
|
||||
No repository linked
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<Tooltip content={settings ? 'Unlink Repository' : 'Link Repository'}>
|
||||
<Tooltip
|
||||
content={
|
||||
settings ? 'Unlink Repository' : 'Link Repository'
|
||||
}>
|
||||
<button
|
||||
onClick={settings ? () => setShowUnlinkRepo(true) : handleLinkRepo}
|
||||
className={`flex items-center px-4 py-2 ${settings ? 'bg-red-600 hover:bg-red-700' : 'bg-blue-600 hover:bg-blue-700'} text-white rounded-md transition-colors duration-200 ease-in-out text-sm font-medium shadow-sm`}
|
||||
onClick={
|
||||
settings
|
||||
? () => setShowUnlinkRepo(true)
|
||||
: handleLinkRepo
|
||||
}
|
||||
className={`flex items-center px-4 py-2 ${
|
||||
settings
|
||||
? 'bg-red-600 hover:bg-red-700'
|
||||
: 'bg-blue-600 hover:bg-blue-700'
|
||||
} text-white rounded-md transition-colors duration-200 ease-in-out text-m font-medium shadow-sm`}
|
||||
disabled={loadingAction !== ''}>
|
||||
{settings ? (
|
||||
<Unlink size={16} className='mr-2' />
|
||||
@@ -93,6 +127,39 @@ const RepoContainer = ({ settings, setSettings, fetchGitStatus }) => {
|
||||
</button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
{settings && (
|
||||
<div className='flex items-center justify-between mt-4'>
|
||||
<div className='flex items-center'>
|
||||
<GitCommit
|
||||
className='mr-2 text-green-400'
|
||||
size={14}
|
||||
/>
|
||||
<h3 className='text-m font-semibold text-gray-100 mr-2'>
|
||||
Current Branch:
|
||||
</h3>
|
||||
{status ? (
|
||||
<span className='text-blue-400 hover:text-blue-300 transition-colors text-m font-medium'>
|
||||
{status.branch}
|
||||
</span>
|
||||
) : (
|
||||
<span className='text-gray-400 text-m flex items-center'>
|
||||
<Loader
|
||||
className='animate-spin mr-2'
|
||||
size={14}
|
||||
/>
|
||||
Loading branch information...
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setShowBranchModal(true)}
|
||||
className='flex items-center px-3 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors duration-200 ease-in-out text-m'
|
||||
disabled={!status}>
|
||||
<Eye size={14} className='mr-2' />
|
||||
View Branches
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<LinkRepo
|
||||
isOpen={showLinkModal}
|
||||
@@ -104,6 +171,16 @@ const RepoContainer = ({ settings, setSettings, fetchGitStatus }) => {
|
||||
onClose={closeUnlinkModal}
|
||||
onSubmit={handleUnlinkRepo}
|
||||
/>
|
||||
{settings && status && (
|
||||
<ViewBranches
|
||||
isOpen={showBranchModal}
|
||||
onClose={() => setShowBranchModal(false)}
|
||||
repoUrl={settings.gitRepo}
|
||||
currentBranch={status.branch}
|
||||
onBranchChange={fetchGitStatus}
|
||||
isDevMode={isDevMode}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,8 +5,7 @@ import {
|
||||
RotateCcw,
|
||||
Download,
|
||||
CheckCircle,
|
||||
Plus,
|
||||
Eye
|
||||
Plus
|
||||
} from 'lucide-react';
|
||||
import ChangeTable from './ChangeTable';
|
||||
import Tooltip from '../../ui/Tooltip';
|
||||
@@ -15,7 +14,6 @@ import CommitSection from './CommitMessage';
|
||||
const StatusContainer = ({
|
||||
status,
|
||||
isDevMode,
|
||||
onViewBranches,
|
||||
onStageSelected,
|
||||
onCommitSelected,
|
||||
onRevertSelected,
|
||||
@@ -112,20 +110,6 @@ const StatusContainer = ({
|
||||
<h3 className='text-sm font-semibold text-gray-100 mb-2'>
|
||||
Git Status
|
||||
</h3>
|
||||
<div className='flex items-center justify-between mb-4'>
|
||||
<div className='flex items-center'>
|
||||
<GitBranch className='mr-2 text-green-400' size={14} />
|
||||
<span className='text-gray-200 text-sm'>
|
||||
Current Branch: {status.branch}
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={onViewBranches}
|
||||
className='flex items-center px-3 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors duration-200 ease-in-out text-xs'>
|
||||
<Eye size={14} className='mr-2' />
|
||||
View Branches
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{status.incoming_changes.length > 0 && (
|
||||
<ChangeTable
|
||||
|
||||
Reference in New Issue
Block a user