diff --git a/application/dashboardlayout.class.inc.php b/application/dashboardlayout.class.inc.php index fac86d1b6..986fb9823 100644 --- a/application/dashboardlayout.class.inc.php +++ b/application/dashboardlayout.class.inc.php @@ -112,25 +112,31 @@ 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']); - //$oPage->AddUiBlock($oDashboardLayout); $iCellIdx = 0; $iNbRows = ceil(count($aCells) / $this->iNbCols); + // GRID LAYOUT: Global positioning + $iGridCurrentX = 0; + $iGridCurrentY = 0; + $iGridColWidth = (int)(12 / $this->iNbCols); + //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); for ($iCols = 0; $iCols < $this->iNbCols; $iCols++) { $oDashboardColumn = new DashboardColumn($bEditMode); $oDashboardColumn->SetCellIndex($iCellIdx); - //$oDashboardRow->AddDashboardColumn($oDashboardColumn); + + // GRID LAYOUT: Column positioning + $iGridCurrentColX = 0; + $iGridCurrentColY = 0; + $iGridMaxHeightDashlet = -1; if (array_key_exists($iCellIdx, $aCells)) { $aDashlets = $aCells[$iCellIdx]; @@ -143,12 +149,36 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout $aDashletDenormalizedProperties = $oDashlet->GetDenormalizedProperties(); $aDashletsInfo = DashletService::GetInstance()->GetDashletDefinition($sDashletClass); - // Also set minimal height/width - $iPositionX = $aPosDashlet['position_x'] ?? 0; - $iPositionY = $aPosDashlet['position_y'] ?? 0; - $iWidth = max($aPosDashlet['width'], array_key_exists('min_width', $aDashletsInfo) ? $aDashletsInfo['min_width'] : 1); - $iHeight = max($aPosDashlet['height'], array_key_exists('min_height', $aDashletsInfo) ? $aDashletsInfo['min_height'] : 1); + // GRID LAYOUT: Set position relative to grid + $iPositionX = $iGridCurrentX + $iGridCurrentColX; + $iPositionY = $iGridCurrentY + $iGridCurrentColY; + $iWidth = array_key_exists('preferred_width', $aDashletsInfo) ? $aDashletsInfo['preferred_width'] : 1; + // GRID LAYOUT: Limit dashlet width to fit column width + if ($iWidth > $iGridColWidth) { + $iWidth = $iGridColWidth; + } + $iHeight = array_key_exists('preferred_height', $aDashletsInfo) ? $aDashletsInfo['preferred_height'] : 1; + // GRID LAYOUT: Store max height of dashlets in this current row + if ($iHeight > $iGridMaxHeightDashlet) { + $iGridMaxHeightDashlet = $iHeight; + } + // GRID LAYOUT: Ensure that dashlet fits in the current row of the column + if ($iGridCurrentColX + $iWidth > $iGridColWidth) { + $iPositionX = $iGridCurrentX; + $iPositionY++; + } + $oDashboardGrid->AddDashlet($oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams), $sDashletId, $sDashletClass, $aDashletDenormalizedProperties, $iPositionX, $iPositionY, $iWidth, $iHeight); + + // GRID LAYOUT: Update column cursor + $iGridCurrentColX += $iWidth; + if ($iGridCurrentColX >= $iGridColWidth) { + $iGridCurrentColX = 0; + $iGridCurrentColY += $iGridMaxHeightDashlet; + $iGridMaxHeightDashlet = -1; + } + + //$oDashboardColumn->AddUIBlock($oDashlet->DoRender($oPage, $bEditMode, true /* bEnclosingDiv */, $aExtraParams)); } } } else { @@ -158,7 +188,16 @@ abstract class DashboardLayoutMultiCol extends DashboardLayout $oDashboardColumn->AddUIBlock(new Html(' ')); } $iCellIdx++; + + // GRID LAYOUT: Next column + $iGridCurrentX += $iGridColWidth; + } + + // GRID LAYOUT: Next Row + $iGridCurrentY++; + $iGridCurrentX = 0; + $sJSReload .= $oDashboardRow->GetJSRefreshCallback()." "; } diff --git a/application/datamodel.application.xml b/application/datamodel.application.xml index db04f7426..04652d6df 100644 --- a/application/datamodel.application.xml +++ b/application/datamodel.application.xml @@ -856,9 +856,9 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att images/dashlets/icons8-transaction-list-48.png UI:DashletGroupByTable:Description - 2 + 3 2 - 3 + 6 3 true @@ -869,7 +869,7 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att UI:DashletGroupByBars:Description 2 2 - 3 + 6 3 true @@ -880,7 +880,7 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att UI:DashletGroupByPie:Description 2 2 - 3 + 6 3 true @@ -891,7 +891,7 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att UI:DashletBadge:Description 2 1 - 2 + 3 1 @@ -901,8 +901,8 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att UI:DashletHeaderDynamic:Description 2 1 - 4 - 3 + 12 + 2 @@ -911,7 +911,7 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att UI:DashletHeaderStatic:Description 4 1 - 4 + 12 1 @@ -921,7 +921,7 @@ Call $this->AddInitialAttributeFlags($sAttCode, $iFlags) for all the initial att UI:DashletObjectList:Description 2 1 - 4 + 12 3 true diff --git a/css/backoffice/blocks-integrations/dashlet/_dashlet-within-dashboard.scss b/css/backoffice/blocks-integrations/dashlet/_dashlet-within-dashboard.scss index 16a559e5c..a25c58c29 100644 --- a/css/backoffice/blocks-integrations/dashlet/_dashlet-within-dashboard.scss +++ b/css/backoffice/blocks-integrations/dashlet/_dashlet-within-dashboard.scss @@ -20,4 +20,156 @@ $ibo-dashlet-within-dashboard--dashlet-header-static--margin-top--is-not-first-d } } } -} \ No newline at end of file +} + +// TODO 3.3: This css is for dashboard editor demo purpose and needs to be updated + +ibo-dashboard[data-edit-mode="edit"]{ + ibo-dashlet .ibo-dashlet{ + pointer-events: none; + } +} + +ibo-dashlet{ + // do not apply to this dashlets + &:not([data-dashlet-type="DashletBadge"]):not([data-dashlet-type="DashletHeaderStatic"]){ + border: 1px solid #ccd4db; + border-radius: 5px; + background-color: white; + padding: 16px; + } + // Make the dashlet body take all the available height to allow scrollbars when needed + .ibo-dashlet > .ibo-content-block{ + display: flex; + flex-direction: column; + height: 100%; + row-gap: 10px; + .ibo-panel--header{ + align-items: flex-start; + } + > .ibo-panel--body{ + flex-grow: 1; + overflow: auto; + } + } +} + + +ibo-dashlet[data-dashlet-type="DashletBadge"] { + .ibo-dashlet-badge{ + max-width: unset; + } + .ibo-dashlet-badge--body{ + height: 100%; + display: flex; + } +} + +ibo-dashlet[data-dashlet-type="DashletHeaderStatic"]{ + background-color: #f2f2f2; + > .ibo-content-block{ + display: flex; + align-items: center; + > .ibo-dashlet-header-static{ + padding: 0; + width: 100%; + } + } +} + +ibo-dashlet[data-dashlet-type="DashletHeaderDynamic"] { + > .ibo-content-block > .ibo-content-block{ + .ibo-panel--body{ + border: none; + padding: 0; + &:before{ + display: none; + } + .ibo-panel-boy{ + flex-grow: 1; + overflow-y: scroll; + } + } + } +} + +ibo-dashlet[data-dashlet-type="DashletObjectList"] { + overflow-y: hidden!important; + + > .ibo-dashlet > .ibo-content-block > .ibo-content-block{ + display: flex; + max-height: 100%; + flex-direction: column; + + .dataTables_wrapper{ + height: 100%; + + .dataTables_scroll{ + max-height: 100%; + height: 100%; + display: flex; + flex-direction: column; + + .dataTables_scrollHead{ + overflow: hidden; + position: relative; + border: 0px; + width: 100%; + flex-shrink: 0; + } + + .dataTables_scrollBody{ + max-height: unset!important; + } + } + } + } + + .ibo-panel--body{ + margin: 0 -16px; + border: none; + padding: 0; + &:before{ + display: none; + } + .ibo-datatable{ + margin-top: 10px; + } + } +} + +ibo-dashlet[data-dashlet-type="DashletGroupByTable"] { + .ibo-panel--body{ + margin: 0 -16px; + border: none; + padding: 0; + &:before{ + display: none; + } + .ibo-datatable{ + margin-top: 10px; + } + } +} + + +ibo-dashlet[data-dashlet-type="DashletGroupByPie"] { + .ibo-panel--body { + border: none; + padding: 0; + &:before { + display: none; + } + } +} + +ibo-dashlet[data-dashlet-type="DashletGroupByBars"] { + .ibo-panel--body { + border: none; + padding: 0; + &:before { + display: none; + } + } +} +