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": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.49.2",
|
"react-hook-form": "^7.49.2",
|
||||||
"react-hot-toast": "^2.4.1",
|
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.20.1",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
@@ -3749,6 +3748,7 @@
|
|||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/d3-color": {
|
"node_modules/d3-color": {
|
||||||
@@ -4682,15 +4682,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"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": {
|
"node_modules/gopd": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
@@ -5706,23 +5697,6 @@
|
|||||||
"react": "^16.8.0 || ^17 || ^18 || ^19"
|
"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": {
|
"node_modules/react-icons": {
|
||||||
"version": "4.12.0",
|
"version": "4.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz",
|
||||||
|
|||||||
@@ -43,7 +43,6 @@
|
|||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.49.2",
|
"react-hook-form": "^7.49.2",
|
||||||
"react-hot-toast": "^2.4.1",
|
|
||||||
"react-icons": "^4.12.0",
|
"react-icons": "^4.12.0",
|
||||||
"react-router-dom": "^6.20.1",
|
"react-router-dom": "^6.20.1",
|
||||||
"sonner": "^2.0.7",
|
"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 { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { endpointsApi, foldersApi, databasesApi, versionsApi, giteaApi } from '@/services/api';
|
import { endpointsApi, foldersApi, databasesApi, versionsApi, giteaApi } from '@/services/api';
|
||||||
import { EndpointParameter, QueryTestResult, LogEntry, QueryExecution, EndpointVersion } from '@/types';
|
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 { toast } from 'sonner';
|
||||||
import SqlEditor from '@/components/SqlEditor';
|
import SqlEditor from '@/components/SqlEditor';
|
||||||
import CodeEditor from '@/components/CodeEditor';
|
import CodeEditor from '@/components/CodeEditor';
|
||||||
@@ -903,35 +903,35 @@ export default function EndpointEditor() {
|
|||||||
{/* Form buttons */}
|
{/* Form buttons */}
|
||||||
<div className="flex gap-3 pt-4 border-t border-gray-200">
|
<div className="flex gap-3 pt-4 border-t border-gray-200">
|
||||||
<div className="flex-1"></div>
|
<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 && (
|
{isEditing && (
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
|
variant="outline"
|
||||||
disabled={draftMutation?.isPending}
|
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()}
|
onClick={() => draftMutation?.mutate()}
|
||||||
>
|
>
|
||||||
{draftMutation?.isPending ? 'Сохранение...' : 'Save Draft'}
|
{draftMutation?.isPending ? 'Сохранение...' : 'Save Draft'}
|
||||||
</button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
<button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
variant="outline"
|
||||||
disabled={saveMutation.isPending}
|
disabled={saveMutation.isPending}
|
||||||
className="btn btn-secondary"
|
|
||||||
onClick={() => setSaveAndStay(true)}
|
onClick={() => setSaveAndStay(true)}
|
||||||
>
|
>
|
||||||
{saveMutation.isPending && saveAndStay ? 'Публикация...' : 'Publish'}
|
{saveMutation.isPending && saveAndStay ? 'Публикация...' : 'Publish'}
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={saveMutation.isPending}
|
disabled={saveMutation.isPending}
|
||||||
className="btn btn-primary"
|
|
||||||
onClick={() => setSaveAndStay(false)}
|
onClick={() => setSaveAndStay(false)}
|
||||||
>
|
>
|
||||||
{saveMutation.isPending && !saveAndStay ? 'Публикация...' : 'Publish & Exit'}
|
{saveMutation.isPending && !saveAndStay ? 'Публикация...' : 'Publish & Exit'}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -941,7 +941,7 @@ export default function EndpointEditor() {
|
|||||||
<div className="flex-[2] min-w-0 space-y-4">
|
<div className="flex-[2] min-w-0 space-y-4">
|
||||||
{/* Test parameters */}
|
{/* Test parameters */}
|
||||||
{formData.parameters.length > 0 && (
|
{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 className="block text-sm font-medium text-gray-700 mb-3">
|
||||||
Тестовые параметры
|
Тестовые параметры
|
||||||
</label>
|
</label>
|
||||||
@@ -956,7 +956,7 @@ export default function EndpointEditor() {
|
|||||||
<select
|
<select
|
||||||
value={testParams[param.name] || ''}
|
value={testParams[param.name] || ''}
|
||||||
onChange={(e) => setTestParams({ ...testParams, [param.name]: e.target.value })}
|
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="">Не задано</option>
|
||||||
<option value="true">true</option>
|
<option value="true">true</option>
|
||||||
@@ -968,7 +968,7 @@ export default function EndpointEditor() {
|
|||||||
placeholder={param.example_value || param.description || `Введите ${param.name}`}
|
placeholder={param.example_value || param.description || `Введите ${param.name}`}
|
||||||
value={testParams[param.name] || ''}
|
value={testParams[param.name] || ''}
|
||||||
onChange={(e) => setTestParams({ ...testParams, [param.name]: e.target.value })}
|
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>
|
</div>
|
||||||
@@ -978,7 +978,7 @@ export default function EndpointEditor() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Environment toggle + Test button */}
|
{/* 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">
|
<div className="flex items-center gap-2">
|
||||||
<span className="text-xs font-medium text-gray-500">Среда:</span>
|
<span className="text-xs font-medium text-gray-500">Среда:</span>
|
||||||
<div className="flex rounded-lg overflow-hidden border border-gray-200">
|
<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>
|
<span className="text-xs text-amber-600">Test env не настроена — fallback на prod</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => testMutation.mutate()}
|
onClick={() => testMutation.mutate()}
|
||||||
disabled={
|
disabled={
|
||||||
@@ -1021,19 +1021,19 @@ export default function EndpointEditor() {
|
|||||||
: !formData.script_code
|
: !formData.script_code
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className={`btn w-full flex items-center justify-center gap-2 ${
|
className={`w-full ${
|
||||||
testEnvironment === 'test'
|
testEnvironment === 'test'
|
||||||
? 'bg-orange-500 hover:bg-orange-600 text-white'
|
? '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})`}
|
{testMutation.isPending ? 'Тестирование...' : `Тест (${testEnvironment})`}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* cURL generator */}
|
{/* 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 justify-between mb-3">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<Terminal size={16} className="text-gray-600" />
|
<Terminal size={16} className="text-gray-600" />
|
||||||
@@ -1054,7 +1054,7 @@ export default function EndpointEditor() {
|
|||||||
placeholder="X-API-Key (необязательно)"
|
placeholder="X-API-Key (необязательно)"
|
||||||
value={curlApiKey}
|
value={curlApiKey}
|
||||||
onChange={(e) => setCurlApiKey(e.target.value)}
|
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>
|
</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">
|
<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 */}
|
{/* Version History */}
|
||||||
{isEditing && (
|
{isEditing && (
|
||||||
<div className="card p-4">
|
<div className="rounded-lg border bg-card shadow-sm p-4">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowVersionHistory(!showVersionHistory)}
|
onClick={() => setShowVersionHistory(!showVersionHistory)}
|
||||||
@@ -1147,7 +1147,7 @@ export default function EndpointEditor() {
|
|||||||
|
|
||||||
{/* Test results */}
|
{/* Test results */}
|
||||||
{testResult && (
|
{testResult && (
|
||||||
<div className="card overflow-hidden">
|
<div className="rounded-lg border bg-card shadow-sm overflow-hidden">
|
||||||
{/* Status bar */}
|
{/* 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 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">
|
<div className="flex items-center gap-2">
|
||||||
@@ -1360,7 +1360,7 @@ export default function EndpointEditor() {
|
|||||||
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], name: e.target.value };
|
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], name: e.target.value };
|
||||||
setFormData({ ...formData, script_queries: newQueries });
|
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>
|
||||||
<div>
|
<div>
|
||||||
@@ -1373,7 +1373,7 @@ export default function EndpointEditor() {
|
|||||||
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], database_id: e.target.value };
|
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], database_id: e.target.value };
|
||||||
setFormData({ ...formData, script_queries: newQueries });
|
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>
|
<option value="">Выберите базу данных</option>
|
||||||
{databases?.map((db) => (
|
{databases?.map((db) => (
|
||||||
@@ -1397,7 +1397,7 @@ export default function EndpointEditor() {
|
|||||||
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], aql_method: e.target.value as any };
|
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], aql_method: e.target.value as any };
|
||||||
setFormData({ ...formData, script_queries: newQueries });
|
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="GET">GET</option>
|
||||||
<option value="POST">POST</option>
|
<option value="POST">POST</option>
|
||||||
@@ -1419,7 +1419,7 @@ export default function EndpointEditor() {
|
|||||||
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], aql_endpoint: e.target.value };
|
newQueries[editingQueryIndex] = { ...newQueries[editingQueryIndex], aql_endpoint: e.target.value };
|
||||||
setFormData({ ...formData, script_queries: newQueries });
|
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"
|
placeholder="/query"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -1478,20 +1478,12 @@ export default function EndpointEditor() {
|
|||||||
})()}
|
})()}
|
||||||
</div>
|
</div>
|
||||||
<div className="p-6 border-t border-gray-200 flex gap-3">
|
<div className="p-6 border-t border-gray-200 flex gap-3">
|
||||||
<button
|
<Button type="button" onClick={() => setEditingQueryIndex(null)}>
|
||||||
type="button"
|
|
||||||
onClick={() => setEditingQueryIndex(null)}
|
|
||||||
className="btn btn-primary"
|
|
||||||
>
|
|
||||||
Сохранить
|
Сохранить
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button type="button" variant="outline" onClick={() => setEditingQueryIndex(null)}>
|
||||||
type="button"
|
|
||||||
onClick={() => setEditingQueryIndex(null)}
|
|
||||||
className="btn btn-secondary"
|
|
||||||
>
|
|
||||||
Закрыть
|
Закрыть
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1527,20 +1519,12 @@ export default function EndpointEditor() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-6 border-t border-gray-200 flex gap-3">
|
<div className="p-6 border-t border-gray-200 flex gap-3">
|
||||||
<button
|
<Button type="button" onClick={() => setShowScriptCodeEditor(false)}>
|
||||||
type="button"
|
|
||||||
onClick={() => setShowScriptCodeEditor(false)}
|
|
||||||
className="btn btn-primary"
|
|
||||||
>
|
|
||||||
Сохранить
|
Сохранить
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button type="button" variant="outline" onClick={() => setShowScriptCodeEditor(false)}>
|
||||||
type="button"
|
|
||||||
onClick={() => setShowScriptCodeEditor(false)}
|
|
||||||
className="btn btn-secondary"
|
|
||||||
>
|
|
||||||
Закрыть
|
Закрыть
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1586,7 +1570,7 @@ function FolderSelector({ value, onChange }: { value: string; onChange: (value:
|
|||||||
const folderList = buildFolderList();
|
const folderList = buildFolderList();
|
||||||
|
|
||||||
return (
|
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>
|
<option value="">Без папки</option>
|
||||||
{folderList.map((folder) => (
|
{folderList.map((folder) => (
|
||||||
<option key={folder.id} value={folder.id}>
|
<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