Files
crm.clientright.ru/backups/20250921_173241_WORKING_S3_NEXTCLOUD_AI/Header.tpl

321 lines
16 KiB
Smarty
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{*+**********************************************************************************
* The contents of this file are subject to the vtiger CRM Public License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* The Original Code is: vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
************************************************************************************}
{strip}
<!DOCTYPE html>
<html>
<head>
<title>{vtranslate($PAGETITLE, $QUALIFIED_MODULE)}</title>
<link rel="SHORTCUT ICON" href="layouts/v7/skins/images/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/todc/css/bootstrap.min.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/todc/css/docs.min.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/todc/css/todc-bootstrap.min.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/font-awesome/css/font-awesome.min.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/select2/select2.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/select2-bootstrap/select2-bootstrap.css'>
<link type='text/css' rel='stylesheet' href='libraries/bootstrap/js/eternicode-bootstrap-datepicker/css/datepicker3.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/jquery-ui-1.11.3.custom/jquery-ui.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/vt-icons/style.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/animate/animate.min.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/malihu-custom-scrollbar/jquery.mCustomScrollbar.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/jquery.qtip.custom/jquery.qtip.css'>
<link type='text/css' rel='stylesheet' href='layouts/v7/lib/jquery/daterangepicker/daterangepicker.css'>
{*Salesplatform.ru begin PBXManager porting*}
<link type='text/css' rel='stylesheet' href='libraries/jquery/pnotify/jquery.pnotify.default.css'>
{*Salesplatform.ru end PBXManager porting*}
<input type="hidden" id="inventoryModules" value={ZEND_JSON::encode($INVENTORY_MODULES)}>
{assign var=V7_THEME_PATH value=Vtiger_Theme::getv7AppStylePath($SELECTED_MENU_CATEGORY)}
{if strpos($V7_THEME_PATH,".less")!== false}
<link type="text/css" rel="stylesheet/less" href="{vresource_url($V7_THEME_PATH)}" media="screen" />
{else}
<link type="text/css" rel="stylesheet" href="{vresource_url($V7_THEME_PATH)}" media="screen" />
{/if}
{foreach key=index item=cssModel from=$STYLES}
<link type="text/css" rel="{$cssModel->getRel()}" href="{vresource_url($cssModel->getHref())}" media="{$cssModel->getMedia()}" />
{/foreach}
{* For making pages - print friendly *}
<style type="text/css">
@media print {
.noprint { display:none; }
}
</style>
<script type="text/javascript">var __pageCreationTime = (new Date()).getTime();</script>
<script src="{vresource_url('layouts/v7/lib/jquery/jquery.min.js')}"></script>
<script src="{vresource_url('layouts/v7/lib/jquery/jquery-migrate-1.0.0.js')}"></script>
<script type="text/javascript">
var _META = { 'module': "{$MODULE}", view: "{$VIEW}", 'parent': "{$PARENT_MODULE}", 'notifier':"{$NOTIFIER_URL}", 'app':"{$SELECTED_MENU_CATEGORY}" };
{if $EXTENSION_MODULE}
var _EXTENSIONMETA = { 'module': "{$EXTENSION_MODULE}", view: "{$EXTENSION_VIEW}"};
{/if}
var _USERMETA;
{if $CURRENT_USER_MODEL}
_USERMETA = { 'id' : "{$CURRENT_USER_MODEL->get('id')}", 'menustatus' : "{$CURRENT_USER_MODEL->get('leftpanelhide')}",
'currency' : "{$USER_CURRENCY_SYMBOL}", 'currencySymbolPlacement' : "{$CURRENT_USER_MODEL->get('currency_symbol_placement')}",
'currencyGroupingPattern' : "{$CURRENT_USER_MODEL->get('currency_grouping_pattern')}", 'truncateTrailingZeros' : "{$CURRENT_USER_MODEL->get('truncate_trailing_zeros')}"};
{/if}
</script>
{* AI Drawer - подключение внешних файлов только для авторизованных пользователей *}
{if $CURRENT_USER_MODEL}
<link rel="stylesheet" href="layouts/v7/resources/css/ai-drawer.css">
<script src="layouts/v7/resources/js/ai-drawer.js"></script>
<script src="ai_drawer_improvements.js"></script>
<script src="crm_extensions/nextcloud_editor/js/nextcloud-editor-v2.js?v=2.4"></script>
<script type="text/javascript">
{literal}
// Простая функция для редактирования в Nextcloud
function editInNextcloud(recordId, fileName) {
console.log('🎯 Opening file in Nextcloud:', recordId, fileName);
// Проверяем расширение
const ext = fileName.split('.').pop().toLowerCase();
if (!['docx', 'xlsx', 'pptx'].includes(ext)) {
alert('Файл ' + fileName + ' не поддерживается для редактирования. Поддерживаются: docx, xlsx, pptx');
return;
}
// Отправляем запрос к нашему API
const apiUrl = `crm_extensions/nextcloud_api.php?record=${encodeURIComponent(recordId)}&fileName=${encodeURIComponent(fileName)}`;
fetch(apiUrl, {
method: 'GET'
})
.then(response => {
console.log('📥 Response status:', response.status);
return response.json();
})
.then(json => {
console.log('📋 JSON response:', json);
if (json.success && json.data && json.data.urls) {
// Сначала пробуем файловый менеджер, потом прямой редактор
const filesManagerUrl = json.data.urls.files_manager;
const collaboraUrl = json.data.urls.collabora_id;
const onlyofficeUrl = json.data.urls.onlyoffice_id;
if (filesManagerUrl) {
console.log('🎯 Opening files manager:', filesManagerUrl);
window.open(filesManagerUrl, '_blank');
} else if (collaboraUrl) {
console.log('🎯 Opening Collabora:', collaboraUrl);
window.open(collaboraUrl, '_blank');
} else if (onlyofficeUrl) {
console.log('🎯 Opening OnlyOffice:', onlyofficeUrl);
window.open(onlyofficeUrl, '_blank');
} else {
console.error('❌ No valid URLs found');
alert('Ошибка: Не удалось получить URL для редактирования');
}
} else {
console.error('❌ Invalid response structure:', json);
alert('Ошибка: ' + (json.error || 'Не удалось получить URL для редактирования. Проверьте консоль для деталей.'));
}
})
.catch(error => {
console.error('❌ Error:', error);
alert('❌ Ошибка: ' + error.message);
});
}
// Алиас для совместимости с FilePreview.tpl
function openNextcloudEditor(recordId, fileName) {
console.log('🔄 openNextcloudEditor called, redirecting to editInNextcloud');
return editInNextcloud(recordId, fileName);
}
// Делаем функции глобальными для доступа из шаблонов
window.editInNextcloud = editInNextcloud;
window.openNextcloudEditor = openNextcloudEditor;
// Тестовая функция для отладки
function testEditButton(recordId, fileName) {
console.log('🧪 TEST: testEditButton called with:', recordId, fileName);
console.log('🧪 TEST: typeof editInNextcloud:', typeof editInNextcloud);
console.log('🧪 TEST: typeof window.editInNextcloud:', typeof window.editInNextcloud);
if (typeof editInNextcloud === 'function') {
console.log('✅ Функция editInNextcloud найдена, вызываем...');
editInNextcloud(recordId, fileName);
} else {
console.log('❌ Функция editInNextcloud НЕ найдена!');
alert('❌ Функция editInNextcloud не найдена!\n\nRecord ID: ' + recordId + '\nFile Name: ' + fileName);
}
}
window.testEditButton = testEditButton;
{/literal}
</script>
<script type="text/javascript">
{literal}
// Инициализация нового AI Drawer только для авторизованных пользователей
document.addEventListener('DOMContentLoaded', function() {
try {
console.log('AI Drawer: Initializing new version');
// Инициализируем новый AI Drawer
if (typeof AIDrawer !== 'undefined') {
window.aiDrawerInstance = new AIDrawer();
console.log('AI Drawer: New version initialized successfully');
// Отслеживаем смену URL для обновления истории
let currentURL = window.location.href;
const urlObserver = setInterval(function() {
if (window.location.href !== currentURL) {
currentURL = window.location.href;
console.log('AI Drawer: URL changed, refreshing history');
if (window.aiDrawerInstance && typeof window.aiDrawerInstance.refreshPreloadedHistory === 'function') {
// Обновляем историю с небольшой задержкой чтобы страница успела загрузиться
setTimeout(() => {
window.aiDrawerInstance.refreshPreloadedHistory();
}, 1000);
}
}
}, 1000);
// Также слушаем события навигации
window.addEventListener('popstate', function() {
console.log('AI Drawer: Popstate event, refreshing history');
if (window.aiDrawerInstance && typeof window.aiDrawerInstance.refreshPreloadedHistory === 'function') {
setTimeout(() => {
window.aiDrawerInstance.refreshPreloadedHistory();
}, 1000);
}
});
} else {
console.error('AI Drawer: AIDrawer class not found');
}
} catch (error) {
console.error('AI Drawer: Initialization error:', error);
}
});
{/literal}
</script>
{/if}
<!-- Nextcloud Editor Integration -->
<script type="text/javascript">
function testEditButton(recordId, fileName) {
console.log("🚀 Nextcloud Editor:", recordId, fileName);
// Простая версия для начала
var editUrl = "https://office.klientprav.tech/apps/files/?dir=/CRM_Active_Files";
var editorWindow = window.open(editUrl, "nextcloud_editor", "width=1200,height=800");
if (editorWindow) {
alert("✅ Открываю Nextcloud для файла: " + fileName + "\n\nПерейдите в папку CRM_Active_Files и найдите ваш файл для редактирования.");
} else {
alert("❌ Всплывающие окна заблокированы. Откройте Nextcloud вручную:\n" + editUrl);
}
}
console.log("✅ Nextcloud Editor функция загружена");
// Умная функция для редактирования с автозагрузкой файла
function openNextcloudEditorSmart(recordId, fileName) {
console.log("🚀 Smart Editor для:", recordId, fileName);
// Показываем индикатор
var loadingDiv = document.createElement("div");
loadingDiv.id = "nextcloud-smart-loading";
loadingDiv.innerHTML = '<div style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.8); z-index: 99999; display: flex; align-items: center; justify-content: center;"><div style="background: white; padding: 40px; border-radius: 15px; text-align: center;"><i class="fa fa-cloud-upload fa-3x" style="color: #28a745;"></i><h3>Подготавливаю файл</h3><p>Загружаю ' + fileName + ' в Nextcloud...</p></div></div>';
document.body.appendChild(loadingDiv);
fetch("/crm_extensions/file_storage/api/simple_edit.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ record_id: recordId, file_name: fileName })
})
.then(response => response.json())
.then(data => {
var loading = document.getElementById("nextcloud-smart-loading");
if (loading) document.body.removeChild(loading);
if (data.success) {
var win = window.open(data.edit_url, "nextcloud_editor", "width=1200,height=800");
if (win) {
alert("✅ Nextcloud открыт!\n\n" + data.message);
} else {
alert("❌ Всплывающие окна заблокированы");
}
} else {
alert("❌ Ошибка: " + data.error);
}
})
.catch(error => {
var loading = document.getElementById("nextcloud-smart-loading");
if (loading) document.body.removeChild(loading);
alert("❌ Ошибка API: " + error.message);
});
}
body: JSON.stringify({ record_id: recordId, file_name: fileName })
})
.then(response => response.json())
.then(data => {
// Убираем индикатор
var loading = document.getElementById("nextcloud-smart-loading");
if (loading) document.body.removeChild(loading);
if (data.success) {
// Открываем редактор
var win = window.open(data.edit_url, "nextcloud_editor", "width=1200,height=800,scrollbars=yes,resizable=yes");
if (win) {
alert("✅ Файл подготовлен и загружен в Nextcloud!\n\nФайл: " + fileName + "\n\nОткрывается редактор...");
} else {
alert("❌ Всплывающие окна заблокированы.\n\nОткройте ссылку:\n" + data.edit_url);
}
} else {
alert("❌ Ошибка: " + data.error);
}
})
.catch(error => {
// Убираем индикатор
var loading = document.getElementById("nextcloud-smart-loading");
if (loading) document.body.removeChild(loading);
console.error("API Error:", error);
alert("❌ Ошибка подключения: " + error.message);
});
}
</script>
</head>
<body data-skinpath="{Vtiger_Theme::getBaseThemePath()}" data-language="{$LANGUAGE}"{if $CURRENT_USER_MODEL} data-user-decimalseparator="{$CURRENT_USER_MODEL->get('currency_decimal_separator')}" data-user-dateformat="{$CURRENT_USER_MODEL->get('date_format')}"
data-user-groupingseparator="{$CURRENT_USER_MODEL->get('currency_grouping_separator')}" data-user-numberofdecimals="{$CURRENT_USER_MODEL->get('no_of_currency_decimals')}" data-user-hourformat="{$CURRENT_USER_MODEL->get('hour_format')}"
data-user-calendar-reminder-interval="{$CURRENT_USER_MODEL->getCurrentUserActivityReminderInSeconds()}"{/if}>
{if $CURRENT_USER_MODEL}<input type="hidden" id="start_day" value="{$CURRENT_USER_MODEL->get('dayoftheweek')}" />{/if}
{* SalesPlatform.ru begin #5116 fixed localization *}
<input type="hidden" name="locale" value='{json_encode($LOCALE)}'>
{* SalesPlatform.ru end *}
<!-- AI Drawer HTML -->
{if $CURRENT_USER_MODEL}
<div id="ai-drawer" class="ai-drawer">
<div class="ai-drawer-content">
<div class="ai-drawer-header">
<h3>AI Ассистент</h3>
<button type="button" class="ai-drawer-close">&times;</button>
</div>
<div class="ai-drawer-body">
<div class="ai-chat-container">
<div class="ai-chat-messages"></div>
<div class="ai-chat-input-container">
<textarea class="ai-chat-input" placeholder="Задайте вопрос AI ассистенту..."></textarea>
<button class="ai-send-btn">Отправить</button>
</div>
</div>
</div>
</div>
</div>
<button type="button" class="ai-drawer-toggle">AI</button>
{/if}
<div id="page">
<div id="pjaxContainer" class="hide noprint"></div>
<div id="messageBar" class="hide"></div>