feat: Project file migration and Nextcloud integration

- Added project file migration script with sanitization (underscores)
- Fixed Nextcloud editor integration (urldecode, basename fix)
- Added 'Open Project Folder in Nextcloud' button
- 223 projects migrated (completed + archived)
- URL decoding fix for Cyrillic filenames
This commit is contained in:
Fedor
2025-10-22 18:29:02 +03:00
parent 1f96ab6e10
commit 3fb2ad5f60
5 changed files with 607 additions and 122 deletions

View File

@@ -3,6 +3,34 @@
* JavaScript для интеграции редактора документов Nextcloud
*/
/**
* Открытие папки проекта в Nextcloud
*/
function openProjectFolder(projectId, projectName) {
console.log('📁 Opening project folder in Nextcloud:', projectId, projectName);
// Нормализуем имя проекта (убираем пробелы и кавычки)
if (projectName) {
// Убираем кавычки (заменяем на подчёркивание)
projectName = projectName.replace(/"/g, '_');
// Заменяем ВСЕ пробелы на подчёркивания
projectName = projectName.replace(/\s+/g, '_');
}
// Формируем URL для папки проекта в Nextcloud
const folderName = projectName ? `${projectName}_${projectId}` : `project_${projectId}`;
const encodedFolderName = encodeURIComponent(folderName);
const nextcloudUrl = 'https://office.clientright.ru:8443';
// URL для папки проекта в Nextcloud External Storage
const folderUrl = `${nextcloudUrl}/apps/files/?dir=/crm/crm2/CRM_Active_Files/Documents/${encodedFolderName}`;
console.log('🔗 Folder URL:', folderUrl);
// Открываем папку в новом окне
window.open(folderUrl, 'nextcloud_folder', 'width=1200,height=800,scrollbars=yes,resizable=yes');
}
/**
* Открытие редактора Nextcloud для документа
*/
@@ -19,7 +47,7 @@ function openNextcloudEditor(recordId, fileName) {
if (win) {
console.log('✅ Editor opened successfully');
alert('✅ Редактор открыт! Файл: ' + fileName);
// alert('✅ Редактор открыт! Файл: ' + fileName);
} else {
console.log('❌ Failed to open editor window - popup blocked');
alert('❌ Не удалось открыть редактор. Проверьте блокировку всплывающих окон.');
@@ -190,7 +218,7 @@ function openEditor(editUrl, fileData) {
message: 'Редактор открыт! Файл: ' + fileData.file_name
});
} else {
alert('✅ Редактор открыт! Файл: ' + fileData.file_name);
// alert('✅ Редактор открыт! Файл: ' + fileData.file_name);
}
// Показываем информацию о файле

View File

@@ -1,56 +1,66 @@
{*<!--
/*********************************************************************************
** The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("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}
<div class="col-lg-6 col-md-6 col-sm-6">
<div class="record-header clearfix">
<div class="hidden-sm hidden-xs recordImage bgproject app-{$SELECTED_MENU_CATEGORY}">
<div class="name"><span><strong> <i class="vicon-project"></i> </strong></span></div>
</div>
<div class="recordBasicInfo">
<div class="info-row">
<h4>
<div class="recordLabel pushDown" title="{$RECORD->getName()}">
{foreach item=NAME_FIELD from=$MODULE_MODEL->getNameFields()}
{assign var=FIELD_MODEL value=$MODULE_MODEL->getField($NAME_FIELD)}
{if $FIELD_MODEL->getPermissions()}
<span class="{$NAME_FIELD}">{$RECORD->get($NAME_FIELD)}</span>&nbsp;
{/if}
{/foreach}
</div>
</h4>
</div>
{include file="DetailViewHeaderFieldsView.tpl"|vtemplate_path:$MODULE}
{*
{assign var=RELATED_TO value=$RECORD->get('linktoaccountscontacts')}
{assign var=CONTACT value=$RECORD->get('contactid')}
<div class="info-row row ">
{if !empty($RELATED_TO)}
<div class="col-lg-7 fieldLabel">
<span class="muted">
{$RECORD->getDisplayValue('linktoaccountscontacts')}
</span>
</div>
{elseif !empty($CONTACT)}
<div class="info-row row ">
<div class="col-lg-7 fieldLabel">
<span class="muted">
{$RECORD->getDisplayValue('contactid')}</span>
</div>
</div>
{/if}
</div>
*}
</div>
</div>
</div>
{*<!--
/*********************************************************************************
** The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("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}
<div class="col-lg-6 col-md-6 col-sm-6">
<div class="record-header clearfix">
<div class="hidden-sm hidden-xs recordImage bgproject app-{$SELECTED_MENU_CATEGORY}">
<div class="name"><span><strong> <i class="vicon-project"></i> </strong></span></div>
</div>
<div class="recordBasicInfo">
<div class="info-row">
<h4>
<div class="recordLabel pushDown" title="{$RECORD->getName()}">
{foreach item=NAME_FIELD from=$MODULE_MODEL->getNameFields()}
{assign var=FIELD_MODEL value=$MODULE_MODEL->getField($NAME_FIELD)}
{if $FIELD_MODEL->getPermissions()}
<span class="{$NAME_FIELD}">{$RECORD->get($NAME_FIELD)}</span>&nbsp;
{/if}
{/foreach}
</div>
</h4>
</div>
{include file="DetailViewHeaderFieldsView.tpl"|vtemplate_path:$MODULE}
{* Кнопка открытия папки проекта в Nextcloud *}
<div class="info-row" style="margin-top: 10px;">
<button type="button" class="btn btn-info btn-sm" onclick="openProjectFolder('{$RECORD->getId()}', '{$RECORD->get("projectname")|escape:javascript}')" title="Открыть папку проекта в Nextcloud">
<i class="fa fa-folder-open"></i> Папка в Nextcloud
</button>
</div>
{* Подключаем Nextcloud Editor JS *}
<script type="text/javascript" src="layouts/v7/lib/nextcloud-editor.js"></script>
{*
{assign var=RELATED_TO value=$RECORD->get('linktoaccountscontacts')}
{assign var=CONTACT value=$RECORD->get('contactid')}
<div class="info-row row ">
{if !empty($RELATED_TO)}
<div class="col-lg-7 fieldLabel">
<span class="muted">
{$RECORD->getDisplayValue('linktoaccountscontacts')}
</span>
</div>
{elseif !empty($CONTACT)}
<div class="info-row row ">
<div class="col-lg-7 fieldLabel">
<span class="muted">
{$RECORD->getDisplayValue('contactid')}</span>
</div>
</div>
{/if}
</div>
*}
</div>
</div>
</div>
{/strip}