project map script | semantic parcer

This commit is contained in:
2026-01-01 16:58:21 +03:00
parent a747a163c8
commit 4c6fc8256d
84 changed files with 10178 additions and 537 deletions

View File

@@ -39,7 +39,7 @@
console.error(`[App.handleFormSubmit][Coherence:Failed] Task creation failed error=${error}`);
}
}
// [/DEF:handleFormSubmit]
// [/DEF:handleFormSubmit:Function]
// [DEF:navigate:Function]
/**
@@ -56,7 +56,7 @@
// Then set page
currentPage.set(page);
}
// [/DEF:navigate]
// [/DEF:navigate:Function]
</script>
<!-- [SECTION: TEMPLATE] -->
@@ -110,4 +110,4 @@
</main>
<!-- [/SECTION] -->
<!-- [/DEF:App] -->
<!-- [/DEF:App:Component] -->

View File

@@ -69,7 +69,7 @@
sortDirection = "asc";
}
}
// [/DEF:handleSort]
// [/DEF:handleSort:Function]
// [DEF:handleSelectionChange:Function]
// @PURPOSE: Handles individual checkbox changes.
@@ -83,7 +83,7 @@
selectedIds = newSelected;
dispatch('selectionChanged', newSelected);
}
// [/DEF:handleSelectionChange]
// [/DEF:handleSelectionChange:Function]
// [DEF:handleSelectAll:Function]
// @PURPOSE: Handles select all checkbox.
@@ -101,7 +101,7 @@
selectedIds = newSelected;
dispatch('selectionChanged', newSelected);
}
// [/DEF:handleSelectAll]
// [/DEF:handleSelectAll:Function]
// [DEF:goToPage:Function]
// @PURPOSE: Changes current page.
@@ -110,7 +110,7 @@
currentPage = page;
}
}
// [/DEF:goToPage]
// [/DEF:goToPage:Function]
</script>
@@ -202,4 +202,4 @@
/* Component styles */
</style>
<!-- [/DEF:DashboardGrid] -->
<!-- [/DEF:DashboardGrid:Component] -->

View File

@@ -28,7 +28,7 @@
console.log("[DynamicForm][Action] Submitting form data.", { formData });
dispatch('submit', formData);
}
// [/DEF:handleSubmit]
// [/DEF:handleSubmit:Function]
// [DEF:initializeForm:Function]
/**
@@ -41,7 +41,7 @@
}
}
}
// [/DEF:initializeForm]
// [/DEF:initializeForm:Function]
initializeForm();
</script>
@@ -85,4 +85,4 @@
</form>
<!-- [/SECTION] -->
<!-- [/DEF:DynamicForm] -->
<!-- [/DEF:DynamicForm:Component] -->

View File

@@ -31,7 +31,7 @@
selectedId = target.value;
dispatch('change', { id: selectedId });
}
// [/DEF:handleSelect]
// [/DEF:handleSelect:Function]
</script>
<!-- [SECTION: TEMPLATE] -->
@@ -55,4 +55,4 @@
/* Component specific styles */
</style>
<!-- [/DEF:EnvSelector] -->
<!-- [/DEF:EnvSelector:Component] -->

View File

@@ -1,3 +1,10 @@
<!-- [DEF:Footer:Component] -->
<!--
@SEMANTICS: footer, layout, copyright
@PURPOSE: Displays the application footer with copyright information.
@LAYER: UI
-->
<footer class="bg-white border-t p-4 mt-8 text-center text-gray-500 text-sm">
&copy; 2025 Superset Tools. All rights reserved.
</footer>
<!-- [/DEF:Footer:Component] -->

View File

@@ -29,7 +29,7 @@
function updateMapping(sourceUuid: string, targetUuid: string) {
dispatch('update', { sourceUuid, targetUuid });
}
// [/DEF:updateMapping]
// [/DEF:updateMapping:Function]
// [DEF:getSuggestion:Function]
/**
@@ -38,7 +38,7 @@
function getSuggestion(sourceUuid: string) {
return suggestions.find(s => s.source_db_uuid === sourceUuid);
}
// [/DEF:getSuggestion]
// [/DEF:getSuggestion:Function]
</script>
<!-- [SECTION: TEMPLATE] -->
@@ -91,4 +91,4 @@
/* Component specific styles */
</style>
<!-- [/DEF:MappingTable] -->
<!-- [/DEF:MappingTable:Component] -->

View File

@@ -24,6 +24,7 @@
const dispatch = createEventDispatcher();
// [DEF:resolve:Function]
// @PURPOSE: Dispatches the resolution event with the selected mapping.
function resolve() {
if (!selectedTargetUuid) return;
dispatch('resolve', {
@@ -33,14 +34,15 @@
});
show = false;
}
// [/DEF:resolve]
// [/DEF:resolve:Function]
// [DEF:cancel:Function]
// @PURPOSE: Cancels the mapping resolution modal.
function cancel() {
dispatch('cancel');
show = false;
}
// [/DEF:cancel]
// [/DEF:cancel:Function]
</script>
<!-- [SECTION: TEMPLATE] -->
@@ -109,4 +111,4 @@
/* Modal specific styles */
</style>
<!-- [/DEF:MissingMappingModal] -->
<!-- [/DEF:MissingMappingModal:Component] -->

View File

@@ -1,3 +1,10 @@
<!-- [DEF:Navbar:Component] -->
<!--
@SEMANTICS: navbar, navigation, header, layout
@PURPOSE: Main navigation bar for the application.
@LAYER: UI
@RELATION: USES -> $app/stores
-->
<script>
import { page } from '$app/stores';
</script>
@@ -36,3 +43,4 @@
</a>
</nav>
</header>
<!-- [/DEF:Navbar:Component] -->

View File

@@ -18,6 +18,8 @@
let passwords = {};
let submitting = false;
// [DEF:handleSubmit:Function]
// @PURPOSE: Validates and dispatches the passwords to resume the task.
function handleSubmit() {
if (submitting) return;
@@ -32,11 +34,15 @@
dispatch('resume', { passwords });
// Reset submitting state is handled by parent or on close
}
// [/DEF:handleSubmit:Function]
// [DEF:handleCancel:Function]
// @PURPOSE: Cancels the password prompt.
function handleCancel() {
dispatch('cancel');
show = false;
}
// [/DEF:handleCancel:Function]
// Reset passwords when modal opens/closes
$: if (!show) {
@@ -120,4 +126,4 @@
</div>
</div>
{/if}
<!-- [/DEF:PasswordPrompt] -->
<!-- [/DEF:PasswordPrompt:Component] -->

View File

@@ -15,6 +15,8 @@
let error = "";
let interval;
// [DEF:fetchTasks:Function]
// @PURPOSE: Fetches the list of recent tasks from the API.
async function fetchTasks() {
try {
const res = await fetch('/api/tasks?limit=10');
@@ -41,7 +43,10 @@
loading = false;
}
}
// [/DEF:fetchTasks:Function]
// [DEF:clearTasks:Function]
// @PURPOSE: Clears tasks from the history, optionally filtered by status.
async function clearTasks(status = null) {
if (!confirm('Are you sure you want to clear tasks?')) return;
try {
@@ -57,7 +62,10 @@
error = e.message;
}
}
// [/DEF:clearTasks:Function]
// [DEF:selectTask:Function]
// @PURPOSE: Selects a task and fetches its full details.
async function selectTask(task) {
try {
// Fetch the full task details (including logs) before setting it as selected
@@ -74,7 +82,10 @@
selectedTask.set(task);
}
}
// [/DEF:selectTask:Function]
// [DEF:getStatusColor:Function]
// @PURPOSE: Returns the CSS color class for a given task status.
function getStatusColor(status) {
switch (status) {
case 'SUCCESS': return 'bg-green-100 text-green-800';
@@ -85,15 +96,22 @@
default: return 'bg-gray-100 text-gray-800';
}
}
// [/DEF:getStatusColor:Function]
// [DEF:onMount:Function]
// @PURPOSE: Initializes the component by fetching tasks and starting polling.
onMount(() => {
fetchTasks();
interval = setInterval(fetchTasks, 5000); // Poll every 5s
});
// [/DEF:onMount:Function]
// [DEF:onDestroy:Function]
// @PURPOSE: Cleans up the polling interval when the component is destroyed.
onDestroy(() => {
clearInterval(interval);
});
// [/DEF:onDestroy:Function]
</script>
<div class="bg-white shadow overflow-hidden sm:rounded-lg mb-8">
@@ -176,4 +194,4 @@
</ul>
{/if}
</div>
<!-- [/DEF:TaskHistory] -->
<!-- [/DEF:TaskHistory:Component] -->

View File

@@ -15,6 +15,8 @@
const dispatch = createEventDispatcher();
// [DEF:getStatusColor:Function]
// @PURPOSE: Returns the CSS color class for a given task status.
function getStatusColor(status: string) {
switch (status) {
case 'SUCCESS': return 'bg-green-100 text-green-800';
@@ -26,7 +28,10 @@
default: return 'bg-gray-100 text-gray-800';
}
}
// [/DEF:getStatusColor:Function]
// [DEF:formatTime:Function]
// @PURPOSE: Formats a date string using date-fns.
function formatTime(dateStr: string | null) {
if (!dateStr) return 'N/A';
try {
@@ -35,10 +40,14 @@
return 'Invalid date';
}
}
// [/DEF:formatTime:Function]
// [DEF:handleTaskClick:Function]
// @PURPOSE: Dispatches a select event when a task is clicked.
function handleTaskClick(taskId: string) {
dispatch('select', { id: taskId });
}
// [/DEF:handleTaskClick:Function]
</script>
<div class="bg-white shadow overflow-hidden sm:rounded-md">
@@ -91,4 +100,4 @@
{/if}
</div>
<!-- [/DEF:TaskList] -->
<!-- [/DEF:TaskList:Component] -->

View File

@@ -22,6 +22,8 @@
let autoScroll = true;
let logContainer;
// [DEF:fetchLogs:Function]
// @PURPOSE: Fetches logs for the current task.
async function fetchLogs() {
if (!taskId) return;
try {
@@ -35,7 +37,10 @@
loading = false;
}
}
// [/DEF:fetchLogs:Function]
// [DEF:scrollToBottom:Function]
// @PURPOSE: Scrolls the log container to the bottom.
function scrollToBottom() {
if (logContainer) {
setTimeout(() => {
@@ -43,7 +48,10 @@
}, 0);
}
}
// [/DEF:scrollToBottom:Function]
// [DEF:handleScroll:Function]
// @PURPOSE: Updates auto-scroll preference based on scroll position.
function handleScroll() {
if (!logContainer) return;
// If user scrolls up, disable auto-scroll
@@ -51,12 +59,18 @@
const atBottom = scrollHeight - scrollTop - clientHeight < 50;
autoScroll = atBottom;
}
// [/DEF:handleScroll:Function]
// [DEF:close:Function]
// @PURPOSE: Closes the log viewer modal.
function close() {
dispatch('close');
show = false;
}
// [/DEF:close:Function]
// [DEF:getLogLevelColor:Function]
// @PURPOSE: Returns the CSS color class for a given log level.
function getLogLevelColor(level) {
switch (level) {
case 'INFO': return 'text-blue-600';
@@ -66,6 +80,7 @@
default: return 'text-gray-800';
}
}
// [/DEF:getLogLevelColor:Function]
// React to changes in show/taskId
$: if (show && taskId) {
@@ -82,9 +97,12 @@
if (interval) clearInterval(interval);
}
// [DEF:onDestroy:Function]
// @PURPOSE: Cleans up the polling interval.
onDestroy(() => {
if (interval) clearInterval(interval);
});
// [/DEF:onDestroy:Function]
</script>
{#if show}
@@ -150,4 +168,4 @@
</div>
</div>
{/if}
<!-- [/DEF:TaskLogViewer] -->
<!-- [/DEF:TaskLogViewer:Component] -->

View File

@@ -127,8 +127,10 @@
}
};
}
// [/DEF:connect]
// [/DEF:connect:Function]
// [DEF:fetchTargetDatabases:Function]
// @PURPOSE: Fetches the list of databases in the target environment.
async function fetchTargetDatabases() {
const task = get(selectedTask);
if (!task || !task.params.to_env) return;
@@ -147,7 +149,10 @@
console.error('Failed to fetch target databases', e);
}
}
// [/DEF:fetchTargetDatabases:Function]
// [DEF:handleMappingResolve:Function]
// @PURPOSE: Handles the resolution of a missing database mapping.
async function handleMappingResolve(event) {
const task = get(selectedTask);
const { sourceDbUuid, targetDbUuid, targetDbName } = event.detail;
@@ -187,7 +192,10 @@
addToast('Failed to resolve mapping: ' + e.message, 'error');
}
}
// [/DEF:handleMappingResolve:Function]
// [DEF:handlePasswordResume:Function]
// @PURPOSE: Handles the submission of database passwords to resume a task.
async function handlePasswordResume(event) {
const task = get(selectedTask);
const { passwords } = event.detail;
@@ -206,7 +214,10 @@
addToast('Failed to resume task: ' + e.message, 'error');
}
}
// [/DEF:handlePasswordResume:Function]
// [DEF:startDataTimeout:Function]
// @PURPOSE: Starts a timeout to detect when the log stream has stalled.
function startDataTimeout() {
waitingForData = false;
dataTimeout = setTimeout(() => {
@@ -215,14 +226,19 @@
}
}, 5000);
}
// [/DEF:startDataTimeout:Function]
// [DEF:resetDataTimeout:Function]
// @PURPOSE: Resets the data stall timeout.
function resetDataTimeout() {
clearTimeout(dataTimeout);
waitingForData = false;
startDataTimeout();
}
// [/DEF:resetDataTimeout:Function]
// [DEF:onMount:Function]
// @PURPOSE: Initializes the component and subscribes to task selection changes.
onMount(() => {
// Subscribe to selectedTask changes
const unsubscribe = selectedTask.subscribe(task => {
@@ -246,7 +262,7 @@
});
return unsubscribe;
});
// [/DEF:onMount]
// [/DEF:onMount:Function]
// [DEF:onDestroy:Function]
/**
@@ -260,7 +276,7 @@
ws.close();
}
});
// [/DEF:onDestroy]
// [/DEF:onDestroy:Function]
</script>
<!-- [SECTION: TEMPLATE] -->
@@ -360,4 +376,4 @@
/>
<!-- [/SECTION] -->
<!-- [/DEF:TaskRunner] -->
<!-- [/DEF:TaskRunner:Component] -->

View File

@@ -28,4 +28,4 @@
</div>
<!-- [/SECTION] -->
<!-- [/DEF:Toast] -->
<!-- [/DEF:Toast:Component] -->

View File

@@ -8,11 +8,10 @@ import { PUBLIC_WS_URL } from '$env/static/public';
const API_BASE_URL = '/api';
/**
* Returns the WebSocket URL for a specific task, with fallback logic.
* @param {string} taskId
* @returns {string}
*/
// [DEF:getWsUrl:Function]
// @PURPOSE: Returns the WebSocket URL for a specific task, with fallback logic.
// @PARAM: taskId (string) - The ID of the task.
// @RETURN: string - The WebSocket URL.
export const getWsUrl = (taskId) => {
let baseUrl = PUBLIC_WS_URL;
if (!baseUrl) {
@@ -22,6 +21,7 @@ export const getWsUrl = (taskId) => {
}
return `${baseUrl}/ws/logs/${taskId}`;
};
// [/DEF:getWsUrl:Function]
// [DEF:fetchApi:Function]
// @PURPOSE: Generic GET request wrapper.
@@ -41,7 +41,7 @@ async function fetchApi(endpoint) {
throw error;
}
}
// [/DEF:fetchApi]
// [/DEF:fetchApi:Function]
// [DEF:postApi:Function]
// @PURPOSE: Generic POST request wrapper.
@@ -68,7 +68,7 @@ async function postApi(endpoint, body) {
throw error;
}
}
// [/DEF:postApi]
// [/DEF:postApi:Function]
// [DEF:requestApi:Function]
// @PURPOSE: Generic request wrapper.
@@ -96,6 +96,7 @@ async function requestApi(endpoint, method = 'GET', body = null) {
throw error;
}
}
// [/DEF:requestApi:Function]
// [DEF:api:Data]
// @PURPOSE: API client object with specific methods.
@@ -116,7 +117,9 @@ export const api = {
updateEnvironmentSchedule: (id, schedule) => requestApi(`/environments/${id}/schedule`, 'PUT', schedule),
getEnvironmentsList: () => fetchApi('/environments'),
};
// [/DEF:api_module]
// [/DEF:api:Data]
// [/DEF:api_module:Module]
// Export individual functions for easier use in components
export const getPlugins = api.getPlugins;

View File

@@ -9,26 +9,32 @@ import { api } from './api.js';
// [DEF:plugins:Data]
// @PURPOSE: Store for the list of available plugins.
export const plugins = writable([]);
// [/DEF:plugins:Data]
// [DEF:tasks:Data]
// @PURPOSE: Store for the list of tasks.
export const tasks = writable([]);
// [/DEF:tasks:Data]
// [DEF:selectedPlugin:Data]
// @PURPOSE: Store for the currently selected plugin.
export const selectedPlugin = writable(null);
// [/DEF:selectedPlugin:Data]
// [DEF:selectedTask:Data]
// @PURPOSE: Store for the currently selected task.
export const selectedTask = writable(null);
// [/DEF:selectedTask:Data]
// [DEF:currentPage:Data]
// @PURPOSE: Store for the current page.
export const currentPage = writable('dashboard');
// [/DEF:currentPage:Data]
// [DEF:taskLogs:Data]
// @PURPOSE: Store for the logs of the currently selected task.
export const taskLogs = writable([]);
// [/DEF:taskLogs:Data]
// [DEF:fetchPlugins:Function]
// @PURPOSE: Fetches plugins from the API and updates the plugins store.
@@ -42,7 +48,7 @@ export async function fetchPlugins() {
console.error(`[stores.fetchPlugins][Coherence:Failed] Error fetching plugins context={{'error': '${error}'}}`);
}
}
// [/DEF:fetchPlugins]
// [/DEF:fetchPlugins:Function]
// [DEF:fetchTasks:Function]
// @PURPOSE: Fetches tasks from the API and updates the tasks store.
@@ -56,5 +62,5 @@ export async function fetchTasks() {
console.error(`[stores.fetchTasks][Coherence:Failed] Error fetching tasks context={{'error': '${error}'}}`);
}
}
// [/DEF:fetchTasks]
// [/DEF:stores_module]
// [/DEF:fetchTasks:Function]
// [/DEF:stores_module:Module]

View File

@@ -8,6 +8,7 @@ import { writable } from 'svelte/store';
// [DEF:toasts:Data]
// @PURPOSE: Writable store containing the list of active toasts.
export const toasts = writable([]);
// [/DEF:toasts:Data]
// [DEF:addToast:Function]
// @PURPOSE: Adds a new toast message.
@@ -20,7 +21,7 @@ export function addToast(message, type = 'info', duration = 3000) {
toasts.update(all => [...all, { id, message, type }]);
setTimeout(() => removeToast(id), duration);
}
// [/DEF:addToast]
// [/DEF:addToast:Function]
// [DEF:removeToast:Function]
// @PURPOSE: Removes a toast message by ID.
@@ -29,5 +30,5 @@ function removeToast(id) {
console.log(`[toasts.removeToast][Action] Removing toast context={{'id': '${id}'}}`);
toasts.update(all => all.filter(t => t.id !== id));
}
// [/DEF:removeToast]
// [/DEF:toasts_module]
// [/DEF:removeToast:Function]
// [/DEF:toasts_module:Module]

View File

@@ -12,6 +12,7 @@ const app = new App({
target: document.getElementById('app'),
props: {}
})
// [/DEF:app_instance:Data]
export default app
// [/DEF:main]
// [/DEF:main:Module]

View File

@@ -22,7 +22,7 @@
console.log("[Dashboard][Entry] Component mounted, fetching plugins.");
await fetchPlugins();
});
// [/DEF:onMount]
// [/DEF:onMount:Function]
// [DEF:selectPlugin:Function]
/**
@@ -33,7 +33,7 @@
console.log(`[Dashboard][Action] Selecting plugin: ${plugin.id}`);
selectedPlugin.set(plugin);
}
// [/DEF:selectPlugin]
// [/DEF:selectPlugin:Function]
</script>
<!-- [SECTION: TEMPLATE] -->
@@ -57,4 +57,4 @@
</div>
<!-- [/SECTION] -->
<!-- [/DEF:Dashboard] -->
<!-- [/DEF:Dashboard:Component] -->

View File

@@ -62,7 +62,7 @@
addToast('Failed to load settings', 'error');
}
}
// [/DEF:loadSettings]
// [/DEF:loadSettings:Function]
// [DEF:handleSaveGlobal:Function]
/**
@@ -79,7 +79,7 @@
addToast('Failed to save global settings', 'error');
}
}
// [/DEF:handleSaveGlobal]
// [/DEF:handleSaveGlobal:Function]
// [DEF:handleAddOrUpdateEnv:Function]
/**
@@ -103,7 +103,7 @@
addToast('Failed to save environment', 'error');
}
}
// [/DEF:handleAddOrUpdateEnv]
// [/DEF:handleAddOrUpdateEnv:Function]
// [DEF:handleDeleteEnv:Function]
/**
@@ -124,7 +124,7 @@
}
}
}
// [/DEF:handleDeleteEnv]
// [/DEF:handleDeleteEnv:Function]
// [DEF:handleTestEnv:Function]
/**
@@ -147,7 +147,7 @@
addToast('Failed to test connection', 'error');
}
}
// [/DEF:handleTestEnv]
// [/DEF:handleTestEnv:Function]
// [DEF:editEnv:Function]
/**
@@ -158,7 +158,7 @@
newEnv = { ...env };
editingEnvId = env.id;
}
// [/DEF:editEnv]
// [/DEF:editEnv:Function]
// [DEF:resetEnvForm:Function]
/**
@@ -179,7 +179,7 @@
};
editingEnvId = null;
}
// [/DEF:resetEnvForm]
// [/DEF:resetEnvForm:Function]
onMount(loadSettings);
</script>
@@ -330,4 +330,4 @@
</div>
<!-- [/SECTION] -->
<!-- [/DEF:Settings] -->
<!-- [/DEF:Settings:Component] -->

View File

@@ -64,7 +64,7 @@
loading = false;
}
}
// [/DEF:fetchEnvironments]
// [/DEF:fetchEnvironments:Function]
// [DEF:fetchDashboards:Function]
/**
@@ -83,7 +83,7 @@
dashboards = [];
}
}
// [/DEF:fetchDashboards]
// [/DEF:fetchDashboards:Function]
onMount(fetchEnvironments);
@@ -123,7 +123,7 @@
fetchingDbs = false;
}
}
// [/DEF:fetchDatabases]
// [/DEF:fetchDatabases:Function]
// [DEF:handleMappingUpdate:Function]
/**
@@ -158,18 +158,20 @@
error = e.message;
}
}
// [/DEF:handleMappingUpdate]
// [/DEF:handleMappingUpdate:Function]
// [DEF:handleViewLogs:Function]
// @PURPOSE: Opens the log viewer for a specific task.
function handleViewLogs(event: CustomEvent) {
const task = event.detail;
logViewerTaskId = task.id;
logViewerTaskStatus = task.status;
showLogViewer = true;
}
// [/DEF:handleViewLogs]
// [/DEF:handleViewLogs:Function]
// [DEF:handlePasswordPrompt:Function]
// @PURPOSE: Reactive logic to show password prompt when a task is awaiting input.
// This is triggered by TaskRunner or TaskHistory when a task needs input
// For now, we rely on the WebSocket or manual check.
// Ideally, TaskHistory or TaskRunner emits an event when input is needed.
@@ -188,7 +190,10 @@
// showPasswordPrompt = false;
// Actually, don't auto-close, let the user or success handler close it.
}
// [/DEF:handlePasswordPrompt:Function]
// [DEF:handleResumeMigration:Function]
// @PURPOSE: Resumes a migration task with provided passwords.
async function handleResumeMigration(event: CustomEvent) {
if (!$selectedTask) return;
@@ -203,6 +208,7 @@
// Keep prompt open
}
}
// [/DEF:handleResumeMigration:Function]
// [DEF:startMigration:Function]
/**
@@ -270,7 +276,7 @@
error = e.message;
}
}
// [/DEF:startMigration]
// [/DEF:startMigration:Function]
</script>
<!-- [SECTION: TEMPLATE] -->
@@ -396,4 +402,4 @@
/* Page specific styles */
</style>
<!-- [/DEF:MigrationDashboard] -->
<!-- [/DEF:MigrationDashboard:Component] -->

View File

@@ -30,6 +30,8 @@
let success = "";
// [/SECTION]
// [DEF:fetchEnvironments:Function]
// @PURPOSE: Fetches the list of environments.
async function fetchEnvironments() {
try {
const response = await fetch('/api/environments');
@@ -41,6 +43,7 @@
loading = false;
}
}
// [/DEF:fetchEnvironments:Function]
onMount(fetchEnvironments);
@@ -78,7 +81,7 @@
fetchingDbs = false;
}
}
// [/DEF:fetchDatabases]
// [/DEF:fetchDatabases:Function]
// [DEF:handleUpdate:Function]
/**
@@ -114,7 +117,7 @@
error = e.message;
}
}
// [/DEF:handleUpdate]
// [/DEF:handleUpdate:Function]
</script>
<!-- [SECTION: TEMPLATE] -->
@@ -180,4 +183,4 @@
/* Page specific styles */
</style>
<!-- [/DEF:MappingManagement] -->
<!-- [/DEF:MappingManagement:Component] -->