mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-29 06:35:24 +00:00
feat: point core frontend snippets pickers at the plugin (B2)
This commit is contained in:
1 parent
e07221eaf3
commit
1eac0f54b0
22 files changed
+170
-2968
No files matched your search
@@ -195,7 +195,7 @@ export async function adminGetUserSnippets(
|
||||
targetUserId: string,
|
||||
): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.get("/snippets", {
|
||||
const response = await authApi.get("/plugin-api/snippets", {
|
||||
headers: adminHeaders(targetUserId),
|
||||
});
|
||||
return response.data;
|
||||
@@ -209,7 +209,7 @@ export async function adminCreateUserSnippet(
|
||||
snippetData: Record<string, unknown>,
|
||||
): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.post("/snippets", snippetData, {
|
||||
const response = await authApi.post("/plugin-api/snippets", snippetData, {
|
||||
headers: adminHeaders(targetUserId),
|
||||
});
|
||||
return response.data;
|
||||
@@ -224,9 +224,13 @@ export async function adminUpdateUserSnippet(
|
||||
snippetData: Record<string, unknown>,
|
||||
): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.put(`/snippets/${snippetId}`, snippetData, {
|
||||
headers: adminHeaders(targetUserId),
|
||||
});
|
||||
const response = await authApi.put(
|
||||
`/plugin-api/snippets/${snippetId}`,
|
||||
snippetData,
|
||||
{
|
||||
headers: adminHeaders(targetUserId),
|
||||
},
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "update user's snippet");
|
||||
@@ -238,7 +242,7 @@ export async function adminDeleteUserSnippet(
|
||||
snippetId: number,
|
||||
): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.delete(`/snippets/${snippetId}`, {
|
||||
const response = await authApi.delete(`/plugin-api/snippets/${snippetId}`, {
|
||||
headers: adminHeaders(targetUserId),
|
||||
});
|
||||
return response.data;
|
||||
|
||||
@@ -115,7 +115,6 @@ export interface UserPreferences {
|
||||
pinAppRail?: boolean | null;
|
||||
expandAppRailOnHover?: boolean | null;
|
||||
showPinAppRailButton?: boolean | null;
|
||||
foldersCollapsed?: boolean | null;
|
||||
confirmSnippetExecution?: boolean | null;
|
||||
disableUpdateCheck?: boolean | null;
|
||||
confirmTabClose?: boolean | null;
|
||||
|
||||
@@ -397,47 +397,6 @@ export async function setHostAuthOverride(
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// SNIPPET SHARING
|
||||
// ============================================================================
|
||||
|
||||
export async function shareSnippet(
|
||||
snippetId: number,
|
||||
shareData: {
|
||||
targetType: "user" | "role";
|
||||
targetUserId?: string;
|
||||
targetRoleId?: number;
|
||||
durationHours?: number;
|
||||
},
|
||||
): Promise<{ success: boolean }> {
|
||||
try {
|
||||
const response = await rbacApi.post(
|
||||
`/rbac/snippet/${snippetId}/share`,
|
||||
shareData,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "share snippet");
|
||||
}
|
||||
}
|
||||
|
||||
export async function shareSnippetFolder(
|
||||
folder: string,
|
||||
targets: ShareTarget[],
|
||||
durationHours?: number,
|
||||
): Promise<{ success: boolean; snippetsShared: number }> {
|
||||
try {
|
||||
const response = await rbacApi.post("/rbac/snippet-folder/share", {
|
||||
folder,
|
||||
targets,
|
||||
durationHours,
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "share snippet folder");
|
||||
}
|
||||
}
|
||||
|
||||
export type CredentialPermissionLevel = "use" | "manage";
|
||||
|
||||
export async function shareCredential(
|
||||
@@ -480,48 +439,3 @@ export async function revokeCredentialAccess(
|
||||
throw handleApiError(error, "revoke credential access");
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSnippetAccess(
|
||||
snippetId: number,
|
||||
): Promise<{ accessList: AccessRecord[] }> {
|
||||
try {
|
||||
const response = await rbacApi.get(`/rbac/snippet/${snippetId}/access`);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "fetch snippet access");
|
||||
}
|
||||
}
|
||||
|
||||
export async function revokeSnippetAccess(
|
||||
snippetId: number,
|
||||
accessId: number,
|
||||
): Promise<{ success: boolean }> {
|
||||
try {
|
||||
const response = await rbacApi.delete(
|
||||
`/rbac/snippet/${snippetId}/access/${accessId}`,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "revoke snippet access");
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSharedSnippets(): Promise<{
|
||||
sharedSnippets: Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
content: string;
|
||||
description: string | null;
|
||||
folder: string | null;
|
||||
ownerUsername: string;
|
||||
permissionLevel: string;
|
||||
expiresAt: string | null;
|
||||
}>;
|
||||
}> {
|
||||
try {
|
||||
const response = await rbacApi.get("/rbac/shared-snippets");
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
handleApiError(error, "fetch shared snippets");
|
||||
}
|
||||
}
|
||||
+8
-163
@@ -3,6 +3,12 @@ import { authApi, handleApiError } from "@/main-axios";
|
||||
/**
|
||||
* A snippet row as the list endpoint returns it. Callers that need the full
|
||||
* shape narrow it themselves; only the id is relied on across the app.
|
||||
*
|
||||
* Snippets themselves are owned by the snippets plugin
|
||||
* (/plugin-api/snippets); this is the thin read/run surface used by a few
|
||||
* core and plugin callers (the host editor's startup snippet, the command
|
||||
* palette, custom keybindings, host-metrics quick actions) that cannot
|
||||
* reach into the snippets plugin's own frontend code.
|
||||
*/
|
||||
export interface SnippetRow {
|
||||
id: number;
|
||||
@@ -11,54 +17,20 @@ export interface SnippetRow {
|
||||
|
||||
export async function getSnippets(): Promise<SnippetRow[]> {
|
||||
try {
|
||||
const response = await authApi.get("/snippets");
|
||||
const response = await authApi.get("/plugin-api/snippets");
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "fetch snippets");
|
||||
}
|
||||
}
|
||||
|
||||
export async function createSnippet(
|
||||
snippetData: Record<string, unknown>,
|
||||
): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.post("/snippets", snippetData);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "create snippet");
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateSnippet(
|
||||
snippetId: number,
|
||||
snippetData: Record<string, unknown>,
|
||||
): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.put(`/snippets/${snippetId}`, snippetData);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "update snippet");
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteSnippet(
|
||||
snippetId: number,
|
||||
): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.delete(`/snippets/${snippetId}`);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "delete snippet");
|
||||
}
|
||||
}
|
||||
|
||||
export async function executeSnippet(
|
||||
snippetId: number,
|
||||
hostId: number,
|
||||
inputValues?: Record<string, string>,
|
||||
): Promise<{ success: boolean; output: string; error?: string }> {
|
||||
try {
|
||||
const response = await authApi.post("/snippets/execute", {
|
||||
const response = await authApi.post("/plugin-api/snippets/execute", {
|
||||
snippetId,
|
||||
hostId,
|
||||
...(inputValues ? { inputValues } : {}),
|
||||
@@ -68,130 +40,3 @@ export async function executeSnippet(
|
||||
throw handleApiError(error, "execute snippet");
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSnippetFolders(): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.get("/snippets/folders");
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "fetch snippet folders");
|
||||
}
|
||||
}
|
||||
|
||||
export async function createSnippetFolder(folderData: {
|
||||
name: string;
|
||||
color?: string;
|
||||
icon?: string;
|
||||
}): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.post("/snippets/folders", folderData);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "create snippet folder");
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateSnippetFolderMetadata(
|
||||
folderName: string,
|
||||
metadata: { color?: string; icon?: string },
|
||||
): Promise<Record<string, unknown>> {
|
||||
try {
|
||||
const response = await authApi.put(
|
||||
`/snippets/folders/${encodeURIComponent(folderName)}/metadata`,
|
||||
metadata,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "update snippet folder metadata");
|
||||
}
|
||||
}
|
||||
|
||||
export async function renameSnippetFolder(
|
||||
oldName: string,
|
||||
newName: string,
|
||||
): Promise<{ success: boolean; oldName: string; newName: string }> {
|
||||
try {
|
||||
const response = await authApi.put("/snippets/folders/rename", {
|
||||
oldName,
|
||||
newName,
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "rename snippet folder");
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteSnippetFolder(
|
||||
folderName: string,
|
||||
): Promise<{ success: boolean }> {
|
||||
try {
|
||||
const response = await authApi.delete(
|
||||
`/snippets/folders/${encodeURIComponent(folderName)}`,
|
||||
);
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "delete snippet folder");
|
||||
}
|
||||
}
|
||||
|
||||
export async function reorderSnippets(
|
||||
updates: Array<{ id: number; order: number; folder?: string }>,
|
||||
): Promise<{ success: boolean }> {
|
||||
try {
|
||||
const response = await authApi.put("/snippets/reorder", {
|
||||
snippets: updates,
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "reorder snippets");
|
||||
}
|
||||
}
|
||||
|
||||
export interface SnippetExportData {
|
||||
snippets: Array<{
|
||||
name: string;
|
||||
content: string;
|
||||
description?: string | null;
|
||||
folder?: string | null;
|
||||
order?: number;
|
||||
hostFilter?: string | null;
|
||||
}>;
|
||||
folders: Array<{
|
||||
name: string;
|
||||
color?: string | null;
|
||||
icon?: string | null;
|
||||
}>;
|
||||
}
|
||||
|
||||
export async function exportSnippets(): Promise<SnippetExportData> {
|
||||
try {
|
||||
const response = await authApi.get("/snippets/export");
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "export snippets");
|
||||
}
|
||||
}
|
||||
|
||||
export async function importSnippets(
|
||||
data: SnippetExportData,
|
||||
overwrite: boolean,
|
||||
): Promise<{
|
||||
success: boolean;
|
||||
snippetsImported: number;
|
||||
snippetsSkipped: number;
|
||||
snippetsUpdated: number;
|
||||
foldersImported: number;
|
||||
foldersSkipped: number;
|
||||
failed: number;
|
||||
errors: string[];
|
||||
}> {
|
||||
try {
|
||||
const response = await authApi.post("/snippets/bulk-import", {
|
||||
...data,
|
||||
overwrite,
|
||||
});
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
throw handleApiError(error, "import snippets");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user