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
5 changes: 5 additions & 0 deletions .changeset/lemon-plums-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@wpengine/wpgraphql-logging-wordpress-plugin": patch
---

UI improvements for WPGraphQL Logging plugin: refactored styles, added GraphQL query formatting, and implemented unsaved changes warning
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.settings_page_wpgraphql-logging #poststuff .postbox .inside h2 {
font-size: 1.3em;
.graphql-logs_page_wpgraphql-logging #poststuff .postbox .inside h2 {
font-size: 16.9px;
font-weight: 600;
padding-left: 0;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
.wpgraphql-logging-view-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}

.wpgraphql-logging-details pre.wpgraphql-logging-query,
.wpgraphql-logging-details pre.wpgraphql-logging-context,
.wpgraphql-logging-details pre.wpgraphql-logging-extra {
white-space: pre-wrap;
max-height: 540px;
overflow-y: scroll;
padding: 15px;
border: 1px solid #ddd;
border-radius: 4px;
}

pre.wpgraphql-logging-list-table-query {
overflow-x: auto;
background: #f4f4f4;
margin-top: 0;
margin-bottom: 0;
padding: 15px;
border: 1px solid #ddd;
border-radius: 4px;
max-height: 20px;
}

.wpgraphql-logging-filters input.wpgraphql-logging-datepicker,
.wpgraphql-logging-filters select[name="level_filter"] {
width: 120px;
}

.wpgraphql-logging-filters {
display: inline-flex;
align-items: center;
gap: 8px;
margin-right: 10px;
}

.wpgraphql-logging-filters .clear-all-button {
margin: 0;
margin-left: 5px;
text-decoration: none;
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,96 @@
document.addEventListener('DOMContentLoaded', function() {
const sanitizationMethodSelect = document.querySelector("#data_sanitization_method");
if (!sanitizationMethodSelect) {
return;
document.addEventListener("DOMContentLoaded", function () {
function listenForSanitizationMethodChange() {
const sanitizationMethodSelect = document.querySelector(
"#data_sanitization_method"
);

if (!sanitizationMethodSelect) {
return;
}

function toggleCustomFields() {
const isCustom = sanitizationMethodSelect.value === "custom";
const customElements = document.querySelectorAll(
".wpgraphql-logging-custom"
);

customElements.forEach((el) => {
if (isCustom) {
el.classList.add("block");
} else {
el.classList.remove("block");
}
});
}

toggleCustomFields();
sanitizationMethodSelect.addEventListener("change", toggleCustomFields);
}

function toggleCustomFields() {
const isCustom = sanitizationMethodSelect.value === 'custom';
const customElements = document.querySelectorAll('.wpgraphql-logging-custom');
function listenForUnsavedChanges() {
const formElement = document.querySelector("form");

function getFormState(form) {
const data = new FormData(form);
return JSON.stringify(Array.from(data.entries()));
}

customElements.forEach((el) => {
if (isCustom) {
el.classList.add('block');
} else {
el.classList.remove('block');
// Save the initial state of the form for later comparison
const initialState = getFormState(formElement);

// Warn the user if they try to leave with unsaved changes
function beforeUnload(e) {
const formState = getFormState(formElement);

if (formState !== initialState) {
e.preventDefault();
e.returnValue = true;
}
}

window.addEventListener("beforeunload", beforeUnload);

// Remove the warning on submit so it doesn't appear when saving
formElement.addEventListener("submit", function () {
window.removeEventListener("beforeunload", beforeUnload);
});
}

toggleCustomFields();
sanitizationMethodSelect.addEventListener('change', toggleCustomFields);
function listenForLogPointsSelection() {
const logPointsInput = document.querySelector("#event_log_selection");
const enableCheckbox = document.querySelector(
"input[name='wpgraphql_logging_settings[basic_configuration][enabled]']"
);

function checkLogPointsSelection() {
const anyLogPointsSelected = logPointsInput.selectedOptions.length > 0;

const existingDescription =
logPointsInput.parentElement.querySelector(".description");
if (existingDescription) {
existingDescription.remove();
}

// If the logging is enabled and no log points are selected, show a description
if (enableCheckbox?.checked && !anyLogPointsSelected) {
const description = document.createElement("p");

if (!logPointsInput.parentElement.querySelector(".description")) {
description.className = "description";
description.textContent =
"If you don't select any log points, no data will be logged.";
description.style.marginLeft = "25px";
logPointsInput.parentElement.appendChild(description);
}
}
}

logPointsInput.addEventListener("change", checkLogPointsSelection);
enableCheckbox.addEventListener("change", checkLogPointsSelection);
checkLogPointsSelection();
}

listenForSanitizationMethodChange();
listenForUnsavedChanges();
listenForLogPointsSelection();
});
124 changes: 124 additions & 0 deletions plugins/wpgraphql-logging/assets/js/view/wp-graphql-logging-view.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,127 @@ jQuery(document).ready(function($) {
timeFormat: "HH:mm:ss"
});
});

document.addEventListener("DOMContentLoaded", function () {
function formatGraphQLQuery(query, indentSize = 2) {
if (!query || typeof query !== "string") return "";

try {
let formatted = query.trim().replace(/\s+/g, " ");
let indentLevel = 0,
result = "",
inString = false,
stringChar = null,
afterClosingParen = false;
const operationTypes = ["query", "mutation", "subscription", "fragment"];
const indent = () => "\n" + " ".repeat(indentLevel * indentSize);

for (let i = 0; i < formatted.length; i++) {
const char = formatted[i],
prev = formatted[i - 1],
next = formatted[i + 1];

// Track string literals
if ((char === '"' || char === "'") && prev !== "\\") {
if (!inString) {
inString = true;
stringChar = char;
} else if (char === stringChar) {
inString = false;
stringChar = null;
}
}

if (inString) {
result += char;
continue;
}

// Handle braces and parentheses
if (char === "{" || char === "(") {
result = result.trimEnd() + (char === "{" ? " {" : "(");
if (next !== (char === "{" ? "}" : ")")) {
indentLevel++;
result += indent();
}
afterClosingParen = false;
} else if (char === "}" || char === ")") {
if (prev !== (char === "}" ? "{" : "(")) {
indentLevel--;
result = result.trimEnd() + indent();
}
result += char;
afterClosingParen = char === ")";
} else if (char === ",") {
result += "," + indent();
afterClosingParen = false;
} else if (char === " ") {
const trimmed = result.trimEnd();
const lastWord =
trimmed
.split(/[\s\n{}(),]/)
.filter((w) => w)
.pop() || "";
const lastChar = trimmed.slice(-1);

if (
(afterClosingParen && next === "@") ||
trimmed.endsWith("...") ||
lastWord === "on" ||
operationTypes.includes(lastWord) ||
lastChar === ":" ||
lastChar === "@" ||
trimmed.match(/@\w+$/)
) {
result += char;
} else {
const isBetweenFields =
lastChar &&
/[a-zA-Z0-9_]/.test(lastChar) &&
next &&
/[a-zA-Z_]/.test(next) &&
!["{", "}", "(", ")", ",", ":", "\n", "@", "."].includes(next);

if (isBetweenFields) {
result = result.trimEnd() + indent();
afterClosingParen = false;
} else if (!["\n", " "].includes(result.slice(-1))) {
result += char;
}
}
} else {
if (
afterClosingParen &&
char !== "@" &&
char !== "{" &&
char !== "}"
) {
result = result.trimEnd() + " ";
}
result += char;
afterClosingParen = false;
}
}

return result
.split("\n")
.map((line) => line.trimEnd())
.join("\n");
} catch (error) {
console.error("GraphQL formatting error:", error);
return query;
}
}

const queryElements = document.querySelectorAll(
"pre.wpgraphql-logging-query"
);

if (queryElements.length > 0) {
queryElements.forEach(function (element) {
const rawQuery = element.textContent;
const formattedQuery = formatGraphQLQuery(rawQuery);
element.textContent = formattedQuery;
});
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ protected function format_code(string $code): string {
if ( empty( $code ) ) {
return '';
}
return '<pre style="overflow-x: auto; background: #f4f4f4; padding: 15px; border: 1px solid #ddd; border-radius: 4px; max-height: 300px;">' . esc_html( $code ) . '</pre>';
return '<pre class="wpgraphql-logging-list-table-query">' . esc_html( $code ) . '</pre>';
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,22 @@
$wpgraphql_logging_log_levels = apply_filters( 'wpgraphql_logging_log_levels', $wpgraphql_logging_log_levels );
?>

<div class="alignleft actions" style="display: inline-flex; align-items: center; gap: 8px; margin-right: 10px;">
<div class="alignleft actions wpgraphql-logging-filters">
<input type="text"
name="start_date"
class="wpgraphql-logging-datepicker"
placeholder="Start Date"
value="<?php echo esc_attr( $wpgraphql_logging_current_start_date ); ?>"
autocomplete="off"
style="width: 120px;" />
autocomplete="off" />

<input type="text"
name="end_date"
class="wpgraphql-logging-datepicker"
placeholder="End Date"
value="<?php echo esc_attr( $wpgraphql_logging_current_end_date ); ?>"
autocomplete="off"
style="width: 120px;" />
autocomplete="off" />

<select name="level_filter" style="width: 120px;">
<select name="level_filter">
<option value="">All Levels</option>
<?php foreach ( $wpgraphql_logging_log_levels as $wpgraphql_logging_level ) : ?>
<option value="<?php echo esc_attr( $wpgraphql_logging_level ); ?>" <?php selected( $wpgraphql_logging_current_level, $wpgraphql_logging_level ); ?>>
Expand All @@ -51,8 +49,7 @@ class="wpgraphql-logging-datepicker"
<?php submit_button( __( 'Filter', 'wpgraphql-logging' ), 'secondary', '', false, [ 'style' => 'margin: 0;' ] ); ?>

<a href="<?php echo esc_url( admin_url( 'admin.php?page=wpgraphql-logging-view' ) ); ?>"
class="clear-all-button"
style="margin: 0; margin-left: 5px; text-decoration: none;">
class="clear-all-button">
<?php esc_html_e( 'Clear All', 'wpgraphql-logging' ); ?>
</a>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/
?>
<div class="wrap">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;">
<div class="wpgraphql-logging-view-header">
<h1><?php esc_html_e( 'Log Entry', 'wpgraphql-logging' ); ?></h1>
<a href="
<?php
Expand All @@ -33,7 +33,7 @@
</a>
</div>

<table class="widefat striped">
<table class="widefat striped wpgraphql-logging-details">
<tbody>
<tr>
<th><?php esc_html_e( 'ID', 'wpgraphql-logging' ); ?></th>
Expand Down Expand Up @@ -61,15 +61,15 @@
</tr>
<tr>
<th><?php esc_html_e( 'Query', 'wpgraphql-logging' ); ?></th>
<td><pre style="overflow-x: auto; background: #f4f4f4; padding: 15px; border: 1px solid #ddd; border-radius: 4px;"><?php echo esc_html( (string) $log->get_query() ); ?></pre></td>
<td><pre class="wpgraphql-logging-query"><?php echo esc_html( (string) $log->get_query() ); ?></pre></td>
</tr>
<tr>
<th><?php esc_html_e( 'Context', 'wpgraphql-logging' ); ?></th>
<td><pre><?php echo esc_html( (string) wp_json_encode( $log->get_context(), JSON_PRETTY_PRINT ) ); ?></pre></td>
<td><pre class="wpgraphql-logging-context"><?php echo esc_html( (string) wp_json_encode( $log->get_context(), JSON_PRETTY_PRINT ) ); ?></pre></td>
</tr>
<tr>
<th><?php esc_html_e( 'Extra', 'wpgraphql-logging' ); ?></th>
<td><pre><?php echo esc_html( (string) wp_json_encode( $log->get_extra(), JSON_PRETTY_PRINT ) ); ?></pre></td>
<td><pre class="wpgraphql-logging-extra"><?php echo esc_html( (string) wp_json_encode( $log->get_extra(), JSON_PRETTY_PRINT ) ); ?></pre></td>
</tr>
</tbody>
</table>
Expand Down
8 changes: 8 additions & 0 deletions plugins/wpgraphql-logging/src/Admin/ViewLogsPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,14 @@ public function enqueue_admin_scripts_styles( string $hook_suffix ): void {
);
}

if ( file_exists( trailingslashit( WPGRAPHQL_LOGGING_PLUGIN_DIR ) . 'assets/css/view/wp-graphql-logging-view.css' ) ) {
wp_enqueue_style(
'wpgraphql-graphql-logging-view',
trailingslashit( WPGRAPHQL_LOGGING_PLUGIN_URL ) . 'assets/css/view/wp-graphql-logging-view.css',
[],
WPGRAPHQL_LOGGING_VERSION
);
}

// Allow other plugins to enqueue their own scripts/styles.
do_action( 'wpgraphql_logging_view_logs_admin_enqueue_scripts', $hook_suffix );
Expand Down
Loading
Loading