Merge pull request #6645 from lasniscinote/gl_SCI_9670

Implement a link in the relationships column [SCI-9670]
This commit is contained in:
Martin Artnik 2023-11-28 09:21:33 +01:00 committed by GitHub
commit 3da2e68177
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 91 deletions

View file

@ -6,8 +6,11 @@
$(document).on('click', '.relationships-cell-wrapper', function(e) { $(document).on('click', '.relationships-cell-wrapper', function(e) {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
const relationshipsUrl = $(this).attr('data-relationships-url'); const myModuleId = $('.my-module-content').data('task-id');
window.itemRelationshipsModal.show(relationshipsUrl); // extract the href attribute from a neighboring column cell, required for sidebar to open
const repositoryRowURL = $(this).closest('tr').find('.sorting_1 a').attr('href');
window.repositoryItemSidebarComponent.toggleShowHideSidebar(repositoryRowURL, myModuleId, 'relationships-section');
}); });
$(document).on('click', '.record-info-link', function (e) { $(document).on('click', '.record-info-link', function (e) {
@ -17,7 +20,7 @@
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
window.repositoryItemSidebarComponent.toggleShowHideSidebar(repositoryRowURL, myModuleId); window.repositoryItemSidebarComponent.toggleShowHideSidebar(repositoryRowURL, myModuleId, null);
}); });
$(document).on('click', '.print-label-button', function(e) { $(document).on('click', '.print-label-button', function(e) {

View file

@ -271,9 +271,9 @@
{ id: 'highlight-item-1', textId: 'text-item-1', labelAlias: 'information_label', label: 'information-label', sectionId: 'information-section' }, { id: 'highlight-item-1', textId: 'text-item-1', labelAlias: 'information_label', label: 'information-label', sectionId: 'information-section' },
{ id: 'highlight-item-2', textId: 'text-item-2', labelAlias: 'custom_columns_label', label: 'custom-columns-label', sectionId: 'custom-columns-section' }, { id: 'highlight-item-2', textId: 'text-item-2', labelAlias: 'custom_columns_label', label: 'custom-columns-label', sectionId: 'custom-columns-section' },
{ id: 'highlight-item-3', textId: 'text-item-3', labelAlias: 'relationships_label', label: 'relationships-label', sectionId: 'relationships-section' }, { id: 'highlight-item-3', textId: 'text-item-3', labelAlias: 'relationships_label', label: 'relationships-label', sectionId: 'relationships-section' },
{ id: 'highlight-item-3', textId: 'text-item-3', labelAlias: 'assigned_label', label: 'assigned-label', sectionId: 'assigned-section' }, { id: 'highlight-item-4', textId: 'text-item-4', labelAlias: 'assigned_label', label: 'assigned-label', sectionId: 'assigned-section' },
{ id: 'highlight-item-4', textId: 'text-item-4', labelAlias: 'QR_label', label: 'QR-label', sectionId: 'qr-section' } { id: 'highlight-item-5', textId: 'text-item-5', labelAlias: 'QR_label', label: 'QR-label', sectionId: 'qr-section' }
]" v-show="isShowing"> ]" v-show="isShowing" :initialSectionId="this.initialSectionId">
</scroll-spy> </scroll-spy>
</div> </div>
</div> </div>
@ -300,7 +300,7 @@
import InlineEdit from '../shared/inline_edit.vue'; import InlineEdit from '../shared/inline_edit.vue';
import ScrollSpy from './repository_values/ScrollSpy.vue'; import ScrollSpy from './repository_values/ScrollSpy.vue';
import CustomColumns from './customColumns.vue'; import CustomColumns from './customColumns.vue';
import RepositoryItemSidebarTitle from './Title.vue' import RepositoryItemSidebarTitle from './Title.vue';
export default { export default {
name: 'RepositoryItemSidebar', name: 'RepositoryItemSidebar',
@ -333,7 +333,8 @@ export default {
inRepository: false, inRepository: false,
icons: null, icons: null,
relationshipDetailsState: {}, relationshipDetailsState: {},
} initialSectionId: null,
};
}, },
created() { created() {
window.repositoryItemSidebarComponent = this; window.repositoryItemSidebarComponent = this;
@ -341,19 +342,19 @@ export default {
computed: { computed: {
repositoryRowName() { repositoryRowName() {
return this.defaultColumns?.archived ? `${I18n.t('labels.archived')} ${this.defaultColumns?.name}` : this.defaultColumns?.name; return this.defaultColumns?.archived ? `${I18n.t('labels.archived')} ${this.defaultColumns?.name}` : this.defaultColumns?.name;
} },
}, },
watch: { watch: {
parents() { parents() {
this.parents.forEach(parent => { this.parents.forEach((parent) => {
this.$set(this.relationshipDetailsState, parent.code, false); this.$set(this.relationshipDetailsState, parent.code, false);
}); });
}, },
children() { children() {
this.children.forEach(child => { this.children.forEach((child) => {
this.$set(this.relationshipDetailsState, child.code, false); this.$set(this.relationshipDetailsState, child.code, false);
}); });
} },
}, },
mounted() { mounted() {
// Add a click event listener to the document // Add a click event listener to the document
@ -366,36 +367,37 @@ export default {
}, },
methods: { methods: {
handleOutsideClick(event) { handleOutsideClick(event) {
if (!this.isShowing) return if (!this.isShowing) return;
// Check if the clicked element is not within the sidebar and it's not another item link or belogs to modals // Check if the clicked element is not within the sidebar and it's not another item link or belogs to modals
const selectors = ['a', '.modal', '.label-printing-progress-modal', '.atwho-view']; const selectors = ['a', '.modal', '.label-printing-progress-modal', '.atwho-view'];
if (!$(event.target).parents('#repository-item-sidebar-wrapper').length && if (!$(event.target).parents('#repository-item-sidebar-wrapper').length
!selectors.some(selector => event.target.closest(selector))) { && !selectors.some((selector) => event.target.closest(selector))) {
this.toggleShowHideSidebar(null); this.toggleShowHideSidebar(null);
} }
}, },
toggleShowHideSidebar(repositoryRowUrl, myModuleId = null) { toggleShowHideSidebar(repositoryRowUrl, myModuleId = null, initialSectionId = null) {
if (initialSectionId) {
this.initialSectionId = initialSectionId;
} else this.initialSectionId = null;
// initial click // initial click
if (this.currentItemUrl === null) { if (this.currentItemUrl === null) {
this.myModuleId = myModuleId; this.myModuleId = myModuleId;
this.isShowing = true; this.isShowing = true;
this.loadRepositoryRow(repositoryRowUrl); this.loadRepositoryRow(repositoryRowUrl);
this.currentItemUrl = repositoryRowUrl; this.currentItemUrl = repositoryRowUrl;
return
} }
// click on the same item - should just open/close it // click on the same item - should just open/close it
else if (this.currentItemUrl === repositoryRowUrl) { else if (this.currentItemUrl === repositoryRowUrl) {
this.isShowing = !this.isShowing; this.isShowing = !this.isShowing;
return
} }
// explicit close (from emit) // explicit close (from emit)
else if (repositoryRowUrl === null) { else if (repositoryRowUrl === null) {
this.isShowing = false; this.isShowing = false;
this.currentItemUrl = null; this.currentItemUrl = null;
this.myModuleId = null; this.myModuleId = null;
return
} }
// click on a different item - if the item card is already showing should just fetch new data // click on a different item - if the item card is already showing should just fetch new data
else { else {
@ -403,11 +405,10 @@ export default {
this.myModuleId = myModuleId; this.myModuleId = myModuleId;
this.loadRepositoryRow(repositoryRowUrl); this.loadRepositoryRow(repositoryRowUrl);
this.currentItemUrl = repositoryRowUrl; this.currentItemUrl = repositoryRowUrl;
return
} }
}, },
loadRepositoryRow(repositoryRowUrl) { loadRepositoryRow(repositoryRowUrl) {
this.dataLoading = true this.dataLoading = true;
$.ajax({ $.ajax({
method: 'GET', method: 'GET',
url: repositoryRowUrl, url: repositoryRowUrl,
@ -432,7 +433,7 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.generateBarCode(this.defaultColumns.code); this.generateBarCode(this.defaultColumns.code);
}); });
} },
}); });
}, },
reload() { reload() {
@ -450,7 +451,7 @@ export default {
const barCodeCanvas = bwipjs.toCanvas('bar-code-canvas', { const barCodeCanvas = bwipjs.toCanvas('bar-code-canvas', {
bcid: 'qrcode', bcid: 'qrcode',
text, text,
scale: 3 scale: 3,
}); });
this.barCodeSrc = barCodeCanvas.toDataURL('image/png'); this.barCodeSrc = barCodeCanvas.toDataURL('image/png');
}, },
@ -468,7 +469,7 @@ export default {
}, },
}).done((response) => { }).done((response) => {
if (response) { if (response) {
this.customColumns = this.customColumns.map(col => col.id === response.id ? { ...col, ...response } : col) this.customColumns = this.customColumns.map((col) => (col.id === response.id ? { ...col, ...response } : col));
if ($('.dataTable')[0]) $('.dataTable').DataTable().ajax.reload(null, false); if ($('.dataTable')[0]) $('.dataTable').DataTable().ajax.reload(null, false);
} }
}); });
@ -476,6 +477,6 @@ export default {
updateOpenState(code, isOpen) { updateOpenState(code, isOpen) {
this.$set(this.relationshipDetailsState, code, isOpen); this.$set(this.relationshipDetailsState, code, isOpen);
}, },
} },
} };
</script> </script>

View file

@ -26,6 +26,7 @@ export default {
props: { props: {
itemsToCreate: Array, itemsToCreate: Array,
initialSectionId: String || null,
}, },
data() { data() {
@ -40,23 +41,21 @@ export default {
centerOfScrollThumb: null, centerOfScrollThumb: null,
}; };
}, },
mounted() { mounted() {
console.log('mounted'); console.log('mounted');
window.addEventListener('resize', this.handleResize); window.addEventListener('resize', this.handleResize);
this.initializeComponent(); this.initializeComponent();
this.$nextTick(() => { this.$nextTick(() => {
this.calculateAllSectionsCumulativeHeight() this.calculateAllSectionsCumulativeHeight();
this.calculateSectionsHeight(); this.calculateSectionsHeight();
this.constructThresholds() this.constructThresholds();
this.handleScroll() this.handleScroll();
if (!this.initialSectionId) { if (!this.initialSectionId) {
this.navigateToSection(this.itemsToCreate[0]) this.navigateToSection(this.itemsToCreate[0]);
} } else {
else { const itemToNavigateTo = this.itemsToCreate.find((item) => item.sectionId === this.initialSectionId);
const itemToNavigateTo = this.itemsToCreate.find((item) => item.sectionId === this.initialSectionId) this.navigateToSection(itemToNavigateTo);
this.navigateToSection(itemToNavigateTo)
} }
}); });
}, },
@ -65,12 +64,11 @@ export default {
window.removeEventListener('resize', this.handleResize); window.removeEventListener('resize', this.handleResize);
this.removeScrollListener(); this.removeScrollListener();
}, },
methods: { methods: {
initializeComponent() { initializeComponent() {
const bodyWrapperEl = document.getElementById('body-wrapper') const bodyWrapperEl = document.getElementById('body-wrapper');
const scrollSpyContentEl = document.getElementById('scrollSpyContent') const scrollSpyContentEl = document.getElementById('scrollSpyContent');
this.bodyContainerEl = bodyWrapperEl this.bodyContainerEl = bodyWrapperEl;
this.sections = Array.from(scrollSpyContentEl.querySelectorAll('section[id]')); this.sections = Array.from(scrollSpyContentEl.querySelectorAll('section[id]'));
this.navigationItemsStatus = Array(this.sections.length).fill(false); this.navigationItemsStatus = Array(this.sections.length).fill(false);
this.navigationItemsStatus[0] = true; this.navigationItemsStatus[0] = true;
@ -86,18 +84,18 @@ export default {
}, },
calculateAllSectionsCumulativeHeight() { calculateAllSectionsCumulativeHeight() {
let totalHeight = 0 let totalHeight = 0;
this.itemsToCreate.forEach((item) => { this.itemsToCreate.forEach((item) => {
const sectionEl = document.getElementById(item.sectionId); const sectionEl = document.getElementById(item.sectionId);
totalHeight += sectionEl.offsetHeight totalHeight += sectionEl.offsetHeight;
}) });
this.allSectionsCumulativeHeight = totalHeight this.allSectionsCumulativeHeight = totalHeight;
}, },
calculateSectionsHeight() { calculateSectionsHeight() {
// Initialize an array to store the height data for each section // Initialize an array to store the height data for each section
this.sectionsWithHeight = this.itemsToCreate.map(item => { this.sectionsWithHeight = this.itemsToCreate.map((item) => {
// Find the DOM element for the section // Find the DOM element for the section
const sectionEl = document.getElementById(item.sectionId); const sectionEl = document.getElementById(item.sectionId);
@ -108,8 +106,8 @@ export default {
// Return an object containing the section ID and its percentage height // Return an object containing the section ID and its percentage height
return { return {
sectionId: item.sectionId, sectionId: item.sectionId,
heightPx: heightPx, heightPx,
percentHeight: percentHeight percentHeight,
}; };
}); });
}, },
@ -119,57 +117,55 @@ export default {
// on the % of vertical space of scrollable content that they occupy // on the % of vertical space of scrollable content that they occupy
constructThresholds() { constructThresholds() {
const scrollableArea = this.bodyContainerEl; const scrollableArea = this.bodyContainerEl;
const deltaTravel = scrollableArea.scrollHeight - scrollableArea.clientHeight const deltaTravel = scrollableArea.scrollHeight - scrollableArea.clientHeight;
const viewportHeight = scrollableArea.clientHeight; const viewportHeight = scrollableArea.clientHeight;
const scrollableAreaHeight = scrollableArea.scrollHeight; const scrollableAreaHeight = scrollableArea.scrollHeight;
const scrollThumbHeight = Math.round(viewportHeight / scrollableAreaHeight * viewportHeight); const scrollThumbHeight = Math.round(viewportHeight / scrollableAreaHeight * viewportHeight);
const scrollThumbCenter = Math.round(scrollThumbHeight / 2) const scrollThumbCenter = Math.round(scrollThumbHeight / 2);
this.centerOfScrollThumb = scrollThumbCenter this.centerOfScrollThumb = scrollThumbCenter;
this.scrollPosition = scrollThumbCenter this.scrollPosition = scrollThumbCenter;
let prevThreshold = scrollThumbCenter let prevThreshold = scrollThumbCenter;
for (let i = 0; i < this.sectionsWithHeight.length; i++) { for (let i = 0; i < this.sectionsWithHeight.length; i++) {
// first section // first section
if (i === 0) { if (i === 0) {
const from = prevThreshold const from = prevThreshold;
const to = Math.round(deltaTravel * this.sectionsWithHeight[i].percentHeight / 100) + prevThreshold const to = Math.round(deltaTravel * this.sectionsWithHeight[i].percentHeight / 100) + prevThreshold;
const id = this.sectionsWithHeight[i].sectionId const id = this.sectionsWithHeight[i].sectionId;
prevThreshold = to + 1 prevThreshold = to + 1;
const threshold = { const threshold = {
id, id,
index: i, index: i,
from, from,
to to,
} };
this.thresholds[i] = threshold this.thresholds[i] = threshold;
} } else if (i === this.sectionsWithHeight.length - 1) {
// last section // last section
else if (i === this.sectionsWithHeight.length - 1) { const from = prevThreshold;
const from = prevThreshold const to = scrollableArea.scrollHeight;
const to = scrollableArea.scrollHeight const id = this.sectionsWithHeight[i].sectionId;
const id = this.sectionsWithHeight[i].sectionId
const threshold = { const threshold = {
id, id,
index: i, index: i,
from, from,
to to,
} };
this.thresholds[i] = threshold this.thresholds[i] = threshold;
} } else {
else {
// other sections // other sections
const from = prevThreshold const from = prevThreshold;
const to = Math.round(deltaTravel * this.sectionsWithHeight[i].percentHeight / 100) + prevThreshold - 1 const to = Math.round(deltaTravel * this.sectionsWithHeight[i].percentHeight / 100) + prevThreshold - 1;
const id = this.sectionsWithHeight[i].sectionId const id = this.sectionsWithHeight[i].sectionId;
prevThreshold = to + 1 prevThreshold = to + 1;
const threshold = { const threshold = {
id, id,
index: i, index: i,
from, from,
to to,
} };
this.thresholds[i] = threshold this.thresholds[i] = threshold;
} }
} }
}, },
@ -188,26 +184,24 @@ export default {
this.removeScrollListener(); this.removeScrollListener();
const scrollableArea = this.bodyContainerEl; const scrollableArea = this.bodyContainerEl;
const foundThreshold = this.thresholds.find((obj) => obj.id === navigationItem.sectionId) const foundThreshold = this.thresholds.find((obj) => obj.id === navigationItem.sectionId);
const domElToScrollTo = document.getElementById(navigationItem.label) const domElToScrollTo = document.getElementById(navigationItem.label);
if (foundThreshold.index === 0) { if (foundThreshold.index === 0) {
// scroll to top // scroll to top
this.bodyContainerEl.scrollTo({ this.bodyContainerEl.scrollTo({
top: 0, top: 0,
behavior: "auto" behavior: 'auto',
}); });
} } else if (foundThreshold.index === this.thresholds.length - 1) {
else if (foundThreshold.index === this.thresholds.length - 1) {
// scroll to bottom // scroll to bottom
this.bodyContainerEl.scrollTo({ this.bodyContainerEl.scrollTo({
top: 99999, top: 99999,
behavior: "auto" behavior: 'auto',
}); });
} } else {
else {
// scroll to the start of a section's threshold, adjusted for the center thumb value (true center) // scroll to the start of a section's threshold, adjusted for the center thumb value (true center)
scrollableArea.scrollTop = foundThreshold.from - this.centerOfScrollThumb scrollableArea.scrollTop = foundThreshold.from - this.centerOfScrollThumb;
} }
this.flashTitleColor(domElToScrollTo); this.flashTitleColor(domElToScrollTo);
@ -216,7 +210,7 @@ export default {
}, },
flashTitleColor(domEl) { flashTitleColor(domEl) {
if (!domEl) return if (!domEl) return;
domEl.classList.add('text-sn-science-blue'); domEl.classList.add('text-sn-science-blue');
setTimeout(() => domEl.classList.remove('text-sn-science-blue'), 300); setTimeout(() => domEl.classList.remove('text-sn-science-blue'), 300);
@ -224,9 +218,9 @@ export default {
handleResize() { handleResize() {
this.$nextTick(() => { this.$nextTick(() => {
this.calculateAllSectionsCumulativeHeight() this.calculateAllSectionsCumulativeHeight();
this.calculateSectionsHeight(); this.calculateSectionsHeight();
this.constructThresholds() this.constructThresholds();
}); });
}, },
@ -249,6 +243,6 @@ export default {
} }
}); });
}, },
} },
} };
</script> </script>