Skip to content

Commit

Permalink
feat: custom value mapping for boolean attributes
Browse files Browse the repository at this point in the history
Refs: #43
  • Loading branch information
Jumas committed Oct 3, 2024
1 parent e57a9e2 commit 9778864
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 27 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>ch.sbb.polarion.extensions</groupId>
<artifactId>ch.sbb.polarion.extension.generic</artifactId>
<version>7.2.0</version>
<version>7.3.1</version>
</parent>

<artifactId>ch.sbb.polarion.extension.excel-importer</artifactId>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import ch.sbb.polarion.extension.excel_importer.settings.ExcelSheetMappingSettingsModel;
import ch.sbb.polarion.extension.generic.fields.FieldType;
import ch.sbb.polarion.extension.generic.fields.model.FieldMetadata;
import ch.sbb.polarion.extension.generic.util.OptionsMappingUtils;
import com.polarion.alm.projects.model.IUniqueObject;
import com.polarion.alm.shared.api.transaction.TransactionalExecutor;
import com.polarion.alm.tracker.model.ITrackerProject;
Expand Down Expand Up @@ -113,6 +114,9 @@ private String getIdentifierValue(Map<String, Object> recordMap, String columnLe
private void fillWorkItemFields(IWorkItem workItem, Map<String, Object> mappingRecord, ExcelSheetMappingSettingsModel model, String linkColumnId) {
mappingRecord.forEach((columnId, value) -> {
String fieldId = model.getColumnsMapping().get(columnId);
// we need to know possible mapped value asap because some types (at least boolean) need it to check value for modification
String mappedOption = OptionsMappingUtils.getMappedOptionKey(fieldId, value, model.getEnumsMapping());
value = mappedOption != null ? mappedOption : value;
Set<FieldMetadata> fieldMetadataSet = polarionServiceExt.getWorkItemsFields(workItem.getProjectId(), workItem.getType() == null ? "" : workItem.getType().getId());
// The linkColumn field's value can't change, therefore it doesn't need to be overwritten.
// However, it must be saved to the newly created work item otherwise sequential imports will produce several objects.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ch.sbb.polarion.extension.excel_importer.service;

import ch.sbb.polarion.extension.generic.fields.model.FieldMetadata;
import ch.sbb.polarion.extension.generic.fields.model.Option;
import com.polarion.alm.projects.IProjectService;
import com.polarion.alm.tracker.ITrackerService;
import com.polarion.alm.tracker.model.ITrackerProject;
Expand All @@ -12,6 +13,7 @@
import com.polarion.platform.security.ISecurityService;
import com.polarion.platform.service.repository.IRepositoryService;
import com.polarion.subterra.base.data.identification.IContextId;
import com.polarion.subterra.base.data.model.internal.PrimitiveType;
import org.jetbrains.annotations.NotNull;

import java.util.List;
Expand All @@ -21,6 +23,8 @@

public class PolarionServiceExt extends ch.sbb.polarion.extension.generic.service.PolarionService {

private static final Set<Option> BOOLEAN_OPTIONS_MAPPING = Set.of(new Option("True", "true"), new Option("False", "false"));

public PolarionServiceExt() {
}

Expand All @@ -41,6 +45,7 @@ public Set<FieldMetadata> getWorkItemsFields(@NotNull String projectId, @NotNull
fields.addAll(getGeneralFields(IWorkItem.PROTO, contextId)); // get common fields for WorkItem
fields.addAll(getCustomFields(IWorkItem.PROTO, contextId, null)); // get custom fields for WorkItem with any type in the project (-- All Types --)
fields.addAll(getCustomFields(IWorkItem.PROTO, contextId, typeOpt.getId())); // get custom fields for WorkItem with specific type in the project
fillBooleanOptionMappings(fields); // set mappings for booleans
return fields;
}

Expand Down Expand Up @@ -84,4 +89,12 @@ public ITrackerProject findProject(@NotNull String projectId) {
}
return trackerProject;
}

private void fillBooleanOptionMappings(Set<FieldMetadata> fields) {
fields.forEach(f -> {
if (f.getType() instanceof PrimitiveType primitiveType && Boolean.class.getTypeName().equals(primitiveType.getTypeName())) {
f.setOptions(BOOLEAN_OPTIONS_MAPPING);
}
});
}
}
2 changes: 2 additions & 0 deletions src/main/resources/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Require-Bundle: com.polarion.portal.tomcat,
com.fasterxml.jackson,
com.fasterxml.jackson.jaxrs,
io.swagger,
org.apache.commons.logging,
slf4j.api,
org.springframework.spring-core,
org.springframework.spring-web,
ch.sbb.polarion.thirdparty.bundles.org.apache.poi;resolution:=optional
Expand Down
9 changes: 4 additions & 5 deletions src/main/resources/webapp/excel-importer-admin/js/mappings.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ function createFieldCell(tableRow, fieldValue) {

const mappingButton = document.createElement('button');
mappingButton.classList.add('toolbar-button', 'options-mapping-button');
mappingButton.textContent = 'Enum mapping';
mappingButton.textContent = 'Options mapping';
mappingButton.style.display = 'none';
mappingButton.addEventListener('click', () => {

Expand All @@ -74,8 +74,7 @@ function createFieldCell(tableRow, fieldValue) {

const hint = document.createElement('span');
hint.classList.add('option-mapping-hint');
hint.innerHTML = 'By default both key and value are used for mapping to proper enum option. ' +
'Overriding values below will discontinue this behavior, so do not forget to specify enum default value explicitly if it still required.';
hint.innerHTML = 'Use <b>(empty)</b> keyword to map empty column value to some specific option.';
const hintWrapper = document.createElement('span');
hintWrapper.classList.add('option-mapping-hint-wrapper');
hintWrapper.appendChild(hint);
Expand Down Expand Up @@ -107,7 +106,7 @@ function createFieldCell(tableRow, fieldValue) {
const input = document.createElement('input');
input.type = "text";
input.placeholder = option.name;
input.title = `Comma-separated list of alternative values, which will be mapped to the enum option "${option.key}"`;
input.title = `Comma-separated list of alternative values, which will be mapped to the option "${option.key}"`;
input.value = getEnumMappingForField(fieldSelect.value, option.key);
input.classList.add('fs-14', 'option-mapping-value');
cell.appendChild(input);
Expand Down Expand Up @@ -159,7 +158,7 @@ function createHiddenInput(className, value) {
return idInput;
}

function saveEnumMapping() {
function saveOptionsMapping() {
const fieldId = (document.getElementById('modal-popup').getElementsByClassName('field-id')[0]).value;
cache.enumsMapping[fieldId] = Object.fromEntries(getOptionsMapping());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@
</div>

<jsp:include page='modal.jsp'>
<jsp:param name="titleText" value="Enum mapping"/>
<jsp:param name="titleText" value="Options mapping"/>
<jsp:param name="okText" value="Accept"/>
<jsp:param name="cancelText" value="Cancel"/>
<jsp:param name="okClickFunction" value="saveEnumMapping()"/>
<jsp:param name="okClickFunction" value="saveOptionsMapping()"/>
</jsp:include>

<script type="text/javascript" src="../ui/generic/js/common.js?bundle=<%= bundleTimestamp %>"></script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
package ch.sbb.polarion.extension.excel_importer.settings;

import ch.sbb.polarion.extension.generic.exception.ObjectNotFoundException;
import ch.sbb.polarion.extension.generic.rest.model.Context;
import ch.sbb.polarion.extension.generic.settings.GenericNamedSettings;
import ch.sbb.polarion.extension.generic.settings.SettingId;
import ch.sbb.polarion.extension.generic.settings.SettingsService;
import ch.sbb.polarion.extension.generic.util.ContextUtils;
import ch.sbb.polarion.extension.generic.util.ScopeUtils;
import com.polarion.subterra.base.location.ILocation;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockedStatic;
import org.mockito.junit.jupiter.MockitoExtension;

Expand All @@ -21,6 +27,21 @@

@ExtendWith(MockitoExtension.class)
class ExcelSheetMappingSettingsTest {

@Mock(answer = Answers.RETURNS_DEEP_STUBS)
MockedStatic<ContextUtils> contextUtils;

@BeforeEach
void setUp() {
Context context = new Context("excel-importer");
contextUtils.when(ContextUtils::getContext).thenReturn(context);
}

@AfterEach
void tearDown() {
contextUtils.close();
}

@Test
void testSettingDoesNotExist() {
try (MockedStatic<ScopeUtils> mockScopeUtils = mockStatic(ScopeUtils.class)) {
Expand Down

0 comments on commit 9778864

Please sign in to comment.