diff --git a/app/logbook/inmemory/src/main/java/org/phoebus/applications/logbook/InMemoryLogClient.java b/app/logbook/inmemory/src/main/java/org/phoebus/applications/logbook/InMemoryLogClient.java index 468e545180..826155d52f 100644 --- a/app/logbook/inmemory/src/main/java/org/phoebus/applications/logbook/InMemoryLogClient.java +++ b/app/logbook/inmemory/src/main/java/org/phoebus/applications/logbook/InMemoryLogClient.java @@ -1,14 +1,28 @@ package org.phoebus.applications.logbook; +import org.phoebus.logbook.Attachment; +import org.phoebus.logbook.AttachmentImpl; +import org.phoebus.logbook.LogClient; +import org.phoebus.logbook.LogEntry; +import org.phoebus.logbook.LogEntryImpl; +import org.phoebus.logbook.LogEntryImpl.LogEntryBuilder; +import org.phoebus.logbook.LogEntryLevel; +import org.phoebus.logbook.Logbook; +import org.phoebus.logbook.LogbookException; +import org.phoebus.logbook.LogbookImpl; +import org.phoebus.logbook.Property; +import org.phoebus.logbook.PropertyImpl; +import org.phoebus.logbook.SearchResult; +import org.phoebus.logbook.Tag; +import org.phoebus.logbook.TagImpl; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URLConnection; -import java.nio.file.CopyOption; import java.nio.file.Files; -import java.nio.file.StandardCopyOption; import java.time.Instant; import java.util.Arrays; import java.util.Collection; @@ -23,21 +37,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import org.phoebus.logbook.Attachment; -import org.phoebus.logbook.AttachmentImpl; -import org.phoebus.logbook.LogClient; -import org.phoebus.logbook.LogEntry; -import org.phoebus.logbook.LogEntryImpl; -import org.phoebus.logbook.LogEntryImpl.LogEntryBuilder; -import org.phoebus.logbook.Logbook; -import org.phoebus.logbook.LogbookException; -import org.phoebus.logbook.LogbookImpl; -import org.phoebus.logbook.Property; -import org.phoebus.logbook.PropertyImpl; -import org.phoebus.logbook.SearchResult; -import org.phoebus.logbook.Tag; -import org.phoebus.logbook.TagImpl; - /** * A logbook which maintains logentries in memory. It is mainly for testing and debugging purpose. */ @@ -47,16 +46,16 @@ public class InMemoryLogClient implements LogClient { private final Map logEntries; private final Collection logbooks = Arrays.asList(LogbookImpl.of("Controls"), - LogbookImpl.of("Commissioning"), - LogbookImpl.of("Scratch Pad")); + LogbookImpl.of("Commissioning"), + LogbookImpl.of("Scratch Pad")); private final Collection tags = Arrays.asList(TagImpl.of("Operations"), - TagImpl.of("Alarm"), - TagImpl.of("Example")); + TagImpl.of("Alarm"), + TagImpl.of("Example")); private final List levels = Arrays.asList("Urgent", "Suggestion", "Info", "Request", "Problem"); private static List inMemoryProperties() { Map tracAttributes = new HashMap<>(); - Property track = PropertyImpl.of("Track",tracAttributes); + Property track = PropertyImpl.of("Track", tracAttributes); Map experimentAttributes = new HashMap<>(); Property experimentProperty = PropertyImpl.of("Experiment", experimentAttributes); Map resourceAttributes = new HashMap<>(); @@ -80,8 +79,8 @@ public InMemoryLogClient() { } @Override - public Collection listLevels() { - return levels; + public Collection listLevels() { + return levels.stream().map(l -> new LogEntryLevel(l, false)).toList(); } @Override @@ -110,6 +109,7 @@ public LogEntry getLog(Long logId) { } String prefix = "phoebus_tmp_file"; + @Override public LogEntry set(LogEntry log) { long id = logIdCounter.incrementAndGet(); @@ -155,12 +155,12 @@ public SearchResult search(Map map) { @Override public List findLogs(Map map) { Stream searchStream = logEntries.values().stream(); - if(map.containsKey("start")) { + if (map.containsKey("start")) { searchStream = searchStream.filter(log -> { return log.getCreatedDate().isAfter(Instant.ofEpochSecond(Long.valueOf(map.get("start")))); }); } - if(map.containsKey("end")) { + if (map.containsKey("end")) { searchStream = searchStream.filter(log -> { return log.getCreatedDate().isBefore(Instant.ofEpochSecond(Long.valueOf(map.get("end")))); }); @@ -169,7 +169,7 @@ public List findLogs(Map map) { final String searchString = map.get("search").replaceAll("\\*", ""); if (!searchString.isEmpty()) { searchStream = searchStream.filter(log -> { - return log.getDescription().contains(searchString)||log.getTitle().contains(searchString); + return log.getDescription().contains(searchString) || log.getTitle().contains(searchString); }); } } diff --git a/app/logbook/olog/client-es/src/main/java/org/phoebus/olog/es/api/OlogHttpClient.java b/app/logbook/olog/client-es/src/main/java/org/phoebus/olog/es/api/OlogHttpClient.java index 93c3ac1d8f..7c3504e454 100644 --- a/app/logbook/olog/client-es/src/main/java/org/phoebus/olog/es/api/OlogHttpClient.java +++ b/app/logbook/olog/client-es/src/main/java/org/phoebus/olog/es/api/OlogHttpClient.java @@ -13,6 +13,7 @@ import org.phoebus.logbook.LogClient; import org.phoebus.logbook.LogEntry; import org.phoebus.logbook.LogEntryChangeHandler; +import org.phoebus.logbook.LogEntryLevel; import org.phoebus.logbook.LogTemplate; import org.phoebus.logbook.Logbook; import org.phoebus.logbook.LogbookException; @@ -49,6 +50,7 @@ import java.util.List; import java.util.Map; import java.util.ServiceLoader; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -548,4 +550,22 @@ public LogTemplate saveTemplate(LogTemplate template) throws LogbookException { throw new LogbookException(e); } } + + @Override + public Collection listLevels(){ + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(Preferences.olog_url + "/levels")) + .GET() + .build(); + + try { + HttpResponse response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); + return OlogObjectMappers.logEntryDeserializer.readValue( + response.body(), new TypeReference>() { + }); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Unable to get templates from service", e); + return Collections.emptySet(); + } + } } diff --git a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogClient.java b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogClient.java index 0d3dd02ffd..6e5ad73660 100644 --- a/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogClient.java +++ b/app/logbook/olog/client/src/main/java/org/phoebus/olog/api/OlogClient.java @@ -6,6 +6,7 @@ import org.phoebus.logbook.Attachment; import org.phoebus.logbook.LogClient; import org.phoebus.logbook.LogEntry; +import org.phoebus.logbook.LogEntryLevel; import org.phoebus.logbook.Logbook; import org.phoebus.logbook.LogbookException; import org.phoebus.logbook.Messages; @@ -197,13 +198,12 @@ private OlogClient(HttpClient httpClient, String userName, String password) { } - // A predefined set of levels supported by olog private final List levels = Arrays.asList("Urgent", "Suggestion", "Info", "Request", "Problem"); @Override - public Collection listLevels() { - return levels; + public Collection listLevels() { + return levels.stream().map(l -> new LogEntryLevel(l, false)).toList(); } @Override diff --git a/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/AdvancedSearchViewController.java b/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/AdvancedSearchViewController.java index 3a7e06bb95..909b05dcb3 100644 --- a/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/AdvancedSearchViewController.java +++ b/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/AdvancedSearchViewController.java @@ -20,33 +20,43 @@ import javafx.application.Platform; import javafx.beans.property.SimpleBooleanProperty; +import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; import javafx.fxml.FXML; import javafx.geometry.Pos; +import javafx.geometry.Side; import javafx.scene.control.Button; -import javafx.scene.control.ComboBox; +import javafx.scene.control.CheckBox; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.CustomMenuItem; import javafx.scene.control.Label; import javafx.scene.control.RadioButton; import javafx.scene.control.TextField; +import javafx.scene.control.ToggleButton; +import javafx.scene.image.ImageView; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.HBox; import javafx.scene.layout.VBox; +import org.phoebus.logbook.LogEntryLevel; import org.phoebus.logbook.LogClient; import org.phoebus.logbook.Logbook; import org.phoebus.logbook.Tag; -import org.phoebus.olog.es.api.Preferences; import org.phoebus.ui.dialog.ListSelectionPopOver; import org.phoebus.ui.dialog.PopOver; +import org.phoebus.ui.javafx.ImageCache; import org.phoebus.ui.time.TimeRelativeIntervalPane; import org.phoebus.util.text.Strings; import org.phoebus.util.time.TimeParser; import org.phoebus.util.time.TimeRelativeInterval; import org.phoebus.util.time.TimestampFormats; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -84,31 +94,48 @@ public class AdvancedSearchViewController { TextField searchLogbooks; ListSelectionPopOver logbookSearchPopover; - @FXML - ComboBox levelSelector; - @FXML TextField searchTags; ListSelectionPopOver tagSearchPopover; private final LogClient logClient; + @SuppressWarnings("unused") @FXML private AnchorPane advancedSearchPane; + @SuppressWarnings("unused") @FXML private RadioButton sortDescRadioButton; + @SuppressWarnings("unused") @FXML private RadioButton sortAscRadioButton; + @SuppressWarnings("unused") @FXML private TextField attachmentTypes; + @SuppressWarnings("unused") + @FXML + private TextField selectedLevelsField; + + @SuppressWarnings("unused") + @FXML + private ToggleButton levelsToggleButton; + + @SuppressWarnings("unused") + @FXML + private GridPane gridPane; + + private final ContextMenu levelsContextMenu = new ContextMenu(); + private final SearchParameters searchParameters; private final SimpleBooleanProperty sortAscending = new SimpleBooleanProperty(false); - private final SimpleBooleanProperty requireAttachments = new SimpleBooleanProperty(false); + private final ObservableList levelSelections = FXCollections.observableArrayList(); + private final SimpleStringProperty selectedLevelsString = new SimpleStringProperty(); + private final List levelsList = new ArrayList<>(); private Runnable searchCallback = () -> { throw new IllegalStateException("Search callback is not set on AdvancedSearchViewController!"); @@ -133,8 +160,18 @@ public void initialize() { searchText.setOnKeyReleased(this::searchOnEnter); searchAuthor.textProperty().bindBidirectional(this.searchParameters.authorProperty()); searchAuthor.setOnKeyReleased(this::searchOnEnter); - levelSelector.valueProperty().bindBidirectional(this.searchParameters.levelProperty()); - levelSelector.setOnAction(e -> searchCallback.run()); + selectedLevelsField.textProperty().bind(selectedLevelsString); + levelsToggleButton.setGraphic(new ImageView(ImageCache.getImage(AdvancedSearchViewController.class, "/icons/down_triangle.png"))); + levelsToggleButton.focusedProperty().addListener((changeListener, oldVal, newVal) -> + { + if (!newVal && !levelsContextMenu.isShowing()) + levelsToggleButton.setSelected(false); + }); + + selectedLevelsString.addListener((obs, o, n) -> { + this.searchParameters.levelsProperty().setValue(selectedLevelsString.get()); + searchCallback.run(); + }); searchTags.textProperty().bindBidirectional(this.searchParameters.tagsProperty()); searchParameters.tagsProperty().addListener(searchOnTextChange); searchLogbooks.textProperty().bindBidirectional(this.searchParameters.logbooksProperty()); @@ -143,9 +180,7 @@ public void initialize() { startTime.setOnKeyReleased(this::searchOnEnter); endTime.textProperty().bindBidirectional(this.searchParameters.endTimeProperty()); endTime.setOnKeyReleased(this::searchOnEnter); - searchParameters.addListener((observable, oldValue, newValue) -> { - updateControls(newValue); - }); + searchParameters.addListener((observable, oldValue, newValue) -> updateControls(newValue)); sortAscending.addListener(searchOnSortChange); attachmentTypes.textProperty().bindBidirectional(this.searchParameters.attachmentsProperty()); @@ -170,24 +205,22 @@ public void initialize() { Button apply = new Button(); apply.setText(Messages.Apply); apply.setPrefWidth(80); - apply.setOnAction((event) -> { - Platform.runLater(() -> { - TimeRelativeInterval interval = timeSelectionPane.getInterval(); - if (interval.isStartAbsolute()) { - searchParameters.startTimeProperty().setValue(TimestampFormats.MILLI_FORMAT.format(interval.getAbsoluteStart().get())); - } else { - searchParameters.startTimeProperty().setValue(TimeParser.format(interval.getRelativeStart().get())); - } - if (interval.isEndAbsolute()) { - searchParameters.endTimeProperty().setValue(TimestampFormats.MILLI_FORMAT.format(interval.getAbsoluteEnd().get())); - } else { - searchParameters.endTimeProperty().setValue(TimeParser.format(interval.getRelativeEnd().get())); - } - if (timeSearchPopover.isShowing()) - timeSearchPopover.hide(); - searchCallback.run(); - }); - }); + apply.setOnAction((event) -> Platform.runLater(() -> { + TimeRelativeInterval interval = timeSelectionPane.getInterval(); + if (interval.isStartAbsolute()) { + searchParameters.startTimeProperty().setValue(TimestampFormats.MILLI_FORMAT.format(interval.getAbsoluteStart().get())); + } else { + searchParameters.startTimeProperty().setValue(TimeParser.format(interval.getRelativeStart().get())); + } + if (interval.isEndAbsolute()) { + searchParameters.endTimeProperty().setValue(TimestampFormats.MILLI_FORMAT.format(interval.getAbsoluteEnd().get())); + } else { + searchParameters.endTimeProperty().setValue(TimeParser.format(interval.getRelativeEnd().get())); + } + if (timeSearchPopover.isShowing()) + timeSearchPopover.hide(); + searchCallback.run(); + })); Button cancel = new Button(); cancel.setText("Cancel"); cancel.setPrefWidth(80); @@ -283,9 +316,19 @@ public void initialize() { } }); - List levelList = Arrays.stream(Preferences.levels).toList(); - levelSelector.getItems().add(""); - levelSelector.getItems().addAll(levelList); + levelsList.addAll(logClient.listLevels().stream().map(LogEntryLevel::name).sorted().toList()); + levelsList.forEach(level -> { + LevelSelection levelSelection = new LevelSelection(level, false); + levelSelections.add(levelSelection); + CheckBox checkBox = new CheckBox(level); + LevelSelectionMenuItem levelSelectionMenuItem = new LevelSelectionMenuItem(checkBox); + levelSelectionMenuItem.setHideOnClick(false); + checkBox.selectedProperty().addListener((observable, oldValue, newValue) -> { + levelSelection.selected = newValue; + setSelectedLevelsString(); + }); + levelsContextMenu.getItems().add(levelSelectionMenuItem); + }); sortAscending.addListener((observable, oldValue, newValue) -> { sortDescRadioButton.selectedProperty().set(!newValue); @@ -295,6 +338,11 @@ public void initialize() { sortDescRadioButton.setOnAction(ae -> sortAscending.set(false)); sortAscRadioButton.setOnAction(ae -> sortAscending.set(true)); + + gridPane.setOnMouseClicked(e -> levelsToggleButton.setSelected(false)); + + // Make sure controls are updated based on search string entered by user + updateControls(searchParameters.getValue()); } public AnchorPane getPane() { @@ -308,23 +356,30 @@ public AnchorPane getPane() { */ private void updateControls(String queryString) { Map queryStringParameters = LogbookQueryUtil.parseHumanReadableQueryString(queryString); - queryStringParameters.entrySet().stream().forEach(entry -> { + queryStringParameters.entrySet().forEach(entry -> { Keys keys = Keys.findKey(entry.getKey()); if (keys != null) { if (keys.equals(Keys.LEVEL)) { - List levels = Arrays.stream(Preferences.levels).toList(); - if (levels.contains(entry.getValue())) { - searchParameters.levelProperty().setValue(entry.getValue()); + List validatedLevels = getValidatedLevelsSelection(entry.getValue()); + if (validatedLevels.isEmpty()) { + searchParameters.levelsProperty().setValue(null); } else { - searchParameters.levelProperty().setValue(null); + String selectedLevels = + String.join(",", validatedLevels); + searchParameters.levelsProperty().setValue(selectedLevels); } + levelsContextMenu.getItems().forEach(mi -> { + LevelSelectionMenuItem levelSelectionMenuItem = + (LevelSelectionMenuItem) mi; + levelSelectionMenuItem.setSelected(validatedLevels.contains(levelSelectionMenuItem.getCheckBox().getText())); + }); } else if (keys.equals(Keys.LOGBOOKS)) { List validatedLogbookNames = getValidatedLogbooksSelection(entry.getValue()); if (validatedLogbookNames.isEmpty()) { searchParameters.logbooksProperty().setValue(null); } else { String selectedLogbooks = - validatedLogbookNames.stream().collect(Collectors.joining(",")); + String.join(",", validatedLogbookNames); searchParameters.logbooksProperty().setValue(selectedLogbooks); } logbookSearchPopover.setSelected(validatedLogbookNames); @@ -333,7 +388,7 @@ private void updateControls(String queryString) { if (validatedTagsNames.isEmpty()) { searchParameters.tagsProperty().setValue(null); } else { - String selectedTags = validatedTagsNames.stream().collect(Collectors.joining(",")); + String selectedTags = String.join(",", validatedTagsNames); searchParameters.tagsProperty().setValue(selectedTags); } tagSearchPopover.setSelected(validatedTagsNames); @@ -347,12 +402,10 @@ protected List getValidatedLogbooksSelection(String logbooks) { return Collections.emptyList(); } List validLogbookNames = - logClient.listLogbooks().stream().map(Logbook::getName).sorted().collect(Collectors.toList()); + logClient.listLogbooks().stream().map(Logbook::getName).sorted().toList(); List logbooksFromQueryString = - Arrays.stream(logbooks.split(",")).map(s -> s.trim()).collect(Collectors.toList()); - List validatedLogbookNames = - logbooksFromQueryString.stream().filter(logbookName -> validLogbookNames.contains(logbookName)).collect(Collectors.toList()); - return validatedLogbookNames; + Arrays.stream(logbooks.split(",")).map(String::trim).toList(); + return logbooksFromQueryString.stream().filter(validLogbookNames::contains).collect(Collectors.toList()); } protected List getValidatedTagsSelection(String tags) { @@ -360,12 +413,19 @@ protected List getValidatedTagsSelection(String tags) { return Collections.emptyList(); } List validTagsNames = - logClient.listTags().stream().map(Tag::getName).sorted().collect(Collectors.toList()); + logClient.listTags().stream().map(Tag::getName).sorted().toList(); List logbooksFromQueryString = - Arrays.stream(tags.split(",")).map(s -> s.trim()).collect(Collectors.toList()); - List validatedLogbookNames = - logbooksFromQueryString.stream().filter(logbookName -> validTagsNames.contains(logbookName)).collect(Collectors.toList()); - return validatedLogbookNames; + Arrays.stream(tags.split(",")).map(String::trim).toList(); + return logbooksFromQueryString.stream().filter(validTagsNames::contains).collect(Collectors.toList()); + } + + protected List getValidatedLevelsSelection(String levels) { + if (Strings.isNullOrEmpty(levels)) { + return Collections.emptyList(); + } + List levelsFromQueryString = + Arrays.stream(levels.split(",")).map(String::trim).toList(); + return levelsFromQueryString.stream().filter(levelsList::contains).collect(Collectors.toList()); } public SimpleBooleanProperty getSortAscending() { @@ -378,12 +438,64 @@ private void searchOnEnter(KeyEvent e) { } } - private final ChangeListener searchOnTextChange = (options, oldValue, newValue) -> { - searchCallback.run(); - }; + private final ChangeListener searchOnTextChange = (options, oldValue, newValue) -> searchCallback.run(); - private final ChangeListener searchOnSortChange = (options, oldValue, newValue) -> { - searchCallback.run(); - }; + private final ChangeListener searchOnSortChange = (options, oldValue, newValue) -> searchCallback.run(); + + private void setSelectedLevelsString() { + selectedLevelsString.set(levelSelections.stream().filter(LevelSelection::isSelected) + .map(LevelSelection::getName).collect(Collectors.joining(","))); + } + + @SuppressWarnings("unused") + @FXML + public void selectLevels() { + if (levelsToggleButton.isSelected()) { + levelsContextMenu.show(selectedLevelsField, Side.BOTTOM, 0, 0); + } else { + levelsContextMenu.hide(); + } + } + + /** + * Encapsulates data needed to construct the level selection context menu. + */ + private static class LevelSelection { + private final String name; + private boolean selected; + + public LevelSelection(String name, boolean selected) { + this.name = name; + this.selected = selected; + } + + public String getName() { + return name; + } + + public boolean isSelected() { + return selected; + } + } + + /** + * Encapsulates items needed to maintain the level selection context menu. + */ + private static class LevelSelectionMenuItem extends CustomMenuItem { + private final CheckBox checkBox; + + public LevelSelectionMenuItem(CheckBox checkBox) { + super(checkBox); + this.checkBox = checkBox; + } + + public void setSelected(boolean selected) { + checkBox.setSelected(selected); + } + + public CheckBox getCheckBox() { + return checkBox; + } + } } diff --git a/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/LogEntryTableViewController.java b/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/LogEntryTableViewController.java index 9da1d0bcf5..f1fad641dd 100644 --- a/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/LogEntryTableViewController.java +++ b/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/LogEntryTableViewController.java @@ -165,7 +165,9 @@ public void initialize() { configureComboBox(); ologQueries.setAll(ologQueryManager.getQueries()); - searchParameters.addListener((observable, oldValue, newValue) -> query.getEditor().setText(newValue)); + searchParameters.addListener((observable, oldValue, newValue) -> { + query.getEditor().setText(newValue); + }); tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE); diff --git a/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/SearchParameters.java b/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/SearchParameters.java index f50ba2e095..49ca603d69 100644 --- a/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/SearchParameters.java +++ b/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/SearchParameters.java @@ -43,7 +43,7 @@ public class SearchParameters implements ObservableValue { private SimpleStringProperty title = new SimpleStringProperty(); private SimpleStringProperty text = new SimpleStringProperty(); private SimpleStringProperty author = new SimpleStringProperty(); - private SimpleStringProperty level = new SimpleStringProperty(); + private SimpleStringProperty levels = new SimpleStringProperty(); private SimpleStringProperty tags = new SimpleStringProperty(); private SimpleStringProperty logbooks = new SimpleStringProperty(); private SimpleStringProperty startTime = new SimpleStringProperty(); @@ -74,7 +74,7 @@ public SearchParameters() { updateMap(Keys.OWNER, newValue); notifyListeners(); }); - level.addListener((observable, oldValue, newValue) -> { + levels.addListener((observable, oldValue, newValue) -> { updateMap(Keys.LEVEL, newValue); notifyListeners(); }); @@ -106,7 +106,7 @@ private void updateMap(Keys key, String newValue) { } else { searchParameters.put(key, newValue); } - notifyListeners(); + //notifyListeners(); } public void addListener(InvalidationListener listener) { @@ -149,8 +149,8 @@ public SimpleStringProperty authorProperty() { return author; } - public SimpleStringProperty levelProperty() { - return level; + public SimpleStringProperty levelsProperty() { + return levels; } public SimpleStringProperty tagsProperty() { @@ -203,9 +203,9 @@ public void setQuery(String query) { textProperty().setValue(null); } if (map.containsKey(Keys.LEVEL.getName())) { - levelProperty().setValue(map.get(Keys.LEVEL.getName())); + levelsProperty().setValue(map.get(Keys.LEVEL.getName())); } else { - levelProperty().setValue(null); + levelsProperty().setValue(null); } if (map.containsKey(Keys.TAGS.getName())) { tagsProperty().setValue(map.get(Keys.TAGS.getName())); diff --git a/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/write/LogEntryEditorController.java b/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/write/LogEntryEditorController.java index 7cfc30b8ad..97b98be392 100644 --- a/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/write/LogEntryEditorController.java +++ b/app/logbook/olog/ui/src/main/java/org/phoebus/logbook/olog/ui/write/LogEntryEditorController.java @@ -61,6 +61,7 @@ import org.phoebus.framework.selection.SelectionService; import org.phoebus.logbook.LogClient; import org.phoebus.logbook.LogEntry; +import org.phoebus.logbook.LogEntryLevel; import org.phoebus.logbook.LogFactory; import org.phoebus.logbook.LogService; import org.phoebus.logbook.LogTemplate; @@ -341,16 +342,9 @@ public void initialize() { } levelLabel.setText(LogbookUIPreferences.level_field_name); - // Sites may wish to define a different meaning and name for the "level" field. - String[] levelList = org.phoebus.olog.es.api.Preferences.levels; - availableLevels.addAll(Arrays.asList(levelList)); levelSelector.setItems(availableLevels); - selectedLevelProperty.set(logEntry.getLevel() != null ? logEntry.getLevel() : availableLevels.get(0)); - - levelSelector.getSelectionModel().select(selectedLevelProperty.get()); dateField.setText(TimestampFormats.DATE_FORMAT.format(Instant.now())); - titleField.textProperty().bindBidirectional(titleProperty); titleProperty.addListener((changeListener, oldVal, newVal) -> { @@ -830,6 +824,17 @@ private void getServerSideStaticData() { } templatesProperty.setAll(logClient.getTemplates().stream().toList()); + + Collection levels = logClient.listLevels(); + availableLevels.setAll(levels.stream().map(LogEntryLevel::name).sorted().toList()); + Optional optionalLevel = levels.stream().filter(LogEntryLevel::defaultLevel).findFirst(); + String defaultLevel = null; + if(optionalLevel.isPresent()){ + // One level value should be the default level + defaultLevel = optionalLevel.get().name(); + } + selectedLevelProperty.set(logEntry.getLevel() != null ? logEntry.getLevel() : defaultLevel); + levelSelector.getSelectionModel().select(selectedLevelProperty.get()); }); } @@ -902,7 +907,7 @@ public Optional getLogEntryResult() { * Loads template to configure UI elements. * * @param logTemplate A {@link LogTemplate} selected by user. If null, all log entry elements - * will be cleared, except the Level selector, which will be set to the top-most item. + * will be cleared, except the LogEntryLevel selector, which will be set to the top-most item. */ private void loadTemplate(LogTemplate logTemplate) { if (logTemplate != null) { diff --git a/app/logbook/olog/ui/src/main/resources/log_olog_ui_preferences.properties b/app/logbook/olog/ui/src/main/resources/log_olog_ui_preferences.properties index 92935f036f..55bd93601f 100644 --- a/app/logbook/olog/ui/src/main/resources/log_olog_ui_preferences.properties +++ b/app/logbook/olog/ui/src/main/resources/log_olog_ui_preferences.properties @@ -11,7 +11,7 @@ default_logbook_query=desc=*&start=12 hours&end=now # Stylesheet for the items in the log calendar view calendar_view_item_stylesheet=Agenda.css -# Text to render for the "Level" field of a log entry. Sites may wish to customize this with respect to +# Text to render for the "LogEntryLevel" field of a log entry. Sites may wish to customize this with respect to # its wording and its implied purpose. level_field_name=Level: diff --git a/app/logbook/olog/ui/src/main/resources/org/phoebus/logbook/olog/ui/AdvancedSearchView.fxml b/app/logbook/olog/ui/src/main/resources/org/phoebus/logbook/olog/ui/AdvancedSearchView.fxml index 848b9ab321..87e224afbd 100644 --- a/app/logbook/olog/ui/src/main/resources/org/phoebus/logbook/olog/ui/AdvancedSearchView.fxml +++ b/app/logbook/olog/ui/src/main/resources/org/phoebus/logbook/olog/ui/AdvancedSearchView.fxml @@ -23,10 +23,10 @@ ~ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. --> - + - + @@ -67,7 +67,16 @@