Fix unused GitBranch import + minor cleanup
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
28
frontend/package-lock.json
generated
28
frontend/package-lock.json
generated
@@ -37,7 +37,6 @@
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.49.2",
|
||||
"react-hot-toast": "^2.4.1",
|
||||
"react-icons": "^4.12.0",
|
||||
"react-router-dom": "^6.20.1",
|
||||
"sonner": "^2.0.7",
|
||||
@@ -3749,6 +3748,7 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/d3-color": {
|
||||
@@ -4682,15 +4682,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/goober": {
|
||||
"version": "2.1.18",
|
||||
"resolved": "https://registry.npmjs.org/goober/-/goober-2.1.18.tgz",
|
||||
"integrity": "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"csstype": "^3.0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
@@ -5706,23 +5697,6 @@
|
||||
"react": "^16.8.0 || ^17 || ^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/react-hot-toast": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.6.0.tgz",
|
||||
"integrity": "sha512-bH+2EBMZ4sdyou/DPrfgIouFpcRLCJ+HoCA32UoAYHn6T3Ur5yfcDCeSr5mwldl6pFOsiocmrXMuoCJ1vV8bWg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"csstype": "^3.1.3",
|
||||
"goober": "^2.1.16"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=16",
|
||||
"react-dom": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/react-icons": {
|
||||
"version": "4.12.0",
|
||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz",
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.49.2",
|
||||
"react-hot-toast": "^2.4.1",
|
||||
"react-icons": "^4.12.0",
|
||||
"react-router-dom": "^6.20.1",
|
||||
"sonner": "^2.0.7",
|
||||
|
||||
@@ -57,28 +57,3 @@
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.btn {
|
||||
@apply px-4 py-2 rounded-lg font-medium transition-all duration-200;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
@apply bg-primary-600 text-white hover:bg-primary-700 active:bg-primary-800;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply bg-gray-200 text-gray-800 hover:bg-gray-300 active:bg-gray-400;
|
||||
}
|
||||
|
||||
.btn-danger {
|
||||
@apply bg-red-600 text-white hover:bg-red-700 active:bg-red-800;
|
||||
}
|
||||
|
||||
.input-custom {
|
||||
@apply px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-500 focus:border-transparent;
|
||||
}
|
||||
|
||||
.card-custom {
|
||||
@apply bg-white rounded-lg shadow-sm border border-gray-200;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useParams, useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { endpointsApi, foldersApi, databasesApi, versionsApi, giteaApi } from '@/services/api';
|
||||
import { EndpointParameter, QueryTestResult, LogEntry, QueryExecution, EndpointVersion } from '@/types';
|
||||
import { Plus, Trash2, Play, Edit2, ChevronDown, ChevronUp, ArrowLeft, CheckCircle, XCircle, Clock, Copy, X, Terminal, History, RotateCcw, Upload, GitBranch } from 'lucide-react';
|
||||
import { Plus, Trash2, Play, Edit2, ChevronDown, ChevronUp, ArrowLeft, CheckCircle, XCircle, Clock, Copy, X, Terminal, History, RotateCcw, Upload } from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
import SqlEditor from '@/components/SqlEditor';
|
||||
import CodeEditor from '@/components/CodeEditor';
|
||||
@@ -903,35 +903,35 @@ export default function EndpointEditor() {
|
||||
{/* Form buttons */}
|
||||
<div className="flex gap-3 pt-4 border-t border-gray-200">
|
||||
<div className="flex-1"></div>
|
||||
<button type="button" onClick={() => navigate(-1)} className="btn btn-secondary">
|
||||
<Button type="button" variant="outline" onClick={() => navigate(-1)}>
|
||||
Отмена
|
||||
</button>
|
||||
</Button>
|
||||
{isEditing && (
|
||||
<button
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
disabled={draftMutation?.isPending}
|
||||
className="btn bg-orange-50 text-orange-700 border border-orange-200 hover:bg-orange-100"
|
||||
className="bg-orange-50 text-orange-700 border-orange-200 hover:bg-orange-100"
|
||||
onClick={() => draftMutation?.mutate()}
|
||||
>
|
||||
{draftMutation?.isPending ? 'Сохранение...' : 'Save Draft'}
|
||||
</button>
|
||||
</Button>
|
||||
)}
|
||||
<button
|
||||
<Button
|
||||
type="submit"
|
||||
variant="outline"
|
||||
disabled={saveMutation.isPending}
|
||||
className="btn btn-secondary"
|
||||
onClick={() => setSaveAndStay(true)}
|
||||
>
|
||||
{saveMutation.isPending && saveAndStay ? 'Публикация...' : 'Publish'}
|
||||
</button>
|
||||
<button
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={saveMutation.isPending}
|
||||
className="btn btn-primary"
|
||||
onClick={() => setSaveAndStay(false)}
|
||||
>
|
||||
{saveMutation.isPending && !saveAndStay ? 'Публикация...' : 'Publish & Exit'}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
@@ -941,7 +941,7 @@ export default function EndpointEditor() {
|
||||
<div className="flex-[2] min-w-0 space-y-4">
|
||||
{/* Test parameters */}
|
||||
{formData.parameters.length > 0 && (
|
||||
<div className="card p-4">
|
||||
<div className="rounded-lg border bg-card shadow-sm p-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-3">
|
||||
Тестовые параметры
|
||||
</label>
|
||||
@@ -956,7 +956,7 @@ export default function EndpointEditor() {
|
||||
<select
|
||||
value={testParams[param.name] || ''}
|
||||
onChange={(e) => setTestParams({ ...testParams, [param.name]: e.target.value })}
|
||||
className="input w-full text-sm"
|
||||
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
>
|
||||
<option value="">Не задано</option>
|
||||
<option value="true">true</option>
|
||||
@@ -968,7 +968,7 @@ export default function EndpointEditor() {
|
||||
placeholder={param.example_value || param.description || `Введите ${param.name}`}
|
||||
value={testParams[param.name] || ''}
|
||||
onChange={(e) => setTestParams({ ...testParams, [param.name]: e.target.value })}
|
||||
className="input w-full text-sm"
|
||||
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -978,7 +978,7 @@ export default function EndpointEditor() {
|
||||
)}
|
||||
|
||||
{/* Environment toggle + Test button */}
|
||||
<div className="card p-4 space-y-3">
|
||||
<div className="rounded-lg border bg-card shadow-sm p-4 space-y-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="text-xs font-medium text-gray-500">Среда:</span>
|
||||
<div className="flex rounded-lg overflow-hidden border border-gray-200">
|
||||
@@ -1009,7 +1009,7 @@ export default function EndpointEditor() {
|
||||
<span className="text-xs text-amber-600">Test env не настроена — fallback на prod</span>
|
||||
)}
|
||||
</div>
|
||||
<button
|
||||
<Button
|
||||
type="button"
|
||||
onClick={() => testMutation.mutate()}
|
||||
disabled={
|
||||
@@ -1021,19 +1021,19 @@ export default function EndpointEditor() {
|
||||
: !formData.script_code
|
||||
)
|
||||
}
|
||||
className={`btn w-full flex items-center justify-center gap-2 ${
|
||||
className={`w-full ${
|
||||
testEnvironment === 'test'
|
||||
? 'bg-orange-500 hover:bg-orange-600 text-white'
|
||||
: 'btn-primary'
|
||||
: ''
|
||||
}`}
|
||||
>
|
||||
<Play size={18} />
|
||||
<Play className="mr-2 h-4 w-4" />
|
||||
{testMutation.isPending ? 'Тестирование...' : `Тест (${testEnvironment})`}
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* cURL generator */}
|
||||
<div className="card p-4">
|
||||
<div className="rounded-lg border bg-card shadow-sm p-4">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<Terminal size={16} className="text-gray-600" />
|
||||
@@ -1054,7 +1054,7 @@ export default function EndpointEditor() {
|
||||
placeholder="X-API-Key (необязательно)"
|
||||
value={curlApiKey}
|
||||
onChange={(e) => setCurlApiKey(e.target.value)}
|
||||
className="input w-full text-sm"
|
||||
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
/>
|
||||
</div>
|
||||
<pre className="text-xs font-mono bg-gray-900 text-green-400 p-3 rounded-lg overflow-x-auto whitespace-pre-wrap max-h-48">
|
||||
@@ -1064,7 +1064,7 @@ export default function EndpointEditor() {
|
||||
|
||||
{/* Version History */}
|
||||
{isEditing && (
|
||||
<div className="card p-4">
|
||||
<div className="rounded-lg border bg-card shadow-sm p-4">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowVersionHistory(!showVersionHistory)}
|
||||
@@ -1147,7 +1147,7 @@ export default function EndpointEditor() {
|
||||
|
||||
{/* Test results */}
|
||||
{testResult && (
|
||||
<div className="card overflow-hidden">
|
||||
<div className="rounded-lg border bg-card shadow-sm overflow-hidden">
|
||||
{/* Status bar */}
|
||||
<div className={`flex items-center justify-between px-4 py-2 ${testResult.success ? 'bg-green-50 border-b border-green-200' : 'bg-red-50 border-b border-red-200'}`}>
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -1360,7 +1360,7 @@ export default function EndpointEditor() {
|
||||
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], name: e.target.value };
|
||||
setFormData({ ...formData, script_queries: newQueries });
|
||||
}}
|
||||
className="input w-full"
|
||||
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -1373,7 +1373,7 @@ export default function EndpointEditor() {
|
||||
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], database_id: e.target.value };
|
||||
setFormData({ ...formData, script_queries: newQueries });
|
||||
}}
|
||||
className="input w-full"
|
||||
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
>
|
||||
<option value="">Выберите базу данных</option>
|
||||
{databases?.map((db) => (
|
||||
@@ -1397,7 +1397,7 @@ export default function EndpointEditor() {
|
||||
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], aql_method: e.target.value as any };
|
||||
setFormData({ ...formData, script_queries: newQueries });
|
||||
}}
|
||||
className="input w-full"
|
||||
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
>
|
||||
<option value="GET">GET</option>
|
||||
<option value="POST">POST</option>
|
||||
@@ -1419,7 +1419,7 @@ export default function EndpointEditor() {
|
||||
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], aql_endpoint: e.target.value };
|
||||
setFormData({ ...formData, script_queries: newQueries });
|
||||
}}
|
||||
className="input w-full"
|
||||
className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||
placeholder="/query"
|
||||
/>
|
||||
</div>
|
||||
@@ -1478,20 +1478,12 @@ export default function EndpointEditor() {
|
||||
})()}
|
||||
</div>
|
||||
<div className="p-6 border-t border-gray-200 flex gap-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setEditingQueryIndex(null)}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
<Button type="button" onClick={() => setEditingQueryIndex(null)}>
|
||||
Сохранить
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setEditingQueryIndex(null)}
|
||||
className="btn btn-secondary"
|
||||
>
|
||||
</Button>
|
||||
<Button type="button" variant="outline" onClick={() => setEditingQueryIndex(null)}>
|
||||
Закрыть
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1527,20 +1519,12 @@ export default function EndpointEditor() {
|
||||
/>
|
||||
</div>
|
||||
<div className="p-6 border-t border-gray-200 flex gap-3">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowScriptCodeEditor(false)}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
<Button type="button" onClick={() => setShowScriptCodeEditor(false)}>
|
||||
Сохранить
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowScriptCodeEditor(false)}
|
||||
className="btn btn-secondary"
|
||||
>
|
||||
</Button>
|
||||
<Button type="button" variant="outline" onClick={() => setShowScriptCodeEditor(false)}>
|
||||
Закрыть
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1586,7 +1570,7 @@ function FolderSelector({ value, onChange }: { value: string; onChange: (value:
|
||||
const folderList = buildFolderList();
|
||||
|
||||
return (
|
||||
<select value={value} onChange={(e) => onChange(e.target.value)} className="input w-full">
|
||||
<select value={value} onChange={(e) => onChange(e.target.value)} className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring">
|
||||
<option value="">Без папки</option>
|
||||
{folderList.map((folder) => (
|
||||
<option key={folder.id} value={folder.id}>
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import { type ClassValue, clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
Reference in New Issue
Block a user