< Summary

Information
Class: AspNetCoreGeneratedDocument.Areas_CategoryTree_Views_Category_Index
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/CategoryTree/Views/Category/Index.cshtml
Line coverage
0%
Covered lines: 0
Uncovered lines: 18
Coverable lines: 18
Total lines: 442
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 4
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
ExecuteAsync()0%2040%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/Areas/CategoryTree/Views/Category/Index.cshtml

#LineLine coverage
 1@{
 02    ViewData["Title"] = "Категории";
 3}
 04@Html.AntiForgeryToken()
 5<link href="~/css/tree-cards.css" rel="stylesheet" />
 6
 7<div class="container">
 8    <!-- Панель действий -->
 9    <div class="action-panel">
 10        <a href="#" class="action-link" id="clear-selection">Очистить выбор</a>
 11        <button id="confirmLinkButton" class="action-button" onclick="sendCategoriesToServer()">Связать категории</butto
 12        <div class="translation-section" id="translation-section-id">
 13            <input type="text" id="translationInput" class="translation-input" placeholder="Введите перевод">
 14            <button id="sendTranslationButton" class="action-button" onclick="sendTranslationToServer()">Добавить перево
 15        </div>
 16        <a href="#" class="action-link" id="settings-button" onclick="showSettingsModal()">Настройки отображения</a>
 17        <a  asp-area="OzonCards" asp-action="Index" asp-controller="Tasks">Задачи</a>
 18    </div>
 19
 20    <!-- Основной контейнер с колонками -->
 21    <div class="row" id="columns-container">
 22        <!-- Правая колонка (Ct) -->
 23        <div class="col-md-4 tree-container main-column" id="ct-column">
 24            <h4 class="text-center">Ct (Главная)</h4>
 25            <input type="text" id="ct-filter" class="form-control filter-input" placeholder="Фильтр категорий">
 26            <div id="ct-category-container" class="tree-scroll">
 27                <p>Загрузка...</p>
 28            </div>
 29        </div>
 30
 31        <!-- Левая колонка (Volna) -->
 32        <div class="col-md-4 tree-container" id="volna-column">
 33            <h4 class="text-center">Volna</h4>
 34            <input type="text" id="volna-filter" class="form-control filter-input" placeholder="Фильтр категорий">
 35            <div id="volna-category-container" class="tree-scroll">
 36                <p>Загрузка...</p>
 37            </div>
 38        </div>
 39
 40        <!-- Центральная колонка (Ozon) -->
 41        <div class="col-md-4 tree-container" id="ozon-column">
 42            <h4 class="text-center">Ozon</h4>
 43            <input type="text" id="ozon-filter" class="form-control filter-input" placeholder="Фильтр категорий">
 44            <div id="ozon-category-container" class="tree-scroll">
 45                <p>Загрузка...</p>
 46            </div>
 47        </div>
 48
 49        <!-- Колонка Метод вызова и фильтрации -->
 50        <div class="col-md-4 tree-container" id="method-column">
 51            <h4 class="text-center">IC</h4>
 52            <input type="text" id="method-filter" class="form-control filter-input" placeholder="Фильтр методов">
 53            <div id="method-category-container" class="tree-scroll">
 54                <p>Загрузка...</p>
 55            </div>
 56        </div>
 57
 58
 59        <div class="col-md-4 tree-container" id="cattree-column">
 60            <h4 class="text-center">CatTree</h4>
 61            <input type="text" id="cattree-filter" class="form-control filter-input" placeholder="Фильтр категорий">
 62            <div id="cattree-category-container" class="tree-scroll">
 63                <p>Загрузка...</p>
 64            </div>
 65        </div>
 66    </div>
 67</div>
 68
 69<!-- Модальное окно настроек -->
 70<div id="settings-modal" class="modal">
 71    <div class="modal-content">
 72        <span class="close" onclick="hideSettingsModal()">&times;</span>
 73        <h3>Настройки отображения</h3>
 74        <div class="settings-options">
 75            <button onclick="toggleColumn('volna-column')">Скрыть/показать Volna</button>
 76            <button onclick="toggleColumn('ozon-column')">Скрыть/показать Ozon</button>
 77            <button onclick="toggleColumn('method-column')">Скрыть/показать Метод вызова и фильтрации</button>
 78            <button onclick="toggleColumn('cattree-column')">Скрыть/показать CatTree</button>
 79        </div>
 80    </div>
 81</div>
 82
 83<script>
 84    async function unlinkCategory(id) {
 85        if (await St2Dialog.confirm("Вы уверены, что хотите отвязать категорию?", { variant: 'danger', confirmText: 'Отв
 86            const token = document.querySelector('input[name="__RequestVerificationToken"]').value;
 87
 88            fetch(`CategoryTree/Category/Unlink?id=${id}`, {
 89                method: 'POST',
 90                headers: {
 91                    'Content-Type': 'application/json',
 92                    'RequestVerificationToken': token
 93                },
 94                body: JSON.stringify({})
 95            })
 96                .then(response => {
 97                    if (response.ok) {
 98                        location.reload();
 99                    } else {
 100                        alert("Ошибка при отвязке.");
 101                    }
 102                });
 103        }
 104    }
 105
 106
 107    // Клик по связанной категории
 108    $(document).on("click", ".link-item", function () {
 109        const type = $(this).data("type");
 110        const id = $(this).data("id");
 111
 112        if (!type || !id) return;
 113
 114        switch (type) {
 115            case "Ozon":
 0116                loadCategories("ozon-category-container", '@Url.Action("GetOzonCategoriesById", "Category")' + '?id=' + 
 117                break;
 118            case "Volna":
 0119                loadCategories("volna-category-container", '@Url.Action("GetVolnaCategoriesById", "Category")' + '?id=' 
 120                break;
 121            case "Ct":
 0122                loadCategories("ct-category-container", '@Url.Action("GetCtCategoriesById", "Category")' + '?id=' + id);
 123                break;
 124            case "CatTree":
 0125                loadCategories("cattree-category-container", '@Url.Action("GetCatTreeCategoriesById", "Category")' + '?i
 126                break;
 127            case "IC":
 0128                loadCategories("method-category-container", '@Url.Action("GetICGroupsCategoriesById", "Category")' + '?i
 129                break;
 130        }
 131    });
 132</script>
 133
 134
 135<!-- jQuery для AJAX -->
 136<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
 137
 138<script>
 139    function showSettingsModal() {
 140        document.getElementById('settings-modal').style.display = 'block';
 141    }
 142
 143    function hideSettingsModal() {
 144        document.getElementById('settings-modal').style.display = 'none';
 145    }
 146
 147    // Закрытие модального окна при клике вне его
 148    window.onclick = function(event) {
 149        const modal = document.getElementById('settings-modal');
 150        if (event.target == modal) {
 151            hideSettingsModal();
 152        }
 153    }
 154
 155    // Ваша существующая функция toggleColumn
 156    function toggleColumn(columnId) {
 157        const column = document.getElementById(columnId);
 158        if (column.style.display === 'none') {
 159            column.style.display = 'block';
 160        } else {
 161            column.style.display = 'none';
 162        }
 163    }
 164</script>
 165
 166<script>
 167    // Функция для скрытия/показа колонок
 168    function toggleColumn(columnId) {
 169        var column = document.getElementById(columnId);
 170        column.classList.toggle('hidden');
 171        saveColumnsState();
 172    }
 173
 174    // Функция для перемещения колонок
 175    function makeColumnsDraggable() {
 176        const columns = document.querySelectorAll('.tree-container');
 177
 178        columns.forEach(function(column) {
 179            column.setAttribute('draggable', true);
 180
 181            column.addEventListener('dragstart', function(e) {
 182                e.dataTransfer.setData('text', column.id);
 183            });
 184
 185            column.addEventListener('dragover', function(e) {
 186                e.preventDefault();
 187            });
 188
 189            column.addEventListener('drop', function(e) {
 190                e.preventDefault();
 191                var draggedColumnId = e.dataTransfer.getData('text');
 192                var draggedColumn = document.getElementById(draggedColumnId);
 193                var currentColumn = column;
 194
 195                // Перемещаем столбцы
 196                if (draggedColumn !== currentColumn) {
 197                    var parent = draggedColumn.parentNode;
 198                    parent.insertBefore(draggedColumn, currentColumn);
 199                    saveColumnsState();
 200                }
 201            });
 202        });
 203    }
 204
 205    // Сохранение состояния колонок в sessionStorage
 206    function saveColumnsState() {
 207        const columnsState = {
 208            volnaColumnHidden: document.getElementById('volna-column').classList.contains('hidden'),
 209            ozonColumnHidden: document.getElementById('ozon-column').classList.contains('hidden'),
 210            cattreeColumnHidden: document.getElementById('cattree-column').classList.contains('hidden'),
 211            columnsOrder: Array.from(document.getElementById('columns-container').children).map(col => col.id),
 212            methodColumnHidden: document.getElementById('method-column').classList.contains('hidden'),
 213
 214        };
 215
 216        sessionStorage.setItem('columnsState', JSON.stringify(columnsState));
 217    }
 218
 219    // Восстановление состояния колонок из sessionStorage
 220    function restoreColumnsState() {
 221        const columnsState = JSON.parse(sessionStorage.getItem('columnsState'));
 222        if (columnsState) {
 223            // Восстанавливаем видимость колонок
 224            if (columnsState.volnaColumnHidden) document.getElementById('volna-column').classList.add('hidden');
 225            if (columnsState.ozonColumnHidden) document.getElementById('ozon-column').classList.add('hidden');
 226            if (columnsState.cattreeColumnHidden) document.getElementById('cattree-column').classList.add('hidden');
 227            if (columnsState.methodColumnHidden) document.getElementById('method-column').classList.add('hidden');
 228
 229            // Восстанавливаем порядок колонок
 230            const container = document.getElementById('columns-container');
 231            columnsState.columnsOrder.forEach(columnId => {
 232                const column = document.getElementById(columnId);
 233                container.appendChild(column);
 234            });
 235        }
 236    }
 237
 238    // Инициализация перемещения колонок и восстановления состояния при загрузке страницы
 239    window.onload = function() {
 240        makeColumnsDraggable();
 241        restoreColumnsState();
 242    };
 243</script>
 244
 245<script>
 246    // Кнопка очистки выбора
 247    document.getElementById("clear-selection").addEventListener("click", function () {
 248        sessionStorage.removeItem("selectedCategories");
 249        document.querySelectorAll(".category-link").forEach(link => {
 250            link.style.color = "";
 251        });
 252        alert("Выбор категорий очищен!");
 253    });
 254
 255    function loadCategories(containerId, action, filterValue) {
 256        $.get(action, { name: filterValue }, function (data) {
 257            $("#" + containerId).html(data);
 258        });
 259    }
 260
 261    $(document).ready(function () {
 262        // Изначальная загрузка деревьев
 263        // Пример вызовов из JavaScript:
 0264        loadCategories("volna-category-container", '@Url.Action("UpdateVolnaCategories", "Category",  new { area = "Cate
 0265        loadCategories("ozon-category-container", '@Url.Action("UpdateOzonCategories", "Category",  new { area = "Catego
 0266        loadCategories("ct-category-container", '@Url.Action("UpdateCtCategories", "Category",  new { area = "CategoryTr
 0267        loadCategories("cattree-category-container", '@Url.Action("UpdateCatTreeCategories", "Category",  new { area = "
 0268        loadCategories("method-category-container", '@Url.Action("UpdateICGroupsCategories", "Category",  new { area = "
 269
 270
 271        // Фильтрация при вводе текста
 272        $(".filter-input").on("input", function () {
 273            let id = $(this).attr("id");
 274            let value = $(this).val();
 275
 276            if (id === "volna-filter") {
 0277                loadCategories("volna-category-container", '@Url.Action("GetVolnaCategories", "Category",  new { area = 
 278            } else if (id === "ozon-filter") {
 0279                loadCategories("ozon-category-container", '@Url.Action("GetOzonCategories", "Category",  new { area = "C
 280            } else if (id === "ct-filter") {
 0281                loadCategories("ct-category-container", '@Url.Action("GetCtCategories", "Category",  new { area = "Categ
 282            } else if (id === "cattree-filter") {  // Обработчик фильтра для нового дерева
 0283                loadCategories("cattree-category-container", '@Url.Action("GetCatTreeCategories", "Category",  new { are
 284            }
 285            else if (id === "method-filter") {
 0286                loadCategories("method-category-container", '@Url.Action("GetICGroupsCategories", "Category",  new { are
 287            }
 288
 289    });
 290    });
 291
 292</script>
 293
 294<script>
 295    document.addEventListener("DOMContentLoaded", function () {
 296        let selectedData = JSON.parse(sessionStorage.getItem("selectedCategories")) || {};
 297
 298        document.querySelectorAll(".category-link").forEach(link => {
 299            let id = link.getAttribute("data-id");
 300            let tree = link.getAttribute("data-tree");
 301
 302            if (selectedData[tree] && selectedData[tree] === id) {
 303                link.style.color = "red";
 304            }
 305        });
 306    });
 307
 308    function handleLeftClick(event, element) {
 309        event.preventDefault();
 310        let id = element.getAttribute("data-id");
 311        let tree = element.getAttribute("data-tree");
 312
 313        let selectedData = JSON.parse(sessionStorage.getItem("selectedCategories")) || {};
 314
 315        // Если уже выбрана категория для данного tree, заменяем на новую
 316        if (selectedData[tree] === id) {
 317            delete selectedData[tree]; // Удаляем, если кликнули повторно (отмена выбора)
 318            element.style.color = "";
 319            // Проверяем, если выбрано ровно 3 категории - показываем окно
 320            if (Object.keys(selectedData).length < 2) {
 321                let button = document.getElementById("confirmLinkButton");
 322                button.style.display = "none"; // Скрываем кнопку
 323            }
 324            if (Object.keys(selectedData).length === 0) {
 325                let translation_section = document.getElementById("translation-section-id")
 326                translation_section.style.display = "none";
 327            }
 328        } else {
 329            // Сбрасываем цвет у старого элемента (если он был выделен)
 330            document.querySelectorAll(`.category-link[data-tree="${tree}"]`).forEach(link => {
 331                link.style.color = "";
 332            });
 333
 334            selectedData[tree] = id; // Добавляем новую категорию
 335            element.style.color = "red";
 336        }
 337
 338        sessionStorage.setItem("selectedCategories", JSON.stringify(selectedData));
 339        console.log("Выбранные категории:", selectedData);
 340
 341        // Проверяем, если выбрано ровно 3 категории - показываем окно
 342        if (Object.keys(selectedData).length > 1) {
 343            showConfirmationDialog();
 344        }
 345        if (Object.keys(selectedData).length >= 1) {
 346            showSection();
 347        }
 348        console.log(sessionStorage.getItem("selectedCategories"));
 349    }
 350
 0351    const ozonCardsBaseUrl = '@Url.Action("Index", "Cards", new { area = "OzonCards" })';
 352
 353    function handleRightClick(event, element) {
 354        event.preventDefault();
 355        const encodedName = encodeURIComponent(element.dataset.name);
 356        window.open(`${ozonCardsBaseUrl}?typeName=${encodedName}`, '_blank');
 357        return false;
 358    }
 359
 360
 361    // Функция для показа окна подтверждения
 362    function showConfirmationDialog() {
 363        let button = document.getElementById("confirmLinkButton");
 364        button.style.display = "block"; // Показываем кнопку
 365    }
 366    function showSection() {
 367        let translation_section = document.getElementById("translation-section-id");
 368        translation_section.style.display = "flex";
 369    }
 370
 371    function sendTranslationToServer() {
 372        const translationText = document.getElementById('translationInput').value.trim();
 373
 374        let selectedData = JSON.parse(sessionStorage.getItem("selectedCategories")) || {};
 375
 376        if (Object.keys(selectedData).length === 0) {
 377            alert('Пожалуйста, сначала выберите категории');
 378            return;
 379        }
 380
 381        const requestData = {
 382            CategoryNames: selectedData,
 383            Translation: translationText
 384        };
 385
 386        fetch('CategoryTree/Category/CreateCategoryTranslation', {
 387            method: 'POST',
 388            headers: {
 389                'Content-Type': 'application/json'
 390            },
 391            body: JSON.stringify(requestData)
 392        })
 393            .then(response => {
 394                if (!response.ok) {
 395                    return response.json().then(err => { throw new Error(err.error || 'Ошибка сервера'); });
 396                }
 397                return response.json();
 398            })
 399            .then(data => {
 400                if (data.success) {
 401                    alert(translationText ? "Перевод сохранен" : "Перевод удален");
 402                    document.getElementById('translationInput').value = '';
 403                    location.reload();
 404                }
 405            })
 406            .catch(error => {
 407                console.error("Ошибка:", error);
 408                alert("Ошибка: " + error.message);
 409            });
 410    }
 411
 412    // Функция для отправки данных в контроллер
 413    function sendCategoriesToServer() {
 414        let selectedData = JSON.parse(sessionStorage.getItem("selectedCategories")) || {};
 415        let endpoint = ""
 416        // Проверка наличия элемента с ключом 'CT' в selectedData
 417        if ("CT" in selectedData) {
 418            endpoint = 'CategoryTree/Category/LinkCategories'
 419        } else {
 420            endpoint = 'CategoryTree/Category/CreateUnifiedCategory'
 421        }
 422
 423        fetch(endpoint, {
 424            method: 'POST',
 425            headers: {
 426                'Content-Type': 'application/json'
 427            },
 428            body: JSON.stringify(selectedData)
 429        })
 430            .then(response => response.json())
 431            .then(data => {
 432                console.log("Ответ сервера:", data);
 433                alert("Категории успешно связаны!");
 434                sessionStorage.removeItem("selectedCategories"); // Очищаем после отправки
 435                location.reload();
 436            })
 437            .catch(error => {
 438                console.error("Ошибка:", error);
 439                alert("Ошибка при связывании категорий.");
 440            });
 441    }
 442</script>

Methods/Properties

ExecuteAsync()