From a93c975da500c356f2a7a6d6b459d02619784679 Mon Sep 17 00:00:00 2001 From: Lukasz Ostafin Date: Mon, 4 Aug 2025 16:07:34 +0200 Subject: [PATCH 1/5] IBX-10416: Wrong styling in sub-items edit translation selector --- .../public/js/scripts/admin.location.view.js | 19 ++- .../public/js/scripts/button.content.edit.js | 13 +- .../js/scripts/button.translation.edit.js | 67 +++++++--- .../js/scripts/sidebar/btn/location.edit.js | 15 ++- .../js/scripts/sidebar/extra.actions.js | 1 + .../Resources/public/scss/_extra-actions.scss | 115 +++++++++------- .../public/scss/_instant-filter.scss | 112 +++++++++------- src/bundle/Resources/public/scss/_mixins.scss | 1 + .../public/scss/_translation-selector.scss | 62 +-------- .../scss/mixins/_edit-language-selector.scss | 19 +++ .../sub-items-list/_language.selector.scss | 13 +- .../_translation.selector.scss | 63 +-------- .../translations/ibexa_admin_ui.en.xliff | 28 +++- .../translations/ibexa_locationview.en.xliff | 20 +++ .../translations/ibexa_sub_items.en.xliff | 28 +++- .../ibexa_universal_discovery_widget.en.xliff | 15 +++ .../content/widget/content_create.html.twig | 2 +- .../content/widget/content_edit.html.twig | 55 +++++--- .../content/widget/form_fields.html.twig | 11 ++ .../edit_content_translation_select.html.twig | 57 ++++++++ .../ui/edit_translation_button.html.twig | 50 +++++-- .../instant.filter.component.js | 31 ++++- .../language.selector.compoment.js | 57 +++++++- .../table-view/table.view.item.component.js | 4 +- .../content.create.widget.js | 2 +- .../translation.selector.js | 126 +++++++++++++++--- 26 files changed, 658 insertions(+), 328 deletions(-) create mode 100644 src/bundle/Resources/public/scss/mixins/_edit-language-selector.scss create mode 100644 src/bundle/Resources/views/themes/admin/content/widget/form_fields.html.twig create mode 100644 src/bundle/Resources/views/themes/admin/ui/component/edit_content_translation_select.html.twig diff --git a/src/bundle/Resources/public/js/scripts/admin.location.view.js b/src/bundle/Resources/public/js/scripts/admin.location.view.js index 9aa3a69fdd..6438d9f667 100644 --- a/src/bundle/Resources/public/js/scripts/admin.location.view.js +++ b/src/bundle/Resources/public/js/scripts/admin.location.view.js @@ -13,13 +13,13 @@ const locationId = location._id; const languageCode = content.mainLanguageCode; const checkVersionDraftLink = Routing.generate('ibexa.version_draft.has_no_conflict', { contentId, languageCode, locationId }); - const submitVersionEditForm = () => { + const updateForm = () => { doc.querySelector('#form_subitems_content_edit_content_info').value = contentId; doc.querySelector(`#form_subitems_content_edit_language_${languageCode}`).checked = true; - doc.querySelector('#form_subitems_content_edit_create').click(); }; const addDraft = () => { - submitVersionEditForm(); + updateForm(); + doc.querySelector('#form_subitems_content_edit_create').click(); bootstrap.Modal.getOrCreateInstance(doc.querySelector('#version-draft-conflict-modal')).hide(); }; const attachModalListeners = (wrapper) => { @@ -37,6 +37,9 @@ if (conflictModal) { bootstrap.Modal.getOrCreateInstance(conflictModal).show(); conflictModal.addEventListener('shown.bs.modal', () => ibexa.helpers.tooltips.parse()); + conflictModal.addEventListener('hide.bs.modal', () => { + doc.body.dispatchEvent(new CustomEvent('ibexa:edit-content-reset-language-selector')); + }); } }; const showModal = (modalHtml) => { @@ -71,7 +74,7 @@ if (response.status === 409) { response.text().then(showModal); } else if (response.status === 200) { - submitVersionEditForm(); + updateForm(); } }) .catch(ibexa.helpers.notification.showErrorNotification); @@ -194,6 +197,14 @@ ); }); + doc.body.addEventListener( + 'ibexa-sub-items:submit-version-edit-form', + () => { + doc.querySelector('#form_subitems_content_edit_create').click(); + }, + false, + ); + if (publishedContentId) { emdedItemsUpdateChannel.postMessage({ contentId: publishedContentId }); } diff --git a/src/bundle/Resources/public/js/scripts/button.content.edit.js b/src/bundle/Resources/public/js/scripts/button.content.edit.js index 8fa5cb7320..e84d9cff67 100644 --- a/src/bundle/Resources/public/js/scripts/button.content.edit.js +++ b/src/bundle/Resources/public/js/scripts/button.content.edit.js @@ -4,7 +4,7 @@ const editVersion = (event) => { const versionEditForm = doc.querySelector(FORM_EDIT); const versionEditFormName = versionEditForm.name; - const { contentId, versionNo, languageCode } = event.currentTarget.dataset; + const { contentId, versionNo, languageCode, withConfirm } = event.currentTarget.dataset; const contentInfoInput = versionEditForm.querySelector(`input[name="${versionEditFormName}[content_info]"]`); const versionInfoContentInfoInput = versionEditForm.querySelector( `input[name="${versionEditFormName}[version_info][content_info]"]`, @@ -34,6 +34,7 @@ wrapper.innerHTML = modalHtml; + const conflictModal = doc.querySelector('#version-draft-conflict-modal'); const addDraftButton = wrapper.querySelector('.ibexa-btn--add-draft'); if (addDraftButton) { @@ -43,7 +44,11 @@ wrapper .querySelectorAll('.ibexa-btn--prevented') .forEach((btn) => btn.addEventListener('click', (wrapperBtnEvent) => wrapperBtnEvent.preventDefault(), false)); - bootstrap.Modal.getOrCreateInstance(doc.querySelector('#version-draft-conflict-modal')).show(); + + bootstrap.Modal.getOrCreateInstance(conflictModal).show(); + conflictModal.addEventListener('hide.bs.modal', () => { + doc.body.dispatchEvent(new CustomEvent('ibexa:edit-content-reset-language-selector')); + }); }; const handleCanEditCheck = (response) => { if (response.canEdit) { @@ -60,7 +65,9 @@ } else if (response.status === 403) { response.text().then(showErrorNotification); } else if (response.status === 200) { - submitVersionEditForm(); + if (!withConfirm) { + submitVersionEditForm(); + } } }; diff --git a/src/bundle/Resources/public/js/scripts/button.translation.edit.js b/src/bundle/Resources/public/js/scripts/button.translation.edit.js index 6242d98a35..c6de4dfd00 100644 --- a/src/bundle/Resources/public/js/scripts/button.translation.edit.js +++ b/src/bundle/Resources/public/js/scripts/button.translation.edit.js @@ -3,34 +3,32 @@ constructor(config) { this.container = config.container; this.toggler = config.container.querySelector('.ibexa-btn--translations-list-toggler'); - this.translationsList = config.container.querySelector('.ibexa-translation-selector__list-wrapper'); + this.extraActionsContainer = config.container.querySelector('.ibexa-extra-actions'); + this.closeBtn = config.container.querySelector('.ibexa-extra-actions__close-btn'); + this.confirmBtn = config.container.querySelector('.ibexa-extra-actions__confirm-btn'); + this.languagesBtns = config.container.querySelectorAll('.ibexa-btn--select-language'); this.backdrop = config.backdrop; this.tableNode = null; - this.hideTranslationsList = this.hideTranslationsList.bind(this); - this.showTranslationsList = this.showTranslationsList.bind(this); + this.hideExtraActionPanel = this.hideExtraActionPanel.bind(this); + this.showExtraActionPanel = this.showExtraActionPanel.bind(this); + this.setActiveLanguage = this.setActiveLanguage.bind(this); + this.resetLanguageSelector = this.resetLanguageSelector.bind(this); + this.setPosition = this.setPosition.bind(this); } setPosition() { - const topOffset = parseInt(this.translationsList.dataset.topOffset, 10); + const topOffset = parseInt(this.extraActionsContainer.dataset.topOffset, 10); const topPosition = window.scrollY > topOffset ? 0 : topOffset - window.scrollY; const height = window.scrollY > topOffset ? window.innerHeight : window.innerHeight + window.scrollY - topOffset; - this.translationsList.style.top = `${topPosition}px`; - this.translationsList.style.height = `${height}px`; + this.extraActionsContainer.style.top = `${topPosition}px`; + this.extraActionsContainer.style.height = `${height}px`; } - hideTranslationsList(event) { - const closestTranslationSelector = event.target.closest('.ibexa-translation-selector'); - const clickedOnTranslationsList = closestTranslationSelector && closestTranslationSelector.isSameNode(this.container); - const clickedOnDraftConflictModal = event.target.closest('.ibexa-modal--version-draft-conflict'); - - if (clickedOnTranslationsList || clickedOnDraftConflictModal) { - return; - } - + hideExtraActionPanel() { if (this.tableNode) { this.tableNode.classList.add('ibexa-table--last-column-sticky'); @@ -38,12 +36,13 @@ } this.backdrop.hide(); - this.translationsList.classList.add('ibexa-translation-selector__list-wrapper--hidden'); - doc.removeEventListener('click', this.hideTranslationsList, false); + this.extraActionsContainer.classList.add('ibexa-extra-actions--hidden'); + + this.closeBtn.removeEventListener('click', this.hideExtraActionPanel, false); } - showTranslationsList({ currentTarget }) { - this.translationsList.classList.remove('ibexa-translation-selector__list-wrapper--hidden'); + showExtraActionPanel({ currentTarget }) { + this.extraActionsContainer.classList.remove('ibexa-extra-actions--hidden'); this.tableNode = currentTarget.closest('.ibexa-table--last-column-sticky'); @@ -52,14 +51,38 @@ } this.setPosition(); - this.backdrop.show(); - doc.addEventListener('click', this.hideTranslationsList, false); + this.closeBtn.addEventListener('click', this.hideExtraActionPanel, false); + ibexa.helpers.tooltips.hideAll(); } + setActiveLanguage(event) { + const { contentId, languageCode } = event.currentTarget.dataset; + + this.confirmBtn.dataset.contentId = contentId; + this.confirmBtn.dataset.languageCode = languageCode; + this.confirmBtn.disabled = false; + + this.languagesBtns.forEach((btn) => btn.classList.remove('ibexa-btn--active')); + event.currentTarget.classList.add('ibexa-btn--active'); + } + + resetLanguageSelector() { + this.confirmBtn.dataset.contentId = null; + this.confirmBtn.dataset.languageCode = null; + this.confirmBtn.disabled = true; + + this.languagesBtns.forEach((btn) => btn.classList.remove('ibexa-btn--active')); + } + init() { - this.toggler.addEventListener('click', this.showTranslationsList, false); + this.toggler.addEventListener('click', this.showExtraActionPanel, false); + this.languagesBtns.forEach((btn) => { + btn.addEventListener('click', this.setActiveLanguage, false); + }); + + document.body.addEventListener('ibexa:edit-content-reset-language-selector', this.resetLanguageSelector, false); } } diff --git a/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js b/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js index 14bdd93530..4c910ae8d5 100644 --- a/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js +++ b/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js @@ -53,21 +53,32 @@ const checkedBtn = event.currentTarget; const languageCode = checkedBtn.value; const checkVersionDraftLink = Routing.generate('ibexa.version_draft.has_no_conflict', { contentId, languageCode, locationId }); + const activeLanguageItem = event.target.closest('.ibexa-instant-filter__group-item').querySelector('.ibexa-label'); + const allLanguageItems = form.querySelectorAll('.ibexa-instant-filter__group-item .ibexa-label'); + const submitBtn = form.querySelector('.ibexa-extra-actions__confirm-btn'); + + allLanguageItems.forEach((item) => { + item.classList.remove('ibexa-label--active'); + }); fetch(checkVersionDraftLink, { credentials: 'same-origin', }).then((response) => { if (response.status === 409) { response.text().then(showModal.bind(null, form, btns)); + submitBtn.disabled = true; + + return; } else if (response.status === 200) { if (form.querySelector('#user_edit_version_info')) { redirectToUserEdit(languageCode, contentId, form); return; } - - form.submit(); } + + submitBtn.disabled = false; + activeLanguageItem.classList.add('ibexa-label--active'); }); }; const attachEventsToEditActionsWidget = (container) => { diff --git a/src/bundle/Resources/public/js/scripts/sidebar/extra.actions.js b/src/bundle/Resources/public/js/scripts/sidebar/extra.actions.js index 5cd3cc3175..9c2eee6d9a 100644 --- a/src/bundle/Resources/public/js/scripts/sidebar/extra.actions.js +++ b/src/bundle/Resources/public/js/scripts/sidebar/extra.actions.js @@ -143,6 +143,7 @@ import { getInstance } from '@ibexa-admin-ui/src/bundle/Resources/public/js/scri initExtraActionsWidget(dataset); }); doc.body.addEventListener('ibexa-extra-actions:toggle-widget', (event) => toggleExtraActionsWidget(event.detail), false); + closeBtns.forEach((closeBtn) => closeBtn.addEventListener( 'click', diff --git a/src/bundle/Resources/public/scss/_extra-actions.scss b/src/bundle/Resources/public/scss/_extra-actions.scss index 4279d4c412..25b0d21df6 100644 --- a/src/bundle/Resources/public/scss/_extra-actions.scss +++ b/src/bundle/Resources/public/scss/_extra-actions.scss @@ -1,9 +1,24 @@ .ibexa-extra-actions { @include container-box-shadow-left; + $self: &; + background-color: $ibexa-color-white; padding: calculateRem(16px) 0; width: calculateRem(700px); + height: calc(100vh - #{calculateRem(73px)}); + position: fixed; + top: calculateRem(73px); + right: 0; + z-index: 200; + transform: translate(0, 0) scaleX(1); + transform-origin: right center; + transition: $ibexa-admin-widget-open-transition; + + &--hidden { + transform: translate(calc(100%), 0) scaleX(0); + transition: $ibexa-admin-widget-close-transition; + } &__action { display: block; @@ -60,13 +75,8 @@ &__content { padding: calculateRem(32px) 25% calculateRem(48px) calculateRem(32px); - max-height: calc(100% - #{calculateRem(90px)}); + max-height: calc(100vh - #{calculateRem(210px)}); overflow: auto; - - &--create { - padding-top: calculateRem(24px); - padding-bottom: 0; - } } &__btns { @@ -85,28 +95,47 @@ gap: calculateRem(16px); } + &__section-content { + padding-bottom: calculateRem(32px); + background: $ibexa-color-white; + font-size: calculateRem(16px); + border-bottom: calculateRem(1px) solid $ibexa-color-light; + + select { + display: inline-block; + width: 75%; + } + } + &--edit-user, &--edit { + padding: 0; + + #{$self} { + &__header, + &__content { + padding: calculateRem(16px); + } + + &__header-content { + margin: 0; + } + + &__confirm-wrapper { + padding: calculateRem(16px) calculateRem(20px); + } + } + .form-check { padding-left: 0; } .ibexa-label { - background: $ibexa-color-white; - display: flex; - width: 100%; - padding: calculateRem(13px) calculateRem(10px); - border: calculateRem(1px) solid $ibexa-color-light; - border-radius: $ibexa-border-radius; - box-shadow: calculateRem(4px) calculateRem(2px) calculateRem(17px) 0 rgba($ibexa-color-info, 0.05); - transition: all $ibexa-admin-transition-duration $ibexa-admin-transition; - cursor: pointer; + @include edit-language-item; + } - &:hover { - border-color: $ibexa-color-dark; - transform: scale(1.02) translateX(-10px); - box-shadow: calculateRem(4px) calculateRem(10px) calculateRem(17px) 0 rgba($ibexa-color-info, 0.2); - } + .ibexa-instant-filter__input-wrapper { + margin: 0 0 calculateRem(30px) 0; } .ibexa-input[type='radio'] { @@ -114,23 +143,12 @@ } } - &__section-content { - padding-bottom: calculateRem(32px); - background: $ibexa-color-white; - font-size: calculateRem(16px); - border-bottom: calculateRem(1px) solid $ibexa-color-light; - - select { - display: inline-block; - width: 75%; - } - } - &--create { - .ibexa-extra-actions { + #{$self} { &__content { - max-height: calc(100% - #{calculateRem(157px)}); - overflow: auto; + max-height: calc(100% - #{calculateRem(155px)}); + padding-top: calculateRem(24px); + padding-bottom: 0; } &__section-content--content-type { @@ -168,6 +186,17 @@ } } } + + &--full-height { + top: 0; + height: 100vh; + + #{$self} { + &__content { + max-height: calc(100vh - #{calculateRem(136px)}); + } + } + } } .ibexa-extra-actions-container { @@ -180,22 +209,6 @@ z-index: 150; background-color: rgba($ibexa-color-dark, 0.4); } - - .ibexa-extra-actions { - height: calc(100vh - #{calculateRem(73px)}); - position: fixed; - top: calculateRem(73px); - right: 0; - z-index: 200; - transform: translate(0, 0) scaleX(1); - transform-origin: right center; - transition: $ibexa-admin-widget-open-transition; - - &--hidden { - transform: translate(calc(100%), 0) scaleX(0); - transition: $ibexa-admin-widget-close-transition; - } - } } .ibexa-main-container { diff --git a/src/bundle/Resources/public/scss/_instant-filter.scss b/src/bundle/Resources/public/scss/_instant-filter.scss index de255680c0..e6ad37c9ac 100644 --- a/src/bundle/Resources/public/scss/_instant-filter.scss +++ b/src/bundle/Resources/public/scss/_instant-filter.scss @@ -13,72 +13,86 @@ } } -.ibexa-extra-actions--create { - .ibexa-instant-filter { - &__desc { - color: $ibexa-color-dark-400; - font-size: $ibexa-text-font-size-small; - padding-top: calculateRem(14px); - } - - &__group { - display: flex; - flex-wrap: wrap; - padding-bottom: calculateRem(16px); - - &:not(:last-of-type) { - border-bottom: calculateRem(1px) solid $ibexa-color-light; +.ibexa-extra-actions { + &--create { + .ibexa-instant-filter { + &__desc { + color: $ibexa-color-dark-400; + font-size: $ibexa-text-font-size-small; + padding-top: calculateRem(14px); } - } - - &__group-name { - margin: calculateRem(16px) 0 calculateRem(8px); - color: $ibexa-color-dark; - flex-basis: 100%; - font-size: $ibexa-text-font-size-small; - } - &__group-item { - position: relative; - flex-basis: 50%; - padding: calculateRem(4px); - display: flex; - align-items: center; + &__group { + display: flex; + flex-wrap: wrap; + padding-bottom: calculateRem(16px); - label { - cursor: pointer; + &:not(:last-of-type) { + border-bottom: calculateRem(1px) solid $ibexa-color-light; + } } - .form-check { - width: 100%; + &__group-name { + margin: calculateRem(16px) 0 calculateRem(8px); + color: $ibexa-color-dark; + flex-basis: 100%; + font-size: $ibexa-text-font-size-small; } - .ibexa-icon { - fill: $ibexa-color-black; - position: absolute; - left: calculateRem(20px); - width: calculateRem(16px); - height: calculateRem(16px); - } + &__group-item { + position: relative; + flex-basis: 50%; + padding: calculateRem(4px); + display: flex; + align-items: center; - &:hover { - .ibexa-label--checkbox-radio { - color: $ibexa-color-primary; + label { + cursor: pointer; + } + + .form-check { + width: 100%; } .ibexa-icon { - fill: $ibexa-color-primary; + fill: $ibexa-color-black; + position: absolute; + left: calculateRem(20px); + width: calculateRem(16px); + height: calculateRem(16px); + } + + &:hover { + .ibexa-label--checkbox-radio { + color: $ibexa-color-primary; + } + + .ibexa-icon { + fill: $ibexa-color-primary; + } + } + + &--selected { + background: $ibexa-color-light-300; + border-radius: $ibexa-border-radius; } } - &--selected { - background: $ibexa-color-light-300; - border-radius: $ibexa-border-radius; + &__group-item-label-icon { + height: calculateRem(16px); } } + } - &__group-item-label-icon { - height: calculateRem(16px); + &--edit, + &--edit-user { + .ibexa-instant-filter { + &__desc { + color: $ibexa-color-dark-400; + font-size: $ibexa-text-font-size-small; + margin-bottom: calculateRem(20px); + padding: 0; + } } } } diff --git a/src/bundle/Resources/public/scss/_mixins.scss b/src/bundle/Resources/public/scss/_mixins.scss index 4709e7d4bb..c14cb10dab 100644 --- a/src/bundle/Resources/public/scss/_mixins.scss +++ b/src/bundle/Resources/public/scss/_mixins.scss @@ -14,6 +14,7 @@ @import 'mixins/spinner'; @import 'mixins/tab-selector'; @import 'mixins/tooltips'; +@import 'mixins/edit-language-selector'; @mixin datetime-field() { &.is-invalid { diff --git a/src/bundle/Resources/public/scss/_translation-selector.scss b/src/bundle/Resources/public/scss/_translation-selector.scss index 937163575d..fa68b88008 100644 --- a/src/bundle/Resources/public/scss/_translation-selector.scss +++ b/src/bundle/Resources/public/scss/_translation-selector.scss @@ -1,63 +1,11 @@ .ibexa-translation-selector { - &__list-wrapper { - display: block; - position: fixed; - opacity: 1; - text-align: left; - background-color: $ibexa-color-white; - border: calculateRem(16px) solid $ibexa-color-white; - width: calculateRem(360px); - padding: calculateRem(9px); - box-shadow: calculateRem(-4px) calculateRem(4px) calculateRem(6px) 0 rgba($ibexa-color-dark-300, 0.35); - border-radius: calculateRem(4px); - top: calculateRem(100px); - right: 0; - height: calc(100vh - #{calculateRem(100px)}); - opacity: 1; - transform: scaleX(1); - transform-origin: right center; - z-index: 200; - transition: - transform 0.4s ease-in, - opacity 0.4s ease-in; + .ibexa-instant-filter__group-item { + .ibexa-btn { + @include edit-language-item; - &--hidden { - opacity: 0; - transform: scaleX(0); - transition: - transform 0.2s ease-out, - opacity 0.2s ease-out; - } - } - - &__title { - color: $ibexa-color-primary; - font-size: calculateRem(16px); - line-height: 2; - font-weight: bold; - border-bottom: calculateRem(1px) solid $ibexa-color-primary; - margin-bottom: calculateRem(15px); - } - - &__list { - display: flex; - flex-direction: column; - max-height: calculateRem(300px); - overflow: auto; - - .ibexa-btn--content-edit { - background-color: $ibexa-color-white; - padding: calculateRem(9px) calculateRem(24px); + display: block; + width: 100%; text-align: left; - box-shadow: 0 calculateRem(2px) calculateRem(4px) 0 rgba($ibexa-color-black, 0.1); - margin-bottom: calculateRem(8px); - - &:hover, - &:focus { - background: $ibexa-color-light; - font-weight: 700; - text-decoration: none; - } } } } diff --git a/src/bundle/Resources/public/scss/mixins/_edit-language-selector.scss b/src/bundle/Resources/public/scss/mixins/_edit-language-selector.scss new file mode 100644 index 0000000000..1d9b14fc3f --- /dev/null +++ b/src/bundle/Resources/public/scss/mixins/_edit-language-selector.scss @@ -0,0 +1,19 @@ +@mixin edit-language-item { + display: block; + margin: 0 0 calculateRem(12px) 0; + padding: calculateRem(8px) calculateRem(16px); + border-radius: calculateRem(8px); + font-size: $ibexa-text-font-size-medium; + color: $ibexa-color-dark; + border: calculateRem(1px) solid $ibexa-color-light; + + &:hover { + border-color: $ibexa-color-primary; + cursor: pointer; + } + + &--active { + background-color: $ibexa-color-light-200; + border-color: $ibexa-color-light-400; + } +} diff --git a/src/bundle/Resources/public/scss/ui/modules/sub-items-list/_language.selector.scss b/src/bundle/Resources/public/scss/ui/modules/sub-items-list/_language.selector.scss index a031328cd0..d9297f37b8 100644 --- a/src/bundle/Resources/public/scss/ui/modules/sub-items-list/_language.selector.scss +++ b/src/bundle/Resources/public/scss/ui/modules/sub-items-list/_language.selector.scss @@ -1,13 +1,12 @@ .c-language-selector { .ibexa-instant-filter { - &__items { - margin-top: calculateRem(5px); - max-height: calc(100vh - #{calculateRem(220px)}); - overflow: auto; - + &__item { .form-check-label { - font-size: $ibexa-text-font-size; - line-height: calculateRem(50px); + @include edit-language-item; + } + + .ibexa-input[type='radio'] { + display: none; } } } diff --git a/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_translation.selector.scss b/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_translation.selector.scss index 866557f336..223d7ad3d2 100644 --- a/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_translation.selector.scss +++ b/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_translation.selector.scss @@ -1,64 +1,7 @@ .c-translation-selector { - position: fixed; - right: 0; - top: 0; - height: 100%; - width: calculateRem(700px); - background-color: $ibexa-color-white; - transform: scaleX(1); - transform-origin: right center; - opacity: 1; - transition: all $ibexa-admin-transition-duration $ibexa-admin-transition; - padding: calculateRem(16px); - z-index: 5; - color: $ibexa-color-dark; - box-shadow: calculateRem(4px) calculateRem(22px) calculateRem(47px) 0 rgba($ibexa-color-info, 0.15); - - &--hidden { - transform: scaleX(0); - opacity: 0; - } - - &__header { - display: flex; - align-items: center; - justify-content: space-between; - padding: calculateRem(4px) calculateRem(8px) calculateRem(24px) calculateRem(16px); - margin-bottom: calculateRem(24px); - border-bottom: calculateRem(1px) solid $ibexa-color-light; - } - - &__title { - margin-bottom: 0; - } - - &__close-button { - padding: calculateRem(8px); - } - - &__languages-wrapper { - max-height: calc(100% - #{calculateRem(50px)}); - overflow: auto; - width: 75%; - padding: calculateRem(16px); - } - - &__language { - background: $ibexa-color-white; - display: flex; - width: 100%; - padding: calculateRem(13px) calculateRem(10px); - border: calculateRem(1px) solid $ibexa-color-light; - border-radius: $ibexa-border-radius; - box-shadow: calculateRem(4px) calculateRem(2px) calculateRem(17px) 0 rgba($ibexa-color-info, 0.05); - transition: all $ibexa-admin-transition-duration $ibexa-admin-transition; - cursor: pointer; - margin-bottom: calculateRem(8px); - - &:hover { - border-color: $ibexa-color-dark; - transform: scale(1.02) translateX(-10px); - box-shadow: calculateRem(4px) calculateRem(10px) calculateRem(17px) 0 rgba($ibexa-color-info, 0.2); + .ibexa-instant-filter { + &__item { + @include edit-language-item; } } } diff --git a/src/bundle/Resources/translations/ibexa_admin_ui.en.xliff b/src/bundle/Resources/translations/ibexa_admin_ui.en.xliff index 8272a323fb..d4701e7130 100644 --- a/src/bundle/Resources/translations/ibexa_admin_ui.en.xliff +++ b/src/bundle/Resources/translations/ibexa_admin_ui.en.xliff @@ -51,10 +51,30 @@ Edit key: edit_translation.edit.title - - Select language - Select language - key: edit_translation.list.title + + Discard + Discard + key: edit_translation.languages.discard + + + Edit + Edit + key: edit_translation.languages.edit + + + Languages + Languages + key: edit_translation.languages.filter.description + + + Search... + Search... + key: edit_translation.languages.filter.placeholder + + + Select translation + Select translation + key: edit_translation.languages.select_language_title Removed '%languageCode%' translation from '%name%'. diff --git a/src/bundle/Resources/translations/ibexa_locationview.en.xliff b/src/bundle/Resources/translations/ibexa_locationview.en.xliff index 244a06bc4c..f966d743f9 100644 --- a/src/bundle/Resources/translations/ibexa_locationview.en.xliff +++ b/src/bundle/Resources/translations/ibexa_locationview.en.xliff @@ -66,6 +66,26 @@ You do not have the '%function%' '%module%' permission for content ID: %contentId% key: dashboard.table.relation.unauthorized + + Discard + Discard + key: edit.languages.discard + + + Edit + Edit + key: edit.languages.edit + + + instant.filter.languages.placeholder + instant.filter.languages.placeholder + key: instant.filter.languages.placeholder + + + Languages + Languages + key: instant.filter.languages.select_language.desc + Add to bookmarks Add to bookmarks diff --git a/src/bundle/Resources/translations/ibexa_sub_items.en.xliff b/src/bundle/Resources/translations/ibexa_sub_items.en.xliff index b1bb4d3c60..5ffb36f68d 100644 --- a/src/bundle/Resources/translations/ibexa_sub_items.en.xliff +++ b/src/bundle/Resources/translations/ibexa_sub_items.en.xliff @@ -181,6 +181,16 @@ The selected location(s) have been revealed. key: bulk_unhide.success.message + + Discard + Discard + key: edit.languages.discard + + + Edit + Edit + key: edit.languages.edit + Edit Edit @@ -191,9 +201,19 @@ Hide key: hide_locations_btn.label + + Search... + Search... + key: instant.filter.languages.placeholder + + + Languages + Languages + key: instant.filter.languages.select_language.desc + - Search by content type - Search by content type + Search... + Search... key: instant.filter.placeholder @@ -282,8 +302,8 @@ key: items_table.row.visible.label - Select language - Select language + Select translation + Select translation key: languages.modal.label diff --git a/src/bundle/Resources/translations/ibexa_universal_discovery_widget.en.xliff b/src/bundle/Resources/translations/ibexa_universal_discovery_widget.en.xliff index 87643b60b2..409a1a880c 100644 --- a/src/bundle/Resources/translations/ibexa_universal_discovery_widget.en.xliff +++ b/src/bundle/Resources/translations/ibexa_universal_discovery_widget.en.xliff @@ -216,11 +216,26 @@ Edit key: meta_preview.edit + + Discard + Discard + key: meta_preview.edit.languages.discard + + + Edit + Edit + key: meta_preview.edit.languages.edit + Select translation Select translation key: meta_preview.edit_translation + + Languages + Languages + key: meta_preview.instant.filter.languages.select_language.desc + Modified Modified diff --git a/src/bundle/Resources/views/themes/admin/content/widget/content_create.html.twig b/src/bundle/Resources/views/themes/admin/content/widget/content_create.html.twig index 1e2ca2fb0d..4075118c31 100644 --- a/src/bundle/Resources/views/themes/admin/content/widget/content_create.html.twig +++ b/src/bundle/Resources/views/themes/admin/content/widget/content_create.html.twig @@ -16,7 +16,7 @@ {% endif %} -
+
{% if form.language.vars.choices|length == 1 %} diff --git a/src/bundle/Resources/views/themes/admin/content/widget/content_edit.html.twig b/src/bundle/Resources/views/themes/admin/content/widget/content_edit.html.twig index 8970f0596d..eca85ead3e 100644 --- a/src/bundle/Resources/views/themes/admin/content/widget/content_edit.html.twig +++ b/src/bundle/Resources/views/themes/admin/content/widget/content_edit.html.twig @@ -1,34 +1,49 @@ {% trans_default_domain 'ibexa_locationview' %} +{% form_theme form '@ibexadesign/content/widget/form_fields.html.twig' %} {% set data_actions = data_actions|default('edit') %} +{% set action = action is defined ? action : path('ibexa.content.edit') %} +{% set checkIsPreventShow = form.language.vars.choices|length == 1 %} -
-
-

{{ 'content.edit.select_language'|trans|desc('Select translation') }} ({{ form.language.vars.choices|length }})

- -
-
- {% set action = action is defined ? action : path('ibexa.content.edit') %} +{% embed '@ibexadesign/ui/component/edit_content_translation_select.html.twig' with { + title: 'content.edit.select_language'|trans|desc('Select translation'), + hasSearch: form.language.vars.choices|length >= 10, + filter_placeholder: 'instant.filter.languages.placeholder'|trans|desc('Search...'), + filter_description: 'instant.filter.languages.select_language.desc'|trans|desc('Languages'), + extra_class: checkIsPreventShow ? 'ibexa-extra-actions--prevent-show', + data_attr: { + 'data-actions': data_actions + }, +} %} + {% block before_body %} {{ form_start(form, { 'action': action }) }} + {% endblock %} + + {% block content_items %} + {{ form_widget(form.language, { 'attr': { 'class': 'ibexa-instant-filter__items' } }) }} + {{ form_widget(form.version_info, { 'attr': { 'hidden': 'hidden' } }) }} {{ form_widget(form.content_info, { 'attr': { 'hidden': 'hidden', 'class': 'ibexa-extra-actions__form-field ibexa-extra-actions__form-field--content-info' } }) }} - {{ form_widget(form.version_info, { 'attr': { - 'hidden': 'hidden', - 'class': 'ibexa-extra-actions__form-field' - } }) }} - {{ form_widget(form.language, { 'attr': { - 'class': 'ibexa-extra-actions__form-values' - } }) }} {{ form_widget(form.location, { 'attr': { 'hidden': 'hidden', 'class': 'ibexa-extra-actions__form-field ibexa-extra-actions__form-field--location' } }) }} + {% endblock %} + + {% block footer_items %} + {% trans_default_domain 'ibexa_locationview' %} + + + + {% endblock %} + + {% block after_body %} {{ form_end(form) }} -
-
+ {% endblock %} +{% endembed %} diff --git a/src/bundle/Resources/views/themes/admin/content/widget/form_fields.html.twig b/src/bundle/Resources/views/themes/admin/content/widget/form_fields.html.twig new file mode 100644 index 0000000000..d510639caf --- /dev/null +++ b/src/bundle/Resources/views/themes/admin/content/widget/form_fields.html.twig @@ -0,0 +1,11 @@ +{% extends '@ibexadesign/content/form_fields.html.twig' %} + +{% block _content_edit_language_entry_widget %} +
+ {{ form_widget(form) }} +
+{% endblock %} + +{% block _content_edit_language_widget %} + {{ form_widget(form, { 'attr': { 'class': 'ibexa-instant-filter__items' } }) }} +{% endblock %} diff --git a/src/bundle/Resources/views/themes/admin/ui/component/edit_content_translation_select.html.twig b/src/bundle/Resources/views/themes/admin/ui/component/edit_content_translation_select.html.twig new file mode 100644 index 0000000000..76fe11ccd5 --- /dev/null +++ b/src/bundle/Resources/views/themes/admin/ui/component/edit_content_translation_select.html.twig @@ -0,0 +1,57 @@ +{% import '@ibexadesign/ui/component/macros.html.twig' as html %} + +{% set title = title|default('') %} +{% set filter_placeholder = filter_placeholder|default('') %} +{% set filter_description = filter_description|default('') %} +{% set hasSearch = hasSearch|default(true) %} +{% set extra_class = extra_class|default('') %} +{% set container_attr = { + class: ('ibexa-extra-actions ibexa-extra-actions--edit ibexa-extra-actions--hidden ' + ~ (hasSearch ? 'ibexa-extra-actions--has-search ') + ~ extra_class), + }|merge(data_attr|default({})) %} + +
+ {% block before_body %} + {% endblock %} + + {% block header %} + {% if title %} +
+

{{ title }}

+
+ {% endif %} + {% endblock %} + + {% block content %} +
+
+
+ +
+ {% if filter_description %} +
+ {{ filter_description }} +
+ {% endif %} + + {% block content_items %} + {% endblock %} +
+
+ {% endblock %} + + {% block footer %} +
+ {% block footer_items %}{% endblock %} +
+ {% endblock %} + + {% block after_body %} + {% endblock %} +
\ No newline at end of file diff --git a/src/bundle/Resources/views/themes/admin/ui/edit_translation_button.html.twig b/src/bundle/Resources/views/themes/admin/ui/edit_translation_button.html.twig index 0ef5372791..1a9422e5d2 100644 --- a/src/bundle/Resources/views/themes/admin/ui/edit_translation_button.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/edit_translation_button.html.twig @@ -17,6 +17,7 @@ {% else %} {% set top_offset = top_offset is defined ? top_offset : 72 %} +
-
-
{{ 'edit_translation.list.title'|trans|desc('Select language') }}:
-
- {% for language in translations %} - - {% endfor %} -
-
+ + {% embed '@ibexadesign/ui/component/edit_content_translation_select.html.twig' with { + title: 'edit_translation.languages.select_language_title'|trans|desc('Select translation'), + hasSearch: translations|length >= 10, + filter_placeholder: 'edit_translation.languages.filter.placeholder'|trans|desc('Search...'), + filter_description: 'edit_translation.languages.filter.description'|trans|desc('Languages'), + data_attr: { + 'data-top-offset': top_offset + }, + } %} + {% block content_items %} +
+ {% for language in translations %} +
+ +
+ {% endfor %} +
+ {% endblock %} + + {% block footer_items %} + {% trans_default_domain 'ibexa_admin_ui' %} + + + + {% endblock %} + {% endembed %}
{% endif %} diff --git a/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/instant.filter.component.js b/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/instant.filter.component.js index ad24b79442..744e4d1408 100644 --- a/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/instant.filter.component.js +++ b/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/instant.filter.component.js @@ -1,14 +1,20 @@ import React, { useEffect, useState, useRef } from 'react'; import PropTypes from 'prop-types'; -const { Translator } = window; +import { getTranslator } from '@ibexa-admin-ui/src/bundle/Resources/public/js/scripts/helpers/context.helper'; +import { createCssClassNames } from '@ibexa-admin-ui-modules/common/helpers/css.class.names'; const FILTER_TIMEOUT = 200; const InstantFilter = (props) => { + const Translator = getTranslator(); const _refInstantFilter = useRef(null); const [filterQuery, setFilterQuery] = useState(''); const [itemsMap, setItemsMap] = useState([]); + const searchInputWrapperClassName = createCssClassNames({ + 'ibexa-instant-filter__input-wrapper': true, + 'ibexa-instant-filter__input-wrapper--hidden': !props.hasSearchEnabled, + }); let filterTimeout = null; useEffect(() => { @@ -39,18 +45,26 @@ const InstantFilter = (props) => { return (
-
+
setFilterQuery(event.target.value)} />
+
+ {Translator.trans(/*@Desc("Languages")*/ 'instant.filter.languages.select_language.desc', {}, 'ibexa_sub_items')} +
{props.items.map((item) => { const radioId = `item_${item.value}`; + const labelClassName = createCssClassNames({ + 'form-check-label': true, + 'ibexa-label': true, + 'ibexa-label--active': props.activeLanguage === item.value, + }); return (
@@ -59,11 +73,12 @@ const InstantFilter = (props) => { type="radio" id={radioId} name="items" - className="form-check-input" + className="form-check-input ibexa-input" value={item.value} + checked={props.activeLanguage === item.value} onChange={() => props.handleItemChange(item.value)} /> -
@@ -76,11 +91,15 @@ const InstantFilter = (props) => { }; InstantFilter.propTypes = { + hasSearchEnabled: PropTypes.bool, + activeLanguage: PropTypes.string, items: PropTypes.array, handleItemChange: PropTypes.func, }; InstantFilter.defaultProps = { + hasSearchEnabled: true, + activeLanguage: '', items: [], handleItemChange: () => {}, }; diff --git a/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/language.selector.compoment.js b/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/language.selector.compoment.js index b68d1efc0b..8c180329dd 100644 --- a/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/language.selector.compoment.js +++ b/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/language.selector.compoment.js @@ -1,35 +1,80 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useRef, useState } from 'react'; import PropTypes from 'prop-types'; +import { getTranslator } from '@ibexa-admin-ui/src/bundle/Resources/public/js/scripts/helpers/context.helper'; + import { createCssClassNames } from '../../../common/helpers/css.class.names'; import InstantFilter from '../sub-items-list/instant.filter.component'; +const MIN_ITEMS_WITH_SEARCH = 10; + const LanguageSelector = (props) => { + const Translator = getTranslator(); + const discardBtnRef = useRef(null); + const submitBtnRef = useRef(null); + const [activeLanguage, setActiveLanguage] = useState(''); + const hasSearchEnabled = props.languageItems.length >= MIN_ITEMS_WITH_SEARCH; const className = createCssClassNames({ - 'ibexa-extra-actions': true, 'c-language-selector': true, + 'ibexa-extra-actions': true, 'ibexa-extra-actions--edit': true, 'ibexa-extra-actions--hidden': !props.isOpen, + 'ibexa-extra-actions--has-search': hasSearchEnabled, }); const closeLanguageSelector = (event) => { if (!event.target.closest('.c-table-view-item__btn') && !event.target.classList.contains('ibexa-instant-filter__input')) { props.close(); + resetLanguageSelector(); } }; + const dispatchSubmitFormEvent = () => { + document.body.dispatchEvent(new CustomEvent('ibexa-sub-items:submit-version-edit-form')); + }; + const handleItemChange = (value) => { + props.handleItemChange(value); + setActiveLanguage(value); + }; + const resetLanguageSelector = () => { + setActiveLanguage(''); + }; useEffect(() => { - window.document.addEventListener('click', closeLanguageSelector, false); + discardBtnRef.current?.addEventListener('click', closeLanguageSelector, false); + submitBtnRef.current?.addEventListener('click', dispatchSubmitFormEvent, false); + document.body.addEventListener('ibexa:edit-content-reset-language-selector', resetLanguageSelector, false); return () => { - window.document.removeEventListener('click', closeLanguageSelector); + discardBtnRef.current?.removeEventListener('click', closeLanguageSelector); + submitBtnRef.current?.removeEventListener('click', dispatchSubmitFormEvent); + document.body.removeEventListener('ibexa:edit-content-reset-language-selector', resetLanguageSelector); }; }, []); return (
-
{props.label}
+
+

{props.label}

+
- + +
+
+ +
); diff --git a/src/bundle/ui-dev/src/modules/sub-items/components/table-view/table.view.item.component.js b/src/bundle/ui-dev/src/modules/sub-items/components/table-view/table.view.item.component.js index 15a078a69d..0150bd8a02 100644 --- a/src/bundle/ui-dev/src/modules/sub-items/components/table-view/table.view.item.component.js +++ b/src/bundle/ui-dev/src/modules/sub-items/components/table-view/table.view.item.component.js @@ -391,15 +391,15 @@ export default class TableViewItemComponent extends PureComponent { getLanguageSelectorData() { const languages = this.props.languages.mappings; const { languageCodes } = this.props.item.content._info.currentVersion; - const label = Translator.trans(/*@Desc("Select language")*/ 'languages.modal.label', {}, 'ibexa_sub_items'); + const label = Translator.trans(/*@Desc("Select translation")*/ 'languages.modal.label', {}, 'ibexa_sub_items'); const languageItems = languageCodes.map((item) => ({ label: languages[item].name, value: item, })); return { + label, languageItems, - label: `${label} (${languageItems.length})`, handleItemChange: this.editItem, }; } diff --git a/src/bundle/ui-dev/src/modules/universal-discovery/components/content-create-widget/content.create.widget.js b/src/bundle/ui-dev/src/modules/universal-discovery/components/content-create-widget/content.create.widget.js index 02d91e9ae6..c1a8e04eac 100644 --- a/src/bundle/ui-dev/src/modules/universal-discovery/components/content-create-widget/content.create.widget.js +++ b/src/bundle/ui-dev/src/modules/universal-discovery/components/content-create-widget/content.create.widget.js @@ -182,7 +182,7 @@ const ContentCreateWidget = () => {

{createContentLabel}

{createUnderLabel}
-
+
{ const Translator = getTranslator(); const adminUiConfig = getAdminUiConfig(); + const _refInstantFilter = useRef(null); + const [filterQuery, setFilterQuery] = useState(''); + const [itemsMap, setItemsMap] = useState([]); + const [activeLanguage, setActiveLanguage] = useState(''); const languageCodes = version ? version.VersionInfo.languageCodes.split(',') : []; + const hasSearchEnabled = languageCodes.length >= MIN_ITEMS_WITH_SEARCH; const editTranslationLabel = Translator.trans( /*@Desc("Select translation")*/ 'meta_preview.edit_translation', {}, 'ibexa_universal_discovery_widget', ); + const resetLanguageSelector = () => { + setFilterQuery(''); + setActiveLanguage(''); + }; + + let filterTimeout = null; + + useEffect(() => { + const items = [..._refInstantFilter.current.querySelectorAll('.ibexa-instant-filter__item')]; + const itemsMapNext = items.map((item) => ({ + label: item.textContent.toLowerCase(), + element: item, + })); + + setItemsMap(itemsMapNext); + }, []); + + useEffect(() => { + const filterQueryLowerCase = filterQuery.toLowerCase(); + + filterTimeout = window.setTimeout(() => { + itemsMap.forEach((item) => { + const methodName = item.label.includes(filterQueryLowerCase) ? 'removeAttribute' : 'setAttribute'; + + item.element[methodName]('hidden', true); + }); + }, FILTER_TIMEOUT); + + return () => { + window.clearTimeout(filterTimeout); + }; + }, [filterQuery]); + + useEffect(() => { + if (!isOpen) { + resetLanguageSelector(); + } + }, [isOpen]); + const className = createCssClassNames({ 'c-translation-selector': true, - 'c-translation-selector--hidden': !isOpen, + 'ibexa-extra-actions': true, + 'ibexa-extra-actions--edit': true, + 'ibexa-extra-actions--full-height': true, + 'ibexa-extra-actions--hidden': !isOpen, + 'ibexa-extra-actions--has-search': hasSearchEnabled, + }); + const searchInputWrapperClassName = createCssClassNames({ + 'ibexa-instant-filter__input-wrapper': true, + 'ibexa-instant-filter__input-wrapper--hidden': !hasSearchEnabled, }); + const renderLanguages = () => { + return languageCodes.map((languageCode) => { + const languageNodeClassName = createCssClassNames({ + 'ibexa-instant-filter__item': true, + 'ibexa-instant-filter__item--active': activeLanguage === languageCode, + }); + + return ( +
setActiveLanguage(languageCode)}> + {adminUiConfig.languages.mappings[languageCode].name} +
+ ); + }); + }; return (
-
-

{`${editTranslationLabel} (${languageCodes.length})`}

- +
+

{editTranslationLabel}

-
- {languageCodes.map((languageCode) => ( -
- {adminUiConfig.languages.mappings[languageCode].name} +
+
+
+ setFilterQuery(event.target.value)} + />
- ))} +
+ {Translator.trans( + /*@Desc("Languages")*/ 'meta_preview.instant.filter.languages.select_language.desc', + {}, + 'ibexa_universal_discovery_widget', + )} +
+
{renderLanguages()}
+
+
+
+ +
); From 9c8a83bb3227eecdfbe3e229923fd176b03dd795 Mon Sep 17 00:00:00 2001 From: tomaszszopinski Date: Fri, 8 Aug 2025 15:56:33 +0200 Subject: [PATCH 2/5] added dependencies.json --- dependencies.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 dependencies.json diff --git a/dependencies.json b/dependencies.json new file mode 100644 index 0000000000..cf3a870fb1 --- /dev/null +++ b/dependencies.json @@ -0,0 +1,11 @@ +{ + "recipesEndpoint": "", + "packages": [ + { + "requirement": "dev-increased-mink-session-width as 4.6.x-dev", + "repositoryUrl": "https://github.com/ibexa/behat", + "package": "ibexa/behat", + "shouldBeAddedAsVCS": false + } + ] +} \ No newline at end of file From 4351dcfca1b63ac9dc958c9f1b248748c68b96cd Mon Sep 17 00:00:00 2001 From: Lukasz Ostafin Date: Tue, 12 Aug 2025 13:11:36 +0200 Subject: [PATCH 3/5] Fixed behat test --- dependencies.json | 11 ----------- .../public/js/scripts/admin.location.view.js | 7 ++++++- .../public/js/scripts/sidebar/btn/content.edit.js | 8 +++++++- .../public/js/scripts/sidebar/btn/location.edit.js | 9 +++++++-- .../public/js/scripts/sidebar/btn/user.edit.js | 8 +++++++- .../themes/admin/content/widget/form_fields.html.twig | 10 +++++++++- .../table-view/table.view.item.component.js | 8 +++++++- 7 files changed, 43 insertions(+), 18 deletions(-) delete mode 100644 dependencies.json diff --git a/dependencies.json b/dependencies.json deleted file mode 100644 index cf3a870fb1..0000000000 --- a/dependencies.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "recipesEndpoint": "", - "packages": [ - { - "requirement": "dev-increased-mink-session-width as 4.6.x-dev", - "repositoryUrl": "https://github.com/ibexa/behat", - "package": "ibexa/behat", - "shouldBeAddedAsVCS": false - } - ] -} \ No newline at end of file diff --git a/src/bundle/Resources/public/js/scripts/admin.location.view.js b/src/bundle/Resources/public/js/scripts/admin.location.view.js index 6438d9f667..9a6c8674fd 100644 --- a/src/bundle/Resources/public/js/scripts/admin.location.view.js +++ b/src/bundle/Resources/public/js/scripts/admin.location.view.js @@ -8,7 +8,7 @@ const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const publishedContentId = urlParams.get('publishedContentId'); - const handleEditItem = (content, location) => { + const handleEditItem = (content, location, isLanguageSelectorOpened) => { const contentId = content._id; const locationId = location._id; const languageCode = content.mainLanguageCode; @@ -75,6 +75,10 @@ response.text().then(showModal); } else if (response.status === 200) { updateForm(); + + if (!isLanguageSelectorOpened) { + doc.querySelector('#form_subitems_content_edit_create').click(); + } } }) .catch(ibexa.helpers.notification.showErrorNotification); @@ -87,6 +91,7 @@ modalTableTitleNode.setAttribute('title', title); modalTableTitleNode.dataset.originalTitle = title; }; + const setModalTableBody = (failedItemsData) => { const modal = doc.querySelector(SELECTOR_MODAL_BULK_ACTION_FAIL); const table = modal.querySelector('.ibexa-bulk-action-failed-modal__table'); diff --git a/src/bundle/Resources/public/js/scripts/sidebar/btn/content.edit.js b/src/bundle/Resources/public/js/scripts/sidebar/btn/content.edit.js index ebf7026dc4..494613836f 100644 --- a/src/bundle/Resources/public/js/scripts/sidebar/btn/content.edit.js +++ b/src/bundle/Resources/public/js/scripts/sidebar/btn/content.edit.js @@ -12,7 +12,13 @@ 'click', () => { languageRadioOption.checked = true; - languageRadioOption.dispatchEvent(new CustomEvent('change')); + languageRadioOption.dispatchEvent( + new CustomEvent('change', { + detail: { + sendImmediately: true, + }, + }), + ); }, false, ); diff --git a/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js b/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js index 4c910ae8d5..00195885f6 100644 --- a/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js +++ b/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js @@ -46,6 +46,7 @@ attachModalListeners(wrapper, form, btns); }; const changeHandler = (form, btns, event) => { + const sendImmediately = event?.detail?.sendImmediately; const contentIdInput = form.querySelector('.ibexa-extra-actions__form-field--content-info'); const locationInput = form.querySelector('.ibexa-extra-actions__form-field--location'); const contentId = contentIdInput.value; @@ -53,7 +54,7 @@ const checkedBtn = event.currentTarget; const languageCode = checkedBtn.value; const checkVersionDraftLink = Routing.generate('ibexa.version_draft.has_no_conflict', { contentId, languageCode, locationId }); - const activeLanguageItem = event.target.closest('.ibexa-instant-filter__group-item').querySelector('.ibexa-label'); + const activeLanguageItem = event.target.closest('.ibexa-instant-filter__group-item')?.querySelector('.ibexa-label'); const allLanguageItems = form.querySelectorAll('.ibexa-instant-filter__group-item .ibexa-label'); const submitBtn = form.querySelector('.ibexa-extra-actions__confirm-btn'); @@ -75,10 +76,14 @@ return; } + + if (sendImmediately) { + form.submit(); + } } submitBtn.disabled = false; - activeLanguageItem.classList.add('ibexa-label--active'); + activeLanguageItem?.classList.add('ibexa-label--active'); }); }; const attachEventsToEditActionsWidget = (container) => { diff --git a/src/bundle/Resources/public/js/scripts/sidebar/btn/user.edit.js b/src/bundle/Resources/public/js/scripts/sidebar/btn/user.edit.js index b4cb65d27a..d2a8204ced 100644 --- a/src/bundle/Resources/public/js/scripts/sidebar/btn/user.edit.js +++ b/src/bundle/Resources/public/js/scripts/sidebar/btn/user.edit.js @@ -11,7 +11,13 @@ 'click', () => { languageRadioOption.checked = true; - languageRadioOption.dispatchEvent(new CustomEvent('change')); + languageRadioOption.dispatchEvent( + new CustomEvent('change', { + detail: { + sendImmediately: true, + }, + }), + ); }, false, ); diff --git a/src/bundle/Resources/views/themes/admin/content/widget/form_fields.html.twig b/src/bundle/Resources/views/themes/admin/content/widget/form_fields.html.twig index d510639caf..e09eaadc87 100644 --- a/src/bundle/Resources/views/themes/admin/content/widget/form_fields.html.twig +++ b/src/bundle/Resources/views/themes/admin/content/widget/form_fields.html.twig @@ -1,11 +1,19 @@ {% extends '@ibexadesign/content/form_fields.html.twig' %} -{% block _content_edit_language_entry_widget %} +{% block language_entry %}
{{ form_widget(form) }}
{% endblock %} +{% block _content_tree_content_edit_language_entry_widget %} + {{ block('language_entry') }} +{% endblock %} + +{% block _content_edit_language_entry_widget %} + {{ block('language_entry') }} +{% endblock %} + {% block _content_edit_language_widget %} {{ form_widget(form, { 'attr': { 'class': 'ibexa-instant-filter__items' } }) }} {% endblock %} diff --git a/src/bundle/ui-dev/src/modules/sub-items/components/table-view/table.view.item.component.js b/src/bundle/ui-dev/src/modules/sub-items/components/table-view/table.view.item.component.js index 0150bd8a02..266e8bcdb0 100644 --- a/src/bundle/ui-dev/src/modules/sub-items/components/table-view/table.view.item.component.js +++ b/src/bundle/ui-dev/src/modules/sub-items/components/table-view/table.view.item.component.js @@ -27,6 +27,7 @@ export default class TableViewItemComponent extends PureComponent { priorityValue: props.item.priority, priorityInputEnabled: false, startingPriorityValue: props.item.priority, + isLanguageSelectorOpened: false, }; this.columnsRenderers = { @@ -118,6 +119,7 @@ export default class TableViewItemComponent extends PureComponent { */ editItem(languageCode) { const { id, currentVersion } = this.props.item.content._info; + const { isLanguageSelectorOpened } = this.state; this.props.handleEditItem( { @@ -132,6 +134,7 @@ export default class TableViewItemComponent extends PureComponent { }, }, this.props.item.id, + isLanguageSelectorOpened, ); } @@ -145,11 +148,14 @@ export default class TableViewItemComponent extends PureComponent { const { mainLanguageCode, currentVersion } = this.props.item.content._info; const { languageCodes } = currentVersion; + this.setState(() => ({ isLanguageSelectorOpened: false })); + if (languageCodes.length > 1) { this.props.setLanguageSelectorData(this.getLanguageSelectorData()); this.props.openLanguageSelector(); + this.setState(() => ({ isLanguageSelectorOpened: true })); } else { - this.editItem(mainLanguageCode); + this.editItem(mainLanguageCode, languageCodes); } } From 7c2f972011faaffac9e9135d05ed45977b83dbd2 Mon Sep 17 00:00:00 2001 From: Lukasz Ostafin Date: Tue, 12 Aug 2025 15:13:11 +0200 Subject: [PATCH 4/5] Fixed sonar --- .../ui/modules/universal-discovery/_translation.selector.scss | 3 +++ .../components/translation-selector/translation.selector.js | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_translation.selector.scss b/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_translation.selector.scss index 223d7ad3d2..0382128c61 100644 --- a/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_translation.selector.scss +++ b/src/bundle/Resources/public/scss/ui/modules/universal-discovery/_translation.selector.scss @@ -2,6 +2,9 @@ .ibexa-instant-filter { &__item { @include edit-language-item; + + width: 100%; + text-align: left; } } } diff --git a/src/bundle/ui-dev/src/modules/universal-discovery/components/translation-selector/translation.selector.js b/src/bundle/ui-dev/src/modules/universal-discovery/components/translation-selector/translation.selector.js index 9cc45077b6..4c7029ca7f 100644 --- a/src/bundle/ui-dev/src/modules/universal-discovery/components/translation-selector/translation.selector.js +++ b/src/bundle/ui-dev/src/modules/universal-discovery/components/translation-selector/translation.selector.js @@ -81,9 +81,9 @@ const TranslationSelectorButton = ({ hideTranslationSelector, selectTranslation, }); return ( -
setActiveLanguage(languageCode)}> +
+ ); }); }; From 0a51772d99d1a9aad7b7dda78d10b6d74c6cec4f Mon Sep 17 00:00:00 2001 From: Lukasz Ostafin Date: Wed, 13 Aug 2025 12:43:38 +0200 Subject: [PATCH 5/5] After CR --- .../public/js/scripts/admin.location.view.js | 22 +++++--- .../js/scripts/sidebar/btn/location.edit.js | 2 +- .../translations/ibexa_locationview.en.xliff | 4 +- .../translations/ibexa_sub_items.en.xliff | 5 -- .../ibexa_universal_discovery_widget.en.xliff | 5 ++ .../content/widget/content_edit.html.twig | 6 +- .../edit_content_translation_select.html.twig | 17 +++--- .../ui/edit_translation_button.html.twig | 2 +- .../instant.filter.component.js | 48 +++++----------- .../language.selector.compoment.js | 6 +- .../translation.selector.js | 56 ++++++++----------- 11 files changed, 74 insertions(+), 99 deletions(-) diff --git a/src/bundle/Resources/public/js/scripts/admin.location.view.js b/src/bundle/Resources/public/js/scripts/admin.location.view.js index 9a6c8674fd..cf55e9624b 100644 --- a/src/bundle/Resources/public/js/scripts/admin.location.view.js +++ b/src/bundle/Resources/public/js/scripts/admin.location.view.js @@ -8,18 +8,22 @@ const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const publishedContentId = urlParams.get('publishedContentId'); + const sendForm = () => { + doc.querySelector('#form_subitems_content_edit_create').click(); + }; + const updateForm = (contentId, languageCode) => { + doc.querySelector('#form_subitems_content_edit_content_info').value = contentId; + doc.querySelector(`#form_subitems_content_edit_language_${languageCode}`).checked = true; + }; const handleEditItem = (content, location, isLanguageSelectorOpened) => { const contentId = content._id; const locationId = location._id; const languageCode = content.mainLanguageCode; const checkVersionDraftLink = Routing.generate('ibexa.version_draft.has_no_conflict', { contentId, languageCode, locationId }); - const updateForm = () => { - doc.querySelector('#form_subitems_content_edit_content_info').value = contentId; - doc.querySelector(`#form_subitems_content_edit_language_${languageCode}`).checked = true; - }; + const addDraft = () => { - updateForm(); - doc.querySelector('#form_subitems_content_edit_create').click(); + updateForm(contentId, languageCode); + sendForm(); bootstrap.Modal.getOrCreateInstance(doc.querySelector('#version-draft-conflict-modal')).hide(); }; const attachModalListeners = (wrapper) => { @@ -74,10 +78,10 @@ if (response.status === 409) { response.text().then(showModal); } else if (response.status === 200) { - updateForm(); + updateForm(contentId, languageCode); if (!isLanguageSelectorOpened) { - doc.querySelector('#form_subitems_content_edit_create').click(); + sendForm(); } } }) @@ -205,7 +209,7 @@ doc.body.addEventListener( 'ibexa-sub-items:submit-version-edit-form', () => { - doc.querySelector('#form_subitems_content_edit_create').click(); + sendForm(); }, false, ); diff --git a/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js b/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js index 00195885f6..5b8d3029e8 100644 --- a/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js +++ b/src/bundle/Resources/public/js/scripts/sidebar/btn/location.edit.js @@ -46,7 +46,7 @@ attachModalListeners(wrapper, form, btns); }; const changeHandler = (form, btns, event) => { - const sendImmediately = event?.detail?.sendImmediately; + const sendImmediately = event?.detail?.sendImmediately ?? false; const contentIdInput = form.querySelector('.ibexa-extra-actions__form-field--content-info'); const locationInput = form.querySelector('.ibexa-extra-actions__form-field--location'); const contentId = contentIdInput.value; diff --git a/src/bundle/Resources/translations/ibexa_locationview.en.xliff b/src/bundle/Resources/translations/ibexa_locationview.en.xliff index f966d743f9..a6bf9ab341 100644 --- a/src/bundle/Resources/translations/ibexa_locationview.en.xliff +++ b/src/bundle/Resources/translations/ibexa_locationview.en.xliff @@ -77,8 +77,8 @@ key: edit.languages.edit - instant.filter.languages.placeholder - instant.filter.languages.placeholder + Search... + Search... key: instant.filter.languages.placeholder diff --git a/src/bundle/Resources/translations/ibexa_sub_items.en.xliff b/src/bundle/Resources/translations/ibexa_sub_items.en.xliff index 5ffb36f68d..570f1bbde4 100644 --- a/src/bundle/Resources/translations/ibexa_sub_items.en.xliff +++ b/src/bundle/Resources/translations/ibexa_sub_items.en.xliff @@ -201,11 +201,6 @@ Hide key: hide_locations_btn.label - - Search... - Search... - key: instant.filter.languages.placeholder - Languages Languages diff --git a/src/bundle/Resources/translations/ibexa_universal_discovery_widget.en.xliff b/src/bundle/Resources/translations/ibexa_universal_discovery_widget.en.xliff index 409a1a880c..7d6670aa57 100644 --- a/src/bundle/Resources/translations/ibexa_universal_discovery_widget.en.xliff +++ b/src/bundle/Resources/translations/ibexa_universal_discovery_widget.en.xliff @@ -191,6 +191,11 @@ Items already added to the list are marked as selected and unable to deselect. key: init_selected_locations.alert.title + + Search... + Search... + key: instant.filter.languages.placeholder + Could not fetch content names Could not fetch content names diff --git a/src/bundle/Resources/views/themes/admin/content/widget/content_edit.html.twig b/src/bundle/Resources/views/themes/admin/content/widget/content_edit.html.twig index eca85ead3e..7925bdb0e7 100644 --- a/src/bundle/Resources/views/themes/admin/content/widget/content_edit.html.twig +++ b/src/bundle/Resources/views/themes/admin/content/widget/content_edit.html.twig @@ -3,14 +3,14 @@ {% set data_actions = data_actions|default('edit') %} {% set action = action is defined ? action : path('ibexa.content.edit') %} -{% set checkIsPreventShow = form.language.vars.choices|length == 1 %} +{% set check_is_prevent_show = form.language.vars.choices|length == 1 %} {% embed '@ibexadesign/ui/component/edit_content_translation_select.html.twig' with { title: 'content.edit.select_language'|trans|desc('Select translation'), - hasSearch: form.language.vars.choices|length >= 10, + has_search: form.language.vars.choices|length >= 10, filter_placeholder: 'instant.filter.languages.placeholder'|trans|desc('Search...'), filter_description: 'instant.filter.languages.select_language.desc'|trans|desc('Languages'), - extra_class: checkIsPreventShow ? 'ibexa-extra-actions--prevent-show', + extra_class: check_is_prevent_show ? 'ibexa-extra-actions--prevent-show', data_attr: { 'data-actions': data_actions }, diff --git a/src/bundle/Resources/views/themes/admin/ui/component/edit_content_translation_select.html.twig b/src/bundle/Resources/views/themes/admin/ui/component/edit_content_translation_select.html.twig index 76fe11ccd5..461b592bc0 100644 --- a/src/bundle/Resources/views/themes/admin/ui/component/edit_content_translation_select.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/component/edit_content_translation_select.html.twig @@ -3,17 +3,16 @@ {% set title = title|default('') %} {% set filter_placeholder = filter_placeholder|default('') %} {% set filter_description = filter_description|default('') %} -{% set hasSearch = hasSearch|default(true) %} {% set extra_class = extra_class|default('') %} + {% set container_attr = { class: ('ibexa-extra-actions ibexa-extra-actions--edit ibexa-extra-actions--hidden ' - ~ (hasSearch ? 'ibexa-extra-actions--has-search ') + ~ (has_search ? 'ibexa-extra-actions--has-search ') ~ extra_class), }|merge(data_attr|default({})) %}
- {% block before_body %} - {% endblock %} + {% block before_body %}{% endblock %} {% block header %} {% if title %} @@ -26,7 +25,7 @@ {% block content %}
-
+
{% endblock %} @@ -52,6 +50,5 @@
{% endblock %} - {% block after_body %} - {% endblock %} -
\ No newline at end of file + {% block after_body %}{% endblock %} +
diff --git a/src/bundle/Resources/views/themes/admin/ui/edit_translation_button.html.twig b/src/bundle/Resources/views/themes/admin/ui/edit_translation_button.html.twig index 1a9422e5d2..53a2e5ff66 100644 --- a/src/bundle/Resources/views/themes/admin/ui/edit_translation_button.html.twig +++ b/src/bundle/Resources/views/themes/admin/ui/edit_translation_button.html.twig @@ -31,7 +31,7 @@ {% embed '@ibexadesign/ui/component/edit_content_translation_select.html.twig' with { title: 'edit_translation.languages.select_language_title'|trans|desc('Select translation'), - hasSearch: translations|length >= 10, + has_search: translations|length >= 10, filter_placeholder: 'edit_translation.languages.filter.placeholder'|trans|desc('Search...'), filter_description: 'edit_translation.languages.filter.description'|trans|desc('Languages'), data_attr: { diff --git a/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/instant.filter.component.js b/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/instant.filter.component.js index 744e4d1408..8e699ab11e 100644 --- a/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/instant.filter.component.js +++ b/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/instant.filter.component.js @@ -1,50 +1,32 @@ -import React, { useEffect, useState, useRef } from 'react'; +import React, { useState, useMemo } from 'react'; import PropTypes from 'prop-types'; import { getTranslator } from '@ibexa-admin-ui/src/bundle/Resources/public/js/scripts/helpers/context.helper'; import { createCssClassNames } from '@ibexa-admin-ui-modules/common/helpers/css.class.names'; -const FILTER_TIMEOUT = 200; - const InstantFilter = (props) => { const Translator = getTranslator(); - const _refInstantFilter = useRef(null); const [filterQuery, setFilterQuery] = useState(''); - const [itemsMap, setItemsMap] = useState([]); const searchInputWrapperClassName = createCssClassNames({ 'ibexa-instant-filter__input-wrapper': true, - 'ibexa-instant-filter__input-wrapper--hidden': !props.hasSearchEnabled, + 'ibexa-instant-filter__input-wrapper--hidden': !props.isSearchEnabled, }); - let filterTimeout = null; - - useEffect(() => { - const items = [..._refInstantFilter.current.querySelectorAll('.ibexa-instant-filter__item')]; - const itemsMapNext = items.map((item) => ({ - label: item.textContent.toLowerCase(), - element: item, - })); + const filteredItems = useMemo(() => { + if (!filterQuery) { + return props.items; + } - setItemsMap(itemsMapNext); - }, [props.items]); - - useEffect(() => { const filterQueryLowerCase = filterQuery.toLowerCase(); - filterTimeout = window.setTimeout(() => { - itemsMap.forEach((item) => { - const methodName = item.label.includes(filterQueryLowerCase) ? 'removeAttribute' : 'setAttribute'; - - item.element[methodName]('hidden', true); - }); - }, FILTER_TIMEOUT); + return props.items.filter((item) => { + const itemLabelLowerCase = item.label.toLowerCase(); - return () => { - window.clearTimeout(filterTimeout); - }; - }, [filterQuery]); + return itemLabelLowerCase.includes(filterQueryLowerCase); + }); + }, [props.items, filterQuery]); return ( -
+
{ {Translator.trans(/*@Desc("Languages")*/ 'instant.filter.languages.select_language.desc', {}, 'ibexa_sub_items')}
- {props.items.map((item) => { + {filteredItems.map((item) => { const radioId = `item_${item.value}`; const labelClassName = createCssClassNames({ 'form-check-label': true, @@ -91,14 +73,14 @@ const InstantFilter = (props) => { }; InstantFilter.propTypes = { - hasSearchEnabled: PropTypes.bool, + isSearchEnabled: PropTypes.bool, activeLanguage: PropTypes.string, items: PropTypes.array, handleItemChange: PropTypes.func, }; InstantFilter.defaultProps = { - hasSearchEnabled: true, + isSearchEnabled: true, activeLanguage: '', items: [], handleItemChange: () => {}, diff --git a/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/language.selector.compoment.js b/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/language.selector.compoment.js index 8c180329dd..c12b45ae35 100644 --- a/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/language.selector.compoment.js +++ b/src/bundle/ui-dev/src/modules/sub-items/components/sub-items-list/language.selector.compoment.js @@ -13,13 +13,13 @@ const LanguageSelector = (props) => { const discardBtnRef = useRef(null); const submitBtnRef = useRef(null); const [activeLanguage, setActiveLanguage] = useState(''); - const hasSearchEnabled = props.languageItems.length >= MIN_ITEMS_WITH_SEARCH; + const isSearchEnabled = props.languageItems.length >= MIN_ITEMS_WITH_SEARCH; const className = createCssClassNames({ 'c-language-selector': true, 'ibexa-extra-actions': true, 'ibexa-extra-actions--edit': true, 'ibexa-extra-actions--hidden': !props.isOpen, - 'ibexa-extra-actions--has-search': hasSearchEnabled, + 'ibexa-extra-actions--has-search': isSearchEnabled, }); const closeLanguageSelector = (event) => { if (!event.target.closest('.c-table-view-item__btn') && !event.target.classList.contains('ibexa-instant-filter__input')) { @@ -60,7 +60,7 @@ const LanguageSelector = (props) => { items={props.languageItems} activeLanguage={activeLanguage} handleItemChange={handleItemChange} - hasSearchEnabled={hasSearchEnabled} + isSearchEnabled={isSearchEnabled} />
diff --git a/src/bundle/ui-dev/src/modules/universal-discovery/components/translation-selector/translation.selector.js b/src/bundle/ui-dev/src/modules/universal-discovery/components/translation-selector/translation.selector.js index 4c7029ca7f..e10a7c2de5 100644 --- a/src/bundle/ui-dev/src/modules/universal-discovery/components/translation-selector/translation.selector.js +++ b/src/bundle/ui-dev/src/modules/universal-discovery/components/translation-selector/translation.selector.js @@ -1,4 +1,4 @@ -import React, { useEffect, useRef, useState } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; import PropTypes from 'prop-types'; import { createCssClassNames } from '../../../common/helpers/css.class.names'; @@ -6,17 +6,14 @@ import { createCssClassNames } from '../../../common/helpers/css.class.names'; import { getAdminUiConfig, getTranslator } from '@ibexa-admin-ui/src/bundle/Resources/public/js/scripts/helpers/context.helper'; const MIN_ITEMS_WITH_SEARCH = 10; -const FILTER_TIMEOUT = 200; const TranslationSelectorButton = ({ hideTranslationSelector, selectTranslation, version, isOpen }) => { const Translator = getTranslator(); const adminUiConfig = getAdminUiConfig(); - const _refInstantFilter = useRef(null); const [filterQuery, setFilterQuery] = useState(''); - const [itemsMap, setItemsMap] = useState([]); const [activeLanguage, setActiveLanguage] = useState(''); const languageCodes = version ? version.VersionInfo.languageCodes.split(',') : []; - const hasSearchEnabled = languageCodes.length >= MIN_ITEMS_WITH_SEARCH; + const isSearchEnabled = languageCodes.length >= MIN_ITEMS_WITH_SEARCH; const editTranslationLabel = Translator.trans( /*@Desc("Select translation")*/ 'meta_preview.edit_translation', {}, @@ -26,33 +23,28 @@ const TranslationSelectorButton = ({ hideTranslationSelector, selectTranslation, setFilterQuery(''); setActiveLanguage(''); }; + const getLanguageName = (languageCode, lowerCase = true) => { + const language = window.ibexa.adminUiConfig.languages.mappings[languageCode]; - let filterTimeout = null; + if (!language) { + return null; + } - useEffect(() => { - const items = [..._refInstantFilter.current.querySelectorAll('.ibexa-instant-filter__item')]; - const itemsMapNext = items.map((item) => ({ - label: item.textContent.toLowerCase(), - element: item, - })); + return lowerCase ? language.name.toLowerCase() : language.name; + }; - setItemsMap(itemsMapNext); - }, []); + const filteredLanguageCodes = useMemo(() => { + if (!filterQuery) { + return languageCodes; + } - useEffect(() => { const filterQueryLowerCase = filterQuery.toLowerCase(); - filterTimeout = window.setTimeout(() => { - itemsMap.forEach((item) => { - const methodName = item.label.includes(filterQueryLowerCase) ? 'removeAttribute' : 'setAttribute'; - - item.element[methodName]('hidden', true); - }); - }, FILTER_TIMEOUT); + return languageCodes.filter((languageCode) => { + const languageNameLowerCase = getLanguageName(languageCode); - return () => { - window.clearTimeout(filterTimeout); - }; + return languageNameLowerCase.includes(filterQueryLowerCase); + }); }, [filterQuery]); useEffect(() => { @@ -61,20 +53,20 @@ const TranslationSelectorButton = ({ hideTranslationSelector, selectTranslation, } }, [isOpen]); - const className = createCssClassNames({ + const containerClassName = createCssClassNames({ 'c-translation-selector': true, 'ibexa-extra-actions': true, 'ibexa-extra-actions--edit': true, 'ibexa-extra-actions--full-height': true, 'ibexa-extra-actions--hidden': !isOpen, - 'ibexa-extra-actions--has-search': hasSearchEnabled, + 'ibexa-extra-actions--has-search': isSearchEnabled, }); const searchInputWrapperClassName = createCssClassNames({ 'ibexa-instant-filter__input-wrapper': true, - 'ibexa-instant-filter__input-wrapper--hidden': !hasSearchEnabled, + 'ibexa-instant-filter__input-wrapper--hidden': !isSearchEnabled, }); const renderLanguages = () => { - return languageCodes.map((languageCode) => { + return filteredLanguageCodes.map((languageCode) => { const languageNodeClassName = createCssClassNames({ 'ibexa-instant-filter__item': true, 'ibexa-instant-filter__item--active': activeLanguage === languageCode, @@ -89,12 +81,12 @@ const TranslationSelectorButton = ({ hideTranslationSelector, selectTranslation, }; return ( -
+

{editTranslationLabel}

-
+
setFilterQuery(event.target.value)}