diff --git a/public/css/icons.css b/public/css/icons.css index afa8085da1..79a6e9f643 100644 --- a/public/css/icons.css +++ b/public/css/icons.css @@ -1095,6 +1095,10 @@ background: url(/bundles/pimcoreadmin/img/flat-color-icons/more.svg) center center no-repeat !important; } +.pimcore_icon_more_white { + background: url(/bundles/pimcoreadmin/img/flat-white-icons/more.svg) center center no-repeat !important; +} + .pimcore_icon_export{ background: url(/bundles/pimcoreadmin/img/flat-color-icons/external.svg) center center no-repeat !important; } @@ -1312,7 +1316,6 @@ background: url(/bundles/pimcoreadmin/img/flat-color-icons/more.svg) center center no-repeat !important; } - .pimcore_icon_gender { background: url(/bundles/pimcoreadmin/img/flat-color-icons/manager.svg) center center no-repeat !important; } @@ -1780,6 +1783,14 @@ background: url(/bundles/pimcoreadmin/img/material-icons/outline-style-24px.svg) center center no-repeat; } +.pimcore_material_icon_logout { + background: url(/bundles/pimcoreadmin/img/material-icons/outline-logout-24px.svg) center center no-repeat; +} + .pimcore_icon_share { background: url(/bundles/pimcoreadmin/img/flat-white-icons/share.svg) center center no-repeat; } + +.pimcore_icon_profile { + background: url(/bundles/pimcoreadmin/img/flat-white-icons/profile.svg) center center no-repeat; +} diff --git a/public/img/avatar.png b/public/img/avatar.png index 26004c20b0..91d1741d47 100644 Binary files a/public/img/avatar.png and b/public/img/avatar.png differ diff --git a/public/img/flat-white-icons/profile.svg b/public/img/flat-white-icons/profile.svg new file mode 100644 index 0000000000..40b15885cc --- /dev/null +++ b/public/img/flat-white-icons/profile.svg @@ -0,0 +1,8 @@ + diff --git a/public/js/pimcore/asset/archive.js b/public/js/pimcore/asset/archive.js index 1afabfaeca..c2722539c4 100644 --- a/public/js/pimcore/asset/archive.js +++ b/public/js/pimcore/asset/archive.js @@ -90,4 +90,4 @@ pimcore.asset.archive = Class.create(pimcore.asset.asset, { this.tabbar = pimcore.helpers.getTabBar({items: items}); return this.tabbar; } -}); \ No newline at end of file +}); diff --git a/public/js/pimcore/asset/asset.js b/public/js/pimcore/asset/asset.js index a3f202320c..210cc08096 100644 --- a/public/js/pimcore/asset/asset.js +++ b/public/js/pimcore/asset/asset.js @@ -66,8 +66,8 @@ pimcore.asset.asset = Class.create(pimcore.element.abstract, { }, addTab: function () { - var tabTitle = this.data.filename; + if (this.id == 1) { tabTitle = "home"; } @@ -75,16 +75,54 @@ pimcore.asset.asset = Class.create(pimcore.element.abstract, { this.tabPanel = Ext.getCmp("pimcore_panel_tabs"); var tabId = "asset_" + this.id; - this.tab = new Ext.Panel({ - id: tabId, - title: htmlspecialchars(tabTitle), - closable:true, - layout: "border", - items: [this.getLayoutToolbar(),this.getTabPanel()], - asset: this, - iconCls: this.getIconClass() + const tabbarContainer = new Ext.Container({ + flex: 2 }); + const tabPanel = this.getTabPanel(); + const toolbar = this.getLayoutToolbar(); + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.tab = new Ext.Panel({ + id: tabId, + cls: "pimcore_panel_toolbar_horizontal_border_layout", + title: htmlspecialchars(tabTitle), + closable:true, + hideMode: "offsets", + layout: "border", + items: [ + { + xtype: 'panel', + width: "100%", + region: 'north', + layout: 'hbox', + items: [ + toolbar, + tabbarContainer, + ] + }, + + tabPanel + ], + iconCls: this.getIconClass(), + asset: this, + }); + + this.toolbarSubmenu.menu.addCls('pimcore_headbar_submenu_menu'); + + pimcore.helpers.headbar.prepareTabPanel(tabPanel, tabbarContainer, this.tab); + } else { + this.tab = new Ext.Panel({ + id: tabId, + title: htmlspecialchars(tabTitle), + closable:true, + layout: "border", + items: [toolbar, tabPanel], + asset: this, + iconCls: this.getIconClass() + }); + } + this.tab.on("activate", function () { this.tab.updateLayout(); pimcore.layout.refresh(); @@ -174,30 +212,49 @@ pimcore.asset.asset = Class.create(pimcore.element.abstract, { buttons.push("-"); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu = new Ext.Button({ + ...pimcore.helpers.headbar.getSubmenuConfig() + }); + + buttons.push(this.toolbarSubmenu); + } if (this.isAllowed("delete") && !this.data.locked) { - this.toolbarButtons.remove = new Ext.Button({ - tooltip: t('delete'), + const deleteConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('delete') } : { tooltip: t('delete') })(), iconCls: "pimcore_material_icon_delete pimcore_material_icon", scale: "medium", handler: this.remove.bind(this) - }); - buttons.push(this.toolbarButtons.remove); + }; + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(deleteConfig); + } else { + this.toolbarButtons.remove = new Ext.Button(deleteConfig); + buttons.push(this.toolbarButtons.remove); + } } if (this.isAllowed("rename") && !this.data.locked) { - this.toolbarButtons.rename = new Ext.Button({ - tooltip: t('rename'), + const renameConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('rename') } : { tooltip: t('rename') })(), iconCls: "pimcore_material_icon_rename pimcore_material_icon", scale: "medium", handler: this.rename.bind(this) - }); - buttons.push(this.toolbarButtons.rename); + }; + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(renameConfig); + } else { + this.toolbarButtons.rename = new Ext.Button(renameConfig); + buttons.push(this.toolbarButtons.rename); + } } if (this.isAllowed("publish")) { - this.toolbarButtons.upload = new Ext.Button({ - tooltip: t("upload_new_version"), + const uploadConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('upload_new_version') } : { tooltip: t('upload_new_version') })(), iconCls: "pimcore_material_icon_upload pimcore_material_icon", scale: "medium", handler: function () { @@ -205,18 +262,30 @@ pimcore.asset.asset = Class.create(pimcore.element.abstract, { this.reload(); }.bind(this)); }.bind(this) - }); - buttons.push(this.toolbarButtons.upload); + }; + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(uploadConfig); + } else { + this.toolbarButtons.upload = new Ext.Button(uploadConfig); + buttons.push(this.toolbarButtons.upload); + } } - buttons.push({ - tooltip: t("download"), + const downloadConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('download') } : { tooltip: t('download') })(), iconCls: "pimcore_material_icon_download pimcore_material_icon", scale: "medium", handler: function () { pimcore.helpers.download(Routing.generate('pimcore_admin_asset_download', {id: this.data.id})); }.bind(this) - }); + }; + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(downloadConfig); + } else { + buttons.push(downloadConfig); + } buttons.push({ tooltip: t('reload'), @@ -245,8 +314,8 @@ pimcore.asset.asset = Class.create(pimcore.element.abstract, { // only for videos and images if (this.isAllowed("publish") && in_array(this.data.type,["image","video"]) || this.data.mimetype == "application/pdf") { - buttons.push({ - tooltip: t("clear_thumbnails"), + const clearThumbnailsConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('clear_thumbnails') } : { tooltip: t('clear_thumbnails') })(), iconCls: "pimcore_material_icon_clear_thumbnails pimcore_material_icon", scale: "medium", handler: function () { @@ -258,24 +327,29 @@ pimcore.asset.asset = Class.create(pimcore.element.abstract, { } }); }.bind(this) - }); + }; + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(clearThumbnailsConfig); + } else { + buttons.push(clearThumbnailsConfig); + } } if (pimcore.globalmanager.get("user").isAllowed('notifications_send')) { - buttons.push({ - tooltip: t('share_via_notifications'), + const notificationConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('share_via_notifications') } : { tooltip: t('share_via_notifications') })(), iconCls: "pimcore_icon_share", scale: "medium", handler: this.shareViaNotifications.bind(this) - }); - } + }; - buttons.push("-"); - buttons.push({ - xtype: 'tbtext', - text: t("id") + " " + this.data.id, - scale: "medium" - }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(notificationConfig); + } else { + buttons.push(notificationConfig); + } + } //workflow management pimcore.elementservice.integrateWorkflowManagement('asset', this.data.id, this, buttons); @@ -284,6 +358,7 @@ pimcore.asset.asset = Class.create(pimcore.element.abstract, { id: "asset_toolbar_" + this.id, region: "north", border: false, + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { flex: 3 } : { })(), cls: "pimcore_main_toolbar", items: buttons, overflowHandler: 'scroller' @@ -309,7 +384,6 @@ pimcore.asset.asset = Class.create(pimcore.element.abstract, { this.save(false, onCompleteCallback, "session") }, - getSaveData : function (only) { var parameters = {}; diff --git a/public/js/pimcore/asset/folder.js b/public/js/pimcore/asset/folder.js index 750b95e4b5..51a388f2e1 100644 --- a/public/js/pimcore/asset/folder.js +++ b/public/js/pimcore/asset/folder.js @@ -162,7 +162,6 @@ pimcore.asset.folder = Class.create(pimcore.asset.asset, { items.push(this.workflows.getLayout()); } - this.tabbar = pimcore.helpers.getTabBar({items: items}); return this.tabbar; }, @@ -258,21 +257,53 @@ pimcore.asset.folder = Class.create(pimcore.asset.asset, { buttons.push("-"); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu = new Ext.Button({ + ...pimcore.helpers.headbar.getSubmenuConfig() + }); + + buttons.push(this.toolbarSubmenu); + } + if (this.isAllowed("delete") && !this.data.locked && this.data.id != 1) { - buttons.push(this.toolbarButtons.remove); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('delete'), + iconCls: "pimcore_material_icon_delete pimcore_material_icon", + scale: "medium", + handler: this.remove.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.remove); + } } if (this.isAllowed("rename") && !this.data.locked && this.data.id != 1) { - buttons.push(this.toolbarButtons.rename); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('rename'), + iconCls: "pimcore_material_icon_rename pimcore_material_icon", + scale: "medium", + handler: this.rename.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.rename); + } } - buttons.push({ - tooltip: t("download_as_zip"), + const downloadAsZipConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('download_as_zip') } : { tooltip: t('download_as_zip') })(), iconCls: "pimcore_material_icon_download_zip pimcore_material_icon", scale: "medium", handler: function () { pimcore.elementservice.downloadAssetFolderAsZip(this.id) }.bind(this) - }); + } + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(downloadAsZipConfig); + } else { + buttons.push(downloadAsZipConfig); + } buttons.push({ tooltip: t('reload'), @@ -298,18 +329,12 @@ pimcore.asset.folder = Class.create(pimcore.asset.asset, { handler: this.showMetaInfo.bind(this), menu: this.getMetaInfoMenuItems() }); - - buttons.push("-"); - buttons.push({ - xtype: 'tbtext', - text: t("id") + " " + this.data.id, - scale: "medium" - }); - + this.toolbar = new Ext.Toolbar({ id: "asset_toolbar_" + this.id, region: "north", border: false, + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { flex: 3 } : { })(), cls: "pimcore_main_toolbar", items: buttons, overflowHandler: 'scroller' diff --git a/public/js/pimcore/asset/unknown.js b/public/js/pimcore/asset/unknown.js index c43835a687..6b2a52c2bd 100644 --- a/public/js/pimcore/asset/unknown.js +++ b/public/js/pimcore/asset/unknown.js @@ -91,4 +91,4 @@ pimcore.asset.unknown = Class.create(pimcore.asset.asset, { this.tabbar = pimcore.helpers.getTabBar({items: items}); return this.tabbar; } -}); \ No newline at end of file +}); diff --git a/public/js/pimcore/document/document.js b/public/js/pimcore/document/document.js index a84adac034..e1668f77aa 100644 --- a/public/js/pimcore/document/document.js +++ b/public/js/pimcore/document/document.js @@ -234,6 +234,10 @@ pimcore.document.document = Class.create(pimcore.element.abstract, { this.toolbarButtons.save.hide(); } + if (this.toolbarButtons.save && this.toolbarButtons.publish) { + this.toolbarButtons.publish.show(); + } + pimcore.elementservice.setElementPublishedState({ elementType: "document", id: this.id, @@ -257,6 +261,10 @@ pimcore.document.document = Class.create(pimcore.element.abstract, { this.toolbarButtons.save.show(); } + if (this.toolbarButtons.publish && this.toolbarButtons.save) { + this.toolbarButtons.publish.hide(); + } + pimcore.elementservice.setElementPublishedState({ elementType: "document", id: this.id, @@ -272,7 +280,6 @@ pimcore.document.document = Class.create(pimcore.element.abstract, { }, reload: function () { - this.tab.on("close", function () { var currentTabIndex = this.tab.ownerCt.items.indexOf(this.tab); window.setTimeout(function (id, type) { @@ -585,7 +592,7 @@ pimcore.document.document = Class.create(pimcore.element.abstract, { win.show(); }, - getTranslationButtons: function () { + getTranslationButtons: function (asMenuItem = false) { var translationsMenu = []; var unlinkTranslationsMenu = []; @@ -639,9 +646,9 @@ pimcore.document.document = Class.create(pimcore.element.abstract, { } return { - tooltip: t("translation"), + ...(() => asMenuItem ? { text: t("translation") } : { tooltip: t("translation") })(), iconCls: "pimcore_material_icon_translation pimcore_material_icon", - scale: "medium", + ...(() => asMenuItem ? {} : { scale: "medium" })(), menu: [{ text: t("new_document"), hidden: !pimcore.helpers.documentTypeHasSpecificRole(this.getType(), "translatable"), diff --git a/public/js/pimcore/document/email.js b/public/js/pimcore/document/email.js index 29da987b87..35f90e20e9 100644 --- a/public/js/pimcore/document/email.js +++ b/public/js/pimcore/document/email.js @@ -182,16 +182,30 @@ pimcore.document.email = Class.create(pimcore.document.page_snippet, { getLayoutToolbar : function ($super) { $super(); - this.toolbar.add( - new Ext.Button({ - text: t('send_test_email'), - iconCls: "pimcore_material_icon_email pimcore_material_icon", - scale: "medium", - handler: function() { - pimcore.helpers.sendTestEmail(this.settings.document.data['from']? this.settings.document.data['from'] : pimcore.settings.mailDefaultAddress, this.settings.document.data['to'], this.settings.document.data['subject'], 'document', this.settings.document.data['path'] + this.settings.document.data['key'], null); - }.bind(this) - }) - ); + const config = { + text: t('send_test_email'), + iconCls: "pimcore_material_icon_email pimcore_material_icon", + scale: "medium", + handler: function() { + pimcore.helpers.sendTestEmail( + this.settings.document.data['from'] ?? pimcore.settings.mailDefaultAddress, + this.settings.document.data['to'], + this.settings.document.data['subject'], + 'document', + this.settings.document.data['path'] + this.settings.document.data['key'], + null + ); + }.bind(this) + } + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + const submenu = this.toolbar.query('[cls*=pimcore_headbar_submenu]')[0]; + submenu.menu.add(config); + } else { + this.toolbar.add( + new Ext.Button(config) + ); + } return this.toolbar; } diff --git a/public/js/pimcore/document/folder.js b/public/js/pimcore/document/folder.js index 86fb5dff39..1a5d03e7b6 100644 --- a/public/js/pimcore/document/folder.js +++ b/public/js/pimcore/document/folder.js @@ -86,19 +86,57 @@ pimcore.document.folder = Class.create(pimcore.document.document, { this.tabPanel = Ext.getCmp("pimcore_panel_tabs"); var tabId = "document_" + this.id; - this.tab = new Ext.Panel({ - id: tabId, - title: tabTitle, - closable:true, - layout: "border", - items: [ - this.getLayoutToolbar(), - this.getTabPanel() - ], - iconCls: this.getIconClass(), - document: this + const tabbarContainer = new Ext.Container({ + flex: 2 }); + const tabPanel = this.getTabPanel(); + const toolbar = this.getLayoutToolbar(); + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.tab = new Ext.Panel({ + id: tabId, + cls: "pimcore_panel_toolbar_horizontal_border_layout", + title: htmlspecialchars(tabTitle), + closable:true, + hideMode: "offsets", + layout: "border", + items: [ + { + xtype: 'panel', + width: "100%", + region: 'north', + layout: 'hbox', + items: [ + toolbar, + tabbarContainer, + ] + }, + + tabPanel + ], + iconCls: this.getIconClass(), + document: this + }); + + this.toolbarSubmenu.menu.addCls('pimcore_headbar_submenu_menu'); + + pimcore.helpers.headbar.prepareTabPanel(tabPanel, tabbarContainer, this.tab); + } else { + this.tab = new Ext.Panel({ + id: tabId, + title: htmlspecialchars(tabTitle), + closable:true, + layout: "border", + items: [ + toolbar, + tabPanel + ], + iconCls: this.getIconClass(), + document: this + }); + } + this.tab.on("beforedestroy", function () { Ext.Ajax.request({ url: Routing.generate('pimcore_admin_element_unlockelement'), @@ -158,14 +196,14 @@ pimcore.document.folder = Class.create(pimcore.document.document, { this.toolbarButtons.remove = new Ext.Button({ tooltip: t('delete_folder'), - iconCls: "pimcore_icon_delete", + iconCls: "pimcore_material_icon_delete pimcore_material_icon", scale: "medium", handler: this.remove.bind(this) }); this.toolbarButtons.rename = new Ext.Button({ tooltip: t('rename'), - iconCls: "pimcore_icon_key pimcore_icon_overlay_go", + iconCls: "pimcore_material_icon_rename pimcore_material_icon", scale: "medium", handler: this.rename.bind(this) }); @@ -178,11 +216,38 @@ pimcore.document.folder = Class.create(pimcore.document.document, { buttons.push("-"); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu = new Ext.Button({ + ...pimcore.helpers.headbar.getSubmenuConfig() + }); + + buttons.push(this.toolbarSubmenu); + } + if(this.isAllowed("delete") && !this.data.locked) { - buttons.push(this.toolbarButtons.remove); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('delete'), + iconCls: "pimcore_material_icon_delete pimcore_material_icon", + scale: "medium", + handler: this.remove.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.remove); + } } + if(this.isAllowed("rename") && !this.data.locked) { - buttons.push(this.toolbarButtons.rename); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('rename'), + iconCls: "pimcore_material_icon_rename pimcore_material_icon", + scale: "medium", + handler: this.rename.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.rename); + } } buttons.push({ @@ -210,19 +275,17 @@ pimcore.document.folder = Class.create(pimcore.document.document, { menu: this.getMetaInfoMenuItems() }); - buttons.push(this.getTranslationButtons()); - - buttons.push("-"); - buttons.push({ - xtype: 'tbtext', - text: t("id") + " " + this.data.id, - scale: "medium" - }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(this.getTranslationButtons(true)); + } else { + buttons.push(this.getTranslationButtons()); + } this.toolbar = new Ext.Toolbar({ id: "document_toolbar_" + this.id, region: "north", border: false, + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { flex: 3 } : { })(), cls: "pimcore_main_toolbar", items: buttons, overflowHandler: 'scroller' @@ -256,7 +319,6 @@ pimcore.document.folder = Class.create(pimcore.document.document, { items.push(this.workflows.getLayout()); } - this.tabbar = pimcore.helpers.getTabBar({items: items}); return this.tabbar; }, diff --git a/public/js/pimcore/document/hardlink.js b/public/js/pimcore/document/hardlink.js index b9fbe510f7..c585b75c9b 100644 --- a/public/js/pimcore/document/hardlink.js +++ b/public/js/pimcore/document/hardlink.js @@ -113,19 +113,57 @@ pimcore.document.hardlink = Class.create(pimcore.document.document, { this.tabPanel = Ext.getCmp("pimcore_panel_tabs"); var tabId = "document_" + this.id; - this.tab = new Ext.Panel({ - id: tabId, - title: tabTitle, - closable: true, - layout: "border", - items: [ - this.getLayoutToolbar(), - this.getTabPanel() - ], - iconCls: this.getIconClass(), - document: this + const tabbarContainer = new Ext.Container({ + flex: 2 }); + const tabPanel = this.getTabPanel(); + const toolbar = this.getLayoutToolbar(); + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.tab = new Ext.Panel({ + id: tabId, + cls: "pimcore_panel_toolbar_horizontal_border_layout", + title: htmlspecialchars(tabTitle), + closable:true, + hideMode: "offsets", + layout: "border", + items: [ + { + xtype: 'panel', + width: "100%", + region: 'north', + layout: 'hbox', + items: [ + toolbar, + tabbarContainer, + ] + }, + + tabPanel + ], + iconCls: this.getIconClass(), + document: this + }); + + this.toolbarSubmenu.menu.addCls('pimcore_headbar_submenu_menu'); + + pimcore.helpers.headbar.prepareTabPanel(tabPanel, tabbarContainer, this.tab); + } else { + this.tab = new Ext.Panel({ + id: tabId, + title: htmlspecialchars(tabTitle), + closable: true, + layout: "border", + items: [ + toolbar, + tabPanel + ], + iconCls: this.getIconClass(), + document: this + }); + } + this.tab.on("beforedestroy", function () { Ext.Ajax.request({ url: Routing.generate('pimcore_admin_element_unlockelement'), @@ -202,6 +240,15 @@ pimcore.document.hardlink = Class.create(pimcore.document.document, { handler: this.unpublish.bind(this) }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarButtons.unpublish = Ext.create('Ext.menu.Item', { + text: t('unpublish'), + iconCls: "pimcore_material_icon_unpublish pimcore_material_icon", + scale: "medium", + handler: this.unpublish.bind(this) + }) + } + this.toolbarButtons.remove = new Ext.Button({ tooltip: t('delete'), iconCls: "pimcore_material_icon_delete pimcore_material_icon", @@ -218,20 +265,56 @@ pimcore.document.hardlink = Class.create(pimcore.document.document, { var buttons = []; + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu = new Ext.Button({ + ...pimcore.helpers.headbar.getSubmenuConfig() + }); + } + if (this.isAllowed("publish")) { buttons.push(this.toolbarButtons.publish); } + if (this.isAllowed("unpublish") && !this.data.locked) { - buttons.push(this.toolbarButtons.unpublish); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add( + this.toolbarButtons.unpublish + ) + } else { + buttons.push(this.toolbarButtons.unpublish); + } } buttons.push("-"); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + buttons.push(this.toolbarSubmenu); + } + if (this.isAllowed("delete") && !this.data.locked) { - buttons.push(this.toolbarButtons.remove); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('delete'), + iconCls: "pimcore_material_icon_delete pimcore_material_icon", + scale: "medium", + handler: this.remove.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.remove); + } } + if (this.isAllowed("rename") && !this.data.locked) { - buttons.push(this.toolbarButtons.rename); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('rename'), + iconCls: "pimcore_material_icon_rename pimcore_material_icon", + scale: "medium", + handler: this.rename.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.rename); + } } buttons.push({ @@ -250,19 +333,17 @@ pimcore.document.hardlink = Class.create(pimcore.document.document, { }); } - buttons.push(this.getTranslationButtons()); - - buttons.push("-"); - buttons.push({ - xtype: 'tbtext', - text: t("id") + " " + this.data.id, - scale: "medium" - }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(this.getTranslationButtons(true)); + } else { + buttons.push(this.getTranslationButtons()); + } this.toolbar = new Ext.Toolbar({ id: "document_toolbar_" + this.id, region: "north", border: false, + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { flex: 3 } : { })(), cls: "pimcore_main_toolbar", items: buttons, overflowHandler: 'scroller' diff --git a/public/js/pimcore/document/link.js b/public/js/pimcore/document/link.js index 28b74fcb64..e0ca8ef474 100644 --- a/public/js/pimcore/document/link.js +++ b/public/js/pimcore/document/link.js @@ -113,19 +113,57 @@ pimcore.document.link = Class.create(pimcore.document.document, { this.tabPanel = Ext.getCmp("pimcore_panel_tabs"); var tabId = "document_" + this.id; - this.tab = new Ext.Panel({ - id: tabId, - title: tabTitle, - closable: true, - layout: "border", - items: [ - this.getLayoutToolbar(), - this.getTabPanel() - ], - iconCls: this.getIconClass(), - document: this + const tabbarContainer = new Ext.Container({ + flex: 2 }); + const tabPanel = this.getTabPanel(); + const toolbar = this.getLayoutToolbar(); + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.tab = new Ext.Panel({ + id: tabId, + cls: "pimcore_panel_toolbar_horizontal_border_layout", + title: htmlspecialchars(tabTitle), + closable:true, + hideMode: "offsets", + layout: "border", + items: [ + { + xtype: 'panel', + width: "100%", + region: 'north', + layout: 'hbox', + items: [ + toolbar, + tabbarContainer, + ] + }, + + tabPanel + ], + iconCls: this.getIconClass(), + document: this + }); + + this.toolbarSubmenu.menu.addCls('pimcore_headbar_submenu_menu'); + + pimcore.helpers.headbar.prepareTabPanel(tabPanel, tabbarContainer, this.tab); + } else { + this.tab = new Ext.Panel({ + id: tabId, + title: htmlspecialchars(tabTitle), + closable: true, + layout: "border", + items: [ + toolbar, + tabPanel + ], + iconCls: this.getIconClass(), + document: this + }); + } + this.tab.on("beforedestroy", function () { Ext.Ajax.request({ url: Routing.generate('pimcore_admin_element_unlockelement'), @@ -194,6 +232,12 @@ pimcore.document.link = Class.create(pimcore.document.document, { ] }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu = new Ext.Button({ + ...pimcore.helpers.headbar.getSubmenuConfig() + }); + } + this.toolbarButtons.unpublish = new Ext.Button({ text: t('unpublish'), iconCls: "pimcore_material_icon_unpublish pimcore_material_icon", @@ -201,6 +245,15 @@ pimcore.document.link = Class.create(pimcore.document.document, { handler: this.unpublish.bind(this) }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarButtons.unpublish = Ext.create('Ext.menu.Item', { + text: t('unpublish'), + iconCls: "pimcore_material_icon_unpublish pimcore_material_icon", + scale: "medium", + handler: this.unpublish.bind(this) + }) + } + this.toolbarButtons.remove = new Ext.Button({ tooltip: t('delete'), iconCls: "pimcore_material_icon_delete pimcore_material_icon", @@ -221,16 +274,44 @@ pimcore.document.link = Class.create(pimcore.document.document, { buttons.push(this.toolbarButtons.publish); } if (this.isAllowed("unpublish") && !this.data.locked) { - buttons.push(this.toolbarButtons.unpublish); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add( + this.toolbarButtons.unpublish + ) + } else { + buttons.push(this.toolbarButtons.unpublish); + } } buttons.push("-"); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + buttons.push(this.toolbarSubmenu); + } + if (this.isAllowed("delete") && !this.data.locked) { - buttons.push(this.toolbarButtons.remove); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('delete'), + iconCls: "pimcore_material_icon_delete pimcore_material_icon", + scale: "medium", + handler: this.remove.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.remove); + } } if (this.isAllowed("rename") && !this.data.locked) { - buttons.push(this.toolbarButtons.rename); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('rename'), + iconCls: "pimcore_material_icon_rename pimcore_material_icon", + scale: "medium", + handler: this.rename.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.rename); + } } buttons.push({ @@ -249,19 +330,17 @@ pimcore.document.link = Class.create(pimcore.document.document, { }); } - buttons.push(this.getTranslationButtons()); - - buttons.push("-"); - buttons.push({ - xtype: 'tbtext', - text: t("id") + " " + this.data.id, - scale: "medium" - }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(this.getTranslationButtons(true)); + } else { + buttons.push(this.getTranslationButtons()); + } this.toolbar = new Ext.Toolbar({ id: "document_toolbar_" + this.id, region: "north", border: false, + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { flex: 3 } : { })(), cls: "pimcore_main_toolbar", items: buttons, overflowHandler: 'scroller' diff --git a/public/js/pimcore/document/page.js b/public/js/pimcore/document/page.js index 528670dc47..82583953c6 100644 --- a/public/js/pimcore/document/page.js +++ b/public/js/pimcore/document/page.js @@ -43,7 +43,6 @@ pimcore.document.page = Class.create(pimcore.document.page_snippet, { }, init: function () { - var user = pimcore.globalmanager.get("user"); if (this.isAllowed("save") || this.isAllowed("publish")) { @@ -118,7 +117,7 @@ pimcore.document.page = Class.create(pimcore.document.page_snippet, { items.push(this.tagAssignment.getLayout()); } - this.tabbar = pimcore.helpers.getTabBar({items: items, tabConfig: {margin: 0}}); + this.tabbar = pimcore.helpers.getTabBar({items: items, tabBar: {tabConfig: {margin: 0}}}); return this.tabbar; }, diff --git a/public/js/pimcore/document/page_snippet.js b/public/js/pimcore/document/page_snippet.js index 2e827af629..111bee6c1d 100644 --- a/public/js/pimcore/document/page_snippet.js +++ b/public/js/pimcore/document/page_snippet.js @@ -12,6 +12,7 @@ */ pimcore.registerNS("pimcore.document.page_snippet"); + /** * @private */ @@ -27,20 +28,66 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { this.tabPanel = Ext.getCmp("pimcore_panel_tabs"); var tabId = "document_" + this.id; - this.tab = new Ext.Panel({ - id: tabId, - title: tabTitle, - closable:true, - hideMode: "offsets", - layout: "border", - items: [ - this.getLayoutToolbar(), - this.getTabPanel() - ], - iconCls: this.getIconClass(), - document: this + const tabbarContainer = new Ext.Container({ + flex: 2 + }); + + const backgroundContainer = new Ext.Container({ + cls: 'pimcore_headbar_background', + width: '100%', + height: 49, }); + const tabPanel = this.getTabPanel(); + const toolbar = this.getLayoutToolbar(); + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.tab = new Ext.Panel({ + id: tabId, + cls: "pimcore_panel_toolbar_horizontal", + title: htmlspecialchars(tabTitle), + closable:true, + hideMode: "offsets", + layout: "absolute", + items: [ + toolbar, + tabPanel, + backgroundContainer, + tabbarContainer + ], + iconCls: this.getIconClass(), + document: this + }); + + this.toolbarSubmenu.menu.addCls('pimcore_headbar_submenu_menu'); + + tabPanel.items.each((item) => { + const title = item.getTitle(); + + if (title) { + item.tab.setTooltip(item.getTitle()); + item.setTitle(''); + } + }); + + tabbarContainer.add(tabPanel.getTabBar()); + tabPanel.y = 46; + } else { + this.tab = new Ext.Panel({ + id: tabId, + title: htmlspecialchars(tabTitle), + closable:true, + hideMode: "offsets", + layout: "border", + items: [ + toolbar, + tabPanel + ], + iconCls: this.getIconClass(), + document: this + }); + } + // remove this instance when the panel is closed this.tab.on("beforedestroy", function () { Ext.Ajax.request({ @@ -55,6 +102,16 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { this.cleanUpOnDestroy(); }.bind(this)); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.tab.on("boxready", function () { + this.calcLayoutPositions(tabPanel, backgroundContainer, tabbarContainer, toolbar); + }.bind(this)); + + this.tab.on('resize', function () { + this.calcLayoutPositions(tabPanel, backgroundContainer, tabbarContainer, toolbar); + }.bind(this)) + } + this.tab.on("destroy", function () { pimcore.globalmanager.remove("document_" + this.id); pimcore.helpers.forgetOpenTab("document_" + this.id + "_" + this.data.type); @@ -88,6 +145,38 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { pimcore.layout.refresh(); }, + calcLayoutPositions: function(tabPanel, backgroundContainer, tabbarContainer, toolbar) { + const headbarWidth = backgroundContainer.getWidth(); + const toolbarWidth = Math.round(headbarWidth * (3 / 5)); + const tabbarWidth = Math.round(headbarWidth * (2 / 5)); + + toolbar.setPosition(0, 0); + toolbar.setMaxWidth(toolbarWidth); + toolbar.setWidth(toolbarWidth); + tabbarContainer.setPosition(toolbarWidth, 0); + tabbarContainer.setWidth(tabbarWidth); + + const tabbarItems = tabPanel.getTabBar().items.items; + const firstTab = tabbarItems[0].getEl().dom; + const lastTab = tabbarItems[tabbarItems.length - 1].getEl().dom; + const firstBoundingRect = firstTab.getBoundingClientRect(); + const lastBoundingRect = lastTab.getBoundingClientRect(); + const firstAndLastTabDistance = lastBoundingRect.x + lastBoundingRect.width - firstBoundingRect.x; + + if (firstAndLastTabDistance > tabbarWidth) { + tabPanel.getTabBar().setLayout({ + pack: 'start' + }) + } else { + tabPanel.getTabBar().setLayout({ + pack: 'end' + }) + } + + tabPanel.setHeight(this.tab.getHeight() - 46); + this.tab.updateLayout(); + }, + cleanUpOnDestroy: function () { if (this.edit) { if (typeof this.edit.onClose == "function") { @@ -115,7 +204,6 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { getLayoutToolbar : function () { if (!this.toolbar) { - this.toolbarButtons = {}; this.toolbarButtons.save = new Ext.SplitButton({ @@ -139,6 +227,25 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { ] }); + if (this.isAllowed("publish")) { + this.toolbarButtons.save.menu.add( + { + text: t('save_and_publish'), + iconCls: "pimcore_icon_save", + cls: "pimcore_save_button", + scale: "medium", + handler: this.publish.bind(this) + } + ); + + this.toolbarButtons.save.menu.add( + { + text: t('save_pubish_close'), + iconCls: "pimcore_icon_save", + handler: this.publishClose.bind(this) + } + ) + } this.toolbarButtons.publish = new Ext.SplitButton({ text: t('save_and_publish'), @@ -166,7 +273,6 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { ] }); - this.toolbarButtons.unpublish = new Ext.Button({ text: t('unpublish'), iconCls: "pimcore_material_icon_unpublish pimcore_material_icon", @@ -174,6 +280,15 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { handler: this.unpublish.bind(this) }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarButtons.unpublish = Ext.create('Ext.menu.Item', { + text: t('unpublish'), + iconCls: "pimcore_material_icon_unpublish pimcore_material_icon", + scale: "medium", + handler: this.unpublish.bind(this) + }) + } + this.toolbarButtons.remove = new Ext.Button({ tooltip: t('delete'), iconCls: "pimcore_material_icon_delete pimcore_material_icon", @@ -188,29 +303,64 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { handler: this.rename.bind(this) }); - var buttons = []; + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu = new Ext.Button({ + ...pimcore.helpers.headbar.getSubmenuConfig() + }); + } + if (this.isAllowed("save")) { buttons.push(this.toolbarButtons.save); } + if (this.isAllowed("publish")) { buttons.push(this.toolbarButtons.publish); } + if (this.isAllowed("unpublish") && !this.data.locked) { - buttons.push(this.toolbarButtons.unpublish); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add( + this.toolbarButtons.unpublish + ) + } else { + buttons.push(this.toolbarButtons.unpublish); + } } buttons.push("-"); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + buttons.push(this.toolbarSubmenu); + } + if(this.isAllowed("delete") && !this.data.locked && this.data.id != 1) { - buttons.push(this.toolbarButtons.remove); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('delete'), + iconCls: "pimcore_material_icon_delete pimcore_material_icon", + scale: "medium", + handler: this.remove.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.remove); + } } + if(this.isAllowed("rename") && !this.data.locked && this.data.id != 1) { - buttons.push(this.toolbarButtons.rename); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('rename'), + iconCls: "pimcore_material_icon_rename pimcore_material_icon", + scale: "medium", + handler: this.rename.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.rename); + } } - buttons.push({ tooltip: t('reload'), iconCls: "pimcore_material_icon_reload pimcore_material_icon", @@ -236,21 +386,39 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { menu: this.getMetaInfoMenuItems() }); - buttons.push(this.getTranslationButtons()); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(this.getTranslationButtons(true)); + } else { + buttons.push(this.getTranslationButtons()); + } if(this.data["url"]) { buttons.push("-"); - buttons.push({ - tooltip: t("open_in_new_window"), + const openInNewWindowConfig = { + ...( + () => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? + { text: t("open_in_new_window") } : + { tooltip: t("open_in_new_window") } + )(), iconCls: "pimcore_material_icon_open_window pimcore_material_icon", scale: "medium", handler: function () { window.open(this.data.url); }.bind(this) - }); + } - buttons.push({ - tooltip: t("open_preview_in_new_window"), + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(openInNewWindowConfig); + } else { + buttons.push(openInNewWindowConfig); + } + + const openPreviewInNewWindowConfig = { + ...( + () => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? + { text: t("open_preview_in_new_window") } : + { tooltip: t("open_preview_in_new_window") } + )(), iconCls: "pimcore_material_icon_preview pimcore_material_icon", scale: "medium", handler: function () { @@ -280,24 +448,33 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { window.open(link); } }.bind(this) - }); + }; + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(openPreviewInNewWindowConfig); + } else { + buttons.push(openPreviewInNewWindowConfig); + } } if (pimcore.globalmanager.get("user").isAllowed('notifications_send')) { - buttons.push({ - tooltip: t('share_via_notifications'), + const shareViaNotificationsConfig = { + ...( + () => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? + { text: t("share_via_notifications") } : + { tooltip: t("share_via_notifications") } + )(), iconCls: "pimcore_icon_share", scale: "medium", handler: this.shareViaNotifications.bind(this) - }); - } + }; - buttons.push("-"); - buttons.push({ - xtype: 'tbtext', - text: t("id") + " " + this.data.id, - scale: "medium" - }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(shareViaNotificationsConfig); + } else { + buttons.push(shareViaNotificationsConfig); + } + } //workflow management pimcore.elementservice.integrateWorkflowManagement('document', this.data.id, this, buttons); @@ -305,6 +482,7 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { this.draftVersionNotification = new Ext.Button({ text: t('draft'), + cls: "pimcore_draft_button", iconCls: "pimcore_icon_delete pimcore_material_icon", scale: "medium", hidden: true, @@ -321,11 +499,22 @@ pimcore.document.page_snippet = Class.create(pimcore.document.document, { id: "document_toolbar_" + this.id, region: "north", border: false, + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { flex: 3 } : { })(), cls: "pimcore_main_toolbar", items: buttons, overflowHandler: 'scroller' }); + if (this.isAllowed('publish') && this.isAllowed('save')) { + if (this.data.published) { + this.toolbarButtons.save.hide(); + this.toolbarButtons.publish.show(); + } else { + this.toolbarButtons.publish.hide(); + this.toolbarButtons.save.show(); + } + } + if (!this.data.published) { this.toolbarButtons.unpublish.hide(); } else if (this.isAllowed("publish")) { diff --git a/public/js/pimcore/element/abstract.js b/public/js/pimcore/element/abstract.js index 23ea7274c9..6bf5ef4c2e 100644 --- a/public/js/pimcore/element/abstract.js +++ b/public/js/pimcore/element/abstract.js @@ -40,6 +40,10 @@ pimcore.element.abstract = Class.create({ addToHistory: true, + checkIfNewHeadbarLayoutIsEnabled: function () { + return pimcore.settings?.new_admin_style; + }, + // startup / opening functions addLoadingPanel: function () { var type = pimcore.helpers.getElementTypeByObject(this); @@ -308,7 +312,7 @@ pimcore.element.abstract = Class.create({ return [ { - text: t("metainfo_copy_id"), + text: t("id") + " " + metainfo.id + ' - ' + t("copy"), iconCls: "pimcore_icon_copy", handler: pimcore.helpers.copyStringToClipboard.bind(this, metainfo.id) }, diff --git a/public/js/pimcore/helpers.js b/public/js/pimcore/helpers.js index c18c209902..5214a42ba8 100644 --- a/public/js/pimcore/helpers.js +++ b/public/js/pimcore/helpers.js @@ -3228,7 +3228,7 @@ pimcore.helpers.reloadUserImage = function (userId) { var image = Routing.generate('pimcore_admin_user_getimage', {id: userId, '_dc': Ext.Date.now()}); if (pimcore.currentuser.id == userId) { - Ext.get("pimcore_avatar").query('img')[0].src = image; + Ext.get("pimcore_notification").query('img')[0].src = image; } if (Ext.getCmp("pimcore_user_image_" + userId)) { @@ -3400,11 +3400,33 @@ pimcore.helpers.documentTypeHasSpecificRole = function(documentType, role) { return pimcore.settings.document_types_configuration[documentType][role]; } +pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled = function() { + return pimcore?.settings?.new_admin_style; +} + pimcore.helpers.getTabBar = function (attributes) { - let tabAttr = Object.assign(attributes, { - tabBar: { + let tabBar; + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + tabBar = { + ...(() => attributes?.tabBar || {})(), + layout: { + pack: 'end' + }, + defaults: { + height: 46, + }, cls: 'pimcore_editor_tabbar' - }, + }; + } else { + tabBar = { + ...(() => attributes?.tabBar || {})(), + cls: 'pimcore_editor_tabbar' + }; + } + + let tabAttr = Object.assign(attributes, { + tabBar: tabBar, tabPosition: 'top', region:'center', deferredRender:true, @@ -3442,4 +3464,4 @@ pimcore.helpers.sendRequest = function ( request.open(method, url); request.send(); -}; \ No newline at end of file +}; diff --git a/public/js/pimcore/layout/toolbar.js b/public/js/pimcore/layout/toolbar.js index c1578e8c8e..d3139b2e8f 100644 --- a/public/js/pimcore/layout/toolbar.js +++ b/public/js/pimcore/layout/toolbar.js @@ -828,6 +828,25 @@ pimcore.layout.toolbar = Class.create({ }; } + // profile + let profileItems = [ + { + text: t("my_profile"), + iconCls: 'pimcore_icon_profile', + handler: () => { + pimcore.helpers.openProfile(); + } + }, + + { + text: t('logout'), + iconCls: 'pimcore_material_icon_logout', + handler: () => { + document.getElementById('pimcore_logout_form').submit(); + } + } + ] + // notifications if (user.isAllowed("notifications")) { var notificationItems = [{ @@ -879,6 +898,7 @@ pimcore.layout.toolbar = Class.create({ window.open('https://pimcore.com/docs/platform/Pimcore/Getting_Started/Installation/Webserver_Installation#5-maintenance-cron-job'); } }); + pimcore.notification.helper.incrementCount(); } @@ -892,18 +912,24 @@ pimcore.layout.toolbar = Class.create({ window.open('https://pimcore.com/docs/pimcore/current/Development_Documentation/Development_Tools_and_Details/Email_Framework'); } }); + pimcore.notification.helper.incrementCount(); } - - menu.notification = { - items: notificationItems, - shadow: false, - cls: "pimcore_navigation_flyout", - exclude: true, - }; + profileItems = [ + ...notificationItems, + '-', + ...profileItems, + ] } + menu.notification = { + items: profileItems, + shadow: false, + cls: "pimcore_navigation_flyout", + exclude: true, + }; + // Additional menu items can be added via this event const preMenuBuild = new CustomEvent(pimcore.events.preMenuBuild, { detail: { diff --git a/public/js/pimcore/object/folder.js b/public/js/pimcore/object/folder.js index fe85291892..7e0a16caa3 100644 --- a/public/js/pimcore/object/folder.js +++ b/public/js/pimcore/object/folder.js @@ -125,19 +125,74 @@ pimcore.object.folder = Class.create(pimcore.object.abstract, { this.tabPanel = Ext.getCmp("pimcore_panel_tabs"); var tabId = "object_" + this.id; - this.tab = new Ext.Panel({ - id: tabId, - title: htmlspecialchars(tabTitle), - closable:true, - layout: "border", - items: [ - this.getLayoutToolbar(), - this.getTabPanel() - ], - iconCls: "pimcore_icon_folder", - object: this + const tabbarContainer = new Ext.Container({ + flex: 2 }); + const tabPanel = this.getTabPanel(); + const toolbar = this.getLayoutToolbar(); + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.tab = new Ext.Panel({ + id: tabId, + cls: "pimcore_panel_toolbar_horizontal_border_layout", + title: htmlspecialchars(tabTitle), + closable:true, + hideMode: "offsets", + layout: "border", + items: [ + { + xtype: 'panel', + width: "100%", + region: 'north', + layout: 'hbox', + items: [ + toolbar, + tabbarContainer, + ] + }, + + tabPanel + ], + iconCls: "pimcore_icon_folder", + object: this + }); + + tabPanel.items.each((item) => { + const title = item.getTitle(); + + if (title) { + item.tab.setTooltip(item.getTitle()); + item.setTitle(''); + } + }); + + tabbarContainer.add(tabPanel.getTabBar()); + + tabPanel.getTabBar().on('add', () => { + setTimeout(() => { + this.handleTabbarLayoutOnSmallDevices(tabPanel, tabbarContainer); + }, 100); + }); + + tabbarContainer.on('resize', () => { + this.handleTabbarLayoutOnSmallDevices(tabPanel, tabbarContainer); + }); + } else { + this.tab = new Ext.Panel({ + id: tabId, + title: htmlspecialchars(tabTitle), + closable:true, + layout: "border", + items: [ + toolbar, + tabPanel + ], + iconCls: "pimcore_icon_folder", + object: this + }); + } + this.tab.on("beforedestroy", function () { Ext.Ajax.request({ url: Routing.generate('pimcore_admin_element_unlockelement'), @@ -193,6 +248,30 @@ pimcore.object.folder = Class.create(pimcore.object.abstract, { pimcore.layout.refresh(); }, + handleTabbarLayoutOnSmallDevices: function(tabPanel, tabbarContainer) { + const tabbarItems = tabPanel.getTabBar().items.items; + const firstTab = tabbarItems[0].getEl()?.dom; + const lastTab = tabbarItems[tabbarItems.length - 1].getEl()?.dom; + + if (!firstTab || !lastTab) return; + + const firstBoundingRect = firstTab.getBoundingClientRect(); + const lastBoundingRect = lastTab.getBoundingClientRect(); + const firstAndLastTabDistance = lastBoundingRect.x + lastBoundingRect.width - firstBoundingRect.x; + + if (firstAndLastTabDistance > tabbarContainer.getWidth()) { + tabPanel.getTabBar().setLayout({ + pack: 'start' + }) + } else { + tabPanel.getTabBar().setLayout({ + pack: 'end' + }) + } + + this.tab.updateLayout(); + }, + activate: function () { var tabId = "object_" + this.id; var tabPanel = Ext.getCmp("pimcore_panel_tabs"); @@ -235,11 +314,40 @@ pimcore.object.folder = Class.create(pimcore.object.abstract, { buttons.push("-"); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu = new Ext.Button({ + ...pimcore.helpers.headbar.getSubmenuConfig() + }); + + buttons.push(this.toolbarSubmenu); + } + if(this.isAllowed("delete") && !this.data.general.locked && this.data.general.id != 1) { - buttons.push(this.toolbarButtons.remove); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('delete'), + iconCls: "pimcore_material_icon_delete pimcore_material_icon", + scale: "medium", + handler: this.remove.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.remove); + } } + if(this.isAllowed("rename") && !this.data.general.locked && this.data.general.id != 1) { - buttons.push(this.toolbarButtons.rename); + if(this.isAllowed("rename") && !this.data.locked) { + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('rename'), + iconCls: "pimcore_material_icon_rename pimcore_material_icon", + scale: "medium", + handler: this.rename.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.rename); + } + } } buttons.push({ @@ -267,8 +375,8 @@ pimcore.object.folder = Class.create(pimcore.object.abstract, { menu: this.getMetaInfoMenuItems() }); - buttons.push({ - tooltip: t("search_and_move"), + const searchAndMoveConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('search_and_move') } : { tooltip: t('search_and_move') })(), iconCls: "pimcore_material_icon_download_zip pimcore_material_icon", scale: "medium", handler: pimcore.helpers.searchAndMove.bind(this, this.data.general.id, @@ -281,14 +389,13 @@ pimcore.object.folder = Class.create(pimcore.object.abstract, { //refresh complete object tree as moved object(s) source is unknown pimcore.elementservice.refreshRootNodeAllTrees("object"); }.bind(this), "object") - }); + } - buttons.push("-"); - buttons.push({ - xtype: 'tbtext', - text: t("id") + " " + this.data.general.id, - scale: "medium" - }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(searchAndMoveConfig); + } else { + buttons.push(searchAndMoveConfig); + } //workflow management pimcore.elementservice.integrateWorkflowManagement('object', this.id, this, buttons); @@ -297,6 +404,7 @@ pimcore.object.folder = Class.create(pimcore.object.abstract, { id: "object_toolbar_" + this.id, region: "north", border: false, + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { flex: 3 } : { })(), cls: "pimcore_main_toolbar", items: buttons, overflowHandler: 'scroller' diff --git a/public/js/pimcore/object/object.js b/public/js/pimcore/object/object.js index 8a9f92d7fb..8d6f15658e 100644 --- a/public/js/pimcore/object/object.js +++ b/public/js/pimcore/object/object.js @@ -20,6 +20,7 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { willClose: false, forceReloadVersionsAfterSave: false, initialize: function (id, options) { + this.id = intval(id); this.options = options; this.addLoadingPanel(); @@ -202,17 +203,60 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { this.tabPanel = Ext.getCmp("pimcore_panel_tabs"); var tabId = "object_" + this.id; - this.tab = new Ext.Panel({ - id: tabId, - title: htmlspecialchars(this.data.general.key), - closable: true, - layout: "border", - items: [this.getLayoutToolbar(), this.getTabPanel()], - object: this, - cls: "pimcore_class_" + this.data.general.className, - iconCls: iconClass + + const tabbarContainer = new Ext.Container({ + flex: 2 }); + const tabPanel = this.getTabPanel(); + const toolbar = this.getLayoutToolbar(); + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.tab = new Ext.Panel({ + id: tabId, + title: htmlspecialchars(this.data.general.key), + closable:true, + hideMode: "offsets", + layout: "border", + items: [ + { + xtype: 'panel', + width: "100%", + minWidth: 300, + region: 'north', + layout: 'hbox', + items: [ + toolbar, + tabbarContainer, + ] + }, + + tabPanel + ], + object: this, + cls: "pimcore_panel_toolbar_horizontal_border_layout pimcore_class_" + this.data.general.className, + iconCls: iconClass + }); + + this.toolbarSubmenu.menu.addCls('pimcore_headbar_submenu_menu'); + + pimcore.helpers.headbar.prepareTabPanel(tabPanel, tabbarContainer, this.tab); + } else { + this.tab = new Ext.Panel({ + id: tabId, + title: htmlspecialchars(this.data.general.key), + closable:true, + layout: "border", + items: [ + toolbar, + tabPanel + ], + object: this, + cls: "pimcore_class_" + this.data.general.className, + iconCls: iconClass + }); + } + this.tab.on("activate", function () { this.tab.updateLayout(); pimcore.layout.refresh(); @@ -408,6 +452,25 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { ] }); + if (this.isAllowed("publish")) { + this.toolbarButtons.save.menu.add( + { + text: t('save_and_publish'), + iconCls: "pimcore_icon_save", + cls: "pimcore_save_button", + scale: "medium", + handler: this.publish.bind(this) + } + ); + + this.toolbarButtons.save.menu.add( + { + text: t('save_pubish_close'), + iconCls: "pimcore_icon_save", + handler: this.publishClose.bind(this) + } + ) + } this.toolbarButtons.publish = new Ext.SplitButton({ text: t('save_and_publish'), @@ -415,11 +478,12 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { cls: "pimcore_save_button", scale: "medium", handler: this.publish.bind(this), - menu: [{ - text: t('save_pubish_close'), - iconCls: "pimcore_icon_save", - handler: this.publishClose.bind(this) - }, + menu: [ + { + text: t('save_pubish_close'), + iconCls: "pimcore_icon_save", + handler: this.publishClose.bind(this) + }, { text: t('save_draft'), iconCls: "pimcore_icon_save", @@ -442,6 +506,15 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { handler: this.unpublish.bind(this) }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarButtons.unpublish = Ext.create('Ext.menu.Item', { + text: t('unpublish'), + iconCls: "pimcore_material_icon_unpublish pimcore_material_icon", + scale: "medium", + handler: this.unpublish.bind(this) + }) + } + this.toolbarButtons.remove = new Ext.Button({ tooltip: t("delete"), iconCls: "pimcore_material_icon_delete pimcore_material_icon", @@ -456,6 +529,12 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { handler: this.rename.bind(this) }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu = new Ext.Button({ + ...pimcore.helpers.headbar.getSubmenuConfig() + }); + } + if (this.isAllowed("save")) { buttons.push(this.toolbarButtons.save); } @@ -463,16 +542,45 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { buttons.push(this.toolbarButtons.publish); } if (this.isAllowed("unpublish") && !this.data.general.locked) { - buttons.push(this.toolbarButtons.unpublish); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add( + this.toolbarButtons.unpublish + ) + } else { + buttons.push(this.toolbarButtons.unpublish); + } } buttons.push("-"); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + buttons.push(this.toolbarSubmenu); + } + if (this.isAllowed("delete") && !this.data.general.locked) { - buttons.push(this.toolbarButtons.remove); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('delete'), + iconCls: "pimcore_material_icon_delete pimcore_material_icon", + scale: "medium", + handler: this.remove.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.remove); + } } + if (this.isAllowed("rename") && !this.data.general.locked) { - buttons.push(this.toolbarButtons.rename); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add({ + text: t('rename'), + iconCls: "pimcore_material_icon_rename pimcore_material_icon", + scale: "medium", + handler: this.rename.bind(this) + }); + } else { + buttons.push(this.toolbarButtons.rename); + } } var reloadConfig = { @@ -519,19 +627,25 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { } } + const metaInfoMenu = this.getMetaInfoMenuItems(); + metaInfoMenu.unshift({ + text: t("class") + ' ' + t(this.data.general.classTitle) + ' - ' + t("copy"), + iconCls: "pimcore_icon_copy", + handler: pimcore.helpers.copyStringToClipboard.bind(this, t(this.data.general.classTitle)) + }); + buttons.push({ xtype: "splitbutton", tooltip: t("show_metainfo"), iconCls: "pimcore_material_icon_info pimcore_material_icon", scale: "medium", handler: this.showMetaInfo.bind(this), - menu: this.getMetaInfoMenuItems() + menu: metaInfoMenu }); if (this.data.general.showFieldLookup) { - buttons.push({ - xtype: "button", - tooltip: t("fieldlookup"), + const showLockupConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('fieldlookup') } : { tooltip: t('fieldlookup') })(), iconCls: "pimcore_material_fieldlookup pimcore_material_icon", scale: "medium", handler: function() { @@ -542,14 +656,18 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { var dialog = new pimcore.object.fieldlookup.filterdialog(config, null, object); dialog.show(); }.bind(this) - }); - } + } + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(showLockupConfig); + } else { + buttons.push(showLockupConfig); + } + } if (this.data.hasPreview) { - buttons.push("-"); - buttons.push({ - tooltip: t("open"), + const previewConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('open') } : { tooltip: t('open') })(), iconCls: "pimcore_material_icon_preview pimcore_material_icon", scale: "medium", handler: function () { @@ -559,34 +677,34 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { window.open(path); }); }.bind(this) - }); + }; + + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(previewConfig); + } else { + buttons.push("-"); + buttons.push(previewConfig); + } } if (pimcore.globalmanager.get("user").isAllowed('notifications_send')) { - buttons.push({ - tooltip: t('share_via_notifications'), + const notificationConfig = { + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { text: t('share_via_notifications') } : { tooltip: t('share_via_notifications') })(), iconCls: "pimcore_icon_share", scale: "medium", handler: this.shareViaNotifications.bind(this) - }); - } + }; - buttons.push("-"); - buttons.push({ - xtype: 'tbtext', - text: t("id") + " " + this.data.general.id, - scale: "medium" - }); - - buttons.push("-"); - buttons.push({ - xtype: 'tbtext', - text: t(this.data.general.classTitle), - scale: "medium" - }); + if (pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled()) { + this.toolbarSubmenu.menu.add(notificationConfig); + } else { + buttons.push(notificationConfig); + } + } this.draftVersionNotification = new Ext.Button({ text: t('draft'), + cls: "pimcore_draft_button", iconCls: "pimcore_icon_delete pimcore_material_icon", scale: "medium", hidden: true, @@ -604,6 +722,7 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { this.languageSwitcher = Ext.create('Ext.button.Split', { iconCls: "pimcore_icon_language_" + this.frontendLanguages[0].toLowerCase(), + cls: "pimcore_translation_button", scale: "medium", menu: this.getLanguageMenuItems(), handler: function() { @@ -622,17 +741,29 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { id: "object_toolbar_" + this.id, region: "north", border: false, + ...(() => pimcore.helpers.checkIfNewHeadbarLayoutIsEnabled() ? { flex: 3 } : { })(), cls: "pimcore_main_toolbar", items: buttons, overflowHandler: 'scroller' }); + if (this.isAllowed('publish') && this.isAllowed('save')) { + if (this.data.general.published) { + this.toolbarButtons.save.hide(); + this.toolbarButtons.publish.show(); + } else { + this.toolbarButtons.publish.hide(); + this.toolbarButtons.save.show(); + } + } + if (!this.data.general.published) { this.toolbarButtons.unpublish.hide(); } else if (this.isAllowed("publish")) { this.toolbarButtons.save.hide(); } } + this.edit.toolbar = this.toolbar; return this.toolbar; @@ -727,6 +858,7 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { // toggle buttons this.toolbarButtons.unpublish.show(); this.toolbarButtons.save.hide(); + this.toolbarButtons.publish.show(); pimcore.elementservice.setElementPublishedState({ elementType: "object", @@ -745,6 +877,7 @@ pimcore.object.object = Class.create(pimcore.object.abstract, { // toggle buttons this.toolbarButtons.unpublish.hide(); this.toolbarButtons.save.show(); + this.toolbarButtons.publish.hide(); pimcore.elementservice.setElementPublishedState({ elementType: "object", diff --git a/public/js/pimcore/startup.js b/public/js/pimcore/startup.js index 8b786261db..3f3e45d662 100644 --- a/public/js/pimcore/startup.js +++ b/public/js/pimcore/startup.js @@ -593,7 +593,7 @@ Ext.onReady(function () { }, 5000); - Ext.get("pimcore_logout").on('click', function () { + Ext.get("pimcore_logout")?.on('click', function () { document.getElementById('pimcore_logout_form').submit(); }) @@ -695,8 +695,8 @@ Ext.onReady(function () { listeners: { "afterrender": function (el) { Ext.get("pimcore_navigation").show(); - Ext.get("pimcore_avatar").show(); - Ext.get("pimcore_logout").show(); + Ext.get("pimcore_avatar")?.show(); + Ext.get("pimcore_logout")?.show(); pimcore.helpers.initMenuTooltips(); @@ -719,7 +719,7 @@ Ext.onReady(function () { el.getEl().dom.addEventListener("dragover", fn, true); // open "My Profile" when clicking on avatar - Ext.get("pimcore_avatar").on("click", function (ev) { + Ext.get("pimcore_avatar")?.on("click", function (ev) { pimcore.helpers.openProfile(); }); } diff --git a/src/Controller/Admin/IndexController.php b/src/Controller/Admin/IndexController.php index b50fb883e0..913feccb0a 100644 --- a/src/Controller/Admin/IndexController.php +++ b/src/Controller/Admin/IndexController.php @@ -120,7 +120,7 @@ public function indexAction( $this->eventDispatcher->dispatch($settingsEvent, AdminEvents::INDEX_ACTION_SETTINGS); $templateParams['settings'] = $settingsEvent->getSettings(); - return $this->render('@PimcoreAdmin/admin/index/index.html.twig', $templateParams); + return $this->render($settingsEvent->getTemplate() ?: '@PimcoreAdmin/admin/index/index.html.twig', $templateParams); } /** diff --git a/src/Event/IndexActionSettingsEvent.php b/src/Event/IndexActionSettingsEvent.php index 4fff748560..cc552079b6 100644 --- a/src/Event/IndexActionSettingsEvent.php +++ b/src/Event/IndexActionSettingsEvent.php @@ -22,6 +22,7 @@ class IndexActionSettingsEvent extends Event { private array $settings; + private ?string $template = null; public function __construct(array $settings) { @@ -42,4 +43,20 @@ public function addSetting(string $key, mixed $value): void { $this->settings[$key] = $value; } + + /** + * @return string|null + */ + public function getTemplate(): ?string + { + return $this->template; + } + + /** + * @param string|null $template + */ + public function setTemplate(?string $template): void + { + $this->template = $template; + } } diff --git a/templates/admin/index/index.html.twig b/templates/admin/index/index.html.twig index c7e3a823a2..fbb3410f57 100644 --- a/templates/admin/index/index.html.twig +++ b/templates/admin/index/index.html.twig @@ -123,22 +123,30 @@
-