Skip to content
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
20 changes: 13 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
- Adding predefined timeframes to the DQL execution toolbar (user can still define a custom one)
- The DQL execution result will show an empty cell for a boolean column that had a `null` value (instead of the
unchecked checkbox). This change helps to differentiate between `false` and `null` values.
- Executed DQL queries will now be grouped by the tenant they were executed on in the Services tab
- All executed DQL queries will be grouped in the `Services` tab. The root group allows the user to easily access the
most common settings related to DQL execution. All queries will be additionally grouped by the tenant they were
executed with, allowing the user to easily find the query they are looking for in case of using multiple connected
tenants.
- Double-clicking the executed DQL query in the `Services` tab will now either open the related file (if possible),
or open a new DQL query console with the execution context.
- The "Show DQL query" option when executing DQL will now try to show the parsed query instead of the raw one, if
possible.
- Adding support for "Expression DQL" file (with `.dqlexpr` extension), which allows to define a DQL expression without
Expand All @@ -30,23 +35,24 @@
- Support for `.partial.dql` files will be removed in the future, so it's recommended to migrate to the new extension
as soon as possible.
- **Breaking**: Changing the approach to the default Dynatrace tenant used for connections - it will be the first tenant
specified in the list (previously the user needed to specifically select the default one).
specified in the list (previously the user needed to specifically select the default one). Please update the tenants
order if you wish to change the default tenant.
- Created Wiki pages with documentation for the plugin features
- DQL now supports complex sorting expressions (for example, `sort abs(field) > 10 desc`)
- DQL now supports `/* language=X */` comments in strings
- Added missing quick fixes for inspections:
- Dropping DQL commands and functions for unknown & experimental expressions
- Renaming the DQL file to `.dqlpart` when an invalid command context is detected (only for `.dql` files)
- DQL now supports `/* language=X */` comments in strings
- Adding a Dynatrace Query Console view that allows the user to execute DQL queries without opening a DQL file.
You can open the console via the `Tools` -> `Services` -> `Dynatrace Query Console` menu or by clicking the `+` button
in the `Services` tab.
You can open the console via the `Tools` -> `Services` -> `Dynatrace Query Console` menu or by clicking the dedicated
button in the `Services` tab.

### Bug fixes

- Creating an empty DQL variable using the `$type: dql` syntax will now create a multiline comment instead of causing an
error
- When modifying or deleting a Dynatrace tenant that was already used, files using it will ask the user to select a new
tenant.
- When modifying or deleting a Dynatrace tenant that was already used, files using it will require the user to select
a new tenant.

## [1.4.0] - 2026-01-28

Expand Down
4 changes: 2 additions & 2 deletions docs/wiki/DQL.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ displayed at the bottom part of the result view.
#### Query console

The plugin also adds support for executing DQL queries without the need of creating a `.dql` file.
The console can be opened via the `Tools` -> `Services` -> `Dynatrace Query Console` menu or by clicking the `+` button
in the `Services` tab.
The console can be opened via the `Tools` -> `Services` -> `Dynatrace Query Console` menu or by clicking the dedicated
button in the `Services` tab.

### Partial DQL

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
package pl.thedeem.intellij.common.services;

import com.intellij.execution.services.ServiceViewDescriptor;
import com.intellij.openapi.Disposable;

public interface ManagedServiceGroup extends ServiceViewDescriptor, Disposable {
public interface ManagedServiceGroup extends ManagedService {
}
1 change: 1 addition & 0 deletions src/main/java/pl/thedeem/intellij/dql/DQLIcon.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ public interface DQLIcon extends Icons {
Icon GUTTER_EXECUTE_DQL = IntelliJUtils.scaleToBottomRight(AllIcons.Actions.Execute, DYNATRACE_LOGO, 0.5f);
Icon GUTTER_EXECUTE_SETTINGS = IntelliJUtils.scaleToBottomRight(AllIcons.General.GearPlain, DYNATRACE_LOGO, 0.5f);
Icon QUERY_CONSOLE = IntelliJUtils.scaleToBottomRight(AllIcons.General.ProjectTab, DYNATRACE_LOGO, 0.5f);
Icon MANAGE_TENANTS = IntelliJUtils.scaleToBottomRight(AllIcons.Actions.Annotate, DYNATRACE_LOGO, 0.5f);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,12 @@

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.ProjectManager;
import org.jetbrains.annotations.NotNull;
import pl.thedeem.intellij.dql.settings.tenants.DynatraceTenantsConfigurable;

public class ManageTenantsAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
ShowSettingsUtil.getInstance().editConfigurable(
ProjectManager.getInstance().getDefaultProject(),
new DynatraceTenantsConfigurable()
);
DynatraceTenantsConfigurable.showSettings();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,12 @@
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import pl.thedeem.intellij.dql.DQLBundle;
import pl.thedeem.intellij.dql.fileProviders.DQLQueryConsoleVirtualFile;

import java.util.concurrent.atomic.AtomicInteger;

public class OpenDQLQueryConsoleAction extends AnAction implements DumbAware {
public static final AtomicInteger COUNTER = new AtomicInteger(0);
public static final DataKey<String> INITIAL_TENANT = DataKey.create("DQL.INITIAL_TENANT_FOR_QUERY_CONSOLE");

@Override
Expand All @@ -22,12 +17,7 @@ public void actionPerformed(@NotNull AnActionEvent e) {
if (project == null) {
return;
}

DQLQueryConsoleVirtualFile vf = new DQLQueryConsoleVirtualFile(
DQLBundle.message("action.DQL.OpenDQLQueryConsole.ServiceViewAction.consoleName", COUNTER.incrementAndGet()),
e.getData(INITIAL_TENANT)
);
FileEditorManager.getInstance(project).openFile(vf, true);
DQLQueryConsoleVirtualFile.openForTenant(project, e.getData(INITIAL_TENANT));
}
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package pl.thedeem.intellij.dql.editor;

import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
Expand Down Expand Up @@ -32,7 +31,7 @@ public class DQLMissingTenantNotificationProvider implements EditorNotificationP
panel.setText(DQLBundle.message("notifications.noDynatraceTenants.info"));

panel.createActionLabel(DQLBundle.message("notifications.noDynatraceTenants.actions.add"), () -> {
ShowSettingsUtil.getInstance().showSettingsDialog(project, DQLSettingsConfigurable.class);
DQLSettingsConfigurable.showSettings(project);
panel.setVisible(shouldShowToolbar(tenantsService));
EditorNotifications.getInstance(project).updateNotifications(virtualFile);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import com.intellij.util.concurrency.AppExecutorUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jsoup.internal.StringUtil;
import pl.thedeem.intellij.common.IntelliJUtils;
import pl.thedeem.intellij.common.StandardItemPresentation;
import pl.thedeem.intellij.common.components.InformationComponent;
import pl.thedeem.intellij.common.sdk.DynatraceRestClient;
Expand All @@ -31,9 +35,11 @@
import pl.thedeem.intellij.dql.editor.actions.QueryConfigurationAction;
import pl.thedeem.intellij.dql.exec.panel.DQLExecutionErrorPanel;
import pl.thedeem.intellij.dql.exec.panel.DQLExecutionResult;
import pl.thedeem.intellij.dql.fileProviders.DQLQueryConsoleVirtualFile;
import pl.thedeem.intellij.dql.fileProviders.DQLResultVirtualFile;
import pl.thedeem.intellij.dql.services.query.DQLQueryConfigurationService;
import pl.thedeem.intellij.dql.services.query.DQLQueryParserService;
import pl.thedeem.intellij.dql.services.ui.ConnectedTenantsServiceGroup;
import pl.thedeem.intellij.dql.services.ui.TenantServiceGroup;
import pl.thedeem.intellij.dql.settings.tenants.DynatraceTenant;
import pl.thedeem.intellij.dql.settings.tenants.DynatraceTenantsService;
Expand Down Expand Up @@ -93,9 +99,9 @@ public void dispose() {
public @NotNull List<ManagedServiceGroup> getParentGroups() {
String tenant = configuration.tenant();
if (tenant == null) {
return List.of();
return List.of(ConnectedTenantsServiceGroup.getInstance());
}
return List.of(new TenantServiceGroup(tenant));
return List.of(ConnectedTenantsServiceGroup.getInstance(), new TenantServiceGroup(tenant));
}

public void startExecution() {
Expand Down Expand Up @@ -362,4 +368,17 @@ public int hashCode() {
getServiceId()
);
}

@Override
public @Nullable Navigatable getNavigatable() {
String originalFile = configuration.originalFile();
VirtualFile virtualFile = null;
if (originalFile != null) {
virtualFile = IntelliJUtils.getProjectRelativeFile(originalFile, project);
}
if (virtualFile == null) {
virtualFile = new DQLQueryConsoleVirtualFile(this.name, this.configuration.query());
}
return new OpenFileDescriptor(project, virtualFile);
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
package pl.thedeem.intellij.dql.fileProviders;

import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import pl.thedeem.intellij.dql.DQLBundle;
import pl.thedeem.intellij.dql.DQLFileType;
import pl.thedeem.intellij.dql.exec.panel.DQLQueryConsolePanel;

import javax.swing.*;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

public class DQLQueryConsoleVirtualFile extends DQLVirtualFile<String> {
private final String initialTenant;
public static final AtomicInteger COUNTER = new AtomicInteger(0);
private String initialTenant;

public DQLQueryConsoleVirtualFile(@NotNull String name, @Nullable String initialTenant) {
public DQLQueryConsoleVirtualFile(@NotNull String name) {
super(name, "");
this.initialTenant = initialTenant;
}

public DQLQueryConsoleVirtualFile(@NotNull String name, @NotNull String content) {
super(name, content);
}

@Override
Expand All @@ -31,4 +39,36 @@ public boolean isWritable() {
public @NotNull JComponent createComponent(@NotNull Project project) {
return new DQLQueryConsolePanel(project, content, this, initialTenant);
}

public @NotNull DQLQueryConsoleVirtualFile setInitialTenant(@Nullable String initialTenant) {
this.initialTenant = initialTenant;
return this;
}

public static void open(@NotNull Project project) {
open(project, DQLBundle.message("editor.queryConsole.consoleName", COUNTER.incrementAndGet()), null);
}

public static void openForTenant(@NotNull Project project, @Nullable String tenant) {
open(project, DQLBundle.message("editor.queryConsole.consoleName", COUNTER.incrementAndGet()), tenant);
}

public static void open(@NotNull Project project, @NotNull String name, @Nullable String initialTenant) {
DQLQueryConsoleVirtualFile vf = new DQLQueryConsoleVirtualFile(name)
.setInitialTenant(initialTenant);
FileEditorManager.getInstance(project).openFile(vf, true);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DQLVirtualFile<?> casted = this.getClass().cast(o);
return Objects.equals(getName(), casted.getName());
}

@Override
public int hashCode() {
return getName().hashCode();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package pl.thedeem.intellij.dql.services.ui;

import com.intellij.icons.AllIcons;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import pl.thedeem.intellij.common.StandardItemPresentation;
import pl.thedeem.intellij.common.services.ManagedServiceGroup;
import pl.thedeem.intellij.dql.DQLBundle;
import pl.thedeem.intellij.dql.DQLIcon;
import pl.thedeem.intellij.dql.fileProviders.DQLQueryConsoleVirtualFile;
import pl.thedeem.intellij.dql.settings.DQLSettingsConfigurable;
import pl.thedeem.intellij.dql.settings.tenants.DynatraceTenantsConfigurable;

import java.util.List;

public class ConnectedTenantsServiceGroup implements ManagedServiceGroup {
private static final ConnectedTenantsServiceGroup INSTANCE = new ConnectedTenantsServiceGroup();
private DefaultActionGroup actions;

protected ConnectedTenantsServiceGroup() {
}

public static ConnectedTenantsServiceGroup getInstance() {
return INSTANCE;
}

@Override
public @NotNull ItemPresentation getPresentation() {
return new StandardItemPresentation(
DQLBundle.message("services.connectedTenants.groupName"),
null,
DQLIcon.DYNATRACE_LOGO
);
}

@Override
public void dispose() {
}

@Override
public @Nullable ActionGroup getToolbarActions() {
if (actions == null) {
actions = new DefaultActionGroup();
actions.add(new AnAction(
DQLBundle.message("services.connectedTenants.actions.openConsole.title"),
null,
DQLIcon.QUERY_CONSOLE
) {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
if (project == null) {
return;
}
DQLQueryConsoleVirtualFile.open(project);
}
});
actions.add(new AnAction(
DQLBundle.message("services.connectedTenants.actions.allSettings.title"),
null,
AllIcons.General.GearPlain
) {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
if (project == null) {
return;
}
DQLSettingsConfigurable.showSettings(project);
}
});
actions.addAction(new AnAction(
DQLBundle.message("services.connectedTenants.actions.manageTenants.title"),
null,
DQLIcon.MANAGE_TENANTS
) {
@Override
public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
DynatraceTenantsConfigurable.showSettings();
}

@Override
public @NotNull ActionUpdateThread getActionUpdateThread() {
return ActionUpdateThread.BGT;
}
});
}
return actions;
}

@Override
public @NotNull String getServiceId() {
return "DynatraceTenants";
}

@Override
public @NotNull List<ManagedServiceGroup> getParentGroups() {
return List.of();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package pl.thedeem.intellij.dql.services.ui;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.ProjectActivity;
import kotlin.Unit;
import kotlin.coroutines.Continuation;
import org.jetbrains.annotations.NotNull;
import pl.thedeem.intellij.common.services.ProjectServicesManager;

public final class ServicesAutoRegistrationStartupActivity implements ProjectActivity {
@Override
public @NotNull Object execute(@NotNull Project project, @NotNull Continuation<? super Unit> continuation) {
ProjectServicesManager.getInstance(project).registerService(ConnectedTenantsServiceGroup.getInstance());
return Unit.INSTANCE;
}
}
Loading
Loading