mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-17 09:24:11 +01:00
Compare commits
7 Commits
class_extr
...
issue/9063
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7fdfb78021 | ||
|
|
cc9e64616f | ||
|
|
a39234f438 | ||
|
|
ac8937105d | ||
|
|
fb6f892244 | ||
|
|
0a04c83c7b | ||
|
|
cc8252bebf |
@@ -5,9 +5,6 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\Dashboard\Layout\DashboardLayoutGrid;
|
||||
use Combodo\iTop\Application\Dashlet\DashletFactory;
|
||||
use Combodo\iTop\Application\Dashlet\Service\DashletService;
|
||||
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableSettings;
|
||||
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
|
||||
@@ -15,12 +12,9 @@ use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardLayout as DashboardLayoutUIBlock;
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
use Combodo\iTop\DesignDocument;
|
||||
use Combodo\iTop\DesignElement;
|
||||
use Combodo\iTop\PropertyType\PropertyTypeDesign;
|
||||
use Combodo\iTop\Service\DependencyInjection\ServiceLocator;
|
||||
|
||||
require_once(APPROOT.'application/dashboardlayout.class.inc.php');
|
||||
require_once(APPROOT.'application/dashlet.class.inc.php');
|
||||
require_once(APPROOT.'core/modelreflection.class.inc.php');
|
||||
|
||||
/**
|
||||
@@ -30,7 +24,7 @@ require_once(APPROOT.'core/modelreflection.class.inc.php');
|
||||
*/
|
||||
abstract class Dashboard
|
||||
{
|
||||
/** @var string $sTitle */
|
||||
/** @var string $sTitle*/
|
||||
protected $sTitle;
|
||||
/** @var bool $bAutoReload */
|
||||
protected $bAutoReload;
|
||||
@@ -40,7 +34,7 @@ abstract class Dashboard
|
||||
protected $sLayoutClass;
|
||||
/** @var array $aWidgetsData */
|
||||
protected $aWidgetsData;
|
||||
/** @var DesignElement|null $oDOMNode */
|
||||
/** @var \DOMNode|null $oDOMNode */
|
||||
protected $oDOMNode;
|
||||
/** @var string $sId */
|
||||
protected $sId;
|
||||
@@ -49,11 +43,6 @@ abstract class Dashboard
|
||||
/** @var \ModelReflection $oMetaModel */
|
||||
protected $oMetaModel;
|
||||
|
||||
/** @var array Array of dashlets with position */
|
||||
protected array $aGridDashlets = [];
|
||||
|
||||
protected $oDashletFactory;
|
||||
|
||||
/**
|
||||
* Dashboard constructor.
|
||||
*
|
||||
@@ -68,7 +57,6 @@ abstract class Dashboard
|
||||
$this->aCells = [];
|
||||
$this->oDOMNode = null;
|
||||
$this->sId = $sId;
|
||||
$this->oDashletFactory = DashletFactory::GetInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +68,7 @@ abstract class Dashboard
|
||||
{
|
||||
$this->aCells = []; // reset the content of the dashboard
|
||||
set_error_handler(['Dashboard', 'ErrorHandler']);
|
||||
$oDoc = new PropertyTypeDesign();
|
||||
$oDoc = new DOMDocument();
|
||||
$oDoc->loadXML($sXml);
|
||||
restore_error_handler();
|
||||
$this->FromDOMDocument($oDoc);
|
||||
@@ -89,15 +77,10 @@ abstract class Dashboard
|
||||
/**
|
||||
* @param \DOMDocument $oDoc
|
||||
*/
|
||||
public function FromDOMDocument(DesignDocument $oDoc)
|
||||
public function FromDOMDocument(DOMDocument $oDoc)
|
||||
{
|
||||
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
|
||||
|
||||
if ($this->oDOMNode->getElementsByTagName('cells')->count() === 0) {
|
||||
$this->FromDOMDocumentV2($oDoc);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($oLayoutNode = $this->oDOMNode->getElementsByTagName('layout')->item(0)) {
|
||||
$this->sLayoutClass = $oLayoutNode->textContent;
|
||||
} else {
|
||||
@@ -138,7 +121,7 @@ abstract class Dashboard
|
||||
$aDashletOrder = [];
|
||||
/** @var \DOMElement $oDomNode */
|
||||
foreach ($oDashletList as $oDomNode) {
|
||||
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
|
||||
$oRank = $oDomNode->getElementsByTagName('rank')->item(0);
|
||||
if ($oRank) {
|
||||
$iRank = (float)$oRank->textContent;
|
||||
}
|
||||
@@ -164,39 +147,7 @@ abstract class Dashboard
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DOMDocument $oDoc
|
||||
*/
|
||||
public function FromDOMDocumentV2(DesignDocument $oDoc)
|
||||
{
|
||||
$this->oDOMNode = $oDoc->getElementsByTagName('dashboard')->item(0);
|
||||
|
||||
$this->sLayoutClass = DashboardLayoutGrid::class;
|
||||
$this->sTitle = $this->oDOMNode->GetChildText('title', '');
|
||||
|
||||
$iRefresh = intval($this->oDOMNode->GetChildText('refresh', '0'));
|
||||
|
||||
$this->bAutoReload = $iRefresh > 0;
|
||||
$this->iAutoReloadSec = $iRefresh;
|
||||
|
||||
$oDashletsNode = $this->oDOMNode->GetUniqueElement('pos_dashlets');
|
||||
$oDashletList = $oDashletsNode->getElementsByTagName('pos_dashlet');
|
||||
foreach ($oDashletList as $oPosDashletNode) {
|
||||
$aGridDashlet = [];
|
||||
$aGridDashlet['position_x'] = intval($oPosDashletNode->GetChildText('position_x', '0'));
|
||||
$aGridDashlet['position_y'] = intval($oPosDashletNode->GetChildText('position_y', '0'));
|
||||
$aGridDashlet['width'] = intval($oPosDashletNode->GetChildText('width', '2'));
|
||||
$aGridDashlet['height'] = intval($oPosDashletNode->GetChildText('height', '1'));
|
||||
$oDashletNode = $oPosDashletNode->GetUniqueElement('dashlet');
|
||||
$sId = $oPosDashletNode->getAttribute('id');
|
||||
$oDashlet = $this->InitDashletFromDOMNode($oDashletNode);
|
||||
$oDashlet->SetID($sId);
|
||||
$aGridDashlet['dashlet'] = $oDashlet;
|
||||
$this->aGridDashlets[] = $aGridDashlet;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param DesignElement $oDomNode
|
||||
* @param \DOMElement $oDomNode
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -209,7 +160,7 @@ abstract class Dashboard
|
||||
// Test if dashlet can be instantiated, otherwise (uninstalled, broken, ...) we display a placeholder
|
||||
$sClass = static::GetDashletClassFromType($sDashletType);
|
||||
/** @var \Dashlet $oNewDashlet */
|
||||
$oNewDashlet = $this->oDashletFactory->CreateDashlet($sClass, $sId);
|
||||
$oNewDashlet = new $sClass($this->oMetaModel, $sId);
|
||||
$oNewDashlet->SetDashletType($sDashletType);
|
||||
$oNewDashlet->FromDOMNode($oDomNode);
|
||||
|
||||
@@ -253,31 +204,18 @@ abstract class Dashboard
|
||||
*/
|
||||
public function ToXml()
|
||||
{
|
||||
$oMainNode = $this->CreateEmptyDashboard();
|
||||
|
||||
$this->ToDOMNode($oMainNode);
|
||||
|
||||
$sXml = $oMainNode->ownerDocument->saveXML();
|
||||
|
||||
return $sXml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DesignElement
|
||||
* @throws \DOMException
|
||||
*/
|
||||
public function CreateEmptyDashboard(): DesignElement
|
||||
{
|
||||
$oDoc = new DesignDocument();
|
||||
$oDoc = new DOMDocument();
|
||||
$oDoc->formatOutput = true; // indent (must be loaded with option LIBXML_NOBLANKS)
|
||||
$oDoc->preserveWhiteSpace = true; // otherwise the formatOutput option would have no effect
|
||||
|
||||
/** @var DesignElement $oMainNode */
|
||||
$oMainNode = $oDoc->createElement('dashboard');
|
||||
$oMainNode->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
|
||||
$oMainNode->setAttribute('xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance");
|
||||
$oDoc->appendChild($oMainNode);
|
||||
|
||||
return $oMainNode;
|
||||
$this->ToDOMNode($oMainNode);
|
||||
|
||||
$sXml = $oDoc->saveXML();
|
||||
return $sXml;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -341,7 +279,7 @@ abstract class Dashboard
|
||||
}
|
||||
$this->sTitle = $aParams['title'];
|
||||
$this->bAutoReload = $aParams['auto_reload'] == 'true';
|
||||
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int)$aParams['auto_reload_sec']);
|
||||
$this->iAutoReloadSec = max(MetaModel::GetConfig()->Get('min_reload_interval'), (int) $aParams['auto_reload_sec']);
|
||||
|
||||
foreach ($aParams['cells'] as $aCell) {
|
||||
$aCellDashlets = [];
|
||||
@@ -349,7 +287,7 @@ abstract class Dashboard
|
||||
$sDashletClass = $aDashletParams['dashlet_class'];
|
||||
$sId = $aDashletParams['dashlet_id'];
|
||||
/** @var \Dashlet $oNewDashlet */
|
||||
$oNewDashlet = $this->oDashletFactory->CreateDashlet($sDashletClass, $sId);
|
||||
$oNewDashlet = new $sDashletClass($this->oMetaModel, $sId);
|
||||
if (isset($aDashletParams['dashlet_type'])) {
|
||||
$oNewDashlet->SetDashletType($aDashletParams['dashlet_type']);
|
||||
}
|
||||
@@ -367,11 +305,7 @@ abstract class Dashboard
|
||||
|
||||
public function Save()
|
||||
{
|
||||
}
|
||||
|
||||
public function PersistDashboard(string $sXml): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -569,7 +503,7 @@ EOF
|
||||
{
|
||||
$aExtraParams['dashboard_div_id'] = utils::Sanitize($aExtraParams['dashboard_div_id'] ?? null, $this->GetId(), utils::ENUM_SANITIZATION_FILTER_ELEMENT_IDENTIFIER);
|
||||
|
||||
/** @var \DashboardLayout $oLayout */
|
||||
/** @var \DashboardLayoutMultiCol $oLayout */
|
||||
$oLayout = new $this->sLayoutClass();
|
||||
|
||||
foreach ($this->aCells as $iCellIdx => $aDashlets) {
|
||||
@@ -579,13 +513,7 @@ EOF
|
||||
}
|
||||
}
|
||||
|
||||
if (count($this->aCells) > 0) {
|
||||
$aDashlets = $this->aCells;
|
||||
} else {
|
||||
$aDashlets = $this->aGridDashlets;
|
||||
}
|
||||
|
||||
$oDashboard = $oLayout->Render($oPage, $aDashlets, $bEditMode, $aExtraParams);
|
||||
$oDashboard = $oLayout->Render($oPage, $this->aCells, $bEditMode, $aExtraParams);
|
||||
$oPage->AddUiBlock($oDashboard);
|
||||
|
||||
$bFromDasboardPage = isset($aExtraParams['from_dashboard_page']) ? isset($aExtraParams['from_dashboard_page']) : false;
|
||||
@@ -675,12 +603,29 @@ JS
|
||||
* Return an array of dashlets available for selection.
|
||||
*
|
||||
* @return array
|
||||
* @throws \Combodo\iTop\Application\Dashlet\DashletException
|
||||
* @throws \DOMFormatException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
protected function GetAvailableDashlets(): array
|
||||
protected function GetAvailableDashlets()
|
||||
{
|
||||
return DashletService::GetInstance()->GetAvailableDashlets();
|
||||
$aDashlets = [];
|
||||
|
||||
foreach (get_declared_classes() as $sDashletClass) {
|
||||
// DashletUnknown is not among the selection as it is just a fallback for dashlets that can't instantiated.
|
||||
if (is_subclass_of($sDashletClass, 'Dashlet') && !in_array($sDashletClass, ['DashletUnknown', 'DashletProxy'])) {
|
||||
$oReflection = new ReflectionClass($sDashletClass);
|
||||
if (!$oReflection->isAbstract()) {
|
||||
$aCallSpec = [$sDashletClass, 'IsVisible'];
|
||||
$bVisible = call_user_func($aCallSpec);
|
||||
if ($bVisible) {
|
||||
$aCallSpec = [$sDashletClass, 'GetInfo'];
|
||||
$aInfo = call_user_func($aCallSpec);
|
||||
$aDashlets[$sDashletClass] = $aInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aDashlets;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -695,7 +640,6 @@ JS
|
||||
$iNewId = max($iNewId, (int)$oDashlet->GetID());
|
||||
}
|
||||
}
|
||||
|
||||
return $iNewId + 1;
|
||||
}
|
||||
|
||||
@@ -730,7 +674,6 @@ JS
|
||||
if (is_subclass_of($sType, 'Dashlet')) {
|
||||
return $sType;
|
||||
}
|
||||
|
||||
return 'DashletUnknown';
|
||||
}
|
||||
|
||||
@@ -783,8 +726,6 @@ class RuntimeDashboard extends Dashboard
|
||||
{
|
||||
parent::__construct($sId);
|
||||
$this->oMetaModel = new ModelReflectionRuntime();
|
||||
$this->oDashletFactory->SetModelReflectionRuntime($this->oMetaModel);
|
||||
ServiceLocator::GetInstance()->RegisterService('ModelReflection', $this->oMetaModel);
|
||||
$this->bCustomized = false;
|
||||
}
|
||||
|
||||
@@ -799,7 +740,6 @@ class RuntimeDashboard extends Dashboard
|
||||
|
||||
/**
|
||||
* @param bool $bCustomized
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function SetCustomFlag($bCustomized)
|
||||
@@ -824,26 +764,6 @@ class RuntimeDashboard extends Dashboard
|
||||
public function Save()
|
||||
{
|
||||
$sXml = $this->ToXml();
|
||||
|
||||
return $this->PersistDashboard($sXml);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sXml
|
||||
*
|
||||
* @return bool
|
||||
* @throws \ArchivedObjectException
|
||||
* @throws \CoreCannotSaveObjectException
|
||||
* @throws \CoreException
|
||||
* @throws \CoreUnexpectedValue
|
||||
* @throws \CoreWarning
|
||||
* @throws \MissingQueryArgument
|
||||
* @throws \MySQLException
|
||||
* @throws \MySQLHasGoneAwayException
|
||||
* @throws \OQLException
|
||||
*/
|
||||
public function PersistDashboard(string $sXml): bool
|
||||
{
|
||||
$oUDSearch = new DBObjectSearch('UserDashboard');
|
||||
$oUDSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
|
||||
$oUDSearch->AddCondition('menu_code', $this->sId, '=');
|
||||
@@ -864,7 +784,6 @@ class RuntimeDashboard extends Dashboard
|
||||
utils::PushArchiveMode(false);
|
||||
$oUserDashboard->DBWrite();
|
||||
utils::PopArchiveMode();
|
||||
|
||||
return $bIsNew;
|
||||
}
|
||||
|
||||
@@ -1158,7 +1077,6 @@ JS
|
||||
$sId = utils::Sanitize($this->GetId(), '', 'element_identifier');
|
||||
|
||||
$sMenuTogglerId = "ibo-dashboard-menu-toggler-{$sId}";
|
||||
$sActionEditId = "ibo-dashboard-menu-edit-{$sId}";
|
||||
$sPopoverMenuId = "ibo-dashboard-menu-popover-{$sId}";
|
||||
$sName = 'UI:Dashboard:Actions';
|
||||
|
||||
@@ -1172,21 +1090,6 @@ JS
|
||||
} else {
|
||||
$oToolbar = $oDashboard->GetToolbar();
|
||||
}
|
||||
|
||||
// TODO 3.3 Check if we need different action for custom dashboard creation / edition
|
||||
$oActionEditButton = ButtonUIBlockFactory::MakeIconAction(
|
||||
'fas fa-pen',
|
||||
$this->HasCustomDashboard() ? Dict::S('UI:Dashboard:EditCustom') : Dict::S('UI:Dashboard:CreateCustom'),
|
||||
$sActionEditId,
|
||||
'',
|
||||
false,
|
||||
$sActionEditId
|
||||
)
|
||||
->AddCSSClass('ibo-top-bar--toolbar-dashboard-edit-button')
|
||||
->AddCSSClass('ibo-action-button');
|
||||
|
||||
$oToolbar->AddSubBlock($oActionEditButton);
|
||||
|
||||
$oActionButton = ButtonUIBlockFactory::MakeIconAction('fas fa-ellipsis-v', Dict::S($sName), $sName, '', false, $sMenuTogglerId)
|
||||
->AddCSSClass('ibo-top-bar--toolbar-dashboard-menu-toggler')
|
||||
->AddCSSClass('ibo-action-button');
|
||||
@@ -1196,8 +1099,8 @@ JS
|
||||
$sFile = addslashes(utils::LocalPath($this->sDefinitionFile));
|
||||
$sJSExtraParams = json_encode($aExtraParams);
|
||||
if ($this->HasCustomDashboard()) {
|
||||
// $oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||
// $aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:EditCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||
$oRevert = new JSPopupMenuItem(
|
||||
'UI:Dashboard:RevertConfirm',
|
||||
Dict::S('UI:Dashboard:DeleteCustom'),
|
||||
@@ -1205,8 +1108,8 @@ JS
|
||||
);
|
||||
$aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem();
|
||||
} else {
|
||||
// $oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||
// $aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||
$oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:CreateCustom'), "return EditDashboard('{$this->sId}', '$sFile', $sJSExtraParams)");
|
||||
$aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem();
|
||||
}
|
||||
|
||||
utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions);
|
||||
@@ -1320,7 +1223,7 @@ EOF
|
||||
$sId = json_encode($this->sId);
|
||||
$sLayoutClass = json_encode($this->sLayoutClass);
|
||||
$sAutoReload = $this->bAutoReload ? 'true' : 'false';
|
||||
$sAutoReloadSec = (string)$this->iAutoReloadSec;
|
||||
$sAutoReloadSec = (string) $this->iAutoReloadSec;
|
||||
$sTitle = json_encode($this->sTitle);
|
||||
$sFile = json_encode($this->GetDefinitionFile());
|
||||
$sUrl = utils::GetAbsoluteUrlAppRoot().'pages/ajax.render.php';
|
||||
@@ -1492,11 +1395,19 @@ JS
|
||||
|
||||
// Get the list of possible dashlets that support a creation from
|
||||
// an OQL
|
||||
$aAllDashlets = DashletService::GetInstance()->GetAvailableDashlets();
|
||||
$aDashlets = [];
|
||||
foreach ($aAllDashlets as $sDashletClass => $aInfo) {
|
||||
if ($aInfo['can_create_by_oql']) {
|
||||
$aDashlets[$sDashletClass] = ['label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']];
|
||||
foreach (get_declared_classes() as $sDashletClass) {
|
||||
if (is_subclass_of($sDashletClass, 'Dashlet')) {
|
||||
$oReflection = new ReflectionClass($sDashletClass);
|
||||
if (!$oReflection->isAbstract()) {
|
||||
$aCallSpec = [$sDashletClass, 'CanCreateFromOQL'];
|
||||
$bShorcutMode = call_user_func($aCallSpec);
|
||||
if ($bShorcutMode) {
|
||||
$aCallSpec = [$sDashletClass, 'GetInfo'];
|
||||
$aInfo = call_user_func($aCallSpec);
|
||||
$aDashlets[$sDashletClass] = ['label' => $aInfo['label'], 'class' => $sDashletClass, 'icon' => $aInfo['icon']];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1506,7 +1417,7 @@ JS
|
||||
$oSubForm = new DesignerForm();
|
||||
$oMetaModel = new ModelReflectionRuntime();
|
||||
/** @var \Dashlet $oDashlet */
|
||||
$oDashlet = DashletFactory::GetInstance()->CreateDashlet($sDashletClass, 0);
|
||||
$oDashlet = new $sDashletClass($oMetaModel, 0);
|
||||
$oDashlet->GetPropertiesFieldsFromOQL($oSubForm, $sOQL);
|
||||
|
||||
$oSelectorField->AddSubForm($oSubForm, $aDashletInfo['label'], $aDashletInfo['class']);
|
||||
@@ -1660,7 +1571,7 @@ JS
|
||||
*/
|
||||
private function UpdateDashletUserPrefs(Dashlet $oDashlet, $sDashletIdOrig, array $aExtraParams)
|
||||
{
|
||||
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
|
||||
$bIsDashletWithListPref = ($oDashlet instanceof DashletObjectList);
|
||||
if (!$bIsDashletWithListPref) {
|
||||
return;
|
||||
}
|
||||
@@ -1708,7 +1619,6 @@ JS
|
||||
//on error, return default value
|
||||
return null;
|
||||
}
|
||||
|
||||
return DataTableSettings::GetAppUserPreferenceKey($aClassAliases, $sDataTableId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ use Combodo\iTop\Application\WebPage\WebPage;
|
||||
*/
|
||||
abstract class DashboardLayout
|
||||
{
|
||||
abstract public function Render($oPage, $aDashlets, $bEditMode = false, array $aExtraParams = []);
|
||||
abstract public function Render($oPage, $aDashlets, $bEditMode = false);
|
||||
|
||||
/**
|
||||
* @param int $iCellIdx
|
||||
@@ -43,8 +43,8 @@ abstract class DashboardLayout
|
||||
public static function GetInfo()
|
||||
{
|
||||
return [
|
||||
'label' => '',
|
||||
'icon' => '',
|
||||
'label' => '',
|
||||
'icon' => '',
|
||||
'description' => '',
|
||||
];
|
||||
}
|
||||
@@ -74,7 +74,6 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
|
||||
return $aDashlets;
|
||||
}
|
||||
|
||||
@@ -95,7 +94,6 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
}
|
||||
$idx++;
|
||||
}
|
||||
|
||||
return $aCells;
|
||||
|
||||
}
|
||||
@@ -111,8 +109,7 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
// Trim the list of cells to remove the invisible/empty ones at the end of the array
|
||||
$aCells = $this->TrimCellsArray($aCells);
|
||||
|
||||
// TODO 3.3 Handle dashboard new format, convert old format if needed
|
||||
$oDashboardLayout = new DashboardLayoutUIBlock($aExtraParams['dashboard_div_id']);
|
||||
$oDashboardLayout = new DashboardLayoutUIBlock();
|
||||
//$oPage->AddUiBlock($oDashboardLayout);
|
||||
|
||||
$iCellIdx = 0;
|
||||
@@ -120,16 +117,15 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
|
||||
//Js given by each dashlet to reload
|
||||
$sJSReload = "";
|
||||
$oDashboardGrid = new \Combodo\iTop\Application\UI\Base\Layout\Dashboard\DashboardGrid();
|
||||
$oDashboardLayout->SetGrid($oDashboardGrid);
|
||||
|
||||
for ($iRows = 0; $iRows < $iNbRows; $iRows++) {
|
||||
$oDashboardRow = new DashboardRow();
|
||||
//$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
||||
$oDashboardLayout->AddDashboardRow($oDashboardRow);
|
||||
|
||||
for ($iCols = 0; $iCols < $this->iNbCols; $iCols++) {
|
||||
$oDashboardColumn = new DashboardColumn($bEditMode);
|
||||
$oDashboardColumn->SetCellIndex($iCellIdx);
|
||||
//$oDashboardRow->AddDashboardColumn($oDashboardColumn);
|
||||
$oDashboardRow->AddDashboardColumn($oDashboardColumn);
|
||||
|
||||
if (array_key_exists($iCellIdx, $aCells)) {
|
||||
$aDashlets = $aCells[$iCellIdx];
|
||||
@@ -137,18 +133,6 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
/** @var \Dashlet $oDashlet */
|
||||
foreach ($aDashlets as $oDashlet) {
|
||||
if ($oDashlet::IsVisible()) {
|
||||
$sDashletId = $oDashlet->GetID();
|
||||
$sDashletClass = get_class($oDashlet);
|
||||
$aDashletDenormalizedProperties = $oDashlet->GetDenormalizedProperties();
|
||||
// $aDashletsInfo = $sDashletClass::GetInfo();
|
||||
//
|
||||
// // TODO 3.3 Gather real position and height/width if any.
|
||||
// // Also set minimal height/width
|
||||
// $iPositionX = null;
|
||||
// $iPositionY = null;
|
||||
// $iWidth = array_key_exists('preferred_width', $aDashletsInfo) ? $aDashletsInfo['preferred_width'] : 1;
|
||||
// $iHeight = array_key_exists('preferred_height', $aDashletsInfo) ? $aDashletsInfo['preferred_height'] : 1;
|
||||
// $oDashboardGrid->AddDashlet($oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams), $sDashletId, $sDashletClass, $aDashletDenormalizedProperties, $iPositionX, $iPositionY, $iWidth, $iHeight);
|
||||
$oDashboardColumn->AddUIBlock($oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams));
|
||||
}
|
||||
}
|
||||
@@ -163,7 +147,6 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
$sJSReload .= $oDashboardRow->GetJSRefreshCallback()." ";
|
||||
}
|
||||
|
||||
// TODO 3.3 We can probably do better with the new dashboard
|
||||
$oPage->add_script("function updateDashboard".$aExtraParams['dashboard_div_id']."(){".$sJSReload."}");
|
||||
|
||||
if ($bEditMode) { // Add one row for extensibility
|
||||
@@ -185,8 +168,8 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout
|
||||
*/
|
||||
public function GetDashletCoordinates($iCellIdx)
|
||||
{
|
||||
$iColNumber = (int)$iCellIdx % $this->iNbCols;
|
||||
$iRowNumber = (int)floor($iCellIdx / $this->iNbCols);
|
||||
$iColNumber = (int) $iCellIdx % $this->iNbCols;
|
||||
$iRowNumber = (int) floor($iCellIdx / $this->iNbCols);
|
||||
|
||||
return [$iColNumber, $iRowNumber];
|
||||
}
|
||||
@@ -199,12 +182,11 @@ class DashboardLayoutOneCol extends DashboardLayoutMultiCol
|
||||
parent::__construct();
|
||||
$this->iNbCols = 1;
|
||||
}
|
||||
|
||||
public static function GetInfo()
|
||||
{
|
||||
return [
|
||||
'label' => 'One Column',
|
||||
'icon' => 'images/layout_1col.png',
|
||||
'label' => 'One Column',
|
||||
'icon' => 'images/layout_1col.png',
|
||||
'description' => '',
|
||||
];
|
||||
}
|
||||
@@ -217,12 +199,11 @@ class DashboardLayoutTwoCols extends DashboardLayoutMultiCol
|
||||
parent::__construct();
|
||||
$this->iNbCols = 2;
|
||||
}
|
||||
|
||||
public static function GetInfo()
|
||||
{
|
||||
return [
|
||||
'label' => 'Two Columns',
|
||||
'icon' => 'images/layout_2col.png',
|
||||
'label' => 'Two Columns',
|
||||
'icon' => 'images/layout_2col.png',
|
||||
'description' => '',
|
||||
];
|
||||
}
|
||||
@@ -235,12 +216,11 @@ class DashboardLayoutThreeCols extends DashboardLayoutMultiCol
|
||||
parent::__construct();
|
||||
$this->iNbCols = 3;
|
||||
}
|
||||
|
||||
public static function GetInfo()
|
||||
{
|
||||
return [
|
||||
'label' => 'Two Columns',
|
||||
'icon' => 'images/layout_3col.png',
|
||||
'label' => 'Two Columns',
|
||||
'icon' => 'images/layout_3col.png',
|
||||
'description' => '',
|
||||
];
|
||||
}
|
||||
|
||||
2337
application/dashlet.class.inc.php
Normal file
2337
application/dashlet.class.inc.php
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
||||
<class id="AbstractResource" _delta="define">
|
||||
<parent>cmdbAbstractObject</parent>
|
||||
<properties>
|
||||
<comment>/* Resource access control abstraction. Can be inherited by abstract resource access control classes. Generally controlled using UR_ACTION_MODIFY access right. */</comment>
|
||||
<comment>/* Resource access control abstraction. Can be herited by abstract resource access control classes. Generally controlled using UR_ACTION_MODIFY access right. */</comment>
|
||||
<abstract>true</abstract>
|
||||
</properties>
|
||||
<presentation/>
|
||||
@@ -851,295 +851,9 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att
|
||||
</methods>
|
||||
</class>
|
||||
</classes>
|
||||
<dashlets>
|
||||
<dashlet id="DashletGroupByTable" _delta="define">
|
||||
<label>UI:DashletGroupByTable:Label</label>
|
||||
<icon>images/dashlets/icons8-transaction-list-48.png</icon>
|
||||
<description>UI:DashletGroupByTable:Description</description>
|
||||
<min_width>2</min_width>
|
||||
<min_height>2</min_height>
|
||||
<preferred_width>3</preferred_width>
|
||||
<preferred_height>3</preferred_height>
|
||||
<can_create_by_oql>true</can_create_by_oql>
|
||||
<configuration/>
|
||||
</dashlet>
|
||||
<dashlet id="DashletGroupByBars" _delta="define">
|
||||
<label>UI:DashletGroupByBars:Label</label>
|
||||
<icon>images/dashlets/icons8-bar-chart-48.png</icon>
|
||||
<description>UI:DashletGroupByBars:Description</description>
|
||||
<min_width>2</min_width>
|
||||
<min_height>2</min_height>
|
||||
<preferred_width>3</preferred_width>
|
||||
<preferred_height>3</preferred_height>
|
||||
<can_create_by_oql>true</can_create_by_oql>
|
||||
<configuration/>
|
||||
</dashlet>
|
||||
<dashlet id="DashletGroupByPie" _delta="define">
|
||||
<label>UI:DashletGroupByPie:Label</label>
|
||||
<icon>images/dashlets/icons8-pie-chart-48.png</icon>
|
||||
<description>UI:DashletGroupByPie:Description</description>
|
||||
<min_width>2</min_width>
|
||||
<min_height>2</min_height>
|
||||
<preferred_width>3</preferred_width>
|
||||
<preferred_height>3</preferred_height>
|
||||
<can_create_by_oql>true</can_create_by_oql>
|
||||
<configuration/>
|
||||
</dashlet>
|
||||
<dashlet id="DashletBadge" _delta="define">
|
||||
<label>UI:DashletBadge:Label</label>
|
||||
<icon>images/dashlets/icons8-badge-48.png</icon>
|
||||
<description>UI:DashletBadge:Description</description>
|
||||
<min_width>2</min_width>
|
||||
<min_height>1</min_height>
|
||||
<preferred_width>2</preferred_width>
|
||||
<preferred_height>1</preferred_height>
|
||||
<configuration/>
|
||||
</dashlet>
|
||||
<dashlet id="DashletHeaderDynamic" _delta="define">
|
||||
<label>UI:DashletHeaderDynamic:Label</label>
|
||||
<icon>images/dashlets/icons8-header-altered-48.png</icon>
|
||||
<description>UI:DashletHeaderDynamic:Description</description>
|
||||
<min_width>2</min_width>
|
||||
<min_height>1</min_height>
|
||||
<preferred_width>4</preferred_width>
|
||||
<preferred_height>3</preferred_height>
|
||||
<configuration/>
|
||||
</dashlet>
|
||||
<dashlet id="DashletHeaderStatic" _delta="define">
|
||||
<label>UI:DashletHeaderStatic:Label</label>
|
||||
<icon>images/dashlets/icons8-header-48.png</icon>
|
||||
<description>UI:DashletHeaderStatic:Description</description>
|
||||
<min_width>4</min_width>
|
||||
<min_height>1</min_height>
|
||||
<preferred_width>4</preferred_width>
|
||||
<preferred_height>1</preferred_height>
|
||||
<configuration/>
|
||||
</dashlet>
|
||||
<dashlet id="DashletObjectList" _delta="define">
|
||||
<label>UI:DashletObjectList:Label</label>
|
||||
<icon>images/dashlets/icons8-list-48.png</icon>
|
||||
<description>UI:DashletObjectList:Description</description>
|
||||
<min_width>2</min_width>
|
||||
<min_height>1</min_height>
|
||||
<preferred_width>4</preferred_width>
|
||||
<preferred_height>3</preferred_height>
|
||||
<can_create_by_oql>true</can_create_by_oql>
|
||||
<configuration/>
|
||||
</dashlet>
|
||||
<dashlet id="DashletPlainText" _delta="define">
|
||||
<label>UI:DashletPlainText:Label</label>
|
||||
<icon>images/dashlets/icons8-text-box-48.png</icon>
|
||||
<description>UI:DashletPlainText:Description</description>
|
||||
<min_width>2</min_width>
|
||||
<min_height>1</min_height>
|
||||
<preferred_width>2</preferred_width>
|
||||
<preferred_height>1</preferred_height>
|
||||
<configuration/>
|
||||
</dashlet>
|
||||
</dashlets>
|
||||
<property_types _delta="define">
|
||||
<property_type id="Dashboard" xsi:type="Combodo-AbstractPropertyType"/>
|
||||
<property_type id="DashboardGrid" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashboard</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<label>Dashboard</label>
|
||||
<nodes>
|
||||
<node id="title" xsi:type="Combodo-ValueType-String">
|
||||
<label>UI:DashboardEdit:DashboardTitle</label>
|
||||
</node>
|
||||
<node id="refresh" xsi:type="Combodo-ValueType-Choice"> <!-- Possible de le cacher, etc celui-ci nous met dedans -->
|
||||
<label>UI:DashboardEdit:AutoReload</label>
|
||||
<values>
|
||||
<value id="0">
|
||||
<label>No auto-refresh</label>
|
||||
</value>
|
||||
<value id="30">
|
||||
<label>Every 30 seconds</label>
|
||||
</value>
|
||||
<value id="60">
|
||||
<label>Every 1 minute</label>
|
||||
</value>
|
||||
<value id="300">
|
||||
<label>Every 5 minutes</label>
|
||||
</value>
|
||||
<value id="600">
|
||||
<label>Every 10 minutes</label>
|
||||
</value>
|
||||
<value id="1800">
|
||||
<label>Every 30 minutes</label>
|
||||
</value>
|
||||
<value id="3600">
|
||||
<label>Every 1 hour</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
<node id="pos_dashlets" xsi:type="Combodo-ValueType-Collection">
|
||||
<label>Dashlet List</label>
|
||||
<xml-format xsi:type="Combodo-XMLFormat-CollectionWithId">
|
||||
<tag-name>pos_dashlet</tag-name>
|
||||
</xml-format>
|
||||
<prototype>
|
||||
<node id="position_x" xsi:type="Combodo-ValueType-Integer">
|
||||
<label>X</label>
|
||||
</node>
|
||||
<node id="position_y" xsi:type="Combodo-ValueType-Integer">
|
||||
<label>Y</label>
|
||||
</node>
|
||||
<node id="width" xsi:type="Combodo-ValueType-Integer">
|
||||
<label>W</label>
|
||||
</node>
|
||||
<node id="height" xsi:type="Combodo-ValueType-Integer">
|
||||
<label>H</label>
|
||||
</node>
|
||||
<node id="dashlet" xsi:type="Combodo-ValueType-Polymorphic">
|
||||
<label>Dashlet</label>
|
||||
<allowed-types>
|
||||
<allowed-type>Dashlet</allowed-type>
|
||||
</allowed-types>
|
||||
</node>
|
||||
</prototype>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
<property_type id="Dashlet" xsi:type="Combodo-AbstractPropertyType"/>
|
||||
<property_type id="DashletGroupByTable" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<label>UI:DashletGroupBy:Title</label>
|
||||
<nodes>
|
||||
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||
<label>UI:DashletGroupBy:Prop-Title</label>
|
||||
</node>
|
||||
<node id="query" xsi:type="Combodo-ValueType-OQL">
|
||||
<label>UI:DashletGroupBy:Prop-Query</label>
|
||||
</node>
|
||||
<node id="group_by" xsi:type="Combodo-ValueType-ClassAttributeGroupBy">
|
||||
<label>UI:DashletGroupBy:Prop-GroupBy</label>
|
||||
<class>{{query.selected_class}}</class>
|
||||
</node>
|
||||
<node id="style" xsi:type="Combodo-ValueType-Choice"> <!-- Possible de le cacher, etc celui-ci nous met dedans -->
|
||||
<label>UI:DashletGroupBy:Prop-Style</label>
|
||||
<values>
|
||||
<value id="bars">
|
||||
<label>UI:DashletGroupByBars:Label</label>
|
||||
</value>
|
||||
<value id="pie">
|
||||
<label>UI:DashletGroupByPie:Label</label>
|
||||
</value>
|
||||
<value id="table">
|
||||
<label>UI:DashletGroupByTable:Label</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
<node id="aggregation_function" xsi:type="Combodo-ValueType-AggregateFunction">
|
||||
<label>UI:DashletGroupBy:Prop-Function</label>
|
||||
<class>{{query.selected_class}}</class> <!-- pour savoir si il y a des attributs additionnables -->
|
||||
</node>
|
||||
<node id="aggregation_attribute" xsi:type="Combodo-ValueType-ClassAttribute">
|
||||
<label>UI:DashletGroupBy:Prop-FunctionAttribute</label>
|
||||
<relevance-condition>{{aggregation_function.value != 'count'}}</relevance-condition>
|
||||
<class>{{query.selected_class}}</class>
|
||||
<category>numeric</category>
|
||||
</node>
|
||||
<node id="order_by" xsi:type="Combodo-ValueType-ChoiceFromInput">
|
||||
<label>UI:DashletGroupBy:Prop-OrderField</label>
|
||||
<values>
|
||||
<value id="attribute">
|
||||
<label>{{aggregation_attribute.label}}</label>
|
||||
</value>
|
||||
<value id="function">
|
||||
<label>{{aggregation_function.label}}</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
<node id="limit" xsi:type="Combodo-ValueType-Integer">
|
||||
<label>UI:DashletGroupBy:Prop-Limit</label>
|
||||
<relevance-condition>{{order_by.value = 'function'}}</relevance-condition>
|
||||
</node>
|
||||
<node id="order_direction" xsi:type="Combodo-ValueType-Choice">
|
||||
<label>UI:DashletGroupBy:Prop-OrderDirection</label>
|
||||
<values>
|
||||
<value id="asc">
|
||||
<label>UI:DashletGroupBy:Order:asc</label>
|
||||
</value>
|
||||
<value id="desc">
|
||||
<label>UI:DashletGroupBy:Order:desc</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
<property_type id="DashletGroupByBars" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<label>UI:DashletGroupBy:Title</label>
|
||||
<nodes>
|
||||
<node id="title" xsi:type="Combodo-ValueType-Label">
|
||||
<label>UI:DashletGroupBy:Prop-Title</label>
|
||||
</node>
|
||||
<node id="query" xsi:type="Combodo-ValueType-OQL">
|
||||
<label>UI:DashletGroupBy:Prop-Query</label>
|
||||
</node>
|
||||
<node id="group_by" xsi:type="Combodo-ValueType-ClassAttributeGroupBy">
|
||||
<label>UI:DashletGroupBy:Prop-GroupBy</label>
|
||||
<class>{{query.selected_class}}</class>
|
||||
</node>
|
||||
<node id="style" xsi:type="Combodo-ValueType-Choice"> <!-- Possible de le cacher, etc celui-ci nous met dedans -->
|
||||
<label>UI:DashletGroupBy:Prop-Style</label>
|
||||
<values>
|
||||
<value id="bars">
|
||||
<label>UI:DashletGroupByBars:Label</label>
|
||||
</value>
|
||||
<value id="pie">
|
||||
<label>UI:DashletGroupByPie:Label</label>
|
||||
</value>
|
||||
<value id="table">
|
||||
<label>UI:DashletGroupByTable:Label</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
<node id="aggregation_function" xsi:type="Combodo-ValueType-AggregateFunction">
|
||||
<label>UI:DashletGroupBy:Prop-Function</label>
|
||||
<class>{{query.selected_class}}</class> <!-- pour savoir si il y a des attributs additionnables -->
|
||||
</node>
|
||||
<node id="aggregation_attribute" xsi:type="Combodo-ValueType-ClassAttribute">
|
||||
<label>UI:DashletGroupBy:Prop-FunctionAttribute</label>
|
||||
<relevance-condition>{{aggregation_function.value != 'count'}}</relevance-condition>
|
||||
<class>{{query.selected_class}}</class>
|
||||
<category>numeric</category>
|
||||
</node>
|
||||
<node id="order_by" xsi:type="Combodo-ValueType-ChoiceFromInput">
|
||||
<label>UI:DashletGroupBy:Prop-OrderField</label>
|
||||
<values>
|
||||
<value id="attribute">
|
||||
<label>{{aggregation_attribute.label}}</label>
|
||||
</value>
|
||||
<value id="function">
|
||||
<label>{{aggregation_function.label}}</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
<node id="limit" xsi:type="Combodo-ValueType-Integer">
|
||||
<label>UI:DashletGroupBy:Prop-Limit</label>
|
||||
<relevance-condition>{{order_by.value = 'function'}}</relevance-condition>
|
||||
</node>
|
||||
<node id="order_direction" xsi:type="Combodo-ValueType-Choice">
|
||||
<label>UI:DashletGroupBy:Prop-OrderDirection</label>
|
||||
<values>
|
||||
<value id="asc">
|
||||
<label>UI:DashletGroupBy:Order:asc</label>
|
||||
</value>
|
||||
<value id="desc">
|
||||
<label>UI:DashletGroupBy:Order:desc</label>
|
||||
</value>
|
||||
</values>
|
||||
</node>
|
||||
</nodes>
|
||||
</definition>
|
||||
</property_type>
|
||||
<property_type id="DashletGroupByPie" xsi:type="Combodo-PropertyType">
|
||||
<property_type id="DashletGroupBy" xsi:type="Combodo-PropertyType">
|
||||
<extends>Dashlet</extends>
|
||||
<definition xsi:type="Combodo-ValueType-PropertyTree">
|
||||
<label>UI:DashletGroupBy:Title</label>
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Application\Helper\WebResourcesHelper;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentFactory;
|
||||
use Combodo\iTop\Application\WebPage\ErrorPage;
|
||||
use Combodo\iTop\Application\WebPage\iTopWebPage;
|
||||
use Combodo\iTop\Application\WebPage\WebPage;
|
||||
@@ -1280,14 +1279,13 @@ class DashboardMenuNode extends MenuNode
|
||||
if ($oDashboard != null) {
|
||||
WebResourcesHelper::EnableC3JSToWebPage($oPage);
|
||||
|
||||
// TODO 3.3 this works for dashboard menu, what about other places ?
|
||||
$oPageLayout = PageContentFactory::MakeForDashboard();
|
||||
$oPage->SetContentLayout($oPageLayout, $oPage);
|
||||
$sDivId = utils::Sanitize($this->sMenuId, '', 'element_identifier');
|
||||
$oPage->add('<div id="'.$sDivId.'" class="ibo-dashboard" data-role="ibo-dashboard">');
|
||||
$aExtraParams['dashboard_div_id'] = $sDivId;
|
||||
$aExtraParams['from_dashboard_page'] = true;
|
||||
$oDashboard->SetReloadURL($this->GetHyperlink($aExtraParams));
|
||||
$oDashboard->Render($oPage, false, $aExtraParams);
|
||||
$oPage->add('</div>');
|
||||
|
||||
$bEdit = utils::ReadParam('edit', false);
|
||||
if ($bEdit) {
|
||||
|
||||
@@ -1954,11 +1954,6 @@ class Config
|
||||
*/
|
||||
protected $m_sDefaultLanguage;
|
||||
|
||||
/**
|
||||
* @var string Type of login process allowed: form|basic|url|external
|
||||
*/
|
||||
protected $m_sAllowedLoginTypes;
|
||||
|
||||
/**
|
||||
* @var string Name of the PHP variable in which external authentication information is passed by the web server
|
||||
*/
|
||||
@@ -2032,7 +2027,6 @@ class Config
|
||||
$this->m_iFastReloadInterval = DEFAULT_FAST_RELOAD_INTERVAL;
|
||||
$this->m_bSecureConnectionRequired = DEFAULT_SECURE_CONNECTION_REQUIRED;
|
||||
$this->m_sDefaultLanguage = 'EN US';
|
||||
$this->m_sAllowedLoginTypes = DEFAULT_ALLOWED_LOGIN_TYPES;
|
||||
$this->m_sExtAuthVariable = DEFAULT_EXT_AUTH_VARIABLE;
|
||||
$this->m_aCharsets = [];
|
||||
$this->m_bQueryCacheEnabled = DEFAULT_QUERY_CACHE_ENABLED;
|
||||
@@ -2179,7 +2173,6 @@ class Config
|
||||
$this->m_aModuleSettings = isset($MyModuleSettings) ? $MyModuleSettings : [];
|
||||
|
||||
$this->m_sDefaultLanguage = isset($MySettings['default_language']) ? trim($MySettings['default_language']) : 'EN US';
|
||||
$this->m_sAllowedLoginTypes = isset($MySettings['allowed_login_types']) ? trim($MySettings['allowed_login_types']) : DEFAULT_ALLOWED_LOGIN_TYPES;
|
||||
$this->m_sExtAuthVariable = isset($MySettings['ext_auth_variable']) ? trim($MySettings['ext_auth_variable']) : DEFAULT_EXT_AUTH_VARIABLE;
|
||||
$this->m_sEncryptionKey = isset($MySettings['encryption_key']) ? trim($MySettings['encryption_key']) : $this->m_sEncryptionKey;
|
||||
$this->m_sEncryptionLibrary = isset($MySettings['encryption_library']) ? trim($MySettings['encryption_library']) : $this->m_sEncryptionLibrary;
|
||||
@@ -2339,7 +2332,7 @@ class Config
|
||||
|
||||
public function GetAllowedLoginTypes()
|
||||
{
|
||||
return explode('|', $this->m_sAllowedLoginTypes);
|
||||
return explode('|', $this->m_aSettings['allowed_login_types']['value']);
|
||||
}
|
||||
|
||||
public function GetExternalAuthenticationVariable()
|
||||
@@ -2417,7 +2410,6 @@ class Config
|
||||
|
||||
public function SetAllowedLoginTypes($aAllowedLoginTypes)
|
||||
{
|
||||
$this->m_sAllowedLoginTypes = implode('|', $aAllowedLoginTypes);
|
||||
$this->Set('allowed_login_types', implode('|', $aAllowedLoginTypes));
|
||||
}
|
||||
|
||||
@@ -2495,7 +2487,6 @@ class Config
|
||||
$aSettings['fast_reload_interval'] = $this->m_iFastReloadInterval;
|
||||
$aSettings['secure_connection_required'] = $this->m_bSecureConnectionRequired;
|
||||
$aSettings['default_language'] = $this->m_sDefaultLanguage;
|
||||
$aSettings['allowed_login_types'] = $this->m_sAllowedLoginTypes;
|
||||
$aSettings['ext_auth_variable'] = $this->m_sExtAuthVariable;
|
||||
$aSettings['encryption_key'] = $this->m_sEncryptionKey;
|
||||
$aSettings['encryption_library'] = $this->m_sEncryptionLibrary;
|
||||
@@ -2599,7 +2590,6 @@ class Config
|
||||
// Old fashioned remaining values
|
||||
$aOtherValues = [
|
||||
'default_language' => $this->m_sDefaultLanguage,
|
||||
'allowed_login_types' => $this->m_sAllowedLoginTypes,
|
||||
'ext_auth_variable' => $this->m_sExtAuthVariable,
|
||||
'encryption_key' => $this->m_sEncryptionKey,
|
||||
'encryption_library' => $this->m_sEncryptionLibrary,
|
||||
|
||||
@@ -89,17 +89,9 @@ abstract class ModelReflection
|
||||
* @param string $defaultValue
|
||||
*
|
||||
* @return \RunTimeIconSelectionField
|
||||
* @deprecated since 3.3.0 replaced by GetAvailableIcons
|
||||
*/
|
||||
abstract public function GetIconSelectionField($sCode, $sLabel = '', $defaultValue = '');
|
||||
|
||||
/**
|
||||
* Find available icons for the current context
|
||||
*
|
||||
* @return array of ['value', 'label', 'icon'] where 'value' is the relative path on disk, 'label' the name to display and 'icon' is the URL to get the image
|
||||
*/
|
||||
abstract public function GetAvailableIcons(): array;
|
||||
|
||||
abstract public function GetRootClass($sClass);
|
||||
abstract public function EnumChildClasses($sClass, $iOption = ENUM_CHILD_CLASSES_EXCLUDETOP);
|
||||
}
|
||||
@@ -117,8 +109,6 @@ abstract class QueryReflection
|
||||
|
||||
class ModelReflectionRuntime extends ModelReflection
|
||||
{
|
||||
private static array $aAllIcons = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
@@ -265,52 +255,6 @@ class ModelReflectionRuntime extends ModelReflection
|
||||
return new RunTimeIconSelectionField($sCode, $sLabel, $defaultValue);
|
||||
}
|
||||
|
||||
public function GetAvailableIcons(): array
|
||||
{
|
||||
$aFolderList = [
|
||||
APPROOT.'env-'.utils::GetCurrentEnvironment() => utils::GetAbsoluteUrlModulesRoot(),
|
||||
APPROOT.'images/icons' => utils::GetAbsoluteUrlAppRoot().'images/icons',
|
||||
];
|
||||
if (count(self::$aAllIcons) == 0) {
|
||||
foreach ($aFolderList as $sFolderPath => $sUrlPrefix) {
|
||||
$aIcons = self::FindIconsOnDisk($sFolderPath);
|
||||
ksort($aIcons);
|
||||
|
||||
foreach ($aIcons as $sFilePath) {
|
||||
self::$aAllIcons[] = ['value' => $sFilePath, 'label' => basename($sFilePath), 'icon' => $sUrlPrefix.$sFilePath];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self::$aAllIcons;
|
||||
}
|
||||
|
||||
private static function FindIconsOnDisk(string $sBaseDir, string $sDir = '', array &$aFilesSpecs = []): array
|
||||
{
|
||||
$aResult = [];
|
||||
// Populate automatically the list of icon files
|
||||
if ($hDir = @opendir($sBaseDir.'/'.$sDir)) {
|
||||
while (($sFile = readdir($hDir)) !== false) {
|
||||
$aMatches = [];
|
||||
if (($sFile != '.') && ($sFile != '..') && ($sFile != 'lifecycle') && is_dir($sBaseDir.'/'.$sDir.'/'.$sFile)) {
|
||||
$sDirSubPath = ($sDir == '') ? $sFile : $sDir.'/'.$sFile;
|
||||
$aResult = array_merge($aResult, self::FindIconsOnDisk($sBaseDir, $sDirSubPath, $aFilesSpecs));
|
||||
}
|
||||
$sSize = filesize($sBaseDir.'/'.$sDir.'/'.$sFile);
|
||||
if (isset($aFilesSpecs[$sFile]) && $aFilesSpecs[$sFile] == $sSize) {
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/\.(png|jpg|jpeg|gif|svg)$/i', $sFile, $aMatches)) { // png, jp(e)g, gif and svg are considered valid
|
||||
$aResult[$sFile.'_'.$sDir] = $sDir.'/'.$sFile;
|
||||
$aFilesSpecs[$sFile] = $sSize;
|
||||
}
|
||||
}
|
||||
closedir($hDir);
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
public function GetRootClass($sClass)
|
||||
{
|
||||
return MetaModel::GetRootClass($sClass);
|
||||
|
||||
@@ -75,26 +75,3 @@ collection-entry-element {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.ibo-form-compact{
|
||||
|
||||
.ibo-field{
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
|
||||
label{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
max-width: unset;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -19,10 +19,7 @@ $ibo-dashlet-blocker--height: 100% !default;
|
||||
.ibo-dashlet {
|
||||
position: relative;
|
||||
width: calc(#{$ibo-dashlet--width} - #{$ibo-dashlet--elements-spacing-x});
|
||||
//margin: calc(#{$ibo-dashlet--elements-spacing-y} / 2) calc(#{$ibo-dashlet--elements-spacing-x} / 2);
|
||||
|
||||
height: 100% !important;
|
||||
width: 100% !important;
|
||||
margin: calc(#{$ibo-dashlet--elements-spacing-y} / 2) calc(#{$ibo-dashlet--elements-spacing-x} / 2);
|
||||
|
||||
&.dashlet-selected {
|
||||
position: relative;
|
||||
@@ -41,21 +38,4 @@ $ibo-dashlet-blocker--height: 100% !default;
|
||||
width: $ibo-dashlet-blocker--width;
|
||||
height: $ibo-dashlet-blocker--height;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.ibo-dashlet--actions {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
display: none;
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
|
||||
background-color: $ibo-color-white-100;
|
||||
@extend %ibo-elevation-100;
|
||||
}
|
||||
|
||||
ibo-dashlet[data-edit-mode="edit"] {
|
||||
z-index: 3;
|
||||
}
|
||||
@@ -54,31 +54,3 @@ $ibo-input-select-icon--menu--icon--margin-right: 10px !default;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ts-control > .ibo-input-select-icon--menu--item{
|
||||
|
||||
display: flex;
|
||||
column-gap: 5px;
|
||||
align-items: center;
|
||||
padding: 5px 0;
|
||||
|
||||
> img{
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
&:hover{
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.ts-dropdown > .ts-dropdown-content > .ibo-input-select-icon--menu--item{
|
||||
|
||||
display: flex;
|
||||
column-gap: 5px;
|
||||
|
||||
> img{
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,4 +15,3 @@
|
||||
@import "wizard-container/wizard-container";
|
||||
@import "object/all";
|
||||
@import "activity-panel/all";
|
||||
@import "dashlet-panel/all";
|
||||
|
||||
@@ -175,73 +175,3 @@ input:checked + .ibo-dashboard--slider:before {
|
||||
input:checked + .ibo-dashboard--slider:after {
|
||||
content: $ibo-dashboard--slider--before--content;
|
||||
}
|
||||
|
||||
// TODO 3.3 Cleanup variables
|
||||
// TODO 3.3 Move to vendor what's from gridstack
|
||||
|
||||
|
||||
.grid-stack {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ibo-dashboard[data-edit-mode="edit"] .grid-stack{
|
||||
background-size: calc(100% / 12) var(--gs-cell-height);
|
||||
background-color: $ibo-color-white-100;
|
||||
background-image: linear-gradient(to right, $ibo-color-white-200 8px, transparent 8px), linear-gradient(to bottom, $ibo-color-white-200 8px, transparent 8px);
|
||||
--gs-item-margin-top: 8px;
|
||||
--gs-item-margin-bottom: 0;
|
||||
--gs-item-margin-right: 0;
|
||||
--gs-item-margin-left: 8px;
|
||||
}
|
||||
|
||||
ibo-dashboard[data-edit-mode="view"] {
|
||||
.ibo-dashboard--form {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-dashboard--form {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
height: 55px;
|
||||
background-color: $ibo-color-blue-200;
|
||||
margin: -16px -36px 24px -36px;
|
||||
padding: 0 36px;
|
||||
}
|
||||
|
||||
.ibo-dashboard--form--inputs {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
|
||||
@extend %common-font-ral-med-250;
|
||||
}
|
||||
|
||||
.ibo-dashboard[data-edit-mode="edit"] ibo-dashlet:not([data-edit-mode="edit"]):hover .ibo-dashlet--actions {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.ibo-dashboard[data-edit-mode="error"] .grid-stack{
|
||||
background-image: url($approot-relative + '/images/alpha-fatal-error.gif');
|
||||
}
|
||||
|
||||
// Our edit mode dashboard already has its own header, so we hide the standard one
|
||||
#ibo-page-header:has(+ ibo-dashboard[data-edit-mode="edit"]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ibo-dashboard[data-edit-mode="edit"] .ibo-dashboard--grid:has(ibo-dashboard-grid-slot > ibo-dashlet[data-edit-mode="edit"]) .ibo-dashboard--grid--backdrop {
|
||||
|
||||
position: absolute;
|
||||
height: calc(100% + 24px);
|
||||
// 36px is $ibo-page-container--elements-padding-x, handle variable resolution
|
||||
width: calc(100% + 36px + 36px);
|
||||
margin: -24px -#{36px} 0 -#{36px};
|
||||
background-color: $ibo-color-grey-400;
|
||||
z-index: 2;
|
||||
opacity: 60%;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
@import "dashlet-entry";
|
||||
@import "dashlet-panel";
|
||||
@@ -1,51 +0,0 @@
|
||||
// TODO 3.3 Cleanup variables
|
||||
|
||||
.ibo-dashlet-entry {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
|
||||
|
||||
border: 1px solid $ibo-color-grey-300;
|
||||
border-radius: 5px;
|
||||
padding: 12px;
|
||||
background-color: $ibo-color-grey-100;
|
||||
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
background-color: $ibo-color-grey-200;
|
||||
border-color: $ibo-color-grey-400;
|
||||
}
|
||||
&:active {
|
||||
background-color: $ibo-color-grey-50;
|
||||
border-color: $ibo-color-grey-500;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-dashlet-entry--icon {
|
||||
flex-shrink: 0;
|
||||
height: 36px;
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
.ibo-dashlet-entry--content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
overflow-x: hidden;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.ibo-dashlet-entry--title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: $ibo-color-grey-900;
|
||||
}
|
||||
|
||||
.ibo-dashlet-entry--description {
|
||||
font-size: 12px;
|
||||
color: $ibo-color-grey-700;
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
// TODO 3.3 Cleanup variables
|
||||
|
||||
.ibo-dashlet-panel {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 326px;
|
||||
background-color: $ibo-color-white-100;
|
||||
}
|
||||
|
||||
.ibo-dashlet-panel--title {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
height: 55px;
|
||||
background-color: $ibo-color-white-200;
|
||||
padding: 0 16px;
|
||||
flex-grow: 0;
|
||||
@extend %common-font-ral-med-300;
|
||||
}
|
||||
|
||||
.ibo-dashlet-panel--entries, .ibo-dashlet-panel--form-container {
|
||||
flex-grow: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: auto;
|
||||
|
||||
padding: 16px;
|
||||
gap: 12px;
|
||||
&.ibo-is-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-center-container:has(ibo-dashboard[data-edit-mode="view"]) .ibo-dashlet-panel{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ibo-dashlet-panel--form-container turbo-frame {
|
||||
height: 100%;
|
||||
}
|
||||
.ibo-dashlet-panel--form-container .ibo-form {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
> .form {
|
||||
overflow: auto;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.ibo-dashlet-panel--form-container--buttons {
|
||||
display: flex;
|
||||
flex-direction: row !important;
|
||||
justify-content: end;
|
||||
align-items: center;
|
||||
|
||||
margin: 0 -16px -16px -16px;
|
||||
padding: 0 16px;
|
||||
min-height: 60px;
|
||||
|
||||
background-color: $ibo-color-grey-50;
|
||||
border-top: solid 1px $ibo-color-grey-400;
|
||||
}
|
||||
@@ -698,6 +698,29 @@
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
<transition id="ev_autoresolve">
|
||||
<target>resolved</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>SetCurrentDate</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">resolution_date</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>SetElapsedTime</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">time_spent</param>
|
||||
<param xsi:type="attcode">start_date</param>
|
||||
<param xsi:type="string">DefaultWorkingTimeComputer</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>ResolveChildTickets</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="assigned">
|
||||
@@ -1029,29 +1052,6 @@
|
||||
<actions>
|
||||
</actions>
|
||||
</transition>
|
||||
<transition id="ev_autoresolve">
|
||||
<target>resolved</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>SetCurrentDate</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">resolution_date</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>SetElapsedTime</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">time_spent</param>
|
||||
<param xsi:type="attcode">start_date</param>
|
||||
<param xsi:type="string">DefaultWorkingTimeComputer</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>ResolveChildTickets</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="closed">
|
||||
|
||||
@@ -764,6 +764,29 @@
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
<transition id="ev_autoresolve">
|
||||
<target>resolved</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>SetCurrentDate</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">resolution_date</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>SetElapsedTime</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">time_spent</param>
|
||||
<param xsi:type="attcode">start_date</param>
|
||||
<param xsi:type="string">DefaultWorkingTimeComputer</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>ResolveChildTickets</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="assigned">
|
||||
@@ -964,6 +987,29 @@
|
||||
<target>rejected</target>
|
||||
<actions/>
|
||||
</transition>
|
||||
<transition id="ev_autoresolve">
|
||||
<target>resolved</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>SetCurrentDate</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">resolution_date</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>SetElapsedTime</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">time_spent</param>
|
||||
<param xsi:type="attcode">start_date</param>
|
||||
<param xsi:type="string">DefaultWorkingTimeComputer</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>ResolveChildTickets</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="approved">
|
||||
@@ -1173,29 +1219,6 @@
|
||||
<actions>
|
||||
</actions>
|
||||
</transition>
|
||||
<transition id="ev_autoresolve">
|
||||
<target>resolved</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>SetCurrentDate</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">resolution_date</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>SetElapsedTime</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">time_spent</param>
|
||||
<param xsi:type="attcode">start_date</param>
|
||||
<param xsi:type="string">DefaultWorkingTimeComputer</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>ResolveChildTickets</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="closed">
|
||||
|
||||
@@ -307,7 +307,9 @@
|
||||
</field>
|
||||
<field id="servicesubcategory_id" xsi:type="AttributeExternalKey">
|
||||
<filter><![CDATA[SELECT ServiceSubcategory WHERE service_id = :this->service_id AND status != 'obsolete']]></filter>
|
||||
<dependencies/>
|
||||
<dependencies>
|
||||
<attribute id="service_id"/>
|
||||
</dependencies>
|
||||
<sql>servicesubcategory_id</sql>
|
||||
<target_class>ServiceSubcategory</target_class>
|
||||
<is_null_allowed>true</is_null_allowed>
|
||||
@@ -765,6 +767,29 @@
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
<transition id="ev_autoresolve">
|
||||
<target>resolved</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>SetCurrentDate</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">resolution_date</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>SetElapsedTime</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">time_spent</param>
|
||||
<param xsi:type="attcode">start_date</param>
|
||||
<param xsi:type="string">DefaultWorkingTimeComputer</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>ResolveChildTickets</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="assigned">
|
||||
@@ -968,6 +993,29 @@
|
||||
<target>rejected</target>
|
||||
<actions/>
|
||||
</transition>
|
||||
<transition id="ev_autoresolve">
|
||||
<target>resolved</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>SetCurrentDate</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">resolution_date</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>SetElapsedTime</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">time_spent</param>
|
||||
<param xsi:type="attcode">start_date</param>
|
||||
<param xsi:type="string">DefaultWorkingTimeComputer</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>ResolveChildTickets</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="approved">
|
||||
@@ -1180,29 +1228,6 @@
|
||||
<actions>
|
||||
</actions>
|
||||
</transition>
|
||||
<transition id="ev_autoresolve">
|
||||
<target>resolved</target>
|
||||
<actions>
|
||||
<action>
|
||||
<verb>SetCurrentDate</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">resolution_date</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>SetElapsedTime</verb>
|
||||
<params>
|
||||
<param xsi:type="attcode">time_spent</param>
|
||||
<param xsi:type="attcode">start_date</param>
|
||||
<param xsi:type="string">DefaultWorkingTimeComputer</param>
|
||||
</params>
|
||||
</action>
|
||||
<action>
|
||||
<verb>ResolveChildTickets</verb>
|
||||
<params/>
|
||||
</action>
|
||||
</actions>
|
||||
</transition>
|
||||
</transitions>
|
||||
</state>
|
||||
<state id="closed">
|
||||
|
||||
@@ -243,7 +243,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:Service/Attribute:description' => 'Popis',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Balíček služeb',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Název rodiny služeb',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumenty',
|
||||
|
||||
@@ -242,7 +242,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:Service/Attribute:description' => 'Beskrivelse',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service familie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Ydelses familie navn',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokument',
|
||||
@@ -500,7 +500,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Beskrivelse',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakt',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Kunde',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -242,7 +242,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:Service/Attribute:description' => 'Beschreibung',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service-Familie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service-Familien-Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumente',
|
||||
|
||||
@@ -268,7 +268,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documents',
|
||||
@@ -526,7 +526,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
|
||||
]);
|
||||
|
||||
@@ -268,7 +268,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documents',
|
||||
@@ -526,7 +526,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
|
||||
]);
|
||||
|
||||
@@ -239,7 +239,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:Service/Attribute:description' => 'Descripción',
|
||||
'Class:Service/Attribute:description+' => 'Descripción',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_name+' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:documents_list' => 'Documentos',
|
||||
|
||||
@@ -247,7 +247,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Famille de service',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Obligatoire pour que ce service soit visible dans le portal utilisateur',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nom Famille de service',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documents',
|
||||
@@ -511,7 +511,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Tous les contacts (Equipe ou Personne) pour ce modèle de support',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Il doit y avoir au moins une équipe pour permettre l\'assignation des Tickets',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Clients',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'Tous les clients ayant ce modèle de support',
|
||||
'Class:DeliveryModel/Attribute:customers_list/UI:Links:Create:Button+' => 'Créer un %4$s',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:Service/Attribute:description' => 'Leírás',
|
||||
'Class:Service/Attribute:description+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Szolgáltatáscsalád',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Szolgáltatáscsalád név',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumentumok',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:Service/Attribute:description' => 'Descrizione',
|
||||
'Class:Service/Attribute:description+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Famiglia di Servizi',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nome della Famiglia di Servizi',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:documents_list' => 'Documenti',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:Service/Attribute:description' => '説明',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'サービスファミリ',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'サービスファミリ名',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => '文書',
|
||||
@@ -499,7 +499,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:DeliveryModel/Attribute:description' => '説明',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => '連絡先',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => '顧客',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -243,7 +243,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:Service/Attribute:description' => 'Omschrijving',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Servicecategorie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Naam servicecategorie',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documenten',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:Service/Attribute:description' => 'Opis',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Rodzina usług',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nazwa rodziny usług',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumenty',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:Service/Attribute:description' => 'Descrição',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Família de serviços',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nome da família de serviços',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Documentos',
|
||||
|
||||
@@ -242,7 +242,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:Service/Attribute:description' => 'Описание',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Пакет услуг',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Пакет услуг',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => 'Документы',
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:Service/Attribute:description' => 'Popis',
|
||||
'Class:Service/Attribute:description+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Kategória služieb',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Názov rodiny služieb',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:documents_list' => 'Dokumenty',
|
||||
@@ -499,7 +499,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Popis',
|
||||
'Class:DeliveryModel/Attribute:description+' => '~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakty',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Zákazníci',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -241,7 +241,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:Service/Attribute:description' => 'Tanımlama',
|
||||
'Class:Service/Attribute:description+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name~~',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:documents_list' => 'Documents~~',
|
||||
@@ -499,7 +499,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description~~',
|
||||
'Class:DeliveryModel/Attribute:description+' => '~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -264,7 +264,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:Service/Attribute:description' => '描述',
|
||||
'Class:Service/Attribute:description+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => '服务系列',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => '服务系列名称',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:documents_list' => '文档',
|
||||
|
||||
@@ -218,7 +218,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:Service/Attribute:organization_name' => 'Název poskytovatele',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Balíček služeb',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Název rodiny služeb',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Popis',
|
||||
|
||||
@@ -217,7 +217,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:Service/Attribute:organization_name' => 'Leverandør navn',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service familie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Ydelses familie navn',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Beskrivelse',
|
||||
@@ -463,7 +463,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Beskrivelse',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakt',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Kunde',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -217,7 +217,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:Service/Attribute:organization_name' => 'Provider-Name',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service-Familie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service-Familien-Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Beschreibung',
|
||||
|
||||
@@ -240,7 +240,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:Service/Attribute:organization_name' => 'Provider Name',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
@@ -486,7 +486,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
|
||||
]);
|
||||
|
||||
@@ -240,7 +240,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:Service/Attribute:organization_name' => 'Provider Name',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Service Family',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Service Family Name',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Description',
|
||||
@@ -486,7 +486,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Person) for this delivery model',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Customers',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model',
|
||||
]);
|
||||
|
||||
@@ -214,7 +214,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:Service/Attribute:organization_name' => 'Proveedor',
|
||||
'Class:Service/Attribute:organization_name+' => 'Proveedor',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:servicefamily_name+' => 'Familia de Servicios',
|
||||
'Class:Service/Attribute:description' => 'Descripción',
|
||||
|
||||
@@ -214,7 +214,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:Service/Attribute:organization_name' => 'Nom fournisseur',
|
||||
'Class:Service/Attribute:organization_name+' => 'Nom commun',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Famille de service',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Obligatoire pour que ce service soit visible dans le portal utilisateur',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nom Famille de service',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:services_list/UI:Links:Create:Button+' => 'Créer un %4$s',
|
||||
@@ -478,7 +478,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Description',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Contacts',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Tous les contacts (Equipe ou Personne) pour ce modèle de support',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'Il doit y avoir au moins une équipe pour permettre l\'assignation des Tickets',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Clients',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'Tous les clients ayant ce modèle de support',
|
||||
'Class:DeliveryModel/Attribute:customers_list/UI:Links:Create:Button+' => 'Créer un %4$s',
|
||||
|
||||
@@ -216,7 +216,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:Service/Attribute:organization_name' => 'Szolgáltató név',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Szolgáltatáscsalád',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Szolgáltatáscsalád név',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Leírás',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:Service/Attribute:organization_name' => 'Nome del Fornitore',
|
||||
'Class:Service/Attribute:organization_name+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Famiglia di Servizi',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nome della Famiglia di Servizi',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:description' => 'Descrizione',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:Service/Attribute:organization_name' => 'プロバイダー名',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'サービスファミリ',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'サービスファミリ名',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => '説明',
|
||||
@@ -461,7 +461,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:DeliveryModel/Attribute:description' => '説明',
|
||||
'Class:DeliveryModel/Attribute:description+' => '',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => '連絡先',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => '顧客',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -217,7 +217,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:Service/Attribute:organization_name' => 'Naam leverancier',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Servicecategorie',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Naam servicecategorie',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Omschrijving',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:Service/Attribute:organization_name' => 'Nazwa dostawcy',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Rodzina usług',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nazwa rodziny usług',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Opis',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:Service/Attribute:organization_name' => 'Nome do provedor',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Família de serviços',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Nome da família de serviços',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Descrição',
|
||||
|
||||
@@ -216,7 +216,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:Service/Attribute:organization_name' => 'Поставщик',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Пакет услуг',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Пакет услуг',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => 'Описание',
|
||||
|
||||
@@ -215,7 +215,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:Service/Attribute:organization_name' => 'Meno poskytovateľa',
|
||||
'Class:Service/Attribute:organization_name+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Kategória služieb',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Názov rodiny služieb',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:description' => 'Popis',
|
||||
@@ -461,7 +461,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:DeliveryModel/Attribute:description' => 'Popis',
|
||||
'Class:DeliveryModel/Attribute:description+' => '~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list' => 'Kontakty',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'All the contacts (Teams and Persons) for this delivery model~~',
|
||||
'Class:DeliveryModel/Attribute:contacts_list+' => 'There must be at least one team to enable Ticket assignment~~',
|
||||
'Class:DeliveryModel/Attribute:customers_list' => 'Zákazníci',
|
||||
'Class:DeliveryModel/Attribute:customers_list+' => 'All the customers having this delivering model~~',
|
||||
]);
|
||||
|
||||
@@ -216,7 +216,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:Service/Attribute:organization_name' => 'Sağlayıcı Adı',
|
||||
'Class:Service/Attribute:organization_name+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id' => 'Servis Ailesi',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '~~',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => 'Servis Aile Adı',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '~~',
|
||||
'Class:Service/Attribute:description' => 'Tanımlama',
|
||||
|
||||
@@ -236,7 +236,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:Service/Attribute:organization_name' => '供应商名称',
|
||||
'Class:Service/Attribute:organization_name+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id' => '服务系列',
|
||||
'Class:Service/Attribute:servicefamily_id+' => '',
|
||||
'Class:Service/Attribute:servicefamily_id+' => 'Required for this service to be visible on User Portal~~',
|
||||
'Class:Service/Attribute:servicefamily_name' => '服务系列名称',
|
||||
'Class:Service/Attribute:servicefamily_name+' => '',
|
||||
'Class:Service/Attribute:description' => '描述',
|
||||
|
||||
@@ -12,8 +12,7 @@ SetupWebPage::AddModule(
|
||||
// Setup
|
||||
//
|
||||
'dependencies' => [
|
||||
'itop-structure/2.7.1',
|
||||
'itop-portal/3.0.0', // module_design_itop_design->module_designs->itop-portal
|
||||
'itop-structure/2.7.1 || itop-portal/3.0.0', // itop-portal : module_design_itop_design->module_designs->itop-portal
|
||||
],
|
||||
'mandatory' => false,
|
||||
'visible' => true,
|
||||
|
||||
@@ -708,6 +708,7 @@ Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
Dict::Add('CS CZ', 'Czech', 'Čeština', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Triger \'aktualizace objektu\'',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Spustit při aktualizaci objektu [podřízené třídy] dané třídy',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Cílová pole',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -707,6 +707,7 @@ Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
Dict::Add('DA DA', 'Danish', 'Dansk', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -704,6 +704,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
Dict::Add('DE DE', 'German', 'Deutsch', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (bei Objektanpassung)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger bei Objektanpassung einer gegebenen Klasse oder Kindklasse',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Ziel-Felder',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -801,6 +801,7 @@ Dict::Add('EN US', 'English', 'English', [
|
||||
Dict::Add('EN US', 'English', 'English', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -784,6 +784,7 @@ Dict::Add('EN GB', 'British English', 'British English', [
|
||||
Dict::Add('EN GB', 'British English', 'British English', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -695,6 +695,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
Dict::Add('ES CR', 'Spanish', 'Español, Castellano', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Disparador (actualizando un objecto)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Disparador al actualizar un objeto de la clase dada [o una clase hija]',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campos objetivo',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => 'Campos que serán monitorizados',
|
||||
]);
|
||||
|
||||
@@ -746,6 +746,7 @@ Dict::Add('FR FR', 'French', 'Français', [
|
||||
Dict::Add('FR FR', 'French', 'Français', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Déclencheur sur la modification d\'un objet',
|
||||
'Class:TriggerOnObjectUpdate+' => '',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'Ce filtre est appliqué après la sauvegarde en base de l\'objet modifié. Il restreint les objets qui vont déclencher les actions.',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Attributs cible',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -702,6 +702,7 @@ Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
Dict::Add('HU HU', 'Hungarian', 'Magyar', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Eseményindító (objektum frissítéskor)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Az adott osztály [egy gyermekosztálya] objektumának frissítésekor elinduló eseményindító',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Célmezők',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -702,6 +702,7 @@ Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
Dict::Add('IT IT', 'Italian', 'Italiano', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (alla modifica dell\'oggetto)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger alla modifica dell\'oggetto di [una classe figlia della] classe specificata',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campi di destinazione',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -706,6 +706,7 @@ Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
Dict::Add('JA JP', 'Japanese', '日本語', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '~~',
|
||||
]);
|
||||
|
||||
@@ -704,6 +704,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
Dict::Add('NL NL', 'Dutch', 'Nederlands', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (bij het aanpassen van een object)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger bij het aanpassen van een object van de opgegeven klasse (of subklasse ervan)',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Doelvelden',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -704,6 +704,7 @@ Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
Dict::Add('PL PL', 'Polish', 'Polski', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Wyzwalacz (przy aktualizacji obiektu)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Wyzwalanie przy aktualizacji obiektu [klasy potomnej] danej klasy',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Pola docelowe',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -702,6 +702,7 @@ Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
Dict::Add('PT BR', 'Brazilian', 'Brazilian', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Gatilho (na atualização do objeto)',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Gatilho na atualização de objeto de [uma classe filha] de uma determinada classe',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Campos de destino',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -707,6 +707,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
Dict::Add('RU RU', 'Russian', 'Русский', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Триггер на обновление объекта',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Триггер на обновление объекта данного или дочернего класса',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Отслеживаемые поля',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => 'Поля объекта, при обновлении которых сработает триггер',
|
||||
]);
|
||||
|
||||
@@ -720,6 +720,7 @@ Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
Dict::Add('SK SK', 'Slovak', 'Slovenčina', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '~~',
|
||||
]);
|
||||
|
||||
@@ -707,6 +707,7 @@ Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
Dict::Add('TR TR', 'Turkish', 'Türkçe', [
|
||||
'Class:TriggerOnObjectUpdate' => 'Trigger (on object update)~~',
|
||||
'Class:TriggerOnObjectUpdate+' => 'Trigger on object update of [a child class of] the given class~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => 'Target fields~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
@@ -739,6 +739,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
Dict::Add('ZH CN', 'Chinese', '简体中文', [
|
||||
'Class:TriggerOnObjectUpdate' => '触发器 (对象更新时)',
|
||||
'Class:TriggerOnObjectUpdate+' => '指定类型或子类型对象更新时的触发器',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:filter+' => 'This filter is computed after the object update in database. It restricts the objects which can trigger the actions~~',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes' => '目标字段',
|
||||
'Class:TriggerOnObjectUpdate/Attribute:target_attcodes+' => '',
|
||||
]);
|
||||
|
||||
17
git-split.md
17
git-split.md
@@ -1,17 +0,0 @@
|
||||
git copy of one file into two files without loosing history
|
||||
|
||||
```
|
||||
git mv foo bar
|
||||
git commit
|
||||
|
||||
SAVED=`git rev-parse HEAD`
|
||||
git reset --hard HEAD^
|
||||
git mv foo copy
|
||||
git commit
|
||||
|
||||
git merge $SAVED # This will generate conflicts
|
||||
git commit -a # Trivially resolved like this
|
||||
|
||||
git mv copy foo
|
||||
git commit
|
||||
```
|
||||
@@ -1,19 +1,3 @@
|
||||
/**
|
||||
* Image renderer plugin for TomSelect
|
||||
*/
|
||||
TomSelect.define('image_renderer', function(options) {
|
||||
this.settings.render.option = function(data, escape) {
|
||||
return `<div class="ibo-input-select-icon--menu--item">
|
||||
<img src="${options['images_resource_path']+escape(data.value)}" alt="${data.text}" />${escape(data.text)}
|
||||
</div>`;
|
||||
};
|
||||
this.settings.render.item = function(data, escape) {
|
||||
return `<div class="ibo-input-select-icon--menu--item">
|
||||
<img src="${options['images_resource_path']+escape(data.value)}" alt="${data.text}"/>${escape(data.text)}
|
||||
</div>`;
|
||||
};
|
||||
});
|
||||
|
||||
class ChoicesElement extends HTMLSelectElement {
|
||||
|
||||
// register the custom element
|
||||
@@ -32,14 +16,6 @@ class ChoicesElement extends HTMLSelectElement {
|
||||
this.plugins.push('remove_button');
|
||||
}
|
||||
|
||||
// plugins
|
||||
if(this.hasAttribute('data-plugins')){
|
||||
const aPlugins = JSON.parse(this.getAttribute('data-plugins'));
|
||||
Array.from(aPlugins).values().forEach(plugin => {
|
||||
this.plugins.push(plugin);
|
||||
});
|
||||
}
|
||||
|
||||
const options = {
|
||||
plugins: this.plugins,
|
||||
wrapperClass: 'ts-wrapper ibo-input-wrapper ibo-input-select-wrapper--with-buttons ibo-input-select-autocomplete-wrapper',
|
||||
@@ -53,7 +29,7 @@ class ChoicesElement extends HTMLSelectElement {
|
||||
};
|
||||
|
||||
if (this.getAttribute('data-tom-select-disable-auto-complete')) {
|
||||
options.controlInput = null;
|
||||
// options.controlInput = null;
|
||||
}
|
||||
if (this.getAttribute('data-tom-select-max-items-selected') && this.getAttribute('data-tom-select-max-items-selected') !== '') {
|
||||
options.maxItems = parseInt(this.getAttribute('data-tom-select-max-items-selected'));
|
||||
@@ -67,4 +43,3 @@ class ChoicesElement extends HTMLSelectElement {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@ class TurboStreamEvent extends HTMLElement {
|
||||
},
|
||||
});
|
||||
|
||||
console.log(event);
|
||||
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
class IboGridSlot extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
connectedCallback() {
|
||||
|
||||
/** @type {string} unique cell id */
|
||||
this.id = '';
|
||||
|
||||
/** @type {number} */
|
||||
this.iPosX = this.getAttribute('gs-x') ? parseInt(this.getAttribute('gs-x'), 10) : 0;
|
||||
|
||||
/** @type {number} */
|
||||
this.iPostY = this.getAttribute('gs-y') ? parseInt(this.getAttribute('gs-y'), 10) : 0;
|
||||
|
||||
/** @type {number} */
|
||||
this.iWidth = this.getAttribute('gs-w') ? parseInt(this.getAttribute('gs-w'), 10) : 1;
|
||||
|
||||
/** @type {number} */
|
||||
this.iHeight = this.getAttribute('gs-h') ? parseInt(this.getAttribute('gs-h'), 10) : 1;
|
||||
|
||||
/** @type {IboDashlet|null} contained dashlet id */
|
||||
this.sDashletId = null;
|
||||
/** @type {IboDashlet|null} contained dashlet element */
|
||||
this.oDashlet = this.querySelector('ibo-dashlet') || null;
|
||||
|
||||
/** @type {Object} freeform metadata */
|
||||
this.meta = {};
|
||||
}
|
||||
|
||||
static MakeNew(oDashletElem, aOptions = {}) {
|
||||
const oSlot = document.createElement('ibo-dashboard-grid-slot');
|
||||
oDashletElem.classList.add("grid-stack-item-content");
|
||||
|
||||
oSlot.appendChild(oDashletElem);
|
||||
oSlot.classList.add("grid-stack-item");
|
||||
oSlot.oDashlet = oDashletElem;
|
||||
|
||||
return oSlot;
|
||||
}
|
||||
|
||||
Serialize(bIncludeHtml = false) {
|
||||
const oDashlet = this.oDashlet;
|
||||
|
||||
const aSlotData = {
|
||||
position_x: this.iPosX,
|
||||
position_y: this.iPostY,
|
||||
width: this.iWidth,
|
||||
height: this.iHeight
|
||||
};
|
||||
|
||||
const aDashletData = oDashlet ? oDashlet.Serialize(bIncludeHtml) : {};
|
||||
|
||||
return {
|
||||
...aSlotData,
|
||||
dashlet: {...aDashletData}
|
||||
};
|
||||
}
|
||||
|
||||
static observedAttributes = ['gs-x', 'gs-y', 'gs-w', 'gs-h'];
|
||||
|
||||
|
||||
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
switch (name) {
|
||||
case 'gs-x':
|
||||
this.iPosX = parseInt(newValue, 10) || 0;
|
||||
break;
|
||||
case 'gs-y':
|
||||
this.iPostY = parseInt(newValue, 10) || 0;
|
||||
break;
|
||||
case 'gs-w':
|
||||
this.iWidth = parseInt(newValue, 10) || 1;
|
||||
break;
|
||||
case 'gs-h':
|
||||
this.iHeight = parseInt(newValue, 10) || 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('ibo-dashboard-grid-slot', IboGridSlot);
|
||||
@@ -1,161 +0,0 @@
|
||||
class IboGrid extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
|
||||
/** @type {number} */
|
||||
this.columnsCount = 12;
|
||||
/** @type {boolean} unused yet*/
|
||||
this.bEditable = false;
|
||||
/** @type {GridStack|null} GridStack instance */
|
||||
this.oGrid = null;
|
||||
/** @type {Array<IboGridSlot>} */
|
||||
this.aSlots = [];
|
||||
|
||||
|
||||
this.SetupGrid();
|
||||
}
|
||||
|
||||
SetupGrid() {
|
||||
let aCandidateSlots = Array.from(this.querySelectorAll('ibo-dashboard-grid-slot'));
|
||||
aCandidateSlots.forEach(oSlot => {
|
||||
const aAttrs = ['gs-x', 'gs-y', 'gs-w', 'gs-h', 'id'];
|
||||
aAttrs.forEach(sAttr => {
|
||||
const sVal = oSlot.getAttribute(sAttr) || oSlot.getAttribute('data-'+sAttr);
|
||||
if (sVal !== null) {
|
||||
oSlot.setAttribute(sAttr, sVal);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.oGrid = GridStack.init({
|
||||
column: this.columnsCount,
|
||||
marginTop: 8,
|
||||
marginLeft: 8,
|
||||
marginRight: 0,
|
||||
marginBottom: 0,
|
||||
resizable: {handles: 'all'},
|
||||
disableDrag: true,
|
||||
disableResize: true,
|
||||
float: true
|
||||
}, this);
|
||||
}
|
||||
|
||||
getSlots() {
|
||||
return this.oGrid.getGridItems();
|
||||
}
|
||||
|
||||
SetEditable(bIsEditable) {
|
||||
this.bEditable = bIsEditable;
|
||||
if (this.oGrid !== null) {
|
||||
this.oGrid.enableMove(bIsEditable);
|
||||
this.oGrid.enableResize(bIsEditable);
|
||||
}
|
||||
}
|
||||
|
||||
GetDashletElement(sDashletId) {
|
||||
const aSlots = this.getSlots();
|
||||
|
||||
for (let oSlot of aSlots) {
|
||||
|
||||
if (oSlot.oDashlet && oSlot.oDashlet.sDashletId === sDashletId) {
|
||||
return oSlot.oDashlet;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
AddDashlet(sDashlet, aOptions = {}) {
|
||||
// Get the dashlet as an object
|
||||
const oParser = new DOMParser();
|
||||
const oDocument = oParser.parseFromString(sDashlet, 'text/html');
|
||||
const oDashlet = oDocument.body.firstChild;
|
||||
|
||||
const oSlot = IboGridSlot.MakeNew(oDashlet);
|
||||
|
||||
this.append(oSlot);
|
||||
|
||||
let aDefaultOptions = {
|
||||
autoPosition: !(aOptions.hasOwnProperty('x') || aOptions.hasOwnProperty('y')),
|
||||
}
|
||||
this.oGrid.makeWidget(oSlot, Object.assign(aDefaultOptions, aOptions));
|
||||
|
||||
return oDashlet.sDashletId;
|
||||
}
|
||||
|
||||
RefreshDashlet (sDashlet, aOptions = {}) {
|
||||
const oParser = new DOMParser();
|
||||
const oDocument = oParser.parseFromString(sDashlet, 'text/html');
|
||||
const oNewDashlet = oDocument.body.firstElementChild;
|
||||
|
||||
// Can't use oNewDashet.sDashletId as it's not in the DOM yet and connectedCallback hasn't been called yet
|
||||
const oExistingDashlet = this.GetDashletElement(oNewDashlet.getAttribute('data-dashlet-id') );
|
||||
|
||||
// Copy attributes
|
||||
for (const sAttr of oNewDashlet.attributes) {
|
||||
oExistingDashlet.setAttribute(sAttr.name, sAttr.value);
|
||||
}
|
||||
|
||||
// If we refresh a dashlet, its parent slot remains the same, we just need to update its content
|
||||
let oSlotForExistingDashlet = null;
|
||||
const aSlots = this.getSlots();
|
||||
for (let oSlot of aSlots) {
|
||||
if (oSlot.oDashlet && oSlot.oDashlet.sDashletId === oNewDashlet.getAttribute('data-dashlet-id')) {
|
||||
oSlotForExistingDashlet = oSlot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// There must be a slot for the existing dashlet
|
||||
if(oSlotForExistingDashlet !== null) {
|
||||
this.oGrid.removeWidget(oSlotForExistingDashlet);
|
||||
oSlotForExistingDashlet.innerHTML = oNewDashlet.outerHTML;
|
||||
this.oGrid.makeWidget(oSlotForExistingDashlet);
|
||||
}
|
||||
}
|
||||
|
||||
CloneDashlet(sDashletId) {
|
||||
const aSlots = this.getSlots();
|
||||
for (let oSlot of aSlots) {
|
||||
|
||||
if (oSlot.oDashlet && oSlot.oDashlet.sDashletId === sDashletId) {
|
||||
const sWidth = oSlot.iWidth;
|
||||
const sHeight = oSlot.iHeight;
|
||||
|
||||
// Ask a new rendered dashlet to avoid duplicating IDs
|
||||
// Still we'll copy width and height
|
||||
this.closest('ibo-dashboard')?.AddNewDashlet(oSlot.oDashlet.sType, oSlot.oDashlet.formData, {
|
||||
'w': sWidth,
|
||||
'h': sHeight
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
RemoveDashlet(sDashletId) {
|
||||
const aSlots = this.getSlots();
|
||||
for (let oSlot of aSlots) {
|
||||
if (oSlot.oDashlet && oSlot.oDashlet.sDashletId === sDashletId) {
|
||||
this.oGrid.removeWidget(oSlot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ClearGrid() {
|
||||
this.oGrid.removeAll();
|
||||
}
|
||||
|
||||
Serialize(bIncludeHtml = false) {
|
||||
const aSlots = this.getSlots();
|
||||
|
||||
return aSlots.reduce((aAccumulator, oSlot) => {
|
||||
aAccumulator[oSlot.oDashlet.sDashletId] = oSlot.Serialize(bIncludeHtml);
|
||||
return aAccumulator;
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('ibo-dashboard-grid', IboGrid);
|
||||
@@ -1,371 +0,0 @@
|
||||
class IboDashboard extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
/** @type {string} */
|
||||
this.sId = "";
|
||||
/** @type {string} */
|
||||
this.sTitle = "";
|
||||
/** @type {boolean} unused yet */
|
||||
this.isEditable = false;
|
||||
/** @type {boolean} */
|
||||
this.bEditMode = false;
|
||||
/** @type {boolean} unused yet */
|
||||
this.bAutoRefresh = false;
|
||||
/** @type {number} unused yet */
|
||||
this.iRefreshRate = 0;
|
||||
/** @type {IboGrid|null} */
|
||||
this.oGrid = null;
|
||||
/** @type {string|null} unused yet */
|
||||
this.refreshUrl = null;
|
||||
/** @type {string|null} unused yet */
|
||||
this.csrfToken = null;
|
||||
/** @type {number} Payload schema version */
|
||||
this.schemaVersion = 2;
|
||||
|
||||
/** @type {object|null} Last saved state for cancel functionality, unused yet */
|
||||
this.aLastSavedState = null;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.sId = this.getAttribute("id");
|
||||
this.bEditMode = (this.getAttribute("data-edit-mode") === "edit");
|
||||
this.SetupGrid();
|
||||
|
||||
this.BindEvents();
|
||||
}
|
||||
|
||||
BindEvents() {
|
||||
document.getElementById('ibo-dashboard-menu-edit-'+this.sId)?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.ToggleEditMode();
|
||||
document.getElementById('ibo-dashboard-menu-edit-'+this.sId)?.classList.toggle('active', this.GetEditMode());
|
||||
});
|
||||
|
||||
this.querySelector('[data-role="ibo-button"][name="save"]')?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
this.Save()
|
||||
});
|
||||
|
||||
this.querySelector('[data-role="ibo-button"][name="cancel"]')?.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
if (this.aLastSavedState) {
|
||||
this.Load(this.aLastSavedState);
|
||||
}
|
||||
this.SetEditMode(false);
|
||||
});
|
||||
|
||||
// TODO 3.3 Add event listener to dashboard toggler to get custom/default dashboard switching
|
||||
// TODO 3.3 require load method that's not finished yet
|
||||
|
||||
// Bind IboDashboard object to these listener so we can access current instance
|
||||
this._ListenToDashletFormSubmission = this._ListenToDashletFormSubmission.bind(this);
|
||||
this._ListenToDashletFormCancellation = this._ListenToDashletFormCancellation.bind(this);
|
||||
}
|
||||
SetupGrid() {
|
||||
if(this.oGrid !== null){
|
||||
return;
|
||||
}
|
||||
|
||||
this.oGrid = this.querySelector('ibo-dashboard-grid');
|
||||
}
|
||||
|
||||
|
||||
GetEditMode() {
|
||||
return this.bEditMode;
|
||||
}
|
||||
|
||||
ToggleEditMode(){
|
||||
this.SetEditMode(!this.bEditMode);
|
||||
}
|
||||
|
||||
SetEditMode(bEditMode) {
|
||||
this.bEditMode = bEditMode;
|
||||
|
||||
this.oGrid.SetEditable(this.bEditMode);
|
||||
if(this.bEditMode){
|
||||
// TODO 3.3 If we are in default dashboard display, change to custom to allow editing
|
||||
// TODO 3.3 Get the custom dashboard and load it, show a tooltip on the dashboard toggler to explain that we switched to custom mode
|
||||
this.aLastSavedState = this.Serialize(true);
|
||||
this.setAttribute("data-edit-mode", "edit");
|
||||
}
|
||||
else{
|
||||
this.setAttribute("data-edit-mode", "view");
|
||||
}
|
||||
}
|
||||
|
||||
AddNewDashlet(sDashletClass, sDashletValues, aDashletOptions = {}) {
|
||||
let sNewDashletUrl = GetAbsoluteUrlAppRoot() + '/pages/UI.php?route=dashboard.get_dashlet&dashlet_class='+encodeURIComponent(sDashletClass);
|
||||
|
||||
if(sDashletValues.length > 0) {
|
||||
sNewDashletUrl += '&values=' + encodeURIComponent(sDashletValues);
|
||||
}
|
||||
|
||||
fetch(sNewDashletUrl)
|
||||
.then(async data => {
|
||||
|
||||
const sDashletId = this.oGrid.AddDashlet(await data.text(), aDashletOptions);
|
||||
|
||||
// TODO 3.3 Either open the dashlet form right away, or just enter edit mode
|
||||
this.EditDashlet(sDashletId);
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
RefreshDashlet(oDashlet) {
|
||||
let sGetDashletUrl = GetAbsoluteUrlAppRoot() + '/pages/UI.php?route=dashboard.get_dashlet&dashlet_class=' + encodeURIComponent(oDashlet.sType)
|
||||
+'&dashlet_id=' + encodeURIComponent(oDashlet.sDashletId);
|
||||
|
||||
if(oDashlet.formData.length > 0) {
|
||||
sGetDashletUrl += '&values=' + encodeURIComponent(oDashlet.formData);
|
||||
}
|
||||
|
||||
return fetch(sGetDashletUrl)
|
||||
.then(async data => {
|
||||
|
||||
this.oGrid.RefreshDashlet(await data.text());
|
||||
});
|
||||
}
|
||||
|
||||
HideDashletTogglers() {
|
||||
const aTogglers = document.querySelector('.ibo-dashlet-panel--entries');
|
||||
aTogglers.classList.add('ibo-is-hidden');
|
||||
}
|
||||
|
||||
ShowDashletTogglers() {
|
||||
const aTogglers = document.querySelector('.ibo-dashlet-panel--entries');
|
||||
aTogglers.classList.remove('ibo-is-hidden');
|
||||
}
|
||||
|
||||
SetDashletForm(sFormData) {
|
||||
const oFormContainer = document.querySelector('.ibo-dashlet-panel--form-container');
|
||||
oFormContainer.innerHTML = sFormData;
|
||||
oFormContainer.classList.remove('ibo-is-hidden');
|
||||
}
|
||||
|
||||
ClearDashletForm() {
|
||||
const oFormContainer = document.querySelector('.ibo-dashlet-panel--form-container');
|
||||
oFormContainer.innerHTML = '';
|
||||
oFormContainer.classList.add('ibo-is-hidden');
|
||||
}
|
||||
|
||||
DisableFormButtons() {
|
||||
const aButtons = this.querySelectorAll('.ibo-dashboard--form--actions button');
|
||||
aButtons.forEach( (oButton) => {
|
||||
oButton.setAttribute('disabled', 'disabled');
|
||||
});
|
||||
}
|
||||
|
||||
EnableFormButtons() {
|
||||
const aButtons = this.querySelectorAll('.ibo-dashboard--form--actions button');
|
||||
aButtons.forEach( (oButton) => {
|
||||
oButton.removeAttribute('disabled');
|
||||
});
|
||||
}
|
||||
|
||||
EditDashlet(sDashletId) {
|
||||
const oDashlet = this.oGrid.GetDashletElement(sDashletId);
|
||||
const me = this;
|
||||
|
||||
// Create backdrop to block interactions with other dashlets
|
||||
if(this.oGrid.querySelector('.ibo-dashboard--grid--backdrop') === null) {
|
||||
const oBackdrop = document.createElement("div");
|
||||
oBackdrop.classList.add('ibo-dashboard--grid--backdrop');
|
||||
this.oGrid.append(oBackdrop);
|
||||
}
|
||||
|
||||
this.querySelector('ibo-dashlet[data-dashlet-id="'+sDashletId+'"]').setAttribute('data-edit-mode', 'edit');
|
||||
|
||||
// Disable dashboard buttons so we need to finish this edition first
|
||||
this.DisableFormButtons();
|
||||
|
||||
// Fetch dashlet form from server
|
||||
let sGetashletFormUrl = GetAbsoluteUrlAppRoot() + '/pages/UI.php?route=dashboard.get_dashlet_form&dashlet_class='+encodeURIComponent(oDashlet.sType);
|
||||
|
||||
if(oDashlet.formData.length > 0) {
|
||||
sGetashletFormUrl += '&values=' + encodeURIComponent(oDashlet.formData);
|
||||
}
|
||||
|
||||
fetch(sGetashletFormUrl)
|
||||
.then(async formData => {
|
||||
const sFormData = await formData.text();
|
||||
|
||||
this.HideDashletTogglers();
|
||||
this.SetDashletForm(sFormData);
|
||||
|
||||
// Listen to form submission event and cancellation
|
||||
document.addEventListener('itop:TurboStreamEvent', me._ListenToDashletFormSubmission);
|
||||
document.querySelector('.ibo-dashlet-panel--form-container button[name="dashboard_cancel"]').addEventListener('click', me._ListenToDashletFormCancellation);
|
||||
});
|
||||
}
|
||||
|
||||
_ListenToDashletFormSubmission(event) {
|
||||
const oDashlet = this.querySelector('ibo-dashlet[data-edit-mode="edit"]');
|
||||
const sDashletId = oDashlet.GetDashletId();
|
||||
|
||||
if(event.detail.id === oDashlet.sType + '-turbo-stream-event' && event.detail.valid === "1") {
|
||||
// Remove events
|
||||
document.addEventListener('itop:TurboStreamEvent', this._ListenToDashletFormSubmission);
|
||||
document.querySelector('.ibo-dashlet-panel--form-container button[name="dashboard_cancel"]').removeEventListener('click', this._ListenToDashletFormCancellation);
|
||||
|
||||
// Notify it all went well
|
||||
CombodoToast.OpenToast('Dashlet created/updated', 'success');
|
||||
|
||||
// Clean edit mode
|
||||
this.querySelector('ibo-dashlet[data-dashlet-id="'+sDashletId+'"]').setAttribute('data-edit-mode', 'view');
|
||||
this.ShowDashletTogglers();
|
||||
this.ClearDashletForm();
|
||||
|
||||
// Update local dashlet and refresh it
|
||||
oDashlet.formData = event.detail.view_data;
|
||||
this.RefreshDashlet(oDashlet);
|
||||
|
||||
// Re-enable dashboard buttons
|
||||
this.EnableFormButtons();
|
||||
}
|
||||
}
|
||||
|
||||
_ListenToDashletFormCancellation(event) {
|
||||
const oDashlet = this.querySelector('ibo-dashlet[data-edit-mode="edit"]');
|
||||
const sDashletId = oDashlet.GetDashletId();
|
||||
// Remove events
|
||||
document.addEventListener('itop:TurboStreamEvent', this._ListenToDashletFormSubmission);
|
||||
document.querySelector('.ibo-dashlet-panel--form-container button[name="dashboard_cancel"]').removeEventListener('click', this._ListenToDashletFormCancellation);
|
||||
|
||||
// Clean edit mode
|
||||
this.querySelector('ibo-dashlet[data-dashlet-id="'+sDashletId+'"]').setAttribute('data-edit-mode', 'view');
|
||||
this.ShowDashletTogglers();
|
||||
this.ClearDashletForm();
|
||||
|
||||
// Re-enable dashboard buttons
|
||||
this.EnableFormButtons();
|
||||
|
||||
// TODO 3.3 If this is an addition, remove the previewed dashlet
|
||||
// TODO 3.3 If this is an edition, revert the dashlet to its initial state
|
||||
}
|
||||
|
||||
CloneDashlet(sDashletId) {
|
||||
this.oGrid.CloneDashlet(sDashletId);
|
||||
}
|
||||
|
||||
RemoveDashlet(sDashletId) {
|
||||
this.oGrid.RemoveDashlet(sDashletId);
|
||||
}
|
||||
|
||||
RefreshFromBackend(bCustomDashboard = false) {
|
||||
const sLoadDashboardUrl = GetAbsoluteUrlAppRoot() + `/pages/UI.php?route=dashboard.load&id=${this.sId}&custom=${bCustomDashboard ? 'true' : 'false'}`;
|
||||
fetch(sLoadDashboardUrl)
|
||||
.then(async oResponse => {
|
||||
const oDashletData = await oResponse.json();
|
||||
this.Load(oDashletData);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Serialize(bIncludeHtml = false) {
|
||||
const sDashboardTitle = this.querySelector('.ibo-dashboard--form--inputs input[name="dashboard_title"]').value;
|
||||
const sDashboardRefreshRate = this.querySelector('.ibo-dashboard--form--inputs select[name="refresh_interval"]').value;
|
||||
|
||||
const aSerializedGrid = this.oGrid.Serialize(bIncludeHtml);
|
||||
return {
|
||||
schema_version: this.schemaVersion,
|
||||
id: this.sId,
|
||||
title: sDashboardTitle,
|
||||
refresh: sDashboardRefreshRate,
|
||||
pos_dashlets: aSerializedGrid,
|
||||
_token: ":)"
|
||||
};
|
||||
}
|
||||
|
||||
Save() {
|
||||
// This payload shape is expected by the server
|
||||
const aPayload = this.Serialize();
|
||||
|
||||
let sSaveUrl = GetAbsoluteUrlAppRoot() + '/pages/UI.php?route=dashboard.save&values='+encodeURIComponent(JSON.stringify(aPayload));
|
||||
fetch(sSaveUrl)
|
||||
.then(async data => {
|
||||
const res = await data.json();
|
||||
if(res.status === 'ok') {
|
||||
CombodoToast.OpenToast(res.message, 'success');
|
||||
this.aLastSavedState = this.Serialize(true);
|
||||
this.SetEditMode(false);
|
||||
} else {
|
||||
CombodoToast.OpenToast(res.message, 'error');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Load(aSaveState) {
|
||||
try {
|
||||
// Validate schema version
|
||||
if (aSaveState.schema_version !== this.schemaVersion) {
|
||||
CombodoToast.OpenToast('Somehow, we got an incompatible dashboard schema version.', 'error');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Update dashboard data
|
||||
this.sId = aSaveState.id;
|
||||
this.sTitle = aSaveState.title || "";
|
||||
this.iRefreshRate = parseInt(aSaveState.refresh, 10) || 0;
|
||||
|
||||
// Update form inputs if they exist
|
||||
const oTitleInput = this.querySelector('.ibo-dashboard--form--inputs input[name="dashboard_title"]');
|
||||
if (oTitleInput) {
|
||||
oTitleInput.value = this.sTitle;
|
||||
}
|
||||
|
||||
const oRefreshSelect = this.querySelector('.ibo-dashboard--form--inputs select[name="refresh_interval"]');
|
||||
if (oRefreshSelect) {
|
||||
oRefreshSelect.value = aSaveState.refresh;
|
||||
}
|
||||
|
||||
// Clear existing grid
|
||||
this.ClearGrid();
|
||||
|
||||
// Load dashlets
|
||||
const aDashletSlots = aSaveState.pos_dashlets || {};
|
||||
|
||||
for (const [sDashletId, aDashletData] of Object.entries(aDashletSlots)) {
|
||||
const iPosX = aDashletData.position_x;
|
||||
const iPosY = aDashletData.position_y;
|
||||
const iWidth = aDashletData.width;
|
||||
const iHeight = aDashletData.height;
|
||||
const aDashlet = aDashletData.dashlet;
|
||||
|
||||
// We store the dashlet component in the HTML, not only the rendered dashlet
|
||||
const sDashetHtml = aDashlet.html;
|
||||
|
||||
// Add dashlet to grid with its position and size
|
||||
this.oGrid.AddDashlet(sDashetHtml, {
|
||||
x: iPosX,
|
||||
y: iPosY,
|
||||
w: iWidth,
|
||||
h: iHeight,
|
||||
autoPosition: false
|
||||
});
|
||||
}
|
||||
|
||||
// Update last saved state
|
||||
this.aLastSavedState = aSaveState;
|
||||
|
||||
return true;
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error loading dashboard state:', error);
|
||||
CombodoToast.OpenToast('Error loading dashboard state', 'error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ClearGrid() {
|
||||
this.oGrid.ClearGrid();
|
||||
}
|
||||
|
||||
DisplayError(sMessage, sSeverity = 'error') {
|
||||
// TODO 3.3: Make this real
|
||||
this.setAttribute("data-edit-mode", "error");
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('ibo-dashboard', IboDashboard);
|
||||
@@ -1,68 +0,0 @@
|
||||
class IboDashlet extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
/** @type {string} */
|
||||
this.sDashletId = this.GetDashletId();
|
||||
/** @type {string} */
|
||||
this.sType = this.GetDashletType();
|
||||
/** @type {Object} */
|
||||
this.formData = this.GetFormData();
|
||||
/** @type {Object} unused yet */
|
||||
this.meta = {};
|
||||
|
||||
this.BindEvents();
|
||||
}
|
||||
BindEvents() {
|
||||
// Bind any dashlet-specific events here
|
||||
this.querySelector('.ibo-dashlet--actions [data-role="ibo-dashlet-edit"]')?.addEventListener('click', (e) => {
|
||||
this.closest('ibo-dashboard')?.EditDashlet(this.sDashletId);
|
||||
});
|
||||
|
||||
this.querySelector('.ibo-dashlet--actions [data-role="ibo-dashlet-clone"]')?.addEventListener('click', (e) => {
|
||||
this.closest('ibo-dashboard')?.CloneDashlet(this.sDashletId);
|
||||
});
|
||||
|
||||
this.querySelector('.ibo-dashlet--actions [data-role="ibo-dashlet-remove"]')?.addEventListener('click', (e) => {
|
||||
this.closest('ibo-dashboard')?.RemoveDashlet(this.sDashletId);
|
||||
});
|
||||
}
|
||||
|
||||
GetDashletId() {
|
||||
return this.getAttribute('data-dashlet-id');
|
||||
}
|
||||
|
||||
GetDashletType() {
|
||||
return this.getAttribute("data-dashlet-type") || "";
|
||||
}
|
||||
|
||||
GetFormData() {
|
||||
return this.getAttribute("data-form-view-data") || "";
|
||||
}
|
||||
|
||||
static MakeNew(sDashlet) {
|
||||
const oDashlet = document.createElement('ibo-dashlet');
|
||||
oDashlet.innerHTML = sDashlet;
|
||||
|
||||
return oDashlet;
|
||||
}
|
||||
|
||||
Serialize(bIncludeHtml = false) {
|
||||
// TODO 3.3 Should we use getters ?
|
||||
let aDashletData = {
|
||||
id: this.sDashletId,
|
||||
type: this.sType,
|
||||
properties: JSON.parse(this.formData),
|
||||
};
|
||||
|
||||
if(bIncludeHtml) {
|
||||
aDashletData.html = this.outerHTML;
|
||||
}
|
||||
|
||||
return aDashletData;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('ibo-dashlet', IboDashlet);
|
||||
@@ -130,27 +130,6 @@ return array(
|
||||
'CheckableExpression' => $baseDir . '/core/oql/oqlquery.class.inc.php',
|
||||
'Collator' => $vendorDir . '/symfony/polyfill-intl-icu/Resources/stubs/Collator.php',
|
||||
'Combodo\\iTop\\Application\\Branding' => $baseDir . '/sources/Application/Branding.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\Controller\\DashboardController' => $baseDir . '/sources/Application/Dashboard/Controller/DashboardController.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\DashboardException' => $baseDir . '/sources/Application/Dashboard/DashboardException.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashboardFormBlock' => $baseDir . '/sources/Application/Dashboard/FormBlock/DashboardFormBlock.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashletFormBlock' => $baseDir . '/sources/Application/Dashboard/FormBlock/DashletFormBlock.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashletPropertiesFormBlock' => $baseDir . '/sources/Application/Dashboard/FormBlock/DashletPropertiesFormBlock.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\Layout\\DashboardLayoutGrid' => $baseDir . '/sources/Application/Dashboard/Layout/DashboardLayoutGrid.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletBadge' => $baseDir . '/sources/Application/Dashlet/Core/DashletBadge.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupBy' => $baseDir . '/sources/Application/Dashlet/Core/DashletGroupBy.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByBars' => $baseDir . '/sources/Application/Dashlet/Core/DashletGroupByBars.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByPie' => $baseDir . '/sources/Application/Dashlet/Core/DashletGroupByPie.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByTable' => $baseDir . '/sources/Application/Dashlet/Core/DashletGroupByTable.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletHeaderDynamic' => $baseDir . '/sources/Application/Dashlet/Core/DashletHeaderDynamic.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletHeaderStatic' => $baseDir . '/sources/Application/Dashlet/Core/DashletHeaderStatic.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletObjectList' => $baseDir . '/sources/Application/Dashlet/Core/DashletObjectList.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletPlainText' => $baseDir . '/sources/Application/Dashlet/Core/DashletPlainText.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletProxy' => $baseDir . '/sources/Application/Dashlet/Core/DashletProxy.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletUnknown' => $baseDir . '/sources/Application/Dashlet/Core/DashletUnknown.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Dashlet' => $baseDir . '/sources/Application/Dashlet/Dashlet.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\DashletException' => $baseDir . '/sources/Application/Dashlet/DashletException.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\DashletFactory' => $baseDir . '/sources/Application/Dashlet/DashletFactory.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Service\\DashletService' => $baseDir . '/sources/Application/Dashlet/Service/DashletService.php',
|
||||
'Combodo\\iTop\\Application\\EventRegister\\ApplicationEvents' => $baseDir . '/sources/Application/EventRegister/ApplicationEvents.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\CKEditorHelper' => $baseDir . '/sources/Application/Helper/CKEditorHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\ExportHelper' => $baseDir . '/sources/Application/Helper/ExportHelper.php',
|
||||
@@ -191,7 +170,6 @@ return array(
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletFactory' => $baseDir . '/sources/Application/UI/Base/Component/Dashlet/DashletFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletHeaderStatic' => $baseDir . '/sources/Application/UI/Base/Component/Dashlet/DashletHeaderStatic.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletPlainText' => $baseDir . '/sources/Application/UI/Base/Component/Dashlet/DashletPlainText.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletWrapper' => $baseDir . '/sources/Application/UI/Base/Component/Dashlet/DashletWrapper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTable' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/DataTable.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTableConfig\\DataTableConfig' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/DataTableConfig/DataTableConfig.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTableSettings' => $baseDir . '/sources/Application/UI/Base/Component/DataTable/DataTableSettings.php',
|
||||
@@ -292,13 +270,8 @@ return array(
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryForm' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryFormFactory' => $baseDir . '/sources/Application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryFormFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardColumn' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardColumn.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardGrid' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardGrid.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardGridSlot' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardGridSlot.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardLayout' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardLayout.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardRow' => $baseDir . '/sources/Application/UI/Base/Layout/Dashboard/DashboardRow.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletEntry' => $baseDir . '/sources/Application/UI/Base/Layout/DashletPanel/DashletEntry.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletPanel' => $baseDir . '/sources/Application/UI/Base/Layout/DashletPanel/DashletPanel.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletPanelFactory' => $baseDir . '/sources/Application/UI/Base/Layout/DashletPanel/DashletPanelFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\Column\\Column' => $baseDir . '/sources/Application/UI/Base/Layout/MultiColumn/Column/Column.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\Column\\ColumnUIBlockFactory' => $baseDir . '/sources/Application/UI/Base/Layout/MultiColumn/Column/ColumnUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\MultiColumn' => $baseDir . '/sources/Application/UI/Base/Layout/MultiColumn/MultiColumn.php',
|
||||
@@ -510,7 +483,6 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\CheckboxFormBlock' => $baseDir . '/sources/Forms/Block/Base/CheckboxFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFromInputsBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceFromInputsBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceImageFormBlock' => $baseDir . '/sources/Forms/Block/Base/ChoiceImageFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\CollectionBlock' => $baseDir . '/sources/Forms/Block/Base/CollectionBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\DateFormBlock' => $baseDir . '/sources/Forms/Block/Base/DateFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\DateTimeFormBlock' => $baseDir . '/sources/Forms/Block/Base/DateTimeFormBlock.php',
|
||||
@@ -518,7 +490,6 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\HiddenFormBlock' => $baseDir . '/sources/Forms/Block/Base/HiddenFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\IntegerFormBlock' => $baseDir . '/sources/Forms/Block/Base/IntegerFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\NumberFormBlock' => $baseDir . '/sources/Forms/Block/Base/NumberFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\PolymorphicFormBlock' => $baseDir . '/sources/Forms/Block/Base/PolymorphicFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextAreaFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
|
||||
@@ -586,19 +557,15 @@ return array(
|
||||
'Combodo\\iTop\\PropertyType\\PropertyTypeFactory' => $baseDir . '/sources/PropertyType/PropertyTypeFactory.php',
|
||||
'Combodo\\iTop\\PropertyType\\PropertyTypeService' => $baseDir . '/sources/PropertyType/PropertyTypeService.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\SerializerException' => $baseDir . '/sources/PropertyType/Serializer/SerializerException.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLEncoder' => $baseDir . '/sources/PropertyType/Serializer/XMLEncoder.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\AbstractXMLFormat' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/AbstractXMLFormat.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCSV' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCSV.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCollectionWithId' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCollectionWithId.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFactory' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFactory.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFlatArray' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFlatArray.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatValueAsId' => $baseDir . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatValueAsId.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLNormalizer' => $baseDir . '/sources/PropertyType/Serializer/XMLNormalizer.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLSerializer' => $baseDir . '/sources/PropertyType/Serializer/XMLSerializer.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\AbstractValueType' => $baseDir . '/sources/PropertyType/ValueType/AbstractValueType.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\AbstractBranchValueType' => $baseDir . '/sources/PropertyType/ValueType/Branch/AbstractBranchValueType.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypeCollection' => $baseDir . '/sources/PropertyType/ValueType/Branch/ValueTypeCollection.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePolymorphic' => $baseDir . '/sources/PropertyType/ValueType/Branch/ValueTypePolymorphic.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePropertyTree' => $baseDir . '/sources/PropertyType/ValueType/Branch/ValueTypePropertyTree.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\AbstractLeafValueType' => $baseDir . '/sources/PropertyType/ValueType/Leaf/AbstractLeafValueType.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\ValueTypeAggregateFunction' => $baseDir . '/sources/PropertyType/ValueType/Leaf/ValueTypeAggregateFunction.php',
|
||||
@@ -709,6 +676,19 @@ return array(
|
||||
'DashboardLayoutThreeCols' => $baseDir . '/application/dashboardlayout.class.inc.php',
|
||||
'DashboardLayoutTwoCols' => $baseDir . '/application/dashboardlayout.class.inc.php',
|
||||
'DashboardMenuNode' => $baseDir . '/application/menunode.class.inc.php',
|
||||
'Dashlet' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletBadge' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletEmptyCell' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletGroupBy' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletGroupByBars' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletGroupByPie' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletGroupByTable' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletHeaderDynamic' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletHeaderStatic' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletObjectList' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletPlainText' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletProxy' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'DashletUnknown' => $baseDir . '/application/dashlet.class.inc.php',
|
||||
'Datamatrix' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/datamatrix.php',
|
||||
'DateError' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
|
||||
'DateException' => $vendorDir . '/symfony/polyfill-php83/Resources/stubs/DateException.php',
|
||||
|
||||
@@ -516,27 +516,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'CheckableExpression' => __DIR__ . '/../..' . '/core/oql/oqlquery.class.inc.php',
|
||||
'Collator' => __DIR__ . '/..' . '/symfony/polyfill-intl-icu/Resources/stubs/Collator.php',
|
||||
'Combodo\\iTop\\Application\\Branding' => __DIR__ . '/../..' . '/sources/Application/Branding.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\Controller\\DashboardController' => __DIR__ . '/../..' . '/sources/Application/Dashboard/Controller/DashboardController.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\DashboardException' => __DIR__ . '/../..' . '/sources/Application/Dashboard/DashboardException.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashboardFormBlock' => __DIR__ . '/../..' . '/sources/Application/Dashboard/FormBlock/DashboardFormBlock.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashletFormBlock' => __DIR__ . '/../..' . '/sources/Application/Dashboard/FormBlock/DashletFormBlock.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\FormBlock\\DashletPropertiesFormBlock' => __DIR__ . '/../..' . '/sources/Application/Dashboard/FormBlock/DashletPropertiesFormBlock.php',
|
||||
'Combodo\\iTop\\Application\\Dashboard\\Layout\\DashboardLayoutGrid' => __DIR__ . '/../..' . '/sources/Application/Dashboard/Layout/DashboardLayoutGrid.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletBadge' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletBadge.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupBy' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletGroupBy.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByBars' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletGroupByBars.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByPie' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletGroupByPie.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletGroupByTable' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletGroupByTable.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletHeaderDynamic' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletHeaderDynamic.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletHeaderStatic' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletHeaderStatic.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletObjectList' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletObjectList.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletPlainText' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletPlainText.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletProxy' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletProxy.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Core\\DashletUnknown' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Core/DashletUnknown.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Dashlet' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Dashlet.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\DashletException' => __DIR__ . '/../..' . '/sources/Application/Dashlet/DashletException.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\DashletFactory' => __DIR__ . '/../..' . '/sources/Application/Dashlet/DashletFactory.php',
|
||||
'Combodo\\iTop\\Application\\Dashlet\\Service\\DashletService' => __DIR__ . '/../..' . '/sources/Application/Dashlet/Service/DashletService.php',
|
||||
'Combodo\\iTop\\Application\\EventRegister\\ApplicationEvents' => __DIR__ . '/../..' . '/sources/Application/EventRegister/ApplicationEvents.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\CKEditorHelper' => __DIR__ . '/../..' . '/sources/Application/Helper/CKEditorHelper.php',
|
||||
'Combodo\\iTop\\Application\\Helper\\ExportHelper' => __DIR__ . '/../..' . '/sources/Application/Helper/ExportHelper.php',
|
||||
@@ -577,7 +556,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dashlet/DashletFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletHeaderStatic' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dashlet/DashletHeaderStatic.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletPlainText' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dashlet/DashletPlainText.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\Dashlet\\DashletWrapper' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/Dashlet/DashletWrapper.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTable' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/DataTable.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTableConfig\\DataTableConfig' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/DataTableConfig/DataTableConfig.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Component\\DataTable\\DataTableSettings' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Component/DataTable/DataTableSettings.php',
|
||||
@@ -678,13 +656,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryForm' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryForm.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\ActivityPanel\\CaseLogEntryForm\\CaseLogEntryFormFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/ActivityPanel/CaseLogEntryForm/CaseLogEntryFormFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardColumn' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardColumn.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardGrid' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardGrid.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardGridSlot' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardGridSlot.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardLayout' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardLayout.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\Dashboard\\DashboardRow' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/Dashboard/DashboardRow.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletEntry' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/DashletPanel/DashletEntry.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletPanel' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/DashletPanel/DashletPanel.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\DashletPanel\\DashletPanelFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/DashletPanel/DashletPanelFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\Column\\Column' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/MultiColumn/Column/Column.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\Column\\ColumnUIBlockFactory' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/MultiColumn/Column/ColumnUIBlockFactory.php',
|
||||
'Combodo\\iTop\\Application\\UI\\Base\\Layout\\MultiColumn\\MultiColumn' => __DIR__ . '/../..' . '/sources/Application/UI/Base/Layout/MultiColumn/MultiColumn.php',
|
||||
@@ -896,7 +869,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\CheckboxFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/CheckboxFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceFromInputsBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceFromInputsBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\ChoiceImageFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/ChoiceImageFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\CollectionBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/CollectionBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\DateFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/DateFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\DateTimeFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/DateTimeFormBlock.php',
|
||||
@@ -904,7 +876,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\HiddenFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/HiddenFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\IntegerFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/IntegerFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\NumberFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/NumberFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\PolymorphicFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/PolymorphicFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextAreaFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
|
||||
@@ -972,19 +943,15 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\PropertyType\\PropertyTypeFactory' => __DIR__ . '/../..' . '/sources/PropertyType/PropertyTypeFactory.php',
|
||||
'Combodo\\iTop\\PropertyType\\PropertyTypeService' => __DIR__ . '/../..' . '/sources/PropertyType/PropertyTypeService.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\SerializerException' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/SerializerException.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLEncoder' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLEncoder.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\AbstractXMLFormat' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/AbstractXMLFormat.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCSV' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCSV.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatCollectionWithId' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatCollectionWithId.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFactory' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFactory.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatFlatArray' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatFlatArray.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLFormat\\XMLFormatValueAsId' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLFormat/XMLFormatValueAsId.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLNormalizer' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLNormalizer.php',
|
||||
'Combodo\\iTop\\PropertyType\\Serializer\\XMLSerializer' => __DIR__ . '/../..' . '/sources/PropertyType/Serializer/XMLSerializer.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\AbstractValueType' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/AbstractValueType.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\AbstractBranchValueType' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/AbstractBranchValueType.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypeCollection' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/ValueTypeCollection.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePolymorphic' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/ValueTypePolymorphic.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Branch\\ValueTypePropertyTree' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Branch/ValueTypePropertyTree.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\AbstractLeafValueType' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Leaf/AbstractLeafValueType.php',
|
||||
'Combodo\\iTop\\PropertyType\\ValueType\\Leaf\\ValueTypeAggregateFunction' => __DIR__ . '/../..' . '/sources/PropertyType/ValueType/Leaf/ValueTypeAggregateFunction.php',
|
||||
@@ -1095,6 +1062,19 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'DashboardLayoutThreeCols' => __DIR__ . '/../..' . '/application/dashboardlayout.class.inc.php',
|
||||
'DashboardLayoutTwoCols' => __DIR__ . '/../..' . '/application/dashboardlayout.class.inc.php',
|
||||
'DashboardMenuNode' => __DIR__ . '/../..' . '/application/menunode.class.inc.php',
|
||||
'Dashlet' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletBadge' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletEmptyCell' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletGroupBy' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletGroupByBars' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletGroupByPie' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletGroupByTable' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletHeaderDynamic' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletHeaderStatic' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletObjectList' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletPlainText' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletProxy' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'DashletUnknown' => __DIR__ . '/../..' . '/application/dashlet.class.inc.php',
|
||||
'Datamatrix' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/datamatrix.php',
|
||||
'DateError' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateError.php',
|
||||
'DateException' => __DIR__ . '/..' . '/symfony/polyfill-php83/Resources/stubs/DateException.php',
|
||||
|
||||
16
node_modules/.package-lock.json
generated
vendored
16
node_modules/.package-lock.json
generated
vendored
@@ -186,22 +186,6 @@
|
||||
"delegate": "^3.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/gridstack": {
|
||||
"version": "12.4.2",
|
||||
"resolved": "https://registry.npmjs.org/gridstack/-/gridstack-12.4.2.tgz",
|
||||
"integrity": "sha512-aXbJrQpi3LwpYXYOr4UriPM5uc/dPcjK01SdOE5PDpx2vi8tnLhU7yBg/1i4T59UhNkG/RBfabdFUObuN+gMnw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "paypal",
|
||||
"url": "https://www.paypal.me/alaind831"
|
||||
},
|
||||
{
|
||||
"type": "venmo",
|
||||
"url": "https://www.venmo.com/adumesny"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/jquery": {
|
||||
"version": "3.7.1",
|
||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz",
|
||||
|
||||
21
node_modules/gridstack/LICENSE
generated
vendored
21
node_modules/gridstack/LICENSE
generated
vendored
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019-2025 Alain Dumesny. v0.4.0 and older (c) 2014-2018 Pavel Reznikov, Dylan Weiss
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
565
node_modules/gridstack/README.md
generated
vendored
565
node_modules/gridstack/README.md
generated
vendored
@@ -1,565 +0,0 @@
|
||||
# gridstack.js
|
||||
|
||||
[](https://www.npmjs.com/package/gridstack)
|
||||
[](https://coveralls.io/github/gridstack/gridstack.js?branch=develop)
|
||||
[](https://www.npmjs.com/package/gridstack)
|
||||
|
||||
Mobile-friendly modern Typescript library for dashboard layout and creation. Making a drag-and-drop, multi-column responsive dashboard has never been easier. Has multiple bindings and works great with [Angular](https://angular.io/) (included), [React](https://reactjs.org/), [Vue](https://vuejs.org/), [Knockout.js](http://knockoutjs.com), [Ember](https://www.emberjs.com/) and others (see [frameworks](#specific-frameworks) section).
|
||||
|
||||
Inspired by no-longer maintained gridster, built with love.
|
||||
|
||||
Check http://gridstackjs.com and [these demos](http://gridstackjs.com/demo/).
|
||||
|
||||
If you find this lib useful, please donate [PayPal](https://www.paypal.me/alaind831) (use **“send to a friend”** to avoid 3% fee) or [Venmo](https://www.venmo.com/adumesny) (adumesny) and help support it!
|
||||
|
||||
[](https://www.paypal.me/alaind831)
|
||||
[](https://www.venmo.com/adumesny)
|
||||
|
||||
Join us on Slack: [https://gridstackjs.slack.com](https://join.slack.com/t/gridstackjs/shared_invite/zt-3978nsff6-HDNE_N45DydP36NBSV9JFQ)
|
||||
|
||||
<!-- [](https://gridstackjs.slack.com) -->
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
**Table of Contents** *generated with [DocToc](http://doctoc.herokuapp.com/)*
|
||||
|
||||
- [Demo and API Documentation](#demo-and-api-documentation)
|
||||
- [Usage](#usage)
|
||||
- [Install](#install)
|
||||
- [Include](#include)
|
||||
- [Basic usage](#basic-usage)
|
||||
- [Requirements](#requirements)
|
||||
- [Specific frameworks](#specific-frameworks)
|
||||
- [Extend Library](#extend-library)
|
||||
- [Extend Engine](#extend-engine)
|
||||
- [Change grid columns](#change-grid-columns)
|
||||
- [Custom columns CSS (OLD, not needed with v12+)](#custom-columns-css-old-not-needed-with-v12)
|
||||
- [Override resizable/draggable options](#override-resizabledraggable-options)
|
||||
- [Touch devices support](#touch-devices-support)
|
||||
- [Migrating](#migrating)
|
||||
- [Migrating to v0.6](#migrating-to-v06)
|
||||
- [Migrating to v1](#migrating-to-v1)
|
||||
- [Migrating to v2](#migrating-to-v2)
|
||||
- [Migrating to v3](#migrating-to-v3)
|
||||
- [Migrating to v4](#migrating-to-v4)
|
||||
- [Migrating to v5](#migrating-to-v5)
|
||||
- [Migrating to v6](#migrating-to-v6)
|
||||
- [Migrating to v7](#migrating-to-v7)
|
||||
- [Migrating to v8](#migrating-to-v8)
|
||||
- [Migrating to v9](#migrating-to-v9)
|
||||
- [Migrating to v10](#migrating-to-v10)
|
||||
- [Migrating to v11](#migrating-to-v11)
|
||||
- [Migrating to v12](#migrating-to-v12)
|
||||
- [jQuery Application](#jquery-application)
|
||||
- [Changes](#changes)
|
||||
- [Usage Trend](#usage-trend)
|
||||
- [The Team](#the-team)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
|
||||
# Demo and API Documentation
|
||||
|
||||
Please visit http://gridstackjs.com and [these demos](http://gridstackjs.com/demo/), and complete [API documentation](https://gridstack.github.io/gridstack.js/doc/html/) ([markdown](https://github.com/gridstack/gridstack.js/tree/master/doc/API.md))
|
||||
|
||||
# Usage
|
||||
|
||||
## Install
|
||||
[](https://www.npmjs.com/package/gridstack)
|
||||
|
||||
```js
|
||||
yarn add gridstack
|
||||
// or
|
||||
npm install --save gridstack
|
||||
```
|
||||
|
||||
## Include
|
||||
|
||||
ES6 or Typescript
|
||||
|
||||
```js
|
||||
import 'gridstack/dist/gridstack.min.css';
|
||||
import { GridStack } from 'gridstack';
|
||||
```
|
||||
|
||||
Alternatively (single combined file, notice the -all.js) in html
|
||||
|
||||
```html
|
||||
<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
|
||||
<script src="node_modules/gridstack/dist/gridstack-all.js"></script>
|
||||
```
|
||||
|
||||
**Note**: IE support was dropped in v2, but restored in v4.4 by an external contributor (I have no interest in testing+supporting obsolete browser so this likely will break again in the future) and DROPPED again in v12 (css variable needed).
|
||||
You can use the es5 files and polyfill (larger) for older browser instead. For example:
|
||||
```html
|
||||
<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
|
||||
<script src="node_modules/gridstack/dist/es5/gridstack-poly.js"></script>
|
||||
<script src="node_modules/gridstack/dist/es5/gridstack-all.js"></script>
|
||||
```
|
||||
|
||||
|
||||
## Basic usage
|
||||
|
||||
creating items dynamically...
|
||||
|
||||
```js
|
||||
// ...in your HTML
|
||||
<div class="grid-stack"></div>
|
||||
|
||||
// ...in your script
|
||||
var grid = GridStack.init();
|
||||
grid.addWidget({w: 2, content: 'item 1'});
|
||||
```
|
||||
|
||||
... or creating from list
|
||||
|
||||
```js
|
||||
// using serialize data instead of .addWidget()
|
||||
const serializedData = [
|
||||
{x: 0, y: 0, w: 2, h: 2},
|
||||
{x: 2, y: 3, w: 3, content: 'item 2'},
|
||||
{x: 1, y: 3}
|
||||
];
|
||||
|
||||
grid.load(serializedData);
|
||||
```
|
||||
|
||||
... or DOM created items
|
||||
|
||||
```js
|
||||
// ...in your HTML
|
||||
<div class="grid-stack">
|
||||
<div class="grid-stack-item">
|
||||
<div class="grid-stack-item-content">Item 1</div>
|
||||
</div>
|
||||
<div class="grid-stack-item" gs-w="2">
|
||||
<div class="grid-stack-item-content">Item 2 wider</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
// ...in your script
|
||||
GridStack.init();
|
||||
```
|
||||
|
||||
...or see list of all [API and options](https://github.com/gridstack/gridstack.js/tree/master/doc) available.
|
||||
|
||||
see [stackblitz sample](https://stackblitz.com/edit/gridstack-demo) as running example too.
|
||||
|
||||
## Requirements
|
||||
|
||||
GridStack no longer requires external dependencies as of v1 (lodash was removed in v0.5 and jquery API in v1). v3 is a complete HTML5 re-write removing need for jquery. v6 is native mouse and touch event for mobile support, and no longer have jquery-ui version. All you need to include now is `gridstack-all.js` and `gridstack.min.css` (layouts are done using CSS column based %).
|
||||
|
||||
## Specific frameworks
|
||||
|
||||
search for ['gridstack' under NPM](https://www.npmjs.com/search?q=gridstack&ranking=popularity) for latest, more to come...
|
||||
|
||||
- **Angular**: we ship out of the box an Angular wrapper - see <a href="https://github.com/gridstack/gridstack.js/tree/master/angular" target="_blank">Angular Component</a>.
|
||||
- **Angular9**: [lb-gridstack](https://github.com/pfms84/lb-gridstack) Note: very old v0.3 gridstack instance so recommend for **concept ONLY if you wish to use directive instead**. Code has **not been vented** at as I use components.
|
||||
- **AngularJS**: [gridstack-angular](https://github.com/kdietrich/gridstack-angular)
|
||||
- **Ember**: [ember-gridstack](https://github.com/yahoo/ember-gridstack)
|
||||
- **knockout**: see [demo](https://gridstackjs.com/demo/knockout.html) using component, but check [custom bindings ticket](https://github.com/gridstack/gridstack.js/issues/465) which is likely better approach.
|
||||
- **Rails**: [gridstack-js-rails](https://github.com/randoum/gridstack-js-rails)
|
||||
- **React**: work in progress to have wrapper code: see <a href="https://github.com/gridstack/gridstack.js/tree/master/react" target="_blank">React Component</a>. But also see [demo](https://gridstackjs.com/demo/react.html) with [src](https://github.com/gridstack/gridstack.js/tree/master/demo/react.html), or [react-gridstack-example](https://github.com/Inder2108/react-gridstack-example/tree/master/src/App.js), or read on what [hooks to use](https://github.com/gridstack/gridstack.js/issues/735#issuecomment-329888796)
|
||||
- **Vue**: see [demo](https://gridstackjs.com/demo/vue3js.html) with [v3 src](https://github.com/gridstack/gridstack.js/tree/master/demo/vue3js.html) or [v2 src](https://github.com/gridstack/gridstack.js/tree/master/demo/vue2js.html)
|
||||
- **Aurelia**: [aurelia-gridstack](https://github.com/aurelia-ui-toolkits/aurelia-gridstack), see [demo](https://aurelia-ui-toolkits.github.io/aurelia-gridstack/)
|
||||
|
||||
## Extend Library
|
||||
|
||||
You can easily extend or patch gridstack with code like this:
|
||||
|
||||
```js
|
||||
// extend gridstack with our own custom method
|
||||
GridStack.prototype.printCount = function() {
|
||||
console.log('grid has ' + this.engine.nodes.length + ' items');
|
||||
};
|
||||
|
||||
let grid = GridStack.init();
|
||||
|
||||
// you can now call
|
||||
grid.printCount();
|
||||
```
|
||||
|
||||
## Extend Engine
|
||||
|
||||
You can now (5.1+) easily create your own layout engine to further customize your usage. Here is a typescript example
|
||||
|
||||
```ts
|
||||
import { GridStack, GridStackEngine, GridStackNode, GridStackMoveOpts } from 'gridstack';
|
||||
|
||||
class CustomEngine extends GridStackEngine {
|
||||
|
||||
/** refined this to move the node to the given new location */
|
||||
public override moveNode(node: GridStackNode, o: GridStackMoveOpts): boolean {
|
||||
// keep the same original X and Width and let base do it all...
|
||||
o.x = node.x;
|
||||
o.w = node.w;
|
||||
return super.moveNode(node, o);
|
||||
}
|
||||
}
|
||||
|
||||
GridStack.registerEngine(CustomEngine); // globally set our custom class
|
||||
```
|
||||
|
||||
## Change grid columns
|
||||
|
||||
GridStack makes it very easy if you need [1-12] columns out of the box (default is 12), but you always need **2 things** if you need to customize this:
|
||||
|
||||
1) Change the `column` grid option when creating a grid to your number N
|
||||
```js
|
||||
GridStack.init( {column: N} );
|
||||
```
|
||||
|
||||
NOTE: step 2 is OLD and not needed with v12+ which uses CSS variables instead of classes
|
||||
|
||||
2) also include `gridstack-extra.css` if **N < 12** (else custom CSS - see next). Without these, things will not render/work correctly.
|
||||
```html
|
||||
<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
|
||||
<link href="node_modules/gridstack/dist/gridstack-extra.min.css" rel="stylesheet"/>
|
||||
|
||||
<div class="grid-stack">...</div>
|
||||
```
|
||||
|
||||
Note: class `.grid-stack-N` will automatically be added and we include `gridstack-extra.min.css` which defines CSS for grids with custom [2-11] columns. Anything more and you'll need to generate the SASS/CSS yourself (see next).
|
||||
|
||||
See example: [2 grids demo](http://gridstack.github.io/gridstack.js/demo/two.html) with 6 columns
|
||||
|
||||
## Custom columns CSS (OLD, not needed with v12+)
|
||||
|
||||
NOTE: step is OLD and not needed with v12+ which uses CSS variables instead of classes
|
||||
|
||||
If you need > 12 columns or want to generate the CSS manually you will need to generate CSS rules for `.grid-stack-item[gs-w="X"]` and `.grid-stack-item[gs-x="X"]`.
|
||||
|
||||
For instance for 4-column grid you need CSS to be:
|
||||
|
||||
```css
|
||||
.gs-4 > .grid-stack-item[gs-x="1"] { left: 25% }
|
||||
.gs-4 > .grid-stack-item[gs-x="2"] { left: 50% }
|
||||
.gs-4 > .grid-stack-item[gs-x="3"] { left: 75% }
|
||||
|
||||
.gs-4 > .grid-stack-item { width: 25% }
|
||||
.gs-4 > .grid-stack-item[gs-w="2"] { width: 50% }
|
||||
.gs-4 > .grid-stack-item[gs-w="3"] { width: 75% }
|
||||
.gs-4 > .grid-stack-item[gs-w="4"] { width: 100% }
|
||||
```
|
||||
|
||||
Better yet, here is a SCSS code snippet, you can use sites like [sassmeister.com](https://www.sassmeister.com/) to generate the CSS for you instead:
|
||||
|
||||
```scss
|
||||
$columns: 20;
|
||||
@function fixed($float) {
|
||||
@return round($float * 1000) / 1000; // total 2+3 digits being %
|
||||
}
|
||||
.gs-#{$columns} > .grid-stack-item {
|
||||
|
||||
width: fixed(100% / $columns);
|
||||
|
||||
@for $i from 1 through $columns - 1 {
|
||||
&[gs-x='#{$i}'] { left: fixed((100% / $columns) * $i); }
|
||||
&[gs-w='#{$i+1}'] { width: fixed((100% / $columns) * ($i+1)); }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
you can also use the SCSS [src/gridstack-extra.scss](https://github.com/gridstack/gridstack.js/tree/master/src/gridstack-extra.scss) included in NPM package and modify to add more columns.
|
||||
|
||||
Sample gulp command for 30 columns:
|
||||
```js
|
||||
gulp.src('node_modules/gridstack/dist/src/gridstack-extra.scss')
|
||||
.pipe(replace('$start: 2 !default;','$start: 30;'))
|
||||
.pipe(replace('$end: 11 !default;','$end: 30;'))
|
||||
.pipe(sass({outputStyle: 'compressed'}))
|
||||
.pipe(rename({extname: '.min.css'}))
|
||||
.pipe(gulp.dest('dist/css'))
|
||||
```
|
||||
|
||||
## Override resizable/draggable options
|
||||
|
||||
You can override default `resizable`/`draggable` options. For instance to enable other then bottom right resizing handle
|
||||
you can init gridstack like:
|
||||
|
||||
```js
|
||||
GridStack.init({
|
||||
resizable: {
|
||||
handles: 'e,se,s,sw,w'
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## Touch devices support
|
||||
|
||||
gridstack v6+ now support mobile out of the box, with the addition of native touch event (along with mouse event) for drag&drop and resize.
|
||||
Older versions (3.2+) required the jq version with added touch punch, but doesn't work well with nested grids.
|
||||
|
||||
This option is now the default:
|
||||
|
||||
```js
|
||||
let options = {
|
||||
alwaysShowResizeHandle: 'mobile' // true if we're on mobile devices
|
||||
};
|
||||
GridStack.init(options);
|
||||
```
|
||||
|
||||
See [example](http://gridstack.github.io/gridstack.js/demo/mobile.html).
|
||||
|
||||
# Migrating
|
||||
## Migrating to v0.6
|
||||
|
||||
starting in 0.6.x `change` event are no longer sent (for pretty much most nodes!) when an item is just added/deleted unless it also changes other nodes (was incorrect and causing inefficiencies). You may need to track `added|removed` [events](https://github.com/gridstack/gridstack.js/tree/master/doc#events) if you didn't and relied on the old broken behavior.
|
||||
|
||||
## Migrating to v1
|
||||
|
||||
v1.0.0 removed Jquery from the API and external dependencies, which will require some code changes. Here is a list of the changes:
|
||||
|
||||
0. see previous step if not on v0.6 already
|
||||
|
||||
1. your code only needs to `import GridStack from 'gridstack'` or include `gridstack.all.js` and `gristack.css` (don't include other JS) and is recommended you do that as internal dependencies will change over time. If you are jquery based, see [jquery app](#jquery-application) section.
|
||||
|
||||
2. code change:
|
||||
|
||||
**OLD** initializing code + adding a widget + adding an event:
|
||||
```js
|
||||
// initialization returned Jquery element, requiring second call to get GridStack var
|
||||
var grid = $('.grid-stack').gridstack(opts?).data('gridstack');
|
||||
|
||||
// returned Jquery element
|
||||
grid.addWidget($('<div><div class="grid-stack-item-content"> test </div></div>'), undefined, undefined, 2, undefined, true);
|
||||
|
||||
// jquery event handler
|
||||
$('.grid-stack').on('added', function(e, items) {/* items contains info */});
|
||||
|
||||
// grid access after init
|
||||
var grid = $('.grid-stack').data('gridstack');
|
||||
```
|
||||
**NEW**
|
||||
```js
|
||||
// element identifier defaults to '.grid-stack', returns the grid
|
||||
// Note: for Typescript use window.GridStack.init() until next native 2.x TS version
|
||||
var grid = GridStack.init(opts?, element?);
|
||||
|
||||
// returns DOM element
|
||||
grid.addWidget('<div><div class="grid-stack-item-content"> test </div></div>', {width: 2});
|
||||
// Note: in 3.x it's ever simpler
|
||||
// grid.addWidget({w:2, content: 'test'})
|
||||
|
||||
// event handler
|
||||
grid.on('added', function(e, items) {/* items contains info */});
|
||||
|
||||
// grid access after init
|
||||
var grid = el.gridstack; // where el = document.querySelector('.grid-stack') or other ways...
|
||||
```
|
||||
Other rename changes
|
||||
|
||||
```js
|
||||
`GridStackUI` --> `GridStack`
|
||||
`GridStackUI.GridStackEngine` --> `GridStack.Engine`
|
||||
`grid.container` (jquery grid wrapper) --> `grid.el` // (grid DOM element)
|
||||
`grid.grid` (GridStackEngine) --> `grid.engine`
|
||||
`grid.setColumn(N)` --> `grid.column(N)` and `grid.column()` // to get value, old API still supported though
|
||||
```
|
||||
|
||||
Recommend looking at the [many samples](./demo) for more code examples.
|
||||
|
||||
## Migrating to v2
|
||||
|
||||
make sure to read v1 migration first!
|
||||
|
||||
v2 is a Typescript rewrite of 1.x, removing all jquery events, using classes and overall code cleanup to support ES6 modules. Your code might need to change from 1.x
|
||||
|
||||
1. In general methods that used no args (getter) vs setter can't be used in TS when the arguments differ (set/get are also not function calls so API would have changed). Instead we decided to have <b>all set methods return</b> `GridStack` to they can be chain-able (ex: `grid.float(true).cellHeight(10).column(6)`). Also legacy methods that used to take many parameters will now take a single object (typically `GridStackOptions` or `GridStackWidget`).
|
||||
|
||||
```js
|
||||
`addWidget(el, x, y, width, height)` --> `addWidget(el, {with: 2})`
|
||||
// Note: in 2.1.x you can now just do addWidget({with: 2, content: "text"})
|
||||
`float()` --> `getFloat()` // to get value
|
||||
`cellHeight()` --> `getCellHeight()` // to get value
|
||||
`verticalMargin` --> `margin` // grid options and API that applies to all 4 sides.
|
||||
`verticalMargin()` --> `getMargin()` // to get value
|
||||
```
|
||||
|
||||
2. event signatures are generic and not jquery-ui dependent anymore. `gsresizestop` has been removed as `resizestop|dragstop` are now called **after** the DOM attributes have been updated.
|
||||
|
||||
3. `oneColumnMode` would trigger when `window.width` < 768px by default. We now check for grid width instead (more correct and supports nesting). You might need to adjust grid `oneColumnSize` or `disableOneColumnMode`.
|
||||
|
||||
**Note:** 2.x no longer support legacy IE11 and older due to using more compact ES6 output and typecsript native code. You will need to stay at 1.x
|
||||
|
||||
## Migrating to v3
|
||||
|
||||
make sure to read v2 migration first!
|
||||
|
||||
v3 has a new HTML5 drag&drop plugging (63k total, all native code), while still allowing you to use the legacy jquery-ui version instead (188k), or a new static grid version (34k, no user drag&drop but full API support). You will need to decide which version to use as `gridstack.all.js` no longer exist (same is now `gridstack-jq.js`) - see [include info](#include).
|
||||
|
||||
**NOTE**: HTML5 version is almost on parity with the old jquery-ui based drag&drop. the `containment` (prevent a child from being dragged outside it's parent) and `revert` (not clear what it is for yet) are not yet implemented in initial release of v3.0.0.<br>
|
||||
Also mobile devices don't support h5 `drag` events (will need to handle `touch`) whereas v3.2 jq version now now supports out of the box (see [v3.2 release](https://github.com/gridstack/gridstack.js/releases/tag/v3.2.0))
|
||||
|
||||
Breaking changes:
|
||||
|
||||
1. include (as mentioned) need to change
|
||||
|
||||
2. `GridStack.update(el, opt)` now takes single `GridStackWidget` options instead of only supporting (x,y,w,h) BUT legacy call in JS will continue working the same for now. That method is a complete re-write and does the right constrain and updates now for all the available params.
|
||||
|
||||
3. `locked()`, `move()`, `resize()`, `minWidth()`, `minHeight()`, `maxWidth()`, `maxHeight()` methods are hidden from Typescript (JS can still call for now) as they are just 1 liner wrapper around `update(el, opt)` anyway and will go away soon. (ex: `move(el, x, y)` => `update(el, {x, y})`)
|
||||
|
||||
4. item attribute like `data-gs-min-width` is now `gs-min-w`. We removed 'data-' from all attributes, and shorten 'width|height' to just 'w|h' to require less typing and more efficient (2k saved in .js alone!).
|
||||
|
||||
5. `GridStackWidget` used in most API `width|height|minWidth|minHeight|maxWidth|maxHeight` are now shorter `w|h|minW|minH|maxW|maxH` as well
|
||||
|
||||
## Migrating to v4
|
||||
|
||||
make sure to read v3 migration first!
|
||||
|
||||
v4 is a complete re-write of the collision and drag in/out heuristics to fix some very long standing request & bugs. It also greatly improved usability. Read the release notes for more detail.
|
||||
|
||||
**Unlikely** Breaking Changes (internal usage):
|
||||
|
||||
1. `removeTimeout` was removed (feedback over trash will be immediate - actual removal still on mouse up)
|
||||
|
||||
2. the following `GridStackEngine` methods changed (used internally, doesn't affect `GridStack` public API)
|
||||
|
||||
```js
|
||||
// moved to 3 methods with new option params to support new code and pixel coverage check
|
||||
`collision()` -> `collide(), collideAll(), collideCoverage()`
|
||||
`moveNodeCheck(node, x, y, w, h)` -> `moveNodeCheck(node, opt: GridStackMoveOpts)`
|
||||
`isNodeChangedPosition(node, x, y, w, h)` -> `changedPosConstrain(node, opt: GridStackMoveOpts)`
|
||||
`moveNode(node, x, y, w, h, noPack)` -> `moveNode(node, opt: GridStackMoveOpts)`
|
||||
```
|
||||
|
||||
3. removed old obsolete (v0.6-v1 methods/attrs) `getGridHeight()`, `verticalMargin`, `data-gs-current-height`,
|
||||
`locked()`, `maxWidth()`, `minWidth()`, `maxHeight()`, `minHeight()`, `move()`, `resize()`
|
||||
|
||||
|
||||
## Migrating to v5
|
||||
|
||||
make sure to read v4 migration first!
|
||||
|
||||
v5 does not have any breaking changes from v4, but a focus on nested grids in h5 mode:
|
||||
You can now drag in/out of parent into nested child, with new API parameters values. See the release notes.
|
||||
|
||||
## Migrating to v6
|
||||
|
||||
the API did not really change from v5, but a complete re-write of Drag&Drop to use native `mouseevent` (instead of HTML draggable=true which is buggy on Mac Safari, and doesn't work on mobile devices) and `touchevent` (mobile), and we no longer have jquery ui option (wasn't working well for nested grids, didn't want to maintain legacy lib).
|
||||
|
||||
The main difference is you only need to include gridstack.js and get D&D (desktop and mobile) out of the box for the same size as h5 version.
|
||||
|
||||
## Migrating to v7
|
||||
|
||||
New addition, no API breakage per say. See release notes about creating sub-grids on the fly.
|
||||
|
||||
## Migrating to v8
|
||||
|
||||
Possible breaking change if you use nested grid JSON format, or original Angular wrapper, or relied on specific CSS paths. Also target is now ES2020 (see release notes).
|
||||
* `GridStackOptions.subGrid` -> `GridStackOptions.subGridOpts` rename. We now have `GridStackWidget.subGridOpts` vs `GridStackNode.subGrid` (was both types which is error prone)
|
||||
* `GridStackOptions.addRemoveCB` -> `GridStack.addRemoveCB` is now global instead of grid option
|
||||
* removed `GridStackOptions.dragInOptions` since `GridStack.setupDragIn()` has it replaced since 4.0
|
||||
* remove `GridStackOptions.minWidth` obsolete since 5.1, use `oneColumnSize` instead
|
||||
* CSS rules removed `.grid-stack` prefix for anything already gs based, 12 column (default) now uses `.gs-12`, extra.css is less than 1/4th it original size!, `gs-min|max_w|h` attribute no longer written (but read)
|
||||
|
||||
## Migrating to v9
|
||||
|
||||
New addition - see release notes about `sizeToContent` feature.
|
||||
Possible break:
|
||||
* `GridStack.onParentResize()` is now called `onResize()` as grid now directly track size change, no longer involving parent per say to tell us anything. Note sure why it was public.
|
||||
|
||||
## Migrating to v10
|
||||
|
||||
we now support much richer responsive behavior with `GridStackOptions.columnOpts` including any breakpoint width:column pairs, or automatic column sizing.
|
||||
|
||||
breaking change:
|
||||
* `disableOneColumnMode`, `oneColumnSize` have been removed (thought we temporary convert if you have them). use `columnOpts: { breakpoints: [{w:768, c:1}] }` for the same behavior.
|
||||
* 1 column mode switch is no longer by default (`columnOpts` is not defined) as too many new users had issues. Instead set it explicitly (see above).
|
||||
* `oneColumnModeDomSort` has been removed. Planning to support per column layouts at some future times. TBD
|
||||
|
||||
## Migrating to v11
|
||||
|
||||
* All instances of `el.innerHTML = 'some content'` have been removed for security reason as it opens up some potential for accidental XSS.
|
||||
|
||||
* Side panel drag&drop complete rewrite.
|
||||
|
||||
* new lazy loading option
|
||||
|
||||
**Breaking change:**
|
||||
|
||||
* V11 add new `GridStack.renderCB` that is called for you to create the widget content (entire GridStackWidget is passed so you can use id or some other field as logic) while GS creates the 2 needed parent divs + classes, unlike `GridStack.addRemoveCB` which doesn't create anything for you. Both can be handy for Angular/React/Vue frameworks.
|
||||
* `addWidget(w: GridStackWidget)` is now the only supported format, no more string content passing. You will need to create content yourself as shown below, OR use `GridStack.createWidgetDivs()` to create parent divs, do the innerHtml, then call `makeWidget(el)` instead.
|
||||
* if your code relies on `GridStackWidget.content` with real HTML (like a few demos) it is up to you to do this:
|
||||
```ts
|
||||
// NOTE: REAL apps would sanitize-html or DOMPurify before blinding setting innerHTML. see #2736
|
||||
GridStack.renderCB = function(el: HTMLElement, w: GridStackNode) {
|
||||
el.innerHTML = w.content;
|
||||
};
|
||||
|
||||
// now you can create widgets like this again
|
||||
let gridWidget = grid.addWidget({x, y, w, h, content: '<div>My html content</div>'});
|
||||
```
|
||||
|
||||
**Potential breaking change:**
|
||||
|
||||
* BIG overall to how sidepanel helper drag&drop is done:
|
||||
1. `clone()` helper is now passed full HTML element dragged, not an event on `grid-stack-item-content` so you can clone or set attr at the top.
|
||||
2. use any class/structure you want for side panel items (see two.html)
|
||||
3. `GridStack.setupDragIn()` now support associating a `GridStackWidget` for each sidepanel that will be used to define what to create on drop!
|
||||
4. if no `GridStackWidget` is defined, the helper will now be inserted as is, and NOT original sidepanel item.
|
||||
5. support DOM gs- attr as well as gridstacknode JSON (see two.html) alternatives.
|
||||
|
||||
## Migrating to v12
|
||||
|
||||
* column and cell height code has been re-writen to use browser CSS variables, and we no longer need a tons of custom CSS classes!
|
||||
this fixes a long standing issue where people forget to include the right CSS for non 12 columns layouts, and a big speedup in many cases (many columns, or small cellHeight values).
|
||||
|
||||
**Potential breaking change:**
|
||||
* `gridstack-extra.min.css` no longer exist, nor is custom column CSS classes needed. API/options hasn't changed.
|
||||
* (v12.1) `ES5` folder content has been removed - was for IE support, which has been dropped.
|
||||
* (v12.1) nested grid events are now sent to the main grid. You might have to adjust your workaround of this missing feature. nested.html demo has been adjusted.
|
||||
|
||||
# jQuery Application
|
||||
|
||||
This is **old and no longer apply to v6+**. You'll need to use v5.1.1 and before
|
||||
|
||||
```js
|
||||
import 'gridstack/dist/gridstack.min.css';
|
||||
import { GridStack } from 'gridstack';
|
||||
import 'gridstack/dist/jq/gridstack-dd-jqueryui';
|
||||
```
|
||||
**Note**: `jquery` & `jquery-ui` are imported by name, so you will have to specify their location in your webpack (or equivalent) config file,
|
||||
which means you can possibly bring your own version
|
||||
```js
|
||||
alias: {
|
||||
'jquery': 'gridstack/dist/jq/jquery.js',
|
||||
'jquery-ui': 'gridstack/dist/jq/jquery-ui.js',
|
||||
'jquery.ui': 'gridstack/dist/jq/jquery-ui.js',
|
||||
'jquery.ui.touch-punch': 'gridstack/dist/jq/jquery.ui.touch-punch.js',
|
||||
},
|
||||
```
|
||||
Alternatively (single combined file) in html
|
||||
|
||||
```html
|
||||
<link href="node_modules/gridstack/dist/gridstack.min.css" rel="stylesheet"/>
|
||||
<!-- HTML5 drag&drop (70k) -->
|
||||
<script src="node_modules/gridstack/dist/gridstack-h5.js"></script>
|
||||
<!-- OR jquery-ui drag&drop (195k) -->
|
||||
<script src="node_modules/gridstack/dist/gridstack-jq.js"></script>
|
||||
<!-- OR static grid (40k) -->
|
||||
<script src="node_modules/gridstack/dist/gridstack-static.js"></script>
|
||||
```
|
||||
|
||||
We have a native HTML5 drag'n'drop through the plugin system (default), but the jquery-ui version can be used instead. It will bundle `jquery` (3.5.1) + `jquery-ui` (1.13.1 minimal drag|drop|resize) + `jquery-ui-touch-punch` (1.0.8 for mobile support) in `gridstack-jq.js`.
|
||||
|
||||
**NOTE: in v4, v3**: we ES6 module import jquery & jquery-ui by name, so you need to specify location of those .js files, which means you might be able to bring your own version as well. See the include instructions.
|
||||
|
||||
**NOTE: in v1.x** IFF you want to use gridstack-jq instead and your app needs to bring your own JQ version, you should **instead** include `gridstack-poly.min.js` (optional IE support) + `gridstack.min.js` + `gridstack.jQueryUI.min.js` after you import your JQ libs. But note that there are issue with jQuery and ES6 import (see [1306](https://github.com/gridstack/gridstack.js/issues/1306)).
|
||||
|
||||
As for events, you can still use `$(".grid-stack").on(...)` for the version that uses jquery-ui for things we don't support.
|
||||
|
||||
# Changes
|
||||
|
||||
View our change log [here](https://github.com/gridstack/gridstack.js/tree/master/doc/CHANGES.md).
|
||||
|
||||
# Usage Trend
|
||||
|
||||
[Usage Trend of gridstack](https://npm-compare.com/gridstack#timeRange=THREE_YEARS)
|
||||
|
||||
<a href="https://npm-compare.com/gridstack#timeRange=THREE_YEARS" target="_blank">
|
||||
<img src="https://npm-compare.com/img/npm-trend/THREE_YEARS/gridstack.png" width="70%" alt="NPM Usage Trend of gridstack" />
|
||||
</a>
|
||||
|
||||
# The Team
|
||||
|
||||
gridstack.js is currently maintained by [Alain Dumesny](https://github.com/adumesny), before that [Dylan Weiss](https://github.com/radiolips), originally created by [Pavel Reznikov](https://github.com/troolee). We appreciate [all contributors](https://github.com/gridstack/gridstack.js/graphs/contributors) for help.
|
||||
69
node_modules/gridstack/dist/dd-base-impl.d.ts
generated
vendored
69
node_modules/gridstack/dist/dd-base-impl.d.ts
generated
vendored
@@ -1,69 +0,0 @@
|
||||
/**
|
||||
* dd-base-impl.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
/**
|
||||
* Type for event callback functions used in drag & drop operations.
|
||||
* Can return boolean to indicate if the event should continue propagation.
|
||||
*/
|
||||
export type EventCallback = (event: Event) => boolean | void;
|
||||
/**
|
||||
* Abstract base class for all drag & drop implementations.
|
||||
* Provides common functionality for event handling, enable/disable state,
|
||||
* and lifecycle management used by draggable, droppable, and resizable implementations.
|
||||
*/
|
||||
export declare abstract class DDBaseImplement {
|
||||
/**
|
||||
* Returns the current disabled state.
|
||||
* Note: Use enable()/disable() methods to change state as other operations need to happen.
|
||||
*/
|
||||
get disabled(): boolean;
|
||||
/**
|
||||
* Register an event callback for the specified event.
|
||||
*
|
||||
* @param event - Event name to listen for
|
||||
* @param callback - Function to call when event occurs
|
||||
*/
|
||||
on(event: string, callback: EventCallback): void;
|
||||
/**
|
||||
* Unregister an event callback for the specified event.
|
||||
*
|
||||
* @param event - Event name to stop listening for
|
||||
*/
|
||||
off(event: string): void;
|
||||
/**
|
||||
* Enable this drag & drop implementation.
|
||||
* Subclasses should override to perform additional setup.
|
||||
*/
|
||||
enable(): void;
|
||||
/**
|
||||
* Disable this drag & drop implementation.
|
||||
* Subclasses should override to perform additional cleanup.
|
||||
*/
|
||||
disable(): void;
|
||||
/**
|
||||
* Destroy this drag & drop implementation and clean up resources.
|
||||
* Removes all event handlers and clears internal state.
|
||||
*/
|
||||
destroy(): void;
|
||||
/**
|
||||
* Trigger a registered event callback if one exists and the implementation is enabled.
|
||||
*
|
||||
* @param eventName - Name of the event to trigger
|
||||
* @param event - DOM event object to pass to the callback
|
||||
* @returns Result from the callback function, if any
|
||||
*/
|
||||
triggerEvent(eventName: string, event: Event): boolean | void;
|
||||
}
|
||||
/**
|
||||
* Interface for HTML elements extended with drag & drop options.
|
||||
* Used to associate DD configuration with DOM elements.
|
||||
*/
|
||||
export interface HTMLElementExtendOpt<T> {
|
||||
/** The HTML element being extended */
|
||||
el: HTMLElement;
|
||||
/** The drag & drop options/configuration */
|
||||
option: T;
|
||||
/** Method to update the options and return the DD implementation */
|
||||
updateOption(T: any): DDBaseImplement;
|
||||
}
|
||||
70
node_modules/gridstack/dist/dd-base-impl.js
generated
vendored
70
node_modules/gridstack/dist/dd-base-impl.js
generated
vendored
@@ -1,70 +0,0 @@
|
||||
/**
|
||||
* dd-base-impl.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
/**
|
||||
* Abstract base class for all drag & drop implementations.
|
||||
* Provides common functionality for event handling, enable/disable state,
|
||||
* and lifecycle management used by draggable, droppable, and resizable implementations.
|
||||
*/
|
||||
export class DDBaseImplement {
|
||||
constructor() {
|
||||
/** @internal */
|
||||
this._eventRegister = {};
|
||||
}
|
||||
/**
|
||||
* Returns the current disabled state.
|
||||
* Note: Use enable()/disable() methods to change state as other operations need to happen.
|
||||
*/
|
||||
get disabled() { return this._disabled; }
|
||||
/**
|
||||
* Register an event callback for the specified event.
|
||||
*
|
||||
* @param event - Event name to listen for
|
||||
* @param callback - Function to call when event occurs
|
||||
*/
|
||||
on(event, callback) {
|
||||
this._eventRegister[event] = callback;
|
||||
}
|
||||
/**
|
||||
* Unregister an event callback for the specified event.
|
||||
*
|
||||
* @param event - Event name to stop listening for
|
||||
*/
|
||||
off(event) {
|
||||
delete this._eventRegister[event];
|
||||
}
|
||||
/**
|
||||
* Enable this drag & drop implementation.
|
||||
* Subclasses should override to perform additional setup.
|
||||
*/
|
||||
enable() {
|
||||
this._disabled = false;
|
||||
}
|
||||
/**
|
||||
* Disable this drag & drop implementation.
|
||||
* Subclasses should override to perform additional cleanup.
|
||||
*/
|
||||
disable() {
|
||||
this._disabled = true;
|
||||
}
|
||||
/**
|
||||
* Destroy this drag & drop implementation and clean up resources.
|
||||
* Removes all event handlers and clears internal state.
|
||||
*/
|
||||
destroy() {
|
||||
delete this._eventRegister;
|
||||
}
|
||||
/**
|
||||
* Trigger a registered event callback if one exists and the implementation is enabled.
|
||||
*
|
||||
* @param eventName - Name of the event to trigger
|
||||
* @param event - DOM event object to pass to the callback
|
||||
* @returns Result from the callback function, if any
|
||||
*/
|
||||
triggerEvent(eventName, event) {
|
||||
if (!this.disabled && this._eventRegister && this._eventRegister[eventName])
|
||||
return this._eventRegister[eventName](event);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=dd-base-impl.js.map
|
||||
1
node_modules/gridstack/dist/dd-base-impl.js.map
generated
vendored
1
node_modules/gridstack/dist/dd-base-impl.js.map
generated
vendored
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"dd-base-impl.js","sourceRoot":"","sources":["../src/dd-base-impl.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH;;;;GAIG;AACH,MAAM,OAAgB,eAAe;IAArC;QASE,gBAAgB;QACN,mBAAc,GAEpB,EAAE,CAAC;IAwDT,CAAC;IAnEC;;;OAGG;IACH,IAAW,QAAQ,KAAgB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAS3D;;;;;OAKG;IACI,EAAE,CAAC,KAAa,EAAE,QAAuB;QAC9C,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACI,GAAG,CAAC,KAAa;QACtB,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED;;;OAGG;IACI,MAAM;QACX,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACzB,CAAC;IAED;;;OAGG;IACI,OAAO;QACZ,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAED;;;OAGG;IACI,OAAO;QACZ,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACI,YAAY,CAAC,SAAiB,EAAE,KAAY;QACjD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;YACzE,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;CACF","sourcesContent":["/**\n * dd-base-impl.ts 12.4.2\n * Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license\n */\n\n/**\n * Type for event callback functions used in drag & drop operations.\n * Can return boolean to indicate if the event should continue propagation.\n */\nexport type EventCallback = (event: Event) => boolean|void;\n\n/**\n * Abstract base class for all drag & drop implementations.\n * Provides common functionality for event handling, enable/disable state,\n * and lifecycle management used by draggable, droppable, and resizable implementations.\n */\nexport abstract class DDBaseImplement {\n /**\n * Returns the current disabled state.\n * Note: Use enable()/disable() methods to change state as other operations need to happen.\n */\n public get disabled(): boolean { return this._disabled; }\n\n /** @internal */\n protected _disabled: boolean; // initial state to differentiate from false\n /** @internal */\n protected _eventRegister: {\n [eventName: string]: EventCallback;\n } = {};\n\n /**\n * Register an event callback for the specified event.\n *\n * @param event - Event name to listen for\n * @param callback - Function to call when event occurs\n */\n public on(event: string, callback: EventCallback): void {\n this._eventRegister[event] = callback;\n }\n\n /**\n * Unregister an event callback for the specified event.\n *\n * @param event - Event name to stop listening for\n */\n public off(event: string): void {\n delete this._eventRegister[event];\n }\n\n /**\n * Enable this drag & drop implementation.\n * Subclasses should override to perform additional setup.\n */\n public enable(): void {\n this._disabled = false;\n }\n\n /**\n * Disable this drag & drop implementation.\n * Subclasses should override to perform additional cleanup.\n */\n public disable(): void {\n this._disabled = true;\n }\n\n /**\n * Destroy this drag & drop implementation and clean up resources.\n * Removes all event handlers and clears internal state.\n */\n public destroy(): void {\n delete this._eventRegister;\n }\n\n /**\n * Trigger a registered event callback if one exists and the implementation is enabled.\n *\n * @param eventName - Name of the event to trigger\n * @param event - DOM event object to pass to the callback\n * @returns Result from the callback function, if any\n */\n public triggerEvent(eventName: string, event: Event): boolean|void {\n if (!this.disabled && this._eventRegister && this._eventRegister[eventName])\n return this._eventRegister[eventName](event);\n }\n}\n\n/**\n * Interface for HTML elements extended with drag & drop options.\n * Used to associate DD configuration with DOM elements.\n */\nexport interface HTMLElementExtendOpt<T> {\n /** The HTML element being extended */\n el: HTMLElement;\n /** The drag & drop options/configuration */\n option: T;\n /** Method to update the options and return the DD implementation */\n updateOption(T): DDBaseImplement;\n}\n"]}
|
||||
20
node_modules/gridstack/dist/dd-draggable.d.ts
generated
vendored
20
node_modules/gridstack/dist/dd-draggable.d.ts
generated
vendored
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* dd-draggable.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
import { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';
|
||||
import { GridItemHTMLElement, DDDragOpt } from './types';
|
||||
type DDDragEvent = 'drag' | 'dragstart' | 'dragstop';
|
||||
export declare class DDDraggable extends DDBaseImplement implements HTMLElementExtendOpt<DDDragOpt> {
|
||||
el: GridItemHTMLElement;
|
||||
option: DDDragOpt;
|
||||
helper: HTMLElement;
|
||||
constructor(el: GridItemHTMLElement, option?: DDDragOpt);
|
||||
on(event: DDDragEvent, callback: (event: DragEvent) => void): void;
|
||||
off(event: DDDragEvent): void;
|
||||
enable(): void;
|
||||
disable(forDestroy?: boolean): void;
|
||||
destroy(): void;
|
||||
updateOption(opts: DDDragOpt): DDDraggable;
|
||||
}
|
||||
export {};
|
||||
367
node_modules/gridstack/dist/dd-draggable.js
generated
vendored
367
node_modules/gridstack/dist/dd-draggable.js
generated
vendored
@@ -1,367 +0,0 @@
|
||||
/**
|
||||
* dd-draggable.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
import { DDManager } from './dd-manager';
|
||||
import { Utils } from './utils';
|
||||
import { DDBaseImplement } from './dd-base-impl';
|
||||
import { isTouch, touchend, touchmove, touchstart, pointerdown, DDTouch } from './dd-touch';
|
||||
// make sure we are not clicking on known object that handles mouseDown
|
||||
const skipMouseDown = 'input,textarea,button,select,option,[contenteditable="true"],.ui-resizable-handle';
|
||||
// let count = 0; // TEST
|
||||
class DDDraggable extends DDBaseImplement {
|
||||
constructor(el, option = {}) {
|
||||
super();
|
||||
this.el = el;
|
||||
this.option = option;
|
||||
/** @internal */
|
||||
this.dragTransform = {
|
||||
xScale: 1,
|
||||
yScale: 1,
|
||||
xOffset: 0,
|
||||
yOffset: 0
|
||||
};
|
||||
// get the element that is actually supposed to be dragged by
|
||||
const handleName = option?.handle?.substring(1);
|
||||
const n = el.gridstackNode;
|
||||
this.dragEls = !handleName || el.classList.contains(handleName) ? [el] : (n?.subGrid ? [el.querySelector(option.handle) || el] : Array.from(el.querySelectorAll(option.handle)));
|
||||
if (this.dragEls.length === 0) {
|
||||
this.dragEls = [el];
|
||||
}
|
||||
// create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)
|
||||
this._mouseDown = this._mouseDown.bind(this);
|
||||
this._mouseMove = this._mouseMove.bind(this);
|
||||
this._mouseUp = this._mouseUp.bind(this);
|
||||
this._keyEvent = this._keyEvent.bind(this);
|
||||
this.enable();
|
||||
}
|
||||
on(event, callback) {
|
||||
super.on(event, callback);
|
||||
}
|
||||
off(event) {
|
||||
super.off(event);
|
||||
}
|
||||
enable() {
|
||||
if (this.disabled === false)
|
||||
return;
|
||||
super.enable();
|
||||
this.dragEls.forEach(dragEl => {
|
||||
dragEl.addEventListener('mousedown', this._mouseDown);
|
||||
if (isTouch) {
|
||||
dragEl.addEventListener('touchstart', touchstart);
|
||||
dragEl.addEventListener('pointerdown', pointerdown);
|
||||
// dragEl.style.touchAction = 'none'; // not needed unlike pointerdown doc comment
|
||||
}
|
||||
});
|
||||
this.el.classList.remove('ui-draggable-disabled');
|
||||
}
|
||||
disable(forDestroy = false) {
|
||||
if (this.disabled === true)
|
||||
return;
|
||||
super.disable();
|
||||
this.dragEls.forEach(dragEl => {
|
||||
dragEl.removeEventListener('mousedown', this._mouseDown);
|
||||
if (isTouch) {
|
||||
dragEl.removeEventListener('touchstart', touchstart);
|
||||
dragEl.removeEventListener('pointerdown', pointerdown);
|
||||
}
|
||||
});
|
||||
if (!forDestroy)
|
||||
this.el.classList.add('ui-draggable-disabled');
|
||||
}
|
||||
destroy() {
|
||||
if (this.dragTimeout)
|
||||
window.clearTimeout(this.dragTimeout);
|
||||
delete this.dragTimeout;
|
||||
if (this.mouseDownEvent)
|
||||
this._mouseUp(this.mouseDownEvent);
|
||||
this.disable(true);
|
||||
delete this.el;
|
||||
delete this.helper;
|
||||
delete this.option;
|
||||
super.destroy();
|
||||
}
|
||||
updateOption(opts) {
|
||||
Object.keys(opts).forEach(key => this.option[key] = opts[key]);
|
||||
return this;
|
||||
}
|
||||
/** @internal call when mouse goes down before a dragstart happens */
|
||||
_mouseDown(e) {
|
||||
// if real brower event (trusted:true vs false for our simulated ones) and we didn't correctly clear the last touch event, clear things up
|
||||
if (DDTouch.touchHandled && e.isTrusted)
|
||||
DDTouch.touchHandled = false;
|
||||
// don't let more than one widget handle mouseStart
|
||||
if (DDManager.mouseHandled)
|
||||
return;
|
||||
if (e.button !== 0)
|
||||
return true; // only left click
|
||||
// make sure we are not clicking on known object that handles mouseDown, or ones supplied by the user
|
||||
if (!this.dragEls.find(el => el === e.target) && e.target.closest(skipMouseDown))
|
||||
return true;
|
||||
if (this.option.cancel) {
|
||||
if (e.target.closest(this.option.cancel))
|
||||
return true;
|
||||
}
|
||||
this.mouseDownEvent = e;
|
||||
delete this.dragging;
|
||||
delete DDManager.dragElement;
|
||||
delete DDManager.dropElement;
|
||||
// document handler so we can continue receiving moves as the item is 'fixed' position, and capture=true so WE get a first crack
|
||||
document.addEventListener('mousemove', this._mouseMove, { capture: true, passive: true }); // true=capture, not bubble
|
||||
document.addEventListener('mouseup', this._mouseUp, true);
|
||||
if (isTouch) {
|
||||
e.currentTarget.addEventListener('touchmove', touchmove);
|
||||
e.currentTarget.addEventListener('touchend', touchend);
|
||||
}
|
||||
e.preventDefault();
|
||||
// preventDefault() prevents blur event which occurs just after mousedown event.
|
||||
// if an editable content has focus, then blur must be call
|
||||
if (document.activeElement)
|
||||
document.activeElement.blur();
|
||||
DDManager.mouseHandled = true;
|
||||
return true;
|
||||
}
|
||||
/** @internal method to call actual drag event */
|
||||
_callDrag(e) {
|
||||
if (!this.dragging)
|
||||
return;
|
||||
const ev = Utils.initEvent(e, { target: this.el, type: 'drag' });
|
||||
if (this.option.drag) {
|
||||
this.option.drag(ev, this.ui());
|
||||
}
|
||||
this.triggerEvent('drag', ev);
|
||||
}
|
||||
/** @internal called when the main page (after successful mousedown) receives a move event to drag the item around the screen */
|
||||
_mouseMove(e) {
|
||||
// console.log(`${count++} move ${e.x},${e.y}`)
|
||||
const s = this.mouseDownEvent;
|
||||
this.lastDrag = e;
|
||||
if (this.dragging) {
|
||||
this._dragFollow(e);
|
||||
// delay actual grid handling drag until we pause for a while if set
|
||||
if (DDManager.pauseDrag) {
|
||||
const pause = Number.isInteger(DDManager.pauseDrag) ? DDManager.pauseDrag : 100;
|
||||
if (this.dragTimeout)
|
||||
window.clearTimeout(this.dragTimeout);
|
||||
this.dragTimeout = window.setTimeout(() => this._callDrag(e), pause);
|
||||
}
|
||||
else {
|
||||
this._callDrag(e);
|
||||
}
|
||||
}
|
||||
else if (Math.abs(e.x - s.x) + Math.abs(e.y - s.y) > 3) {
|
||||
/**
|
||||
* don't start unless we've moved at least 3 pixels
|
||||
*/
|
||||
this.dragging = true;
|
||||
DDManager.dragElement = this;
|
||||
// if we're dragging an actual grid item, set the current drop as the grid (to detect enter/leave)
|
||||
const grid = this.el.gridstackNode?.grid;
|
||||
if (grid) {
|
||||
DDManager.dropElement = grid.el.ddElement.ddDroppable;
|
||||
}
|
||||
else {
|
||||
delete DDManager.dropElement;
|
||||
}
|
||||
this.helper = this._createHelper();
|
||||
this._setupHelperContainmentStyle();
|
||||
this.dragTransform = Utils.getValuesFromTransformedElement(this.helperContainment);
|
||||
this.dragOffset = this._getDragOffset(e, this.el, this.helperContainment);
|
||||
this._setupHelperStyle(e);
|
||||
const ev = Utils.initEvent(e, { target: this.el, type: 'dragstart' });
|
||||
if (this.option.start) {
|
||||
this.option.start(ev, this.ui());
|
||||
}
|
||||
this.triggerEvent('dragstart', ev);
|
||||
// now track keyboard events to cancel or rotate
|
||||
document.addEventListener('keydown', this._keyEvent);
|
||||
}
|
||||
// e.preventDefault(); // passive = true. OLD: was needed otherwise we get text sweep text selection as we drag around
|
||||
return true;
|
||||
}
|
||||
/** @internal call when the mouse gets released to drop the item at current location */
|
||||
_mouseUp(e) {
|
||||
document.removeEventListener('mousemove', this._mouseMove, true);
|
||||
document.removeEventListener('mouseup', this._mouseUp, true);
|
||||
if (isTouch && e.currentTarget) { // destroy() during nested grid call us again wit fake _mouseUp
|
||||
e.currentTarget.removeEventListener('touchmove', touchmove, true);
|
||||
e.currentTarget.removeEventListener('touchend', touchend, true);
|
||||
}
|
||||
if (this.dragging) {
|
||||
delete this.dragging;
|
||||
delete this.el.gridstackNode?._origRotate;
|
||||
document.removeEventListener('keydown', this._keyEvent);
|
||||
// reset the drop target if dragging over ourself (already parented, just moving during stop callback below)
|
||||
if (DDManager.dropElement?.el === this.el.parentElement) {
|
||||
delete DDManager.dropElement;
|
||||
}
|
||||
this.helperContainment.style.position = this.parentOriginStylePosition || null;
|
||||
if (this.helper !== this.el)
|
||||
this.helper.remove(); // hide now
|
||||
this._removeHelperStyle();
|
||||
const ev = Utils.initEvent(e, { target: this.el, type: 'dragstop' });
|
||||
if (this.option.stop) {
|
||||
this.option.stop(ev); // NOTE: destroy() will be called when removing item, so expect NULL ptr after!
|
||||
}
|
||||
this.triggerEvent('dragstop', ev);
|
||||
// call the droppable method to receive the item
|
||||
if (DDManager.dropElement) {
|
||||
DDManager.dropElement.drop(e);
|
||||
}
|
||||
}
|
||||
delete this.helper;
|
||||
delete this.mouseDownEvent;
|
||||
delete DDManager.dragElement;
|
||||
delete DDManager.dropElement;
|
||||
delete DDManager.mouseHandled;
|
||||
e.preventDefault();
|
||||
}
|
||||
/** @internal call when keys are being pressed - use Esc to cancel, R to rotate */
|
||||
_keyEvent(e) {
|
||||
const n = this.el.gridstackNode;
|
||||
const grid = n?.grid || DDManager.dropElement?.el?.gridstack;
|
||||
if (e.key === 'Escape') {
|
||||
if (n && n._origRotate) {
|
||||
n._orig = n._origRotate;
|
||||
delete n._origRotate;
|
||||
}
|
||||
grid?.cancelDrag();
|
||||
this._mouseUp(this.mouseDownEvent);
|
||||
}
|
||||
else if (n && grid && (e.key === 'r' || e.key === 'R')) {
|
||||
if (!Utils.canBeRotated(n))
|
||||
return;
|
||||
n._origRotate = n._origRotate || { ...n._orig }; // store the real orig size in case we Esc after doing rotation
|
||||
delete n._moving; // force rotate to happen (move waits for >50% coverage otherwise)
|
||||
grid.setAnimation(false) // immediate rotate so _getDragOffset() gets the right dom size below
|
||||
.rotate(n.el, { top: -this.dragOffset.offsetTop, left: -this.dragOffset.offsetLeft })
|
||||
.setAnimation();
|
||||
n._moving = true;
|
||||
this.dragOffset = this._getDragOffset(this.lastDrag, n.el, this.helperContainment);
|
||||
this.helper.style.width = this.dragOffset.width + 'px';
|
||||
this.helper.style.height = this.dragOffset.height + 'px';
|
||||
Utils.swap(n._orig, 'w', 'h');
|
||||
delete n._rect;
|
||||
this._mouseMove(this.lastDrag);
|
||||
}
|
||||
}
|
||||
/** @internal create a clone copy (or user defined method) of the original drag item if set */
|
||||
_createHelper() {
|
||||
let helper = this.el;
|
||||
if (typeof this.option.helper === 'function') {
|
||||
helper = this.option.helper(this.el);
|
||||
}
|
||||
else if (this.option.helper === 'clone') {
|
||||
helper = Utils.cloneNode(this.el);
|
||||
}
|
||||
if (!helper.parentElement) {
|
||||
Utils.appendTo(helper, this.option.appendTo === 'parent' ? this.el.parentElement : this.option.appendTo);
|
||||
}
|
||||
this.dragElementOriginStyle = DDDraggable.originStyleProp.map(prop => this.el.style[prop]);
|
||||
return helper;
|
||||
}
|
||||
/** @internal set the fix position of the dragged item */
|
||||
_setupHelperStyle(e) {
|
||||
this.helper.classList.add('ui-draggable-dragging');
|
||||
this.el.gridstackNode?.grid?.el.classList.add('grid-stack-dragging');
|
||||
// TODO: set all at once with style.cssText += ... ? https://stackoverflow.com/questions/3968593
|
||||
const style = this.helper.style;
|
||||
style.pointerEvents = 'none'; // needed for over items to get enter/leave
|
||||
// style.cursor = 'move'; // TODO: can't set with pointerEvents=none ! (no longer in CSS either as no-op)
|
||||
style.width = this.dragOffset.width + 'px';
|
||||
style.height = this.dragOffset.height + 'px';
|
||||
style.willChange = 'left, top';
|
||||
style.position = 'fixed'; // let us drag between grids by not clipping as parent .grid-stack is position: 'relative'
|
||||
this._dragFollow(e); // now position it
|
||||
style.transition = 'none'; // show up instantly
|
||||
setTimeout(() => {
|
||||
if (this.helper) {
|
||||
style.transition = null; // recover animation
|
||||
}
|
||||
}, 0);
|
||||
return this;
|
||||
}
|
||||
/** @internal restore back the original style before dragging */
|
||||
_removeHelperStyle() {
|
||||
this.helper.classList.remove('ui-draggable-dragging');
|
||||
this.el.gridstackNode?.grid?.el.classList.remove('grid-stack-dragging');
|
||||
const node = this.helper?.gridstackNode;
|
||||
// don't bother restoring styles if we're gonna remove anyway...
|
||||
if (!node?._isAboutToRemove && this.dragElementOriginStyle) {
|
||||
const helper = this.helper;
|
||||
// don't animate, otherwise we animate offseted when switching back to 'absolute' from 'fixed'.
|
||||
// TODO: this also removes resizing animation which doesn't have this issue, but others.
|
||||
// Ideally both would animate ('move' would immediately restore 'absolute' and adjust coordinate to match,
|
||||
// then trigger a delay (repaint) to restore to final dest with animate) but then we need to make sure 'resizestop'
|
||||
// is called AFTER 'transitionend' event is received (see https://github.com/gridstack/gridstack.js/issues/2033)
|
||||
const transition = this.dragElementOriginStyle['transition'] || null;
|
||||
helper.style.transition = this.dragElementOriginStyle['transition'] = 'none'; // can't be NULL #1973
|
||||
DDDraggable.originStyleProp.forEach(prop => helper.style[prop] = this.dragElementOriginStyle[prop] || null);
|
||||
setTimeout(() => helper.style.transition = transition, 50); // recover animation from saved vars after a pause (0 isn't enough #1973)
|
||||
}
|
||||
delete this.dragElementOriginStyle;
|
||||
return this;
|
||||
}
|
||||
/** @internal updates the top/left position to follow the mouse */
|
||||
_dragFollow(e) {
|
||||
const containmentRect = { left: 0, top: 0 };
|
||||
// if (this.helper.style.position === 'absolute') { // we use 'fixed'
|
||||
// const { left, top } = this.helperContainment.getBoundingClientRect();
|
||||
// containmentRect = { left, top };
|
||||
// }
|
||||
const style = this.helper.style;
|
||||
const offset = this.dragOffset;
|
||||
style.left = (e.clientX + offset.offsetLeft - containmentRect.left) * this.dragTransform.xScale + 'px';
|
||||
style.top = (e.clientY + offset.offsetTop - containmentRect.top) * this.dragTransform.yScale + 'px';
|
||||
}
|
||||
/** @internal */
|
||||
_setupHelperContainmentStyle() {
|
||||
this.helperContainment = this.helper.parentElement;
|
||||
if (this.helper.style.position !== 'fixed') {
|
||||
this.parentOriginStylePosition = this.helperContainment.style.position;
|
||||
if (getComputedStyle(this.helperContainment).position.match(/static/)) {
|
||||
this.helperContainment.style.position = 'relative';
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/** @internal */
|
||||
_getDragOffset(event, el, parent) {
|
||||
// in case ancestor has transform/perspective css properties that change the viewpoint
|
||||
let xformOffsetX = 0;
|
||||
let xformOffsetY = 0;
|
||||
if (parent) {
|
||||
xformOffsetX = this.dragTransform.xOffset;
|
||||
xformOffsetY = this.dragTransform.yOffset;
|
||||
}
|
||||
const targetOffset = el.getBoundingClientRect();
|
||||
return {
|
||||
left: targetOffset.left,
|
||||
top: targetOffset.top,
|
||||
offsetLeft: -event.clientX + targetOffset.left - xformOffsetX,
|
||||
offsetTop: -event.clientY + targetOffset.top - xformOffsetY,
|
||||
width: targetOffset.width * this.dragTransform.xScale,
|
||||
height: targetOffset.height * this.dragTransform.yScale
|
||||
};
|
||||
}
|
||||
/** @internal TODO: set to public as called by DDDroppable! */
|
||||
ui() {
|
||||
const containmentEl = this.el.parentElement;
|
||||
const containmentRect = containmentEl.getBoundingClientRect();
|
||||
const offset = this.helper.getBoundingClientRect();
|
||||
return {
|
||||
position: {
|
||||
top: (offset.top - containmentRect.top) * this.dragTransform.yScale,
|
||||
left: (offset.left - containmentRect.left) * this.dragTransform.xScale
|
||||
}
|
||||
/* not used by GridStack for now...
|
||||
helper: [this.helper], //The object arr representing the helper that's being dragged.
|
||||
offset: { top: offset.top, left: offset.left } // Current offset position of the helper as { top, left } object.
|
||||
*/
|
||||
};
|
||||
}
|
||||
}
|
||||
/** @internal properties we change during dragging, and restore back */
|
||||
DDDraggable.originStyleProp = ['width', 'height', 'transform', 'transform-origin', 'transition', 'pointerEvents', 'position', 'left', 'top', 'minWidth', 'willChange'];
|
||||
export { DDDraggable };
|
||||
//# sourceMappingURL=dd-draggable.js.map
|
||||
1
node_modules/gridstack/dist/dd-draggable.js.map
generated
vendored
1
node_modules/gridstack/dist/dd-draggable.js.map
generated
vendored
File diff suppressed because one or more lines are too long
26
node_modules/gridstack/dist/dd-droppable.d.ts
generated
vendored
26
node_modules/gridstack/dist/dd-droppable.d.ts
generated
vendored
@@ -1,26 +0,0 @@
|
||||
/**
|
||||
* dd-droppable.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
import { DDBaseImplement, HTMLElementExtendOpt } from './dd-base-impl';
|
||||
import { DDUIData } from './types';
|
||||
export interface DDDroppableOpt {
|
||||
accept?: string | ((el: HTMLElement) => boolean);
|
||||
drop?: (event: DragEvent, ui: DDUIData) => void;
|
||||
over?: (event: DragEvent, ui: DDUIData) => void;
|
||||
out?: (event: DragEvent, ui: DDUIData) => void;
|
||||
}
|
||||
export declare class DDDroppable extends DDBaseImplement implements HTMLElementExtendOpt<DDDroppableOpt> {
|
||||
el: HTMLElement;
|
||||
option: DDDroppableOpt;
|
||||
accept: (el: HTMLElement) => boolean;
|
||||
constructor(el: HTMLElement, option?: DDDroppableOpt);
|
||||
on(event: 'drop' | 'dropover' | 'dropout', callback: (event: DragEvent) => void): void;
|
||||
off(event: 'drop' | 'dropover' | 'dropout'): void;
|
||||
enable(): void;
|
||||
disable(forDestroy?: boolean): void;
|
||||
destroy(): void;
|
||||
updateOption(opts: DDDroppableOpt): DDDroppable;
|
||||
/** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */
|
||||
drop(e: MouseEvent): void;
|
||||
}
|
||||
153
node_modules/gridstack/dist/dd-droppable.js
generated
vendored
153
node_modules/gridstack/dist/dd-droppable.js
generated
vendored
@@ -1,153 +0,0 @@
|
||||
/**
|
||||
* dd-droppable.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
import { DDManager } from './dd-manager';
|
||||
import { DDBaseImplement } from './dd-base-impl';
|
||||
import { Utils } from './utils';
|
||||
import { DDTouch, isTouch, pointerenter, pointerleave } from './dd-touch';
|
||||
// let count = 0; // TEST
|
||||
export class DDDroppable extends DDBaseImplement {
|
||||
constructor(el, option = {}) {
|
||||
super();
|
||||
this.el = el;
|
||||
this.option = option;
|
||||
// create var event binding so we can easily remove and still look like TS methods (unlike anonymous functions)
|
||||
this._mouseEnter = this._mouseEnter.bind(this);
|
||||
this._mouseLeave = this._mouseLeave.bind(this);
|
||||
this.enable();
|
||||
this._setupAccept();
|
||||
}
|
||||
on(event, callback) {
|
||||
super.on(event, callback);
|
||||
}
|
||||
off(event) {
|
||||
super.off(event);
|
||||
}
|
||||
enable() {
|
||||
if (this.disabled === false)
|
||||
return;
|
||||
super.enable();
|
||||
this.el.classList.add('ui-droppable');
|
||||
this.el.classList.remove('ui-droppable-disabled');
|
||||
this.el.addEventListener('mouseenter', this._mouseEnter);
|
||||
this.el.addEventListener('mouseleave', this._mouseLeave);
|
||||
if (isTouch) {
|
||||
this.el.addEventListener('pointerenter', pointerenter);
|
||||
this.el.addEventListener('pointerleave', pointerleave);
|
||||
}
|
||||
}
|
||||
disable(forDestroy = false) {
|
||||
if (this.disabled === true)
|
||||
return;
|
||||
super.disable();
|
||||
this.el.classList.remove('ui-droppable');
|
||||
if (!forDestroy)
|
||||
this.el.classList.add('ui-droppable-disabled');
|
||||
this.el.removeEventListener('mouseenter', this._mouseEnter);
|
||||
this.el.removeEventListener('mouseleave', this._mouseLeave);
|
||||
if (isTouch) {
|
||||
this.el.removeEventListener('pointerenter', pointerenter);
|
||||
this.el.removeEventListener('pointerleave', pointerleave);
|
||||
}
|
||||
}
|
||||
destroy() {
|
||||
this.disable(true);
|
||||
this.el.classList.remove('ui-droppable');
|
||||
this.el.classList.remove('ui-droppable-disabled');
|
||||
super.destroy();
|
||||
}
|
||||
updateOption(opts) {
|
||||
Object.keys(opts).forEach(key => this.option[key] = opts[key]);
|
||||
this._setupAccept();
|
||||
return this;
|
||||
}
|
||||
/** @internal called when the cursor enters our area - prepare for a possible drop and track leaving */
|
||||
_mouseEnter(e) {
|
||||
// console.log(`${count++} Enter ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST
|
||||
if (!DDManager.dragElement)
|
||||
return;
|
||||
// During touch drag operations, ignore real browser-generated mouseenter events (isTrusted:true) vs our simulated ones (isTrusted:false).
|
||||
// The browser can fire spurious mouseenter events when we dispatch simulated mousemove events.
|
||||
if (DDTouch.touchHandled && e.isTrusted)
|
||||
return;
|
||||
if (!this._canDrop(DDManager.dragElement.el))
|
||||
return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
// make sure when we enter this, that the last one gets a leave FIRST to correctly cleanup as we don't always do
|
||||
if (DDManager.dropElement && DDManager.dropElement !== this) {
|
||||
DDManager.dropElement._mouseLeave(e, true); // calledByEnter = true
|
||||
}
|
||||
DDManager.dropElement = this;
|
||||
const ev = Utils.initEvent(e, { target: this.el, type: 'dropover' });
|
||||
if (this.option.over) {
|
||||
this.option.over(ev, this._ui(DDManager.dragElement));
|
||||
}
|
||||
this.triggerEvent('dropover', ev);
|
||||
this.el.classList.add('ui-droppable-over');
|
||||
// console.log('tracking'); // TEST
|
||||
}
|
||||
/** @internal called when the item is leaving our area, stop tracking if we had moving item */
|
||||
_mouseLeave(e, calledByEnter = false) {
|
||||
// console.log(`${count++} Leave ${this.el.id || (this.el as GridHTMLElement).gridstack.opts.id}`); // TEST
|
||||
if (!DDManager.dragElement || DDManager.dropElement !== this)
|
||||
return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
const ev = Utils.initEvent(e, { target: this.el, type: 'dropout' });
|
||||
if (this.option.out) {
|
||||
this.option.out(ev, this._ui(DDManager.dragElement));
|
||||
}
|
||||
this.triggerEvent('dropout', ev);
|
||||
if (DDManager.dropElement === this) {
|
||||
delete DDManager.dropElement;
|
||||
// console.log('not tracking'); // TEST
|
||||
// if we're still over a parent droppable, send it an enter as we don't get one from leaving nested children
|
||||
if (!calledByEnter) {
|
||||
let parentDrop;
|
||||
let parent = this.el.parentElement;
|
||||
while (!parentDrop && parent) {
|
||||
parentDrop = parent.ddElement?.ddDroppable;
|
||||
parent = parent.parentElement;
|
||||
}
|
||||
if (parentDrop) {
|
||||
parentDrop._mouseEnter(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** item is being dropped on us - called by the drag mouseup handler - this calls the client drop event */
|
||||
drop(e) {
|
||||
e.preventDefault();
|
||||
const ev = Utils.initEvent(e, { target: this.el, type: 'drop' });
|
||||
if (this.option.drop) {
|
||||
this.option.drop(ev, this._ui(DDManager.dragElement));
|
||||
}
|
||||
this.triggerEvent('drop', ev);
|
||||
}
|
||||
/** @internal true if element matches the string/method accept option */
|
||||
_canDrop(el) {
|
||||
return el && (!this.accept || this.accept(el));
|
||||
}
|
||||
/** @internal */
|
||||
_setupAccept() {
|
||||
if (!this.option.accept)
|
||||
return this;
|
||||
if (typeof this.option.accept === 'string') {
|
||||
this.accept = (el) => el.classList.contains(this.option.accept) || el.matches(this.option.accept);
|
||||
}
|
||||
else {
|
||||
this.accept = this.option.accept;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/** @internal */
|
||||
_ui(drag) {
|
||||
return {
|
||||
draggable: drag.el,
|
||||
...drag.ui()
|
||||
};
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=dd-droppable.js.map
|
||||
1
node_modules/gridstack/dist/dd-droppable.js.map
generated
vendored
1
node_modules/gridstack/dist/dd-droppable.js.map
generated
vendored
File diff suppressed because one or more lines are too long
27
node_modules/gridstack/dist/dd-element.d.ts
generated
vendored
27
node_modules/gridstack/dist/dd-element.d.ts
generated
vendored
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* dd-elements.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
import { DDResizable, DDResizableOpt } from './dd-resizable';
|
||||
import { DDDragOpt, GridItemHTMLElement } from './types';
|
||||
import { DDDraggable } from './dd-draggable';
|
||||
import { DDDroppable, DDDroppableOpt } from './dd-droppable';
|
||||
export interface DDElementHost extends GridItemHTMLElement {
|
||||
ddElement?: DDElement;
|
||||
}
|
||||
export declare class DDElement {
|
||||
el: DDElementHost;
|
||||
static init(el: DDElementHost): DDElement;
|
||||
ddDraggable?: DDDraggable;
|
||||
ddDroppable?: DDDroppable;
|
||||
ddResizable?: DDResizable;
|
||||
constructor(el: DDElementHost);
|
||||
on(eventName: string, callback: (event: MouseEvent) => void): DDElement;
|
||||
off(eventName: string): DDElement;
|
||||
setupDraggable(opts: DDDragOpt): DDElement;
|
||||
cleanDraggable(): DDElement;
|
||||
setupResizable(opts: DDResizableOpt): DDElement;
|
||||
cleanResizable(): DDElement;
|
||||
setupDroppable(opts: DDDroppableOpt): DDElement;
|
||||
cleanDroppable(): DDElement;
|
||||
}
|
||||
91
node_modules/gridstack/dist/dd-element.js
generated
vendored
91
node_modules/gridstack/dist/dd-element.js
generated
vendored
@@ -1,91 +0,0 @@
|
||||
/**
|
||||
* dd-elements.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
import { DDResizable } from './dd-resizable';
|
||||
import { DDDraggable } from './dd-draggable';
|
||||
import { DDDroppable } from './dd-droppable';
|
||||
export class DDElement {
|
||||
static init(el) {
|
||||
if (!el.ddElement) {
|
||||
el.ddElement = new DDElement(el);
|
||||
}
|
||||
return el.ddElement;
|
||||
}
|
||||
constructor(el) {
|
||||
this.el = el;
|
||||
}
|
||||
on(eventName, callback) {
|
||||
if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {
|
||||
this.ddDraggable.on(eventName, callback);
|
||||
}
|
||||
else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {
|
||||
this.ddDroppable.on(eventName, callback);
|
||||
}
|
||||
else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {
|
||||
this.ddResizable.on(eventName, callback);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
off(eventName) {
|
||||
if (this.ddDraggable && ['drag', 'dragstart', 'dragstop'].indexOf(eventName) > -1) {
|
||||
this.ddDraggable.off(eventName);
|
||||
}
|
||||
else if (this.ddDroppable && ['drop', 'dropover', 'dropout'].indexOf(eventName) > -1) {
|
||||
this.ddDroppable.off(eventName);
|
||||
}
|
||||
else if (this.ddResizable && ['resizestart', 'resize', 'resizestop'].indexOf(eventName) > -1) {
|
||||
this.ddResizable.off(eventName);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
setupDraggable(opts) {
|
||||
if (!this.ddDraggable) {
|
||||
this.ddDraggable = new DDDraggable(this.el, opts);
|
||||
}
|
||||
else {
|
||||
this.ddDraggable.updateOption(opts);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
cleanDraggable() {
|
||||
if (this.ddDraggable) {
|
||||
this.ddDraggable.destroy();
|
||||
delete this.ddDraggable;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
setupResizable(opts) {
|
||||
if (!this.ddResizable) {
|
||||
this.ddResizable = new DDResizable(this.el, opts);
|
||||
}
|
||||
else {
|
||||
this.ddResizable.updateOption(opts);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
cleanResizable() {
|
||||
if (this.ddResizable) {
|
||||
this.ddResizable.destroy();
|
||||
delete this.ddResizable;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
setupDroppable(opts) {
|
||||
if (!this.ddDroppable) {
|
||||
this.ddDroppable = new DDDroppable(this.el, opts);
|
||||
}
|
||||
else {
|
||||
this.ddDroppable.updateOption(opts);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
cleanDroppable() {
|
||||
if (this.ddDroppable) {
|
||||
this.ddDroppable.destroy();
|
||||
delete this.ddDroppable;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=dd-element.js.map
|
||||
1
node_modules/gridstack/dist/dd-element.js.map
generated
vendored
1
node_modules/gridstack/dist/dd-element.js.map
generated
vendored
File diff suppressed because one or more lines are too long
82
node_modules/gridstack/dist/dd-gridstack.d.ts
generated
vendored
82
node_modules/gridstack/dist/dd-gridstack.d.ts
generated
vendored
@@ -1,82 +0,0 @@
|
||||
/**
|
||||
* dd-gridstack.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
import { GridItemHTMLElement, GridStackElement, DDDragOpt } from './types';
|
||||
import { DDElementHost } from './dd-element';
|
||||
/**
|
||||
* Drag & Drop options for drop targets.
|
||||
* Configures which elements can be dropped onto a grid.
|
||||
*/
|
||||
export type DDDropOpt = {
|
||||
/** Function to determine if an element can be dropped (see GridStackOptions.acceptWidgets) */
|
||||
accept?: (el: GridItemHTMLElement) => boolean;
|
||||
};
|
||||
/**
|
||||
* Drag & Drop operation types used throughout the DD system.
|
||||
* Can be control commands or configuration objects.
|
||||
*/
|
||||
export type DDOpts = 'enable' | 'disable' | 'destroy' | 'option' | string | any;
|
||||
/**
|
||||
* Keys for DD configuration options that can be set via the 'option' command.
|
||||
*/
|
||||
export type DDKey = 'minWidth' | 'minHeight' | 'maxWidth' | 'maxHeight' | 'maxHeightMoveUp' | 'maxWidthMoveLeft';
|
||||
/**
|
||||
* Values for DD configuration options (numbers or strings with units).
|
||||
*/
|
||||
export type DDValue = number | string;
|
||||
/**
|
||||
* Callback function type for drag & drop events.
|
||||
*
|
||||
* @param event - The DOM event that triggered the callback
|
||||
* @param arg2 - The grid item element being dragged/dropped
|
||||
* @param helper - Optional helper element used during drag operations
|
||||
*/
|
||||
export type DDCallback = (event: Event, arg2: GridItemHTMLElement, helper?: GridItemHTMLElement) => void;
|
||||
/**
|
||||
* HTML Native Mouse and Touch Events Drag and Drop functionality.
|
||||
*
|
||||
* This class provides the main drag & drop implementation for GridStack,
|
||||
* handling resizing, dragging, and dropping of grid items using native HTML5 events.
|
||||
* It manages the interaction between different DD components and the grid system.
|
||||
*/
|
||||
export declare class DDGridStack {
|
||||
/**
|
||||
* Enable/disable/configure resizing for grid elements.
|
||||
*
|
||||
* @param el - Grid item element(s) to configure
|
||||
* @param opts - Resize options or command ('enable', 'disable', 'destroy', 'option', or config object)
|
||||
* @param key - Option key when using 'option' command
|
||||
* @param value - Option value when using 'option' command
|
||||
* @returns this instance for chaining
|
||||
*
|
||||
* @example
|
||||
* dd.resizable(element, 'enable'); // Enable resizing
|
||||
* dd.resizable(element, 'option', 'minWidth', 100); // Set minimum width
|
||||
*/
|
||||
resizable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack;
|
||||
/**
|
||||
* Enable/disable/configure dragging for grid elements.
|
||||
*
|
||||
* @param el - Grid item element(s) to configure
|
||||
* @param opts - Drag options or command ('enable', 'disable', 'destroy', 'option', or config object)
|
||||
* @param key - Option key when using 'option' command
|
||||
* @param value - Option value when using 'option' command
|
||||
* @returns this instance for chaining
|
||||
*
|
||||
* @example
|
||||
* dd.draggable(element, 'enable'); // Enable dragging
|
||||
* dd.draggable(element, {handle: '.drag-handle'}); // Configure drag handle
|
||||
*/
|
||||
draggable(el: GridItemHTMLElement, opts: DDOpts, key?: DDKey, value?: DDValue): DDGridStack;
|
||||
dragIn(el: GridStackElement, opts: DDDragOpt): DDGridStack;
|
||||
droppable(el: GridItemHTMLElement, opts: DDOpts | DDDropOpt, key?: DDKey, value?: DDValue): DDGridStack;
|
||||
/** true if element is droppable */
|
||||
isDroppable(el: DDElementHost): boolean;
|
||||
/** true if element is draggable */
|
||||
isDraggable(el: DDElementHost): boolean;
|
||||
/** true if element is draggable */
|
||||
isResizable(el: DDElementHost): boolean;
|
||||
on(el: GridItemHTMLElement, name: string, callback: DDCallback): DDGridStack;
|
||||
off(el: GridItemHTMLElement, name: string): DDGridStack;
|
||||
}
|
||||
165
node_modules/gridstack/dist/dd-gridstack.js
generated
vendored
165
node_modules/gridstack/dist/dd-gridstack.js
generated
vendored
@@ -1,165 +0,0 @@
|
||||
/**
|
||||
* dd-gridstack.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
import { Utils } from './utils';
|
||||
import { DDManager } from './dd-manager';
|
||||
import { DDElement } from './dd-element';
|
||||
// let count = 0; // TEST
|
||||
/**
|
||||
* HTML Native Mouse and Touch Events Drag and Drop functionality.
|
||||
*
|
||||
* This class provides the main drag & drop implementation for GridStack,
|
||||
* handling resizing, dragging, and dropping of grid items using native HTML5 events.
|
||||
* It manages the interaction between different DD components and the grid system.
|
||||
*/
|
||||
export class DDGridStack {
|
||||
/**
|
||||
* Enable/disable/configure resizing for grid elements.
|
||||
*
|
||||
* @param el - Grid item element(s) to configure
|
||||
* @param opts - Resize options or command ('enable', 'disable', 'destroy', 'option', or config object)
|
||||
* @param key - Option key when using 'option' command
|
||||
* @param value - Option value when using 'option' command
|
||||
* @returns this instance for chaining
|
||||
*
|
||||
* @example
|
||||
* dd.resizable(element, 'enable'); // Enable resizing
|
||||
* dd.resizable(element, 'option', 'minWidth', 100); // Set minimum width
|
||||
*/
|
||||
resizable(el, opts, key, value) {
|
||||
this._getDDElements(el, opts).forEach(dEl => {
|
||||
if (opts === 'disable' || opts === 'enable') {
|
||||
dEl.ddResizable && dEl.ddResizable[opts](); // can't create DD as it requires options for setupResizable()
|
||||
}
|
||||
else if (opts === 'destroy') {
|
||||
dEl.ddResizable && dEl.cleanResizable();
|
||||
}
|
||||
else if (opts === 'option') {
|
||||
dEl.setupResizable({ [key]: value });
|
||||
}
|
||||
else {
|
||||
const n = dEl.el.gridstackNode;
|
||||
const grid = n.grid;
|
||||
let handles = dEl.el.getAttribute('gs-resize-handles') || grid.opts.resizable.handles || 'e,s,se';
|
||||
if (handles === 'all')
|
||||
handles = 'n,e,s,w,se,sw,ne,nw';
|
||||
// NOTE: keep the resize handles as e,w don't have enough space (10px) to show resize corners anyway. limit during drag instead
|
||||
// restrict vertical resize if height is done to match content anyway... odd to have it spring back
|
||||
// if (Utils.shouldSizeToContent(n, true)) {
|
||||
// const doE = handles.indexOf('e') !== -1;
|
||||
// const doW = handles.indexOf('w') !== -1;
|
||||
// handles = doE ? (doW ? 'e,w' : 'e') : (doW ? 'w' : '');
|
||||
// }
|
||||
const autoHide = !grid.opts.alwaysShowResizeHandle;
|
||||
dEl.setupResizable({
|
||||
...grid.opts.resizable,
|
||||
...{ handles, autoHide },
|
||||
...{
|
||||
start: opts.start,
|
||||
stop: opts.stop,
|
||||
resize: opts.resize
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Enable/disable/configure dragging for grid elements.
|
||||
*
|
||||
* @param el - Grid item element(s) to configure
|
||||
* @param opts - Drag options or command ('enable', 'disable', 'destroy', 'option', or config object)
|
||||
* @param key - Option key when using 'option' command
|
||||
* @param value - Option value when using 'option' command
|
||||
* @returns this instance for chaining
|
||||
*
|
||||
* @example
|
||||
* dd.draggable(element, 'enable'); // Enable dragging
|
||||
* dd.draggable(element, {handle: '.drag-handle'}); // Configure drag handle
|
||||
*/
|
||||
draggable(el, opts, key, value) {
|
||||
this._getDDElements(el, opts).forEach(dEl => {
|
||||
if (opts === 'disable' || opts === 'enable') {
|
||||
dEl.ddDraggable && dEl.ddDraggable[opts](); // can't create DD as it requires options for setupDraggable()
|
||||
}
|
||||
else if (opts === 'destroy') {
|
||||
dEl.ddDraggable && dEl.cleanDraggable();
|
||||
}
|
||||
else if (opts === 'option') {
|
||||
dEl.setupDraggable({ [key]: value });
|
||||
}
|
||||
else {
|
||||
const grid = dEl.el.gridstackNode.grid;
|
||||
dEl.setupDraggable({
|
||||
...grid.opts.draggable,
|
||||
...{
|
||||
// containment: (grid.parentGridNode && grid.opts.dragOut === false) ? grid.el.parentElement : (grid.opts.draggable.containment || null),
|
||||
start: opts.start,
|
||||
stop: opts.stop,
|
||||
drag: opts.drag
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
dragIn(el, opts) {
|
||||
this._getDDElements(el).forEach(dEl => dEl.setupDraggable(opts));
|
||||
return this;
|
||||
}
|
||||
droppable(el, opts, key, value) {
|
||||
if (typeof opts.accept === 'function' && !opts._accept) {
|
||||
opts._accept = opts.accept;
|
||||
opts.accept = (el) => opts._accept(el);
|
||||
}
|
||||
this._getDDElements(el, opts).forEach(dEl => {
|
||||
if (opts === 'disable' || opts === 'enable') {
|
||||
dEl.ddDroppable && dEl.ddDroppable[opts]();
|
||||
}
|
||||
else if (opts === 'destroy') {
|
||||
dEl.ddDroppable && dEl.cleanDroppable();
|
||||
}
|
||||
else if (opts === 'option') {
|
||||
dEl.setupDroppable({ [key]: value });
|
||||
}
|
||||
else {
|
||||
dEl.setupDroppable(opts);
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
/** true if element is droppable */
|
||||
isDroppable(el) {
|
||||
return !!(el?.ddElement?.ddDroppable && !el.ddElement.ddDroppable.disabled);
|
||||
}
|
||||
/** true if element is draggable */
|
||||
isDraggable(el) {
|
||||
return !!(el?.ddElement?.ddDraggable && !el.ddElement.ddDraggable.disabled);
|
||||
}
|
||||
/** true if element is draggable */
|
||||
isResizable(el) {
|
||||
return !!(el?.ddElement?.ddResizable && !el.ddElement.ddResizable.disabled);
|
||||
}
|
||||
on(el, name, callback) {
|
||||
this._getDDElements(el).forEach(dEl => dEl.on(name, (event) => {
|
||||
callback(event, DDManager.dragElement ? DDManager.dragElement.el : event.target, DDManager.dragElement ? DDManager.dragElement.helper : null);
|
||||
}));
|
||||
return this;
|
||||
}
|
||||
off(el, name) {
|
||||
this._getDDElements(el).forEach(dEl => dEl.off(name));
|
||||
return this;
|
||||
}
|
||||
/** @internal returns a list of DD elements, creating them on the fly by default unless option is to destroy or disable */
|
||||
_getDDElements(els, opts) {
|
||||
// don't force create if we're going to destroy it, unless it's a grid which is used as drop target for it's children
|
||||
const create = els.gridstack || opts !== 'destroy' && opts !== 'disable';
|
||||
const hosts = Utils.getElements(els);
|
||||
if (!hosts.length)
|
||||
return [];
|
||||
const list = hosts.map(e => e.ddElement || (create ? DDElement.init(e) : null)).filter(d => d); // remove nulls
|
||||
return list;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=dd-gridstack.js.map
|
||||
1
node_modules/gridstack/dist/dd-gridstack.js.map
generated
vendored
1
node_modules/gridstack/dist/dd-gridstack.js.map
generated
vendored
File diff suppressed because one or more lines are too long
43
node_modules/gridstack/dist/dd-manager.d.ts
generated
vendored
43
node_modules/gridstack/dist/dd-manager.d.ts
generated
vendored
@@ -1,43 +0,0 @@
|
||||
/**
|
||||
* dd-manager.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
import { DDDraggable } from './dd-draggable';
|
||||
import { DDDroppable } from './dd-droppable';
|
||||
import { DDResizable } from './dd-resizable';
|
||||
/**
|
||||
* Global state manager for all Drag & Drop instances.
|
||||
*
|
||||
* This class maintains shared state across all drag & drop operations,
|
||||
* ensuring proper coordination between multiple grids and drag/drop elements.
|
||||
* All properties are static to provide global access throughout the DD system.
|
||||
*/
|
||||
export declare class DDManager {
|
||||
/**
|
||||
* Controls drag operation pausing behavior.
|
||||
* If set to true or a number (milliseconds), dragging placement and collision
|
||||
* detection will only happen after the user pauses movement.
|
||||
* This improves performance during rapid mouse movements.
|
||||
*/
|
||||
static pauseDrag: boolean | number;
|
||||
/**
|
||||
* Flag indicating if a mouse down event was already handled.
|
||||
* Prevents multiple handlers from processing the same mouse event.
|
||||
*/
|
||||
static mouseHandled: boolean;
|
||||
/**
|
||||
* Reference to the element currently being dragged.
|
||||
* Used to track the active drag operation across the system.
|
||||
*/
|
||||
static dragElement: DDDraggable;
|
||||
/**
|
||||
* Reference to the drop target element currently under the cursor.
|
||||
* Used to handle drop operations and hover effects.
|
||||
*/
|
||||
static dropElement: DDDroppable;
|
||||
/**
|
||||
* Reference to the element currently being resized.
|
||||
* Helps ignore nested grid resize handles during resize operations.
|
||||
*/
|
||||
static overResizeElement: DDResizable;
|
||||
}
|
||||
14
node_modules/gridstack/dist/dd-manager.js
generated
vendored
14
node_modules/gridstack/dist/dd-manager.js
generated
vendored
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* dd-manager.ts 12.4.2
|
||||
* Copyright (c) 2021-2025 Alain Dumesny - see GridStack root license
|
||||
*/
|
||||
/**
|
||||
* Global state manager for all Drag & Drop instances.
|
||||
*
|
||||
* This class maintains shared state across all drag & drop operations,
|
||||
* ensuring proper coordination between multiple grids and drag/drop elements.
|
||||
* All properties are static to provide global access throughout the DD system.
|
||||
*/
|
||||
export class DDManager {
|
||||
}
|
||||
//# sourceMappingURL=dd-manager.js.map
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user