added category listing
This commit is contained in:
parent
f8241e4305
commit
44c7c7354a
|
|
@ -68,6 +68,50 @@ public function getMagento1Categories()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Magento 1 category tree
|
||||||
|
*/
|
||||||
|
public function getMagento1CategoryTree()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$categories = $this->migrationService->getMagento1Categories();
|
||||||
|
$tree = $this->migrationService->buildCategoryTreeHierarchy($categories);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'tree' => $tree,
|
||||||
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Error fetching M1 category tree: ' . $e->getMessage());
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Failed to fetch category tree: ' . $e->getMessage(),
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Magento 2 category tree
|
||||||
|
*/
|
||||||
|
public function getMagento2CategoryTree()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$categories = $this->migrationService->getMagento2Categories();
|
||||||
|
$tree = $this->migrationService->buildCategoryTreeHierarchy($categories);
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'success' => true,
|
||||||
|
'tree' => $tree,
|
||||||
|
]);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error('Error fetching M2 category tree: ' . $e->getMessage());
|
||||||
|
return response()->json([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Failed to fetch category tree: ' . $e->getMessage(),
|
||||||
|
], 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute the migration
|
* Execute the migration
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,156 @@ public function getMagento1Categories($storeId = null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all categories from Magento 2 for a specific store
|
||||||
|
*/
|
||||||
|
public function getMagento2Categories($storeId = null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Get entity type ID
|
||||||
|
$entityTypeId = DB::connection($this->magento2Connection)
|
||||||
|
->table($this->magento2Prefix . 'eav_entity_type')
|
||||||
|
->where('entity_type_code', 'catalog_category')
|
||||||
|
->value('entity_type_id');
|
||||||
|
|
||||||
|
if (!$entityTypeId) {
|
||||||
|
return collect([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get attribute IDs
|
||||||
|
$nameAttributeId = DB::connection($this->magento2Connection)
|
||||||
|
->table($this->magento2Prefix . 'eav_attribute')
|
||||||
|
->where('entity_type_id', $entityTypeId)
|
||||||
|
->where('attribute_code', 'name')
|
||||||
|
->value('attribute_id');
|
||||||
|
|
||||||
|
$isActiveAttributeId = DB::connection($this->magento2Connection)
|
||||||
|
->table($this->magento2Prefix . 'eav_attribute')
|
||||||
|
->where('entity_type_id', $entityTypeId)
|
||||||
|
->where('attribute_code', 'is_active')
|
||||||
|
->value('attribute_id');
|
||||||
|
|
||||||
|
$urlKeyAttributeId = DB::connection($this->magento2Connection)
|
||||||
|
->table($this->magento2Prefix . 'eav_attribute')
|
||||||
|
->where('entity_type_id', $entityTypeId)
|
||||||
|
->where('attribute_code', 'url_key')
|
||||||
|
->value('attribute_id');
|
||||||
|
|
||||||
|
$targetStoreId = $storeId ?? 0;
|
||||||
|
|
||||||
|
// Get base category data
|
||||||
|
$categories = DB::connection($this->magento2Connection)
|
||||||
|
->table($this->magento2Prefix . 'catalog_category_entity')
|
||||||
|
->select('entity_id', 'parent_id', 'level', 'path', 'position')
|
||||||
|
->orderBy('level')
|
||||||
|
->orderBy('position')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
// Get attribute values
|
||||||
|
$nameValues = [];
|
||||||
|
$isActiveValues = [];
|
||||||
|
$urlKeyValues = [];
|
||||||
|
|
||||||
|
if ($nameAttributeId) {
|
||||||
|
$nameValues = DB::connection($this->magento2Connection)
|
||||||
|
->table($this->magento2Prefix . 'catalog_category_entity_varchar')
|
||||||
|
->where('attribute_id', $nameAttributeId)
|
||||||
|
->where('store_id', $targetStoreId)
|
||||||
|
->pluck('value', 'entity_id')
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($isActiveAttributeId) {
|
||||||
|
$isActiveValues = DB::connection($this->magento2Connection)
|
||||||
|
->table($this->magento2Prefix . 'catalog_category_entity_int')
|
||||||
|
->where('attribute_id', $isActiveAttributeId)
|
||||||
|
->where('store_id', $targetStoreId)
|
||||||
|
->pluck('value', 'entity_id')
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($urlKeyAttributeId) {
|
||||||
|
$urlKeyValues = DB::connection($this->magento2Connection)
|
||||||
|
->table($this->magento2Prefix . 'catalog_category_entity_varchar')
|
||||||
|
->where('attribute_id', $urlKeyAttributeId)
|
||||||
|
->where('store_id', $targetStoreId)
|
||||||
|
->pluck('value', 'entity_id')
|
||||||
|
->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine data
|
||||||
|
return $categories->map(function($category) use ($nameValues, $isActiveValues, $urlKeyValues) {
|
||||||
|
$category->name = $nameValues[$category->entity_id] ?? null;
|
||||||
|
$category->is_active = $isActiveValues[$category->entity_id] ?? null;
|
||||||
|
$category->url_key = $urlKeyValues[$category->entity_id] ?? null;
|
||||||
|
return $category;
|
||||||
|
});
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error('Error fetching Magento 2 categories: ' . $e->getMessage());
|
||||||
|
return collect([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build hierarchical category tree structure
|
||||||
|
*/
|
||||||
|
public function buildCategoryTreeHierarchy($categories)
|
||||||
|
{
|
||||||
|
$categoryMap = [];
|
||||||
|
$rootCategories = [];
|
||||||
|
|
||||||
|
// First pass: create a map of all categories with children array
|
||||||
|
foreach ($categories as $category) {
|
||||||
|
$categoryMap[$category->entity_id] = [
|
||||||
|
'id' => $category->entity_id,
|
||||||
|
'name' => $category->name ?? 'Unnamed Category',
|
||||||
|
'parent_id' => $category->parent_id,
|
||||||
|
'level' => $category->level ?? 0,
|
||||||
|
'position' => $category->position ?? 0,
|
||||||
|
'is_active' => $category->is_active ?? 0,
|
||||||
|
'path' => $category->path ?? '',
|
||||||
|
'children' => []
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second pass: build the tree structure by assigning children to parents
|
||||||
|
foreach ($categoryMap as $id => $category) {
|
||||||
|
$parentId = $category['parent_id'];
|
||||||
|
|
||||||
|
// Skip if parent is self (prevent circular references)
|
||||||
|
if ($parentId == $id) {
|
||||||
|
$rootCategories[] = &$categoryMap[$id];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this is a root category (parent is 0, 1, or doesn't exist in map)
|
||||||
|
if ($parentId == 0 || $parentId == 1 || !isset($categoryMap[$parentId])) {
|
||||||
|
$rootCategories[] = &$categoryMap[$id];
|
||||||
|
} else {
|
||||||
|
// Add as child of parent
|
||||||
|
$categoryMap[$parentId]['children'][] = &$categoryMap[$id];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort function for categories
|
||||||
|
$sortCategories = function(&$categories) use (&$sortCategories) {
|
||||||
|
usort($categories, function($a, $b) {
|
||||||
|
return $a['position'] <=> $b['position'];
|
||||||
|
});
|
||||||
|
// Recursively sort children
|
||||||
|
foreach ($categories as &$category) {
|
||||||
|
if (!empty($category['children'])) {
|
||||||
|
$sortCategories($category['children']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sort root categories and all children recursively
|
||||||
|
$sortCategories($rootCategories);
|
||||||
|
|
||||||
|
return $rootCategories;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate categories from Magento 1 to Magento 2
|
* Migrate categories from Magento 1 to Magento 2
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,154 @@
|
||||||
color: #666;
|
color: #666;
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tabs */
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 2px solid #ddd;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
padding: 15px 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #666;
|
||||||
|
transition: all 0.3s;
|
||||||
|
border-bottom: 3px solid transparent;
|
||||||
|
margin-bottom: -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab:hover {
|
||||||
|
background: #e9ecef;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab.active {
|
||||||
|
color: #667eea;
|
||||||
|
border-bottom-color: #667eea;
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-content {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-content.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tree View */
|
||||||
|
.tree-container {
|
||||||
|
background: white;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 20px;
|
||||||
|
max-height: 600px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-node {
|
||||||
|
margin: 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-node-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-node-item:hover {
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-toggle {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-toggle.expanded::before {
|
||||||
|
content: '▼';
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-toggle.collapsed::before {
|
||||||
|
content: '▶';
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-toggle.leaf {
|
||||||
|
width: 20px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-label {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-label-text {
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-badge {
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 0.75em;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-badge.active {
|
||||||
|
background: #d4edda;
|
||||||
|
color: #155724;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-badge.inactive {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-children {
|
||||||
|
margin-left: 28px;
|
||||||
|
border-left: 2px solid #e0e0e0;
|
||||||
|
padding-left: 12px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-children.expanded {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-loading {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-error {
|
||||||
|
background: #f8d7da;
|
||||||
|
color: #721c24;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 6px;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
@ -261,6 +409,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
<!-- Tabs -->
|
||||||
|
<div class="tabs">
|
||||||
|
<button class="tab active" onclick="switchTab('migration', this)">Migration</button>
|
||||||
|
<button class="tab" onclick="switchTab('categories', this)">Category Trees</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Migration Tab -->
|
||||||
|
<div id="tab-migration" class="tab-content active">
|
||||||
<!-- Connection Status -->
|
<!-- Connection Status -->
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<h2>📡 Database Connections</h2>
|
<h2>📡 Database Connections</h2>
|
||||||
|
|
@ -363,6 +519,33 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Category Trees Tab -->
|
||||||
|
<div id="tab-categories" class="tab-content">
|
||||||
|
<div class="section">
|
||||||
|
<h2>🌳 Category Trees</h2>
|
||||||
|
<p>View category hierarchies from Magento 1 and Magento 2</p>
|
||||||
|
|
||||||
|
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 20px;">
|
||||||
|
<!-- Magento 1 Tree -->
|
||||||
|
<div>
|
||||||
|
<h3 style="margin-bottom: 15px; color: #667eea;">Magento 1 Categories</h3>
|
||||||
|
<div class="tree-container" id="m1-tree-container">
|
||||||
|
<div class="tree-loading">Loading categories...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Magento 2 Tree -->
|
||||||
|
<div>
|
||||||
|
<h3 style="margin-bottom: 15px; color: #764ba2;">Magento 2 Categories</h3>
|
||||||
|
<div class="tree-container" id="m2-tree-container">
|
||||||
|
<div class="tree-loading">Loading categories...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
@ -474,6 +657,158 @@ function addLogEntry(message, type = '') {
|
||||||
logContent.appendChild(entry);
|
logContent.appendChild(entry);
|
||||||
logContent.scrollTop = logContent.scrollHeight;
|
logContent.scrollTop = logContent.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tab switching
|
||||||
|
function switchTab(tabName, tabElement) {
|
||||||
|
// Hide all tabs
|
||||||
|
document.querySelectorAll('.tab-content').forEach(content => {
|
||||||
|
content.classList.remove('active');
|
||||||
|
});
|
||||||
|
document.querySelectorAll('.tab').forEach(tab => {
|
||||||
|
tab.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show selected tab
|
||||||
|
document.getElementById('tab-' + tabName).classList.add('active');
|
||||||
|
tabElement.classList.add('active');
|
||||||
|
|
||||||
|
// Load category trees if switching to categories tab
|
||||||
|
if (tabName === 'categories') {
|
||||||
|
loadCategoryTrees();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load category trees
|
||||||
|
function loadCategoryTrees() {
|
||||||
|
loadM1Tree();
|
||||||
|
loadM2Tree();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load Magento 1 tree
|
||||||
|
function loadM1Tree() {
|
||||||
|
const container = document.getElementById('m1-tree-container');
|
||||||
|
container.innerHTML = '<div class="tree-loading">Loading categories...</div>';
|
||||||
|
|
||||||
|
fetch('{{ route("migration.magento1-category-tree") }}')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
container.innerHTML = '';
|
||||||
|
if (data.tree && data.tree.length > 0) {
|
||||||
|
renderTree(container, data.tree);
|
||||||
|
} else {
|
||||||
|
container.innerHTML = '<div class="tree-loading">No categories found</div>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
container.innerHTML = `<div class="tree-error">Error: ${data.message || 'Failed to load categories'}</div>`;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
container.innerHTML = `<div class="tree-error">Error: ${error.message}</div>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load Magento 2 tree
|
||||||
|
function loadM2Tree() {
|
||||||
|
const container = document.getElementById('m2-tree-container');
|
||||||
|
container.innerHTML = '<div class="tree-loading">Loading categories...</div>';
|
||||||
|
|
||||||
|
fetch('{{ route("migration.magento2-category-tree") }}')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
container.innerHTML = '';
|
||||||
|
if (data.tree && data.tree.length > 0) {
|
||||||
|
renderTree(container, data.tree);
|
||||||
|
} else {
|
||||||
|
container.innerHTML = '<div class="tree-loading">No categories found</div>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
container.innerHTML = `<div class="tree-error">Error: ${data.message || 'Failed to load categories'}</div>`;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
container.innerHTML = `<div class="tree-error">Error: ${error.message}</div>`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render tree structure
|
||||||
|
function renderTree(container, nodes) {
|
||||||
|
nodes.forEach(node => {
|
||||||
|
const nodeElement = createTreeNode(node);
|
||||||
|
container.appendChild(nodeElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a tree node element
|
||||||
|
function createTreeNode(node) {
|
||||||
|
const nodeDiv = document.createElement('div');
|
||||||
|
nodeDiv.className = 'tree-node';
|
||||||
|
|
||||||
|
const hasChildren = node.children && node.children.length > 0;
|
||||||
|
|
||||||
|
const itemDiv = document.createElement('div');
|
||||||
|
itemDiv.className = 'tree-node-item';
|
||||||
|
|
||||||
|
const toggle = document.createElement('span');
|
||||||
|
toggle.className = hasChildren ? 'tree-toggle collapsed' : 'tree-toggle leaf';
|
||||||
|
if (hasChildren) {
|
||||||
|
toggle.onclick = function(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
toggleNode(this);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const label = document.createElement('div');
|
||||||
|
label.className = 'tree-label';
|
||||||
|
|
||||||
|
const labelText = document.createElement('span');
|
||||||
|
labelText.className = 'tree-label-text';
|
||||||
|
labelText.textContent = node.name || 'Unnamed Category';
|
||||||
|
|
||||||
|
const badge = document.createElement('span');
|
||||||
|
badge.className = `tree-badge ${node.is_active ? 'active' : 'inactive'}`;
|
||||||
|
badge.textContent = node.is_active ? 'Active' : 'Inactive';
|
||||||
|
|
||||||
|
label.appendChild(labelText);
|
||||||
|
label.appendChild(badge);
|
||||||
|
|
||||||
|
itemDiv.appendChild(toggle);
|
||||||
|
itemDiv.appendChild(label);
|
||||||
|
|
||||||
|
nodeDiv.appendChild(itemDiv);
|
||||||
|
|
||||||
|
if (hasChildren) {
|
||||||
|
const childrenDiv = document.createElement('div');
|
||||||
|
childrenDiv.className = 'tree-children';
|
||||||
|
node.children.forEach(child => {
|
||||||
|
childrenDiv.appendChild(createTreeNode(child));
|
||||||
|
});
|
||||||
|
nodeDiv.appendChild(childrenDiv);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nodeDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle node expansion
|
||||||
|
function toggleNode(toggleElement) {
|
||||||
|
const nodeItem = toggleElement.parentElement;
|
||||||
|
const nodeDiv = nodeItem.parentElement;
|
||||||
|
const childrenDiv = nodeDiv.querySelector('.tree-children');
|
||||||
|
|
||||||
|
if (childrenDiv) {
|
||||||
|
const isExpanded = childrenDiv.classList.contains('expanded');
|
||||||
|
if (isExpanded) {
|
||||||
|
childrenDiv.classList.remove('expanded');
|
||||||
|
toggleElement.classList.remove('expanded');
|
||||||
|
toggleElement.classList.add('collapsed');
|
||||||
|
} else {
|
||||||
|
childrenDiv.classList.add('expanded');
|
||||||
|
toggleElement.classList.remove('collapsed');
|
||||||
|
toggleElement.classList.add('expanded');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,6 @@
|
||||||
Route::post('/migrate', [MagentoMigrationController::class, 'migrate'])->name('migration.migrate');
|
Route::post('/migrate', [MagentoMigrationController::class, 'migrate'])->name('migration.migrate');
|
||||||
Route::get('/test-connections', [MagentoMigrationController::class, 'testConnections'])->name('migration.test-connections');
|
Route::get('/test-connections', [MagentoMigrationController::class, 'testConnections'])->name('migration.test-connections');
|
||||||
Route::get('/magento1-categories', [MagentoMigrationController::class, 'getMagento1Categories'])->name('migration.magento1-categories');
|
Route::get('/magento1-categories', [MagentoMigrationController::class, 'getMagento1Categories'])->name('migration.magento1-categories');
|
||||||
|
Route::get('/magento1-category-tree', [MagentoMigrationController::class, 'getMagento1CategoryTree'])->name('migration.magento1-category-tree');
|
||||||
|
Route::get('/magento2-category-tree', [MagentoMigrationController::class, 'getMagento2CategoryTree'])->name('migration.magento2-category-tree');
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue