Fix dark theme colors, reload button functionality, and code cleanup
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "jmespath-playground",
|
"name": "jmespath-playground",
|
||||||
"version": "1.2.1",
|
"version": "1.2.2",
|
||||||
"description": "A React-based web application for testing JMESPath expressions against JSON data",
|
"description": "A React-based web application for testing JMESPath expressions against JSON data",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
"prebuild": "node scripts/version-check.js",
|
"prebuild": "node scripts/version-check.js",
|
||||||
"build": "react-scripts build",
|
"build": "react-scripts build",
|
||||||
"test": "react-scripts test",
|
"test": "react-scripts test --watchAll=false",
|
||||||
|
"test:watch": "react-scripts test",
|
||||||
"server": "node server.js"
|
"server": "node server.js"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|||||||
624
src/App.css
624
src/App.css
@@ -1,41 +1,9 @@
|
|||||||
/* JMESPath Testing Tool Custom Styles */
|
/* JMESPath Testing Tool Custom Styles */
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
/* Light theme colors */
|
/* Common variables */
|
||||||
--bg-primary-light: #ffffff;
|
--font-mono: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', monospace;
|
||||||
--bg-secondary-light: #f8f9fa;
|
|
||||||
--text-primary-light: #212529;
|
|
||||||
--text-secondary-light: #495057;
|
|
||||||
--text-muted-light: #6c757d;
|
|
||||||
--border-light: #dee2e6;
|
|
||||||
--border-input-light: #ced4da;
|
|
||||||
--accent-color: #007bff;
|
--accent-color: #007bff;
|
||||||
--accent-shadow: rgba(0, 123, 255, 0.25);
|
|
||||||
|
|
||||||
/* Dark theme colors */
|
|
||||||
--bg-primary-dark: #1a1a1a;
|
|
||||||
--bg-secondary-dark: #2d2d2d;
|
|
||||||
--bg-card-dark: #323232;
|
|
||||||
--text-primary-dark: #ffffff;
|
|
||||||
--text-secondary-dark: #e9ecef;
|
|
||||||
--text-muted-dark: #adb5bd;
|
|
||||||
--border-dark: #495057;
|
|
||||||
--border-input-dark: #6c757d;
|
|
||||||
|
|
||||||
/* State colors */
|
|
||||||
--success-bg-light: #d4edda;
|
|
||||||
--success-border-light: #c3e6cb;
|
|
||||||
--success-text-light: #155724;
|
|
||||||
--success-bg-dark: #1e4a1e;
|
|
||||||
--success-border-dark: #2c6d2c;
|
|
||||||
--success-text-dark: #d4edda;
|
|
||||||
|
|
||||||
--error-bg-light: #f8d7da;
|
|
||||||
--error-border-light: #f5c6cb;
|
|
||||||
--error-text-light: #721c24;
|
|
||||||
--error-bg-dark: #4a1e1e;
|
|
||||||
--error-border-dark: #6d2c2c;
|
|
||||||
--error-text-dark: #f8d7da;
|
|
||||||
|
|
||||||
/* Button variants */
|
/* Button variants */
|
||||||
--btn-success: #28a745;
|
--btn-success: #28a745;
|
||||||
@@ -98,16 +66,10 @@ body {
|
|||||||
.jmespath-input {
|
.jmespath-input {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: var(--bg-primary-light);
|
|
||||||
border: 1px solid var(--border-input-light);
|
|
||||||
color: var(--text-secondary-light);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.json-input, .result-output {
|
.json-input, .result-output {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
background-color: var(--bg-secondary-light);
|
|
||||||
border: 1px solid var(--border-light);
|
|
||||||
color: var(--text-secondary-light);
|
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,15 +87,6 @@ footer {
|
|||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer a {
|
|
||||||
color: var(--text-muted-light);
|
|
||||||
transition: color var(--transition-fast);
|
|
||||||
}
|
|
||||||
|
|
||||||
footer a:hover {
|
|
||||||
color: var(--text-secondary-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive adjustments */
|
/* Responsive adjustments */
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.header-section {
|
.header-section {
|
||||||
@@ -158,519 +111,152 @@ footer a:hover {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Manual theme overrides */
|
/* Bootstrap theme integration */
|
||||||
.theme-light {
|
[data-bs-theme="light"] {
|
||||||
/* Force light theme regardless of system preference */
|
--bg-primary: #ffffff;
|
||||||
background-color: #ffffff !important;
|
--bg-secondary: #f8f9fa;
|
||||||
color: #212529 !important;
|
--text-primary: #212529;
|
||||||
}
|
--text-secondary: #495057;
|
||||||
|
--text-muted: #6c757d;
|
||||||
.theme-light .header-section {
|
--border: #dee2e6;
|
||||||
background-color: transparent !important;
|
--border-input: #ced4da;
|
||||||
border-bottom: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .card {
|
|
||||||
background-color: #ffffff !important;
|
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1) !important;
|
|
||||||
color: #212529 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .card-header {
|
|
||||||
background-color: #f8f9fa !important;
|
|
||||||
border-bottom: 2px solid #dee2e6 !important;
|
|
||||||
color: #212529 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .jmespath-input {
|
|
||||||
background-color: #ffffff;
|
|
||||||
border: 1px solid #ced4da;
|
|
||||||
color: #495057;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .json-input,
|
|
||||||
.theme-light .result-output {
|
|
||||||
background-color: #f8f9fa !important;
|
|
||||||
border: 1px solid #dee2e6 !important;
|
|
||||||
color: #495057 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Success and Error state overrides - must come after base input rules */
|
|
||||||
.theme-light .jmespath-input.success {
|
|
||||||
background-color: #d4edda !important;
|
|
||||||
border-color: #c3e6cb !important;
|
|
||||||
color: #155724 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .jmespath-input.error {
|
|
||||||
background-color: #f8d7da !important;
|
|
||||||
border-color: #f5c6cb !important;
|
|
||||||
color: #721c24 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .text-muted {
|
|
||||||
color: #6c757d !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .jmespath-input:focus {
|
|
||||||
border-color: var(--accent-color);
|
|
||||||
box-shadow: 0 0 0 0.2rem var(--accent-shadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .jmespath-input::placeholder {
|
|
||||||
color: var(--text-muted-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .json-input::placeholder,
|
|
||||||
.theme-light .result-output::placeholder {
|
|
||||||
color: var(--text-muted-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .json-input:focus,
|
|
||||||
.theme-light .result-output:focus {
|
|
||||||
background-color: var(--bg-primary-light) !important;
|
|
||||||
border-color: var(--accent-color) !important;
|
|
||||||
color: var(--text-secondary-light) !important;
|
|
||||||
box-shadow: 0 0 0 0.2rem var(--accent-shadow) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .output-section .form-control {
|
|
||||||
background-color: #f8f9fa !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .alert-danger {
|
|
||||||
background-color: #f8d7da !important;
|
|
||||||
border-color: #f5c6cb !important;
|
|
||||||
color: #721c24 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .alert-success {
|
|
||||||
background-color: #d4edda !important;
|
|
||||||
border-color: #c3e6cb !important;
|
|
||||||
color: #155724 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-primary {
|
|
||||||
background-color: var(--btn-primary) !important;
|
|
||||||
border-color: var(--btn-primary) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-secondary {
|
|
||||||
color: var(--btn-secondary) !important;
|
|
||||||
border-color: var(--btn-secondary) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-secondary:hover {
|
|
||||||
background-color: var(--btn-secondary) !important;
|
|
||||||
border-color: var(--btn-secondary) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-success {
|
|
||||||
color: var(--btn-success) !important;
|
|
||||||
border-color: var(--btn-success) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-success:hover {
|
|
||||||
background-color: var(--btn-success) !important;
|
|
||||||
border-color: var(--btn-success) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-info {
|
|
||||||
color: var(--btn-info) !important;
|
|
||||||
border-color: var(--btn-info) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-info:hover {
|
|
||||||
background-color: var(--btn-info) !important;
|
|
||||||
border-color: var(--btn-info) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-primary {
|
|
||||||
color: var(--btn-primary) !important;
|
|
||||||
border-color: var(--btn-primary) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-primary:hover {
|
|
||||||
background-color: var(--btn-primary) !important;
|
|
||||||
border-color: var(--btn-primary) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-danger {
|
|
||||||
color: var(--btn-danger) !important;
|
|
||||||
border-color: var(--btn-danger) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light .btn-outline-danger:hover {
|
--success-bg: #d4edda;
|
||||||
background-color: var(--btn-danger) !important;
|
--success-border: #c3e6cb;
|
||||||
border-color: var(--btn-danger) !important;
|
--success-text: #155724;
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-light footer {
|
--error-bg: #f8d7da;
|
||||||
background-color: #f8f9fa !important;
|
--error-border: #f5c6cb;
|
||||||
border-top: 1px solid #dee2e6 !important;
|
--error-text: #721c24;
|
||||||
color: #212529 !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-light footer a {
|
[data-bs-theme="dark"] {
|
||||||
color: #6c757d !important;
|
--bg-primary: #1a1a1a;
|
||||||
}
|
--bg-secondary: #2d2d2d;
|
||||||
|
--bg-card: #323232;
|
||||||
|
--text-primary: #ffffff;
|
||||||
|
--text-secondary: #e9ecef;
|
||||||
|
--text-muted: #adb5bd;
|
||||||
|
--border: #495057;
|
||||||
|
--border-input: #6c757d;
|
||||||
|
|
||||||
.theme-light footer a:hover {
|
--success-bg: #1e4a1e;
|
||||||
color: #495057 !important;
|
--success-border: #2c6d2c;
|
||||||
}
|
--success-text: #d4edda;
|
||||||
|
|
||||||
/* Force dark theme regardless of system preference */
|
|
||||||
.theme-dark {
|
|
||||||
background-color: var(--bg-primary-dark) !important;
|
|
||||||
color: var(--text-secondary-dark) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .header-section {
|
--error-bg: #4a1e1e;
|
||||||
background-color: var(--bg-secondary-dark) !important;
|
--error-border: #6d2c2c;
|
||||||
border-bottom: 1px solid #404040 !important;
|
--error-text: #f8d7da;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .card {
|
/* Apply theme colors */
|
||||||
background-color: var(--bg-secondary-dark) !important;
|
body {
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.3) !important;
|
background-color: var(--bg-primary);
|
||||||
color: var(--text-secondary-dark) !important;
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .card-header {
|
.card {
|
||||||
background-color: var(--bg-card-dark) !important;
|
background-color: var(--bg-primary);
|
||||||
border-bottom: 2px solid #505050 !important;
|
border-color: var(--border);
|
||||||
color: var(--text-primary-dark) !important;
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .jmespath-input {
|
.card-header {
|
||||||
background-color: var(--bg-card-dark);
|
background-color: var(--bg-secondary);
|
||||||
border: 1px solid #505050;
|
border-bottom-color: var(--border);
|
||||||
color: var(--text-primary-dark);
|
color: var(--text-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Success and Error state overrides - must come after base input rules */
|
.jmespath-input {
|
||||||
.theme-dark .jmespath-input.success {
|
background-color: var(--bg-primary);
|
||||||
background-color: #1e4a1e !important;
|
border-color: var(--border-input);
|
||||||
border-color: #2c6d2c !important;
|
color: var(--text-secondary);
|
||||||
color: #d4edda !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .jmespath-input.error {
|
.json-input, .result-output {
|
||||||
background-color: #4a1e1e !important;
|
background-color: var(--bg-secondary);
|
||||||
border-color: #6d2c2c !important;
|
border-color: var(--border);
|
||||||
color: #f8d7da !important;
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .jmespath-input::placeholder {
|
footer {
|
||||||
color: var(--text-muted-dark) !important;
|
background-color: var(--bg-secondary);
|
||||||
|
color: var(--text-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .jmespath-input:focus {
|
footer.bg-light {
|
||||||
border-color: var(--accent-color);
|
background-color: var(--bg-secondary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .json-input,
|
footer a {
|
||||||
.theme-dark .result-output {
|
color: var(--text-muted);
|
||||||
background-color: #2a2a2a !important;
|
|
||||||
border: 1px solid #505050 !important;
|
|
||||||
color: var(--text-secondary-dark) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .json-input::placeholder,
|
footer a:hover {
|
||||||
.theme-dark .result-output::placeholder {
|
color: var(--text-secondary);
|
||||||
color: var(--text-muted-dark) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .json-input:focus,
|
/* State styles */
|
||||||
.theme-dark .result-output:focus {
|
.jmespath-input.success {
|
||||||
background-color: var(--bg-card-dark) !important;
|
background-color: var(--success-bg) !important;
|
||||||
border-color: var(--accent-color) !important;
|
border-color: var(--success-border) !important;
|
||||||
color: var(--text-primary-dark) !important;
|
color: var(--success-text) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .output-section .form-control {
|
.jmespath-input.error {
|
||||||
background-color: var(--bg-secondary-dark) !important;
|
background-color: var(--error-bg) !important;
|
||||||
|
border-color: var(--error-border) !important;
|
||||||
|
color: var(--error-text) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .alert-danger {
|
.json-input.success {
|
||||||
background-color: #3d1a1a !important;
|
background-color: var(--success-bg) !important;
|
||||||
border-color: #dc3545 !important;
|
border-color: var(--success-border) !important;
|
||||||
color: #f8d7da !important;
|
color: var(--success-text) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .alert-success {
|
.json-input.error {
|
||||||
background-color: #1e4a1e !important;
|
background-color: var(--error-bg) !important;
|
||||||
border-color: #2c6d2c !important;
|
border-color: var(--error-border) !important;
|
||||||
color: #d4edda !important;
|
color: var(--error-text) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .text-muted {
|
/* Focus states */
|
||||||
color: var(--text-muted-dark) !important;
|
.jmespath-input:focus {
|
||||||
|
border-color: var(--accent-color, #007bff);
|
||||||
|
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark footer {
|
.json-input:focus,
|
||||||
background-color: var(--bg-secondary-dark) !important;
|
.result-output:focus {
|
||||||
border-top: 1px solid #404040 !important;
|
background-color: var(--bg-primary);
|
||||||
color: var(--text-secondary-dark) !important;
|
border-color: var(--accent-color, #007bff);
|
||||||
|
color: var(--text-secondary);
|
||||||
|
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark footer a {
|
/* Placeholder colors */
|
||||||
color: var(--text-muted-dark) !important;
|
.jmespath-input::placeholder,
|
||||||
|
.json-input::placeholder,
|
||||||
|
.result-output::placeholder {
|
||||||
|
color: var(--text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark footer a:hover {
|
/* Alert styles */
|
||||||
color: var(--text-secondary-dark) !important;
|
.alert-danger {
|
||||||
|
background-color: var(--error-bg);
|
||||||
|
border-color: var(--error-border);
|
||||||
|
color: var(--error-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .btn-primary {
|
/* Code block styles */
|
||||||
background-color: var(--btn-primary) !important;
|
pre.bg-light {
|
||||||
border-color: var(--btn-primary) !important;
|
background-color: var(--bg-secondary) !important;
|
||||||
color: var(--bg-primary-light) !important;
|
color: var(--text-secondary) !important;
|
||||||
|
border-color: var(--border) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .btn-outline-secondary {
|
code {
|
||||||
color: var(--btn-secondary) !important;
|
color: var(--text-secondary);
|
||||||
border-color: var(--btn-secondary) !important;
|
|
||||||
}
|
|
||||||
.theme-dark .btn-outline-secondary:hover {
|
|
||||||
background-color: var(--btn-secondary) !important;
|
|
||||||
border-color: var(--btn-secondary) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .btn-outline-success {
|
|
||||||
color: var(--btn-success) !important;
|
|
||||||
border-color: var(--btn-success) !important;
|
|
||||||
}
|
|
||||||
.theme-dark .btn-outline-success:hover {
|
|
||||||
background-color: var(--btn-success) !important;
|
|
||||||
border-color: var(--btn-success) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-dark .btn-outline-info {
|
|
||||||
color: var(--btn-info) !important;
|
|
||||||
border-color: var(--btn-info) !important;
|
|
||||||
}
|
|
||||||
.theme-dark .btn-outline-info:hover {
|
|
||||||
background-color: var(--btn-info) !important;
|
|
||||||
border-color: var(--btn-info) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
.theme-light .btn-outline-info {
|
|
||||||
color: var(--btn-info) !important;
|
|
||||||
border-color: var(--btn-info) !important;
|
|
||||||
}
|
|
||||||
.theme-light .btn-outline-info:hover {
|
|
||||||
background-color: var(--btn-info) !important;
|
|
||||||
border-color: var(--btn-info) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
.theme-dark .btn-outline-info {
|
|
||||||
color: var(--btn-info) !important;
|
|
||||||
border-color: var(--btn-info) !important;
|
|
||||||
}
|
|
||||||
.theme-dark .btn-outline-info:hover {
|
|
||||||
background-color: var(--btn-info) !important;
|
|
||||||
border-color: var(--btn-info) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .btn-outline-primary {
|
|
||||||
color: var(--btn-primary) !important;
|
|
||||||
border-color: var(--btn-primary) !important;
|
|
||||||
}
|
|
||||||
.theme-dark .btn-outline-primary:hover {
|
|
||||||
background-color: var(--btn-primary) !important;
|
|
||||||
border-color: var(--btn-primary) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-dark .btn-outline-danger {
|
|
||||||
color: var(--btn-danger) !important;
|
|
||||||
border-color: var(--btn-danger) !important;
|
|
||||||
}
|
|
||||||
.theme-dark .btn-outline-danger:hover {
|
|
||||||
background-color: var(--btn-danger) !important;
|
|
||||||
border-color: var(--btn-danger) !important;
|
|
||||||
color: var(--bg-primary-light) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dark mode support */
|
|
||||||
@media (prefers-color-scheme: dark) {
|
|
||||||
body:not(.theme-light):not(.theme-dark) {
|
|
||||||
background-color: var(--bg-primary-dark);
|
|
||||||
color: var(--text-secondary-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .header-section {
|
|
||||||
background-color: var(--bg-secondary-dark);
|
|
||||||
border-bottom: 1px solid var(--border-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .card {
|
|
||||||
background-color: var(--bg-secondary-dark);
|
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
||||||
color: var(--text-secondary-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .card-header {
|
|
||||||
background-color: var(--bg-card-dark);
|
|
||||||
border-bottom: 2px solid var(--border-dark);
|
|
||||||
color: var(--text-primary-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .jmespath-input {
|
|
||||||
background-color: var(--bg-card-dark) !important;
|
|
||||||
border: 1px solid var(--border-input-dark) !important;
|
|
||||||
color: var(--text-primary-dark) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .jmespath-input.success {
|
|
||||||
background-color: var(--success-bg-dark) !important;
|
|
||||||
border-color: var(--success-border-dark) !important;
|
|
||||||
color: var(--success-text-dark) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .jmespath-input.error {
|
|
||||||
background-color: var(--error-bg-dark) !important;
|
|
||||||
border-color: var(--error-border-dark) !important;
|
|
||||||
color: var(--error-text-dark) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .jmespath-input::placeholder {
|
|
||||||
color: var(--text-muted-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .jmespath-input:focus {
|
|
||||||
border-color: var(--accent-color);
|
|
||||||
box-shadow: 0 0 0 0.2rem var(--accent-shadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .json-input,
|
|
||||||
body:not(.theme-light):not(.theme-dark) .result-output {
|
|
||||||
background-color: #2a2a2a;
|
|
||||||
border: 1px solid var(--border-input-dark);
|
|
||||||
color: var(--text-secondary-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .json-input::placeholder,
|
|
||||||
body:not(.theme-light):not(.theme-dark) .result-output::placeholder {
|
|
||||||
color: var(--text-muted-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .json-input:focus,
|
|
||||||
body:not(.theme-light):not(.theme-dark) .result-output:focus {
|
|
||||||
background-color: #323232;
|
|
||||||
border-color: var(--accent-color);
|
|
||||||
color: var(--text-primary-dark);
|
|
||||||
box-shadow: 0 0 0 0.2rem var(--accent-shadow);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .alert-danger {
|
|
||||||
background-color: var(--error-bg-dark);
|
|
||||||
border-color: var(--error-border-dark);
|
|
||||||
color: var(--error-text-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .alert-success {
|
|
||||||
background-color: var(--success-bg-dark);
|
|
||||||
border-color: var(--success-border-dark);
|
|
||||||
color: var(--success-text-dark);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .text-muted {
|
|
||||||
color: var(--text-muted-dark) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) footer.bg-light {
|
|
||||||
background-color: var(--bg-secondary-dark) !important;
|
|
||||||
border-top: 1px solid var(--border-dark) !important;
|
|
||||||
color: var(--text-secondary-dark) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) footer .text-muted {
|
|
||||||
color: var(--text-muted-dark) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) footer a {
|
|
||||||
color: var(--text-muted-dark) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) footer a:hover {
|
|
||||||
color: var(--text-secondary-dark) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bootstrap dark mode overrides */
|
|
||||||
body:not(.theme-light):not(.theme-dark) .btn-outline-info {
|
|
||||||
color: var(--btn-info);
|
|
||||||
border-color: var(--btn-info);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .btn-outline-info:hover {
|
|
||||||
background-color: var(--btn-info);
|
|
||||||
border-color: var(--btn-info);
|
|
||||||
color: var(--bg-primary-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .btn-outline-success {
|
|
||||||
color: var(--btn-success);
|
|
||||||
border-color: var(--btn-success);
|
|
||||||
}
|
|
||||||
|
|
||||||
body:not(.theme-light):not(.theme-dark) .btn-outline-success:hover {
|
|
||||||
background-color: var(--btn-success);
|
|
||||||
border-color: var(--btn-success);
|
|
||||||
color: var(--bg-primary-light);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-info {
|
|
||||||
color: #17a2b8;
|
|
||||||
border-color: #17a2b8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-info:hover {
|
|
||||||
background-color: #17a2b8;
|
|
||||||
border-color: #17a2b8;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-primary {
|
|
||||||
color: #007bff;
|
|
||||||
border-color: #007bff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-primary:hover {
|
|
||||||
background-color: #007bff;
|
|
||||||
border-color: #007bff;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-secondary {
|
|
||||||
color: #6c757d;
|
|
||||||
border-color: #6c757d;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-secondary:hover {
|
|
||||||
background-color: #6c757d;
|
|
||||||
border-color: var(--btn-secondary);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-danger {
|
|
||||||
color: var(--btn-danger);
|
|
||||||
border-color: var(--btn-danger);
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-outline-danger:hover {
|
|
||||||
background-color: var(--btn-danger);
|
|
||||||
border-color: var(--btn-danger);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
36
src/App.js
36
src/App.js
@@ -45,21 +45,12 @@ function App() {
|
|||||||
|
|
||||||
// Theme management
|
// Theme management
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Apply theme to document
|
|
||||||
const applyTheme = (selectedTheme) => {
|
const applyTheme = (selectedTheme) => {
|
||||||
const root = document.documentElement;
|
const effectiveTheme = selectedTheme === 'auto'
|
||||||
const body = document.body;
|
? (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')
|
||||||
|
: selectedTheme;
|
||||||
|
|
||||||
// Clear existing theme classes from both html and body
|
document.documentElement.setAttribute('data-bs-theme', effectiveTheme);
|
||||||
root.className = '';
|
|
||||||
body.classList.remove('theme-light', 'theme-dark');
|
|
||||||
|
|
||||||
if (selectedTheme === 'light') {
|
|
||||||
body.classList.add('theme-light');
|
|
||||||
} else if (selectedTheme === 'dark') {
|
|
||||||
body.classList.add('theme-dark');
|
|
||||||
}
|
|
||||||
// 'auto' uses CSS media queries (no class needed)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
applyTheme(theme);
|
applyTheme(theme);
|
||||||
@@ -68,23 +59,18 @@ function App() {
|
|||||||
localStorage.setItem('theme', theme);
|
localStorage.setItem('theme', theme);
|
||||||
}, [theme]);
|
}, [theme]);
|
||||||
|
|
||||||
// Check if we're running on localhost
|
// Get headers for API requests
|
||||||
const isRunningOnLocalhost = () => {
|
|
||||||
const hostname = window.location.hostname;
|
|
||||||
return hostname === 'localhost' ||
|
|
||||||
hostname === '127.0.0.1' ||
|
|
||||||
hostname.startsWith('127.') ||
|
|
||||||
hostname === '::1';
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get headers for API requests (omit API key for localhost)
|
|
||||||
const getApiHeaders = () => {
|
const getApiHeaders = () => {
|
||||||
const headers = {
|
const headers = {
|
||||||
'Accept': 'application/json'
|
'Accept': 'application/json'
|
||||||
};
|
};
|
||||||
|
|
||||||
// Only send API key for non-localhost requests
|
// Only send API key for non-localhost requests
|
||||||
if (!isRunningOnLocalhost()) {
|
// For localhost, let server use its default LOCALHOST_API_KEY
|
||||||
|
if (window.location.hostname !== 'localhost' &&
|
||||||
|
window.location.hostname !== '127.0.0.1' &&
|
||||||
|
!window.location.hostname.startsWith('127.') &&
|
||||||
|
window.location.hostname !== '::1') {
|
||||||
headers['X-API-Key'] = apiKey;
|
headers['X-API-Key'] = apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +102,6 @@ function App() {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Silently handle state check errors
|
// Silently handle state check errors
|
||||||
console.log('State check failed:', error);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,7 +117,6 @@ function App() {
|
|||||||
const data = await response.json();
|
const data = await response.json();
|
||||||
if (data) {
|
if (data) {
|
||||||
setSampleData(data);
|
setSampleData(data);
|
||||||
console.log('Sample data loaded:', data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update current state GUID
|
// Update current state GUID
|
||||||
|
|||||||
@@ -55,8 +55,20 @@ describe('App Component', () => {
|
|||||||
|
|
||||||
test('renders version number', () => {
|
test('renders version number', () => {
|
||||||
render(<App />);
|
render(<App />);
|
||||||
const versionText = screen.getByText(/v1\.1\.7-dev/);
|
const versionText = screen.getByText(/v\d+\.\d+\.\d+(-dev|-test)?/);
|
||||||
expect(versionText).toBeInTheDocument();
|
expect(versionText).toBeInTheDocument();
|
||||||
|
|
||||||
|
// Check if it's a dev/test build
|
||||||
|
const isDevBuild = versionText.textContent.includes('-dev') || versionText.textContent.includes('-test');
|
||||||
|
|
||||||
|
// Additional validations can be added here based on build type
|
||||||
|
if (isDevBuild) {
|
||||||
|
// Dev/test specific validations could go here
|
||||||
|
expect(versionText.textContent).toMatch(/v\d+\.\d+\.\d+-(dev|test)/);
|
||||||
|
} else {
|
||||||
|
// Release build validations - just check that version pattern exists in the text
|
||||||
|
expect(versionText.textContent).toMatch(/v\d+\.\d+\.\d+/);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renders all toolbar buttons', () => {
|
test('renders all toolbar buttons', () => {
|
||||||
@@ -259,7 +271,7 @@ describe('App Component', () => {
|
|||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
expect(fetch).toHaveBeenCalledWith('/api/v1/sample', expect.objectContaining({
|
expect(fetch).toHaveBeenCalledWith('/api/v1/sample', expect.objectContaining({
|
||||||
headers: expect.objectContaining({
|
headers: expect.objectContaining({
|
||||||
'X-API-Key': expect.any(String)
|
'Accept': 'application/json'
|
||||||
})
|
})
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { VERSION } from '../version';
|
|
||||||
|
|
||||||
function Header({ theme, onThemeChange, currentPage, onPageChange }) {
|
function Header({ theme, onThemeChange, currentPage, onPageChange }) {
|
||||||
return (
|
return (
|
||||||
|
|||||||
Reference in New Issue
Block a user