Работает создание коммитов и перенос в новый enviroment
This commit is contained in:
325
frontend/src/services/gitService.js
Normal file
325
frontend/src/services/gitService.js
Normal file
@@ -0,0 +1,325 @@
|
||||
/**
|
||||
* [DEF:GitServiceClient:Module]
|
||||
* @SEMANTICS: git, service, api, client
|
||||
* @PURPOSE: API client for Git operations, managing the communication between frontend and backend.
|
||||
* @LAYER: Service
|
||||
* @RELATION: DEPENDS_ON -> specs/011-git-integration-dashboard/contracts/api.md
|
||||
*/
|
||||
|
||||
const API_BASE = '/api/git';
|
||||
|
||||
// [DEF:gitService:Action]
|
||||
export const gitService = {
|
||||
/**
|
||||
* [DEF:getConfigs:Function]
|
||||
* @purpose Fetches all Git server configurations.
|
||||
* @pre User must be authenticated.
|
||||
* @post Returns a list of Git server configurations.
|
||||
* @returns {Promise<Array>} List of configs.
|
||||
*/
|
||||
async getConfigs() {
|
||||
console.log('[getConfigs][Action] Fetching Git configs');
|
||||
const response = await fetch(`${API_BASE}/config`);
|
||||
if (!response.ok) throw new Error('Failed to fetch Git configs');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:createConfig:Function]
|
||||
* @purpose Creates a new Git server configuration.
|
||||
* @pre Config object must be valid.
|
||||
* @post New config is created and returned.
|
||||
* @param {Object} config - Configuration details.
|
||||
* @returns {Promise<Object>} Created config.
|
||||
*/
|
||||
async createConfig(config) {
|
||||
console.log('[createConfig][Action] Creating Git config');
|
||||
const response = await fetch(`${API_BASE}/config`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(config)
|
||||
});
|
||||
if (!response.ok) throw new Error('Failed to create Git config');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:deleteConfig:Function]
|
||||
* @purpose Deletes an existing Git server configuration.
|
||||
* @pre configId must exist.
|
||||
* @post Config is deleted from the backend.
|
||||
* @param {string} configId - ID of the config to delete.
|
||||
* @returns {Promise<Object>} Result of deletion.
|
||||
*/
|
||||
async deleteConfig(configId) {
|
||||
console.log(`[deleteConfig][Action] Deleting Git config ${configId}`);
|
||||
const response = await fetch(`${API_BASE}/config/${configId}`, {
|
||||
method: 'DELETE'
|
||||
});
|
||||
if (!response.ok) throw new Error('Failed to delete Git config');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:testConnection:Function]
|
||||
* @purpose Tests the connection to a Git server with provided credentials.
|
||||
* @pre Config must contain valid URL and PAT.
|
||||
* @post Returns connection status (success/failure).
|
||||
* @param {Object} config - Configuration to test.
|
||||
* @returns {Promise<Object>} Connection test result.
|
||||
*/
|
||||
async testConnection(config) {
|
||||
console.log('[testConnection][Action] Testing Git connection');
|
||||
const response = await fetch(`${API_BASE}/config/test`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(config)
|
||||
});
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:initRepository:Function]
|
||||
* @purpose Initializes or clones a Git repository for a dashboard.
|
||||
* @pre Dashboard must exist and config_id must be valid.
|
||||
* @post Repository is initialized on the backend.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @param {string} configId - ID of the Git config.
|
||||
* @param {string} remoteUrl - URL of the remote repository.
|
||||
* @returns {Promise<Object>} Initialization result.
|
||||
*/
|
||||
async initRepository(dashboardId, configId, remoteUrl) {
|
||||
console.log(`[initRepository][Action] Initializing repo for dashboard ${dashboardId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/init`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ config_id: configId, remote_url: remoteUrl })
|
||||
});
|
||||
if (!response.ok) {
|
||||
const err = await response.json();
|
||||
throw new Error(err.detail || 'Failed to initialize repository');
|
||||
}
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:getBranches:Function]
|
||||
* @purpose Retrieves the list of branches for a dashboard's repository.
|
||||
* @pre Repository must be initialized.
|
||||
* @post Returns a list of branches.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @returns {Promise<Array>} List of branches.
|
||||
*/
|
||||
async getBranches(dashboardId) {
|
||||
console.log(`[getBranches][Action] Fetching branches for dashboard ${dashboardId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/branches`);
|
||||
if (!response.ok) throw new Error('Failed to fetch branches');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:createBranch:Function]
|
||||
* @purpose Creates a new branch in the dashboard's repository.
|
||||
* @pre Source branch must exist.
|
||||
* @post New branch is created.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @param {string} name - New branch name.
|
||||
* @param {string} fromBranch - Source branch name.
|
||||
* @returns {Promise<Object>} Creation result.
|
||||
*/
|
||||
async createBranch(dashboardId, name, fromBranch) {
|
||||
console.log(`[createBranch][Action] Creating branch ${name} for dashboard ${dashboardId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/branches`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name, from_branch: fromBranch })
|
||||
});
|
||||
if (!response.ok) throw new Error('Failed to create branch');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:checkoutBranch:Function]
|
||||
* @purpose Switches the repository to a different branch.
|
||||
* @pre Target branch must exist.
|
||||
* @post Repository head is moved to the target branch.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @param {string} name - Branch name to checkout.
|
||||
* @returns {Promise<Object>} Checkout result.
|
||||
*/
|
||||
async checkoutBranch(dashboardId, name) {
|
||||
console.log(`[checkoutBranch][Action] Checking out branch ${name} for dashboard ${dashboardId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/checkout`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name })
|
||||
});
|
||||
if (!response.ok) throw new Error('Failed to checkout branch');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:commit:Function]
|
||||
* @purpose Stages and commits changes to the repository.
|
||||
* @pre Message must not be empty.
|
||||
* @post Changes are committed to the current branch.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @param {string} message - Commit message.
|
||||
* @param {Array} files - Optional list of files to commit.
|
||||
* @returns {Promise<Object>} Commit result.
|
||||
*/
|
||||
async commit(dashboardId, message, files) {
|
||||
console.log(`[commit][Action] Committing changes for dashboard ${dashboardId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/commit`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ message, files })
|
||||
});
|
||||
if (!response.ok) throw new Error('Failed to commit changes');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:push:Function]
|
||||
* @purpose Pushes local commits to the remote repository.
|
||||
* @pre Remote must be configured and accessible.
|
||||
* @post Remote is updated with local commits.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @returns {Promise<Object>} Push result.
|
||||
*/
|
||||
async push(dashboardId) {
|
||||
console.log(`[push][Action] Pushing changes for dashboard ${dashboardId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/push`, {
|
||||
method: 'POST'
|
||||
});
|
||||
if (!response.ok) throw new Error('Failed to push changes');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:pull:Function]
|
||||
* @purpose Pulls changes from the remote repository.
|
||||
* @pre Remote must be configured and accessible.
|
||||
* @post Local repository is updated with remote changes.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @returns {Promise<Object>} Pull result.
|
||||
*/
|
||||
async pull(dashboardId) {
|
||||
console.log(`[pull][Action] Pulling changes for dashboard ${dashboardId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/pull`, {
|
||||
method: 'POST'
|
||||
});
|
||||
if (!response.ok) throw new Error('Failed to pull changes');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:getEnvironments:Function]
|
||||
* @purpose Retrieves available deployment environments.
|
||||
* @post Returns a list of environments.
|
||||
* @returns {Promise<Array>} List of environments.
|
||||
*/
|
||||
async getEnvironments() {
|
||||
console.log('[getEnvironments][Action] Fetching environments');
|
||||
const response = await fetch(`${API_BASE}/environments`);
|
||||
if (!response.ok) throw new Error('Failed to fetch environments');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:deploy:Function]
|
||||
* @purpose Deploys a dashboard to a target environment.
|
||||
* @pre Environment must be active and accessible.
|
||||
* @post Dashboard is imported into the target Superset instance.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @param {string} environmentId - ID of the target environment.
|
||||
* @returns {Promise<Object>} Deployment result.
|
||||
*/
|
||||
async deploy(dashboardId, environmentId) {
|
||||
console.log(`[deploy][Action] Deploying dashboard ${dashboardId} to environment ${environmentId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/deploy`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ environment_id: environmentId })
|
||||
});
|
||||
if (!response.ok) throw new Error('Failed to deploy dashboard');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:getHistory:Function]
|
||||
* @purpose Retrieves the commit history for a dashboard.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @param {number} limit - Maximum number of commits to return.
|
||||
* @returns {Promise<Array>} List of commits.
|
||||
*/
|
||||
async getHistory(dashboardId, limit = 50) {
|
||||
console.log(`[getHistory][Action] Fetching history for dashboard ${dashboardId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/history?limit=${limit}`);
|
||||
if (!response.ok) throw new Error('Failed to fetch commit history');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:sync:Function]
|
||||
* @purpose Synchronizes the local dashboard state with the Git repository.
|
||||
* @param {number} dashboardId - ID of the dashboard.
|
||||
* @param {string|null} sourceEnvId - Optional source environment ID.
|
||||
* @returns {Promise<Object>} Sync result.
|
||||
*/
|
||||
async sync(dashboardId, sourceEnvId = null) {
|
||||
console.log(`[sync][Action] Syncing dashboard ${dashboardId}`);
|
||||
const url = new URL(`${window.location.origin}${API_BASE}/repositories/${dashboardId}/sync`);
|
||||
if (sourceEnvId) url.searchParams.append('source_env_id', sourceEnvId);
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST'
|
||||
});
|
||||
if (!response.ok) {
|
||||
const err = await response.json();
|
||||
throw new Error(err.detail || 'Failed to sync dashboard');
|
||||
}
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:getStatus:Function]
|
||||
* @purpose Fetches the current Git status for a dashboard repository.
|
||||
* @pre dashboardId must be a valid integer.
|
||||
* @post Returns a status object with dirty files and branch info.
|
||||
* @param {number} dashboardId - The ID of the dashboard.
|
||||
* @returns {Promise<Object>} Status details.
|
||||
*/
|
||||
async getStatus(dashboardId) {
|
||||
console.log(`[getStatus][Action] Fetching status for dashboard ${dashboardId}`);
|
||||
const response = await fetch(`${API_BASE}/repositories/${dashboardId}/status`);
|
||||
if (!response.ok) throw new Error('Failed to fetch status');
|
||||
return response.json();
|
||||
},
|
||||
|
||||
/**
|
||||
* [DEF:getDiff:Function]
|
||||
* @purpose Retrieves the diff for specific files or the whole repository.
|
||||
* @pre dashboardId must be a valid integer.
|
||||
* @post Returns the Git diff string.
|
||||
* @param {number} dashboardId - The ID of the dashboard.
|
||||
* @param {string|null} filePath - Optional specific file path.
|
||||
* @param {boolean} staged - Whether to show staged changes.
|
||||
* @returns {Promise<string>} The diff content.
|
||||
*/
|
||||
async getDiff(dashboardId, filePath = null, staged = false) {
|
||||
console.log(`[getDiff][Action] Fetching diff for dashboard ${dashboardId} (file: ${filePath}, staged: ${staged})`);
|
||||
let url = `${API_BASE}/repositories/${dashboardId}/diff`;
|
||||
const params = new URLSearchParams();
|
||||
if (filePath) params.append('file_path', filePath);
|
||||
if (staged) params.append('staged', 'true');
|
||||
if (params.toString()) url += `?${params.toString()}`;
|
||||
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error('Failed to fetch diff');
|
||||
return response.json();
|
||||
}
|
||||
};
|
||||
// [/DEF:gitService:Action]
|
||||
|
||||
// [/DEF:GitServiceClient:Module]
|
||||
Reference in New Issue
Block a user