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

321 lines
16 KiB
Smarty
Raw Normal View History

{*+**********************************************************************************
* 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>