Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Auto assign style packages #178

Merged
merged 3 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,53 @@
]
}
},
"/api/settings/style-package/suitable-names": {
"get": {
"operationId": "getSuitableStylePackageNames",
"parameters": [
{
"in": "query",
"name": "projectId",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "spaceId",
"schema": {
"type": "string"
}
},
{
"in": "query",
"name": "documentName",
"schema": {
"type": "string"
}
}
],
"responses": {
"default": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/SettingName"
},
"type": "array"
}
}
},
"description": "default response"
}
},
"summary": "Get list of style packages suitable for a document",
"tags": [
"Settings"
]
}
},
"/api/settings/{feature}/default-content": {
"get": {
"operationId": "getDefaultValues_1",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class PdfExporterFormExtension implements IFormExtension {
private static final String OPTION_SELECTED = "<option value='%s' selected";
private static final String SELECTED = "selected";

private final PdfExporterPolarionService polarionService = new PdfExporterPolarionService();

@Override
@Nullable
public String render(@NotNull IFormExtensionContext context) {
Expand All @@ -66,7 +68,7 @@ public String renderForm(@NotNull SharedContext context, @NotNull IPObject objec
String scope = ScopeUtils.getScopeFromProject(module.getProject().getId());
form = form.replace("{SCOPE_VALUE}", scope);

Collection<SettingName> stylePackageNames = getSettingNames(StylePackageSettings.FEATURE_NAME, scope);
Collection<SettingName> stylePackageNames = getSuitableStylePackages(module);
SettingName stylePackageNameToSelect = getStylePackageNameToSelect(stylePackageNames); // Either default (if exists) or first from list

form = form.replace("{STYLE_PACKAGE_OPTIONS}", generateSelectOptions(stylePackageNames, stylePackageNameToSelect != null ? stylePackageNameToSelect.getName() : null));
Expand Down Expand Up @@ -109,7 +111,7 @@ public String renderForm(@NotNull SharedContext context, @NotNull IPObject objec

private SettingName getStylePackageNameToSelect(Collection<SettingName> stylePackageNames) {
return stylePackageNames.stream()
.filter(stylePackageName -> NamedSettings.DEFAULT_NAME.equals(stylePackageName.getName()))
.filter(stylePackageName -> !NamedSettings.DEFAULT_NAME.equals(stylePackageName.getName()))
.findFirst()
.orElse(stylePackageNames.stream()
.findFirst()
Expand Down Expand Up @@ -161,6 +163,19 @@ private String adjustWebhooks(String scope, String form, StylePackageModel style
return form.replace("{WEBHOOKS_SELECTED}", noHooks ? "" : "checked");
}

private Collection<SettingName> getSuitableStylePackages(@NotNull IModule module) {
String locationPath = module.getModuleLocation().getLocationPath();
String spaceId = "";
final String documentName;
if (locationPath.contains("/")) {
spaceId = locationPath.substring(0, locationPath.lastIndexOf('/'));
documentName = locationPath.substring(locationPath.lastIndexOf('/') + 1);
} else {
documentName = locationPath;
}
return polarionService.getSuitableStylePackages(module.getProject().getId(), spaceId, documentName);
}

private Collection<SettingName> getSettingNames(@NotNull String featureName, @NotNull String scope) {
try {
return NamedSettingsRegistry.INSTANCE.getByFeatureName(featureName).readNames(scope);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ch.sbb.polarion.extension.generic.rest.filter.Secured;
import ch.sbb.polarion.extension.generic.service.PolarionService;
import ch.sbb.polarion.extension.generic.settings.SettingName;
import org.glassfish.jersey.media.multipart.FormDataBodyPart;

import javax.ws.rs.Path;
Expand Down Expand Up @@ -39,4 +40,9 @@ public void persistCoverPageTemplate(String template, String scope) {
public void deleteImages(String coverPageName, String scope) {
polarionService.callPrivileged(() -> super.deleteImages(coverPageName, scope));
}

@Override
public Collection<SettingName> getSuitableStylePackageNames(String projectId, String spaceId, String documentName) {
return polarionService.callPrivileged(() -> super.getSuitableStylePackageNames(projectId, spaceId, documentName));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ch.sbb.polarion.extension.generic.settings.SettingName;
import ch.sbb.polarion.extension.pdf.exporter.rest.model.settings.coverpage.CoverPageModel;
import ch.sbb.polarion.extension.pdf.exporter.rest.model.settings.localization.LocalizationModel;
import ch.sbb.polarion.extension.pdf.exporter.service.PdfExporterPolarionService;
import ch.sbb.polarion.extension.pdf.exporter.settings.CoverPageSettings;
import ch.sbb.polarion.extension.pdf.exporter.settings.LocalizationSettings;
import ch.sbb.polarion.extension.pdf.exporter.util.LocalizationHelper;
Expand All @@ -14,6 +15,7 @@
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
import org.glassfish.jersey.media.multipart.FormDataParam;

import javax.ws.rs.BadRequestException;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
Expand All @@ -38,6 +40,7 @@
public class SettingsInternalController {

private Set<String> predefinedCoverPageTemplates;
private final PdfExporterPolarionService pdfExporterPolarionService = new PdfExporterPolarionService();

@GET
@Path("/settings/localization/names/{name}/download")
Expand Down Expand Up @@ -116,4 +119,17 @@ public void persistCoverPageTemplate(@PathParam("template") String template, @Qu
public void deleteImages(@PathParam("name") String coverPageName, @QueryParam("scope") @DefaultValue("") String scope) {
new CoverPageSettings().deleteCoverPageImages(coverPageName, scope);
}

@GET
@Path("/settings/style-package/suitable-names")
@Produces(MediaType.APPLICATION_JSON)
@Tag(name = "Settings")
@Operation(summary = "Get list of style packages suitable for a document")
public Collection<SettingName> getSuitableStylePackageNames(@QueryParam("projectId") String projectId, @QueryParam("spaceId") String spaceId, @QueryParam("documentName") String documentName) {
if (projectId == null || spaceId == null || documentName == null) {
throw new BadRequestException("Parameters 'projectId', 'spaceId', 'documentName' are required'");
}
return pdfExporterPolarionService.getSuitableStylePackages(projectId, spaceId, documentName);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
@EqualsAndHashCode(callSuper = false)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class StylePackageModel extends SettingsModel {
private static final String MATCHING_QUERY_ENTRY_NAME = "MATCHING QUERY";
private static final String EXPOSE_SETTINGS_ENTRY_NAME = "EXPOSE SETTINGS";
private static final String COVER_PAGE_ENTRY_NAME = "COVER PAGE";
private static final String HEADER_FOOTER_ENTRY_NAME = "HEADER FOOTER";
Expand All @@ -46,6 +47,7 @@ public class StylePackageModel extends SettingsModel {
private static final String LINKED_WORKITEM_ROLES_ENTRY_NAME = "LINKED WORKITEM ROLES";
private static final String EXPOSE_PAGE_WIDTH_VALIDATION_ENTRY_NAME = "EXPOSE PAGE WIDTH VALIDATION";

private String matchingQuery;
private boolean exposeSettings;
private String coverPage;
private String headerFooter;
Expand All @@ -71,7 +73,8 @@ public class StylePackageModel extends SettingsModel {

@Override
protected String serializeModelData() {
return serializeEntry(EXPOSE_SETTINGS_ENTRY_NAME, exposeSettings) +
return serializeEntry(MATCHING_QUERY_ENTRY_NAME, matchingQuery) +
serializeEntry(EXPOSE_SETTINGS_ENTRY_NAME, exposeSettings) +
serializeEntry(COVER_PAGE_ENTRY_NAME, coverPage) +
serializeEntry(HEADER_FOOTER_ENTRY_NAME, headerFooter) +
serializeEntry(CSS_ENTRY_NAME, css) +
Expand All @@ -97,6 +100,7 @@ protected String serializeModelData() {

@Override
protected void deserializeModelData(String serializedString) {
matchingQuery = deserializeEntry(MATCHING_QUERY_ENTRY_NAME, serializedString);
exposeSettings = Boolean.parseBoolean(deserializeEntry(EXPOSE_SETTINGS_ENTRY_NAME, serializedString));
coverPage = deserializeEntry(COVER_PAGE_ENTRY_NAME, serializedString);
headerFooter = deserializeEntry(HEADER_FOOTER_ENTRY_NAME, serializedString);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
package ch.sbb.polarion.extension.pdf.exporter.service;

import ch.sbb.polarion.extension.generic.service.PolarionService;
import ch.sbb.polarion.extension.generic.settings.NamedSettingsRegistry;
import ch.sbb.polarion.extension.generic.settings.SettingId;
import ch.sbb.polarion.extension.generic.settings.SettingName;
import ch.sbb.polarion.extension.generic.util.ScopeUtils;
import ch.sbb.polarion.extension.pdf.exporter.rest.model.settings.stylepackage.StylePackageModel;
import ch.sbb.polarion.extension.pdf.exporter.settings.StylePackageSettings;
import com.polarion.alm.projects.IProjectService;
import com.polarion.alm.tracker.ITrackerService;
import com.polarion.alm.tracker.model.IModule;
import com.polarion.alm.tracker.model.ITrackerProject;
import com.polarion.core.util.StringUtils;
import com.polarion.platform.IPlatformService;
import com.polarion.platform.persistence.IDataService;
import com.polarion.platform.persistence.model.IPObjectList;
import com.polarion.platform.security.ISecurityService;
import com.polarion.platform.service.repository.IRepositoryService;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;

public class PdfExporterPolarionService extends PolarionService {

public PdfExporterPolarionService() {
Expand All @@ -35,4 +45,34 @@ public ITrackerProject getProjectFromScope(String scope) {
}
return project;
}

public Collection<SettingName> getSuitableStylePackages(@NotNull String projectId, @NotNull String spaceId, @NotNull String documentName) {
StylePackageSettings stylePackageSettings = (StylePackageSettings) NamedSettingsRegistry.INSTANCE.getByFeatureName(StylePackageSettings.FEATURE_NAME);
Collection<SettingName> stylePackageNames = stylePackageSettings.readNames(ScopeUtils.getScopeFromProject(projectId));
return stylePackageNames.stream().filter(stylePackageName -> isStylePackageSuitable(projectId, spaceId, documentName, stylePackageSettings, stylePackageName)).toList();
}

@SuppressWarnings("unchecked")
private boolean isStylePackageSuitable(@NotNull String projectId, @NotNull String spaceId, @NotNull String documentName,
@NotNull StylePackageSettings stylePackageSettings, @NotNull SettingName stylePackageName) {
StylePackageModel model = stylePackageSettings.read(ScopeUtils.getScopeFromProject(projectId), SettingId.fromName(stylePackageName.getName()), null);

if (StringUtils.isEmpty(model.getMatchingQuery())) {
return true;
} else {
IDataService dataService = getTrackerService().getDataService();
IPObjectList<IModule> suitableDocuments = dataService.searchInstances(dataService.getPrototype("Module"), model.getMatchingQuery(), "name");
for (IModule suitableDocument : suitableDocuments) {
if (sameDocument(projectId, spaceId, documentName, suitableDocument)) {
return true;
}
}
return false;
}
}

private boolean sameDocument(@NotNull String projectId, @NotNull String spaceId, @NotNull String documentName, @NotNull IModule document) {
return projectId.equals(document.getProjectId()) && String.format("%s/%s", spaceId, documentName).equals(document.getModuleLocation().getLocationPath());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ function saveStylePackage() {
url: `/polarion/${SbbCommon.extension}/rest/internal/settings/${SbbCommon.setting}/names/${Configurations.getSelectedConfiguration()}/content?scope=${SbbCommon.scope}`,
contentType: 'application/json',
body: JSON.stringify({
'matchingQuery': SbbCommon.getValueById('matching-query'),
'exposeSettings': SbbCommon.getCheckboxValueById('exposeSettings'),
'coverPage': SbbCommon.getCheckboxValueById('cover-page-checkbox') ? ChildConfigurations.coverPageSelect.getSelectedValue() : null,
'css': ChildConfigurations.cssSelect.getSelectedValue(),
Expand Down Expand Up @@ -210,6 +211,10 @@ function revertToDefault() {

function setStylePackage(content) {
const stylePackage = JSON.parse(content);

SbbCommon.setValueById('matching-query', stylePackage.matchingQuery || "");
document.getElementById('matching-query-container').style.display = DEFAULT_SETTING_NAME === Configurations.getSelectedConfiguration() ? "none" : "flex";

SbbCommon.setCheckboxValueById('exposeSettings', stylePackage.exposeSettings);
SbbCommon.setCheckboxValueById('cover-page-checkbox', !!stylePackage.coverPage);
document.getElementById('cover-page-checkbox').dispatchEvent(new Event('change'));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,32 @@

<jsp:include page='/common/jsp/configurations.jsp' />

<div class="content-area" style="border-top: 1px solid #ccc; margin-top: 20px; padding-top: 15px;">
<div class="content-area">
<div id="child-configs-load-error" class="style-package-error" style="display: none; margin-bottom: 15px">
There was an error loading names of children configurations. Please, contact project/system administrator to solve the issue, a style package can't be configured without them.
</div>
<div id="link-roles-load-error" class="style-package-error" style="display: none; margin-bottom: 15px">
There was an error loading link role names.
</div>

<div class='checkbox input-group'>
<label for='exposeSettings'>
<input id='exposeSettings' type='checkbox'/>
Expose style package settings to be redefined on UI
</label>
<div class="flex-container" id="matching-query-container" style="border-top: 1px solid #ccc; margin-top: 20px; padding-top: 15px;">
<p>Here you can specify a query to select documents to which this style package will be relevant. For documents not matching this query the style package won't be visible.
If you want to make this style package be available to all documents, just leave this field empty.</p>
<div class='input-group'>
<label for='matching-query'>Matching query:</label>
<input id='matching-query' style="width: 725px;"/>
</div>
</div>

<div class="flex-container" style="border-top: 1px solid #ccc; margin-top: 20px; padding-top: 15px;">
<div class="flex-column">
<div class='checkbox input-group'>
<label for='exposeSettings'>
<input id='exposeSettings' type='checkbox'/>
Expose style package settings to be redefined on UI
</label>
</div>
</div>
</div>

<div class="flex-container">
Expand Down
12 changes: 7 additions & 5 deletions src/main/resources/webapp/pdf-exporter/js/pdf-exporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,16 @@ const PdfExporter = {
this.adjustWebhooksVisibility()
]).then(() => {
return this.loadSettingNames({
setting: "style-package",
scope: this.exportContext.scope,
customUrl: `/polarion/pdf-exporter/rest/internal/settings/style-package/suitable-names?projectId=${this.exportContext.getProjectId()}`
+ `&spaceId=${this.exportContext.getSpaceId()}&documentName=${this.exportContext.getDocumentName()}`,
selectElement: document.getElementById("popup-style-package-select")
}).then(() => {
let valueToPreselect = SbbCommon.getCookie(SELECTED_STYLE_PACKAGE_COOKIE);
const stylePackageSelect = document.getElementById("popup-style-package-select");
const valueToPreselect = SbbCommon.getCookie(SELECTED_STYLE_PACKAGE_COOKIE);
if (valueToPreselect && this.containsOption(stylePackageSelect, valueToPreselect)) {
stylePackageSelect.value = valueToPreselect;
} else if (stylePackageSelect.options.length > 1) {
stylePackageSelect.value = stylePackageSelect.options[1].value;
}

this.onStylePackageChanged();
Expand All @@ -154,11 +156,11 @@ const PdfExporter = {
});
},

loadSettingNames: function ({setting, scope, selectElement}) {
loadSettingNames: function ({setting, scope, selectElement, customUrl}) {
return new Promise((resolve, reject) => {
this.callAsync({
method: "GET",
url: `/polarion/pdf-exporter/rest/internal/settings/${setting}/names?scope=${scope}`,
url: customUrl ? customUrl : `/polarion/pdf-exporter/rest/internal/settings/${setting}/names?scope=${scope}`,
responseType: "json",
}).then(({response}) => {
selectElement.innerHTML = ""; // Clear previously loaded content
Expand Down
Loading