Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.gridsuite.studyconfig.server.StudyConfigApi;
import org.gridsuite.studyconfig.server.dto.ColumnInfos;
import org.gridsuite.studyconfig.server.dto.GlobalFilterInfos;
import org.gridsuite.studyconfig.server.dto.MetadataInfos;
import org.gridsuite.studyconfig.server.dto.SpreadsheetConfigInfos;
import org.gridsuite.studyconfig.server.dto.*;
import org.gridsuite.studyconfig.server.service.SpreadsheetConfigService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -179,6 +176,20 @@ public ResponseEntity<Void> reorderColumns(
return ResponseEntity.noContent().build();
}

@PutMapping("/{id}/columns/states")
@Operation(summary = "Update column states",
description = "Updates the visibility and order of columns in a spreadsheet configuration")
@ApiResponse(responseCode = "204", description = "Column states updated successfully")
@ApiResponse(responseCode = "404", description = "Spreadsheet configuration not found")
@ApiResponse(responseCode = "400", description = "Invalid column state data")
public ResponseEntity<Void> updateColumnStates(
@Parameter(description = "ID of the spreadsheet config") @PathVariable UUID id,
@Parameter(description = "List of column state updates")
@Valid @RequestBody List<ColumnStateUpdateInfos> columnStates) {
spreadsheetConfigService.updateColumnStates(id, columnStates);
return ResponseEntity.noContent().build();
}

@PostMapping("/{id}/global-filters")
@Operation(summary = "Set global filters",
description = "Replaces all existing global filters with the provided list for a spreadsheet configuration")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@ public record ColumnInfos(
String filterValue,

@Schema(description = "Filter tolerance for numeric comparisons")
Double filterTolerance
Double filterTolerance,

@Schema(description = "Column visibility", defaultValue = "true")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultValue without nullable=true?

Suggested change
@Schema(description = "Column visibility", defaultValue = "true")
@Schema(description = "Column visibility", nullable=true, defaultValue = "true")

Boolean visible
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not using the primitive type if null isn't a value we support?

Suggested change
Boolean visible
boolean visible

) { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2025, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.gridsuite.studyconfig.server.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

import java.util.UUID;

/**
* DTO for updating column state (visibility and order)
* @author Achour BERRAHMA <achour.berrahma at rte-france.com>
*/
@Schema(name = "ColumnStateUpdateDto", description = "Column state update information")
public record ColumnStateUpdateInfos(

@NotNull(message = "Column UUID is mandatory")
@Schema(description = "Column UUID")
UUID columnId,

@NotNull(message = "Visible state is mandatory")
@Schema(description = "Column visibility state")
Boolean visible,

@NotNull(message = "Order is mandatory")
@Schema(description = "New position in the column order (0-based index)")
Integer order

) { }
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,7 @@ public class ColumnEntity {
@Column(name = "filter_tolerance")
private Double filterTolerance;

@Column(name = "visible", nullable = false)
@Builder.Default
private Boolean visible = true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If nullable = false, then use primitive type instead of nullable Object.

Suggested change
private Boolean visible = true;
private boolean visible = true;

You can also set the default value at SQL level:

@ColumnDefault(false)

}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ public static ColumnInfos toColumnDto(ColumnEntity entity) {
entity.getFilterDataType(),
entity.getFilterType(),
entity.getFilterValue(),
entity.getFilterTolerance()
entity.getFilterTolerance(),
entity.getVisible()
);
}

Expand All @@ -89,6 +90,7 @@ public static ColumnEntity toColumnEntity(ColumnInfos dto) {
.filterType(dto.filterType())
.filterValue(dto.filterValue())
.filterTolerance(dto.filterTolerance())
.visible(dto.visible() != null ? dto.visible() : true)
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ public void updateColumn(UUID id, UUID columnId, ColumnInfos dto) {
columnEntity.setFilterType(dto.filterType());
columnEntity.setFilterValue(dto.filterValue());
columnEntity.setFilterTolerance(dto.filterTolerance());
columnEntity.setVisible(dto.visible() != null ? dto.visible() : true);

spreadsheetConfigRepository.save(entity);
}
Expand All @@ -352,13 +353,41 @@ public void reorderColumns(UUID id, List<UUID> columnOrder) {
SpreadsheetConfigEntity entity = findEntityById(id);
List<ColumnEntity> columns = entity.getColumns();

reorderColumns(columnOrder, columns);
}

private static void reorderColumns(List<UUID> columnOrder, List<ColumnEntity> columns) {
columns.sort((c1, c2) -> {
int idx1 = columnOrder.indexOf(c1.getUuid());
int idx2 = columnOrder.indexOf(c2.getUuid());
return Integer.compare(idx1, idx2);
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IntelliJ simplify as

Suggested change
private static void reorderColumns(List<UUID> columnOrder, List<ColumnEntity> columns) {
columns.sort((c1, c2) -> {
int idx1 = columnOrder.indexOf(c1.getUuid());
int idx2 = columnOrder.indexOf(c2.getUuid());
return Integer.compare(idx1, idx2);
});
}
private static void reorderColumns(List<UUID> columnOrder, List<ColumnEntity> columns) {
columns.sort(Comparator.comparingInt(c -> columnOrder.indexOf(c.getUuid())));
}


@Transactional
public void updateColumnStates(UUID id, List<ColumnStateUpdateInfos> columnStates) {
SpreadsheetConfigEntity entity = findEntityById(id);
List<ColumnEntity> columns = entity.getColumns();

Map<UUID, ColumnEntity> columnMap = columns.stream()
.collect(Collectors.toMap(ColumnEntity::getUuid, column -> column));

for (ColumnStateUpdateInfos state : columnStates) {
ColumnEntity column = columnMap.get(state.columnId());
if (column == null) {
throw new EntityNotFoundException(COLUMN_NOT_FOUND + state.columnId());
}
column.setVisible(state.visible());
}

// Reorder columns based on the provided states
List<UUID> orderedColumnIds = columnStates.stream()
.sorted(Comparator.comparingInt(ColumnStateUpdateInfos::order))
.map(ColumnStateUpdateInfos::columnId)
.toList();
reorderColumns(orderedColumnIds, columns);
Comment on lines +380 to +384
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of creating an intermediate list, you can order directly in one step.

}

private SpreadsheetConfigCollectionInfos readDefaultSpreadsheetConfigCollection() throws IOException {
try (InputStream inputStream = defaultSpreadsheetConfigCollectionResource.getInputStream()) {
return objectMapper.readValue(inputStream, SpreadsheetConfigCollectionInfos.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:pro="http://www.liquibase.org/xml/ns/pro" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd">
<changeSet author="berrahmaach (generated)" id="1749213150568-4">
<addColumn tableName="spreadsheet_column">
<column name="visible" type="boolean" defaultValueBoolean="true">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>

<!-- Set default value for existing rows -->
<changeSet author="berrahmaach" id="1749213150568-5">
<update tableName="spreadsheet_column">
<column name="visible" valueBoolean="true"/>
<where>visible IS NULL</where>
</update>
</changeSet>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can simplify it:

Suggested change
<changeSet author="berrahmaach (generated)" id="1749213150568-4">
<addColumn tableName="spreadsheet_column">
<column name="visible" type="boolean" defaultValueBoolean="true">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
<!-- Set default value for existing rows -->
<changeSet author="berrahmaach" id="1749213150568-5">
<update tableName="spreadsheet_column">
<column name="visible" valueBoolean="true"/>
<where>visible IS NULL</where>
</update>
</changeSet>
<changeSet author="berrahmaach (generated)" id="1749213150568-4">
<addColumn tableName="spreadsheet_column">
<column name="visible" type="boolean" defaultValueBoolean="true" valueBoolean="true" remarks="Is the column visible in the table?">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>

ref: addColumn > column

</databaseChangeLog>
3 changes: 3 additions & 0 deletions src/main/resources/db/changelog/db.changelog-master.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ databaseChangeLog:
- include:
file: changesets/changelog_20250604T144112Z.xml
relativeToChangelogFile: true
- include:
file: changesets/changelog_20250606T123216Z.xml
relativeToChangelogFile: true
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,14 @@ void testConversionToDtoOfSpreadsheetConfig() {
.sheetType(SheetType.BATTERY)
.columns(Arrays.asList(
ColumnEntity.builder()
.name("Column1")
.formula("A+B")
.id("id1")
.filterDataType("text")
.filterType("contains")
.filterValue("test")
.build(),
.name("Column1")
.formula("A+B")
.id("id1")
.filterDataType("text")
.filterType("contains")
.filterValue("test")
.visible(false)
.build(),
ColumnEntity.builder().name("Column2").formula("C*D").id("id2").build()
))
.globalFilters(Arrays.asList(
Expand Down Expand Up @@ -75,13 +76,16 @@ void testConversionToDtoOfSpreadsheetConfig() {
assertThat(d.columns().get(0).filterDataType()).isEqualTo("text");
assertThat(d.columns().get(0).filterType()).isEqualTo("contains");
assertThat(d.columns().get(0).filterValue()).isEqualTo("test");
assertThat(d.columns().get(0).visible()).isFalse();

assertThat(d.columns().get(1).name()).isEqualTo("Column2");
assertThat(d.columns().get(1).formula()).isEqualTo("C*D");
assertThat(d.columns().get(1).id()).isEqualTo("id2");
assertThat(d.columns().get(1).filterDataType()).isNull();
assertThat(d.columns().get(1).filterType()).isNull();
assertThat(d.columns().get(1).filterValue()).isNull();
assertThat(d.columns().get(1).visible()).isTrue();

// Global filters assertions
assertThat(d.globalFilters()).hasSize(2);
assertThat(d.globalFilters().get(0).id()).isNotNull();
Expand All @@ -102,9 +106,9 @@ void testConversionToEntityOfSpreadsheetConfig() {
SheetType.BUS,
Arrays.asList(
new ColumnInfos(null, "Column1", ColumnType.NUMBER, 1, "X+Y", "[\"col1\", \"col2\"]", "id1",
"number", "greaterThan", "100", 0.5),
"number", "greaterThan", "100", 0.5, true),
new ColumnInfos(null, "Column2", ColumnType.NUMBER, 2, "Z*W", "[\"col1\"]", "id2",
null, null, null, null)
null, null, null, null, true)
),
List.of(
GlobalFilterInfos.builder().uuid(filterId).filterType("country").label("GlobalFilter1").recent(false).build()
Expand All @@ -129,6 +133,7 @@ void testConversionToEntityOfSpreadsheetConfig() {
assertThat(e.getColumns().get(0).getFilterType()).isEqualTo("greaterThan");
assertThat(e.getColumns().get(0).getFilterValue()).isEqualTo("100");
assertThat(e.getColumns().get(0).getFilterTolerance()).isEqualTo(0.5);
assertThat(e.getColumns().get(0).getVisible()).isTrue();

assertThat(e.getColumns().get(1).getName()).isEqualTo("Column2");
assertThat(e.getColumns().get(1).getFormula()).isEqualTo("Z*W");
Expand All @@ -138,6 +143,7 @@ void testConversionToEntityOfSpreadsheetConfig() {
assertThat(e.getColumns().get(1).getFilterType()).isNull();
assertThat(e.getColumns().get(1).getFilterValue()).isNull();
assertThat(e.getColumns().get(1).getFilterTolerance()).isNull();
assertThat(e.getColumns().get(1).getVisible()).isTrue();

// Global filter assertions
assertThat(e.getGlobalFilters()).hasSize(1);
Expand Down Expand Up @@ -173,6 +179,7 @@ void testConversionToDtoOfColumnWithFilter() {
assertThat(d.filterType()).isEqualTo("startsWith");
assertThat(d.filterValue()).isEqualTo("prefix");
assertThat(d.filterTolerance()).isNull();
assertThat(d.visible()).isTrue();
});
}

Expand All @@ -189,7 +196,8 @@ void testConversionToEntityOfColumnWithFilter() {
"number",
"lessThan",
"50.5",
0.1);
0.1,
true);

ColumnEntity column = SpreadsheetConfigMapper.toColumnEntity(dto);

Expand All @@ -204,6 +212,7 @@ void testConversionToEntityOfColumnWithFilter() {
assertThat(e.getFilterType()).isEqualTo("lessThan");
assertThat(e.getFilterValue()).isEqualTo("50.5");
assertThat(e.getFilterTolerance()).isEqualTo(0.1);
assertThat(e.getVisible()).isTrue();
});
}

Expand All @@ -220,7 +229,8 @@ void testConversionOfColumnWithoutFilter() {
null,
null,
null,
null);
null,
true);

ColumnEntity entity = SpreadsheetConfigMapper.toColumnEntity(dto);
ColumnInfos convertedDto = SpreadsheetConfigMapper.toColumnDto(entity);
Expand Down
Loading