fix: stream detail page (schema) layout changed (#8585)

### **User description**
1. This PR introduces a new tab called configuration where we moved all
the configuration settings to that tab
2. This PR introduces a compact table so that more columns are visible
and also all the stream stats above will stay at viewport always


___

### **PR Type**
Enhancement


___

### **Description**
- Redesigned schema page layout and header

- Added Configuration tab for settings

- New compact stats tiles and sticky table

- Added distinct values toggle and UX polish


___

### Diagram Walkthrough


```mermaid
flowchart LR
  Header["Header: title + name + timeline"] -- "context" --> Tabs["Tabs: Schema Settings / Configuration / Extended Retention"]
  Tabs -- "schema fields" --> SchemaTbl["Schema table: compact, sticky header, mini-select"]
  Tabs -- "settings" --> Config["Configuration panel: retention, max range, flatten, toggles"]
  Tabs -- "retention" --> ExtRet["Extended Retention: date selection + table"]
  Stats["Stats tiles: Events, Storage, Compressed, Index"] -- "overview" --> Header
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>schema.vue</strong><dd><code>Schema page UI/UX overhaul
with new configuration</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></summary>
<hr>

web/src/components/logstream/schema.vue

<ul><li>Revamped header with stream name badge and timeline.<br> <li>
Added stats tiles grid and compact layout.<br> <li> Introduced
'Configuration' tab with inputs and toggles.<br> <li> Improved schema
table: sticky header, mini-select, tooltips, <br>pagination.<br> <li>
Added 'Enable Distinct Values' setting wired to backend.<br> <li>
Updated date formatting and preserved original timestamps.<br> <li>
Adjusted per-page options and floating footer behavior.<br> <li> Added
new icons and theme-aware styling; extensive CSS updates.</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/8585/files#diff-9196be2ccae4054a00b0b1aa9d1e87b366c10920d6eaf9ef8c6e6293d50bcf46">+1068/-604</a></td>

</tr>
</table></td></tr></tr></tbody></table>

</details>

___
This commit is contained in:
Sai Nikhil
2025-09-23 15:00:23 +05:30
committed by GitHub
parent 4aa8424682
commit 4fa43fdff7
8 changed files with 1250 additions and 764 deletions
@@ -16,6 +16,7 @@ export default class StreamSettingsPage {
'[data-test="schema-update-settings-button"]'
);
this.closeButton = page.locator('[data-test="schema-cancel-button"]');
this.configurationTab = page.getByRole('tab', { name: 'Configuration' })
}
async updateStreamMaxQueryRange(streamName, newValue) {
@@ -35,9 +36,11 @@ export default class StreamSettingsPage {
// Wait for stream details to appear and click
await this.streamDetailButton.waitFor({ state: "visible", timeout: 5000 });
await this.streamDetailButton.waitFor({ state: "visible", timeout: 2000 });
await this.streamDetailButton.click();
//before clicking for max query range input we need to go to configuration tab due to schema UI layout change
await this.configurationTab.waitFor({ state: "visible", timeout: 2000 });
await this.configurationTab.click();
// Wait and update max query range input
await this.maxQueryInput.waitFor({ state: "visible", timeout: 15000 });
await this.maxQueryInput.click();
@@ -131,7 +131,10 @@ test.describe("Unflattened testcases", () => {
await pageManager.unflattenedPage.streamDetailButton.click();
// Strategic 500ms wait for operation completion - this is functionally necessary
await page.waitForTimeout(500);
//before toggling we need to make sure that we shift to configuration tab
await page.getByRole('tab', { name: 'Configuration' }).waitFor({ state: "visible", timeout: 2000 });
await page.getByRole('tab', { name: 'Configuration' }).click();
// Toggle 'Store Original Data' and update schema
await pageManager.unflattenedPage.storeOriginalDataToggle.waitFor(); // Wait for the toggle to be visible
await pageManager.unflattenedPage.storeOriginalDataToggle.click();
@@ -206,7 +209,9 @@ test.describe("Unflattened testcases", () => {
await pageManager.unflattenedPage.streamDetailButton.click();
// Strategic 500ms wait for operation completion - this is functionally necessary
await page.waitForTimeout(500);
//before toggling we need to make sure that we shift to configuration tab
await page.getByRole('tab', { name: 'Configuration' }).waitFor({ state: "visible", timeout: 2000 });
await page.getByRole('tab', { name: 'Configuration' }).click();
// Toggle 'Store Original Data' and update schema
await pageManager.unflattenedPage.storeOriginalDataToggle.waitFor();
await pageManager.unflattenedPage.storeOriginalDataToggle.click();
@@ -318,7 +323,9 @@ test.describe("Unflattened testcases", () => {
await pageManager.unflattenedPage.streamDetailButton.click();
// Strategic 500ms wait for operation completion - this is functionally necessary
await page.waitForTimeout(500);
//before toggling we need to make sure that we shift to configuration tab
await page.getByRole('tab', { name: 'Configuration' }).waitFor({ state: "visible", timeout: 2000 });
await page.getByRole('tab', { name: 'Configuration' }).click();
await pageManager.unflattenedPage.storeOriginalDataToggle.waitFor();
await pageManager.unflattenedPage.storeOriginalDataToggle.click();
+31
View File
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 493.583 493.583" xml:space="preserve">
<g>
<path d="M474.332,170.706c-3.889-49.328-26.734-94.184-64.346-126.313C376.486,15.759,333.787,0,289.761,0
c-54.305,0-105.654,23.649-140.869,64.89c-32.146,37.601-47.715,85.476-43.828,134.797c1.543,19.635,6.199,38.496,13.479,56.184
l-39.986,46.82c-9.451,11.051-8.133,27.647,2.906,37.098l4.742,4.049l-55.156,64.555c-18.525,21.684-15.953,54.283,5.73,72.809
c21.674,18.525,54.277,15.973,72.799-5.701l55.154-64.537l4.725,4.043c5.322,4.536,12.213,6.766,19.168,6.222
c6.955-0.549,13.414-3.825,17.947-9.144l40.102-46.914c13.975,3.357,28.357,5.241,42.926,5.241
c54.289,0,105.656-23.65,140.904-64.895C462.634,267.892,478.185,220.026,474.332,170.706z M392.974,273.448
c-25.869,30.253-63.527,47.605-103.375,47.605c-32.262,0-63.57-11.57-88.139-32.586c-27.602-23.551-44.359-56.455-47.201-92.635
c-2.842-36.185,8.578-71.305,32.146-98.872c25.85-30.253,63.508-47.606,103.355-47.606c32.264,0,63.59,11.566,88.176,32.57
c27.584,23.568,44.342,56.472,47.166,92.65C427.962,210.743,416.542,245.858,392.974,273.448z"/>
<path d="M289.699,149.575c-19.664,0-35.654,15.988-35.654,35.617c0,19.637,15.99,35.621,35.654,35.621
c19.635,0,35.602-15.984,35.602-35.621C325.3,165.564,309.333,149.575,289.699,149.575z"/>
<path d="M382.269,202.673l-12.916-7.451c0.422-3.328,1.027-6.586,1.027-10.029c0-3.436-0.605-6.695-1.027-10.022l12.916-7.468
c3.217-1.85,5.592-4.934,6.557-8.533c0.965-3.598,0.467-7.439-1.416-10.668l-17.092-29.595c-3.854-6.718-12.467-9.03-19.215-5.159
l-12.789,7.424c-5.43-4.113-11.166-7.76-17.48-10.41V96.267c0-7.775-6.295-14.054-14.07-14.054h-34.158
c-7.775,0-14.06,6.278-14.06,14.054v14.494c-6.348,2.65-12.066,6.297-17.463,10.41l-12.836-7.424
c-3.229-1.859-7.088-2.373-10.686-1.396c-3.6,0.964-6.65,3.31-8.533,6.556l-17.074,29.595c-3.889,6.717-1.578,15.323,5.141,19.201
l12.916,7.468c-0.416,3.327-1.012,6.587-1.012,10.022c0,3.443,0.596,6.701,1.012,10.029l-12.916,7.451
c-6.719,3.877-9.029,12.483-5.141,19.219l17.074,29.595c1.883,3.229,4.934,5.591,8.533,6.557c3.598,0.958,7.457,0.46,10.686-1.398
l12.836-7.423c5.396,4.112,11.115,7.758,17.463,10.426v14.479c0,7.773,6.285,14.054,14.06,14.054h34.158
c7.775,0,14.07-6.28,14.07-14.054v-14.479c6.332-2.668,12.051-6.313,17.48-10.426l12.789,7.423c3.248,1.858,7.1,2.357,10.699,1.398
c3.6-0.966,6.684-3.328,8.516-6.557l17.092-29.595C391.304,215.173,388.988,206.561,382.269,202.673z M289.699,237.265
c-28.728,0-52.105-23.356-52.105-52.072c0-28.709,23.377-52.07,52.105-52.07c28.709,0,52.053,23.361,52.053,52.07
C341.751,213.908,318.408,237.265,289.699,237.265z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

@@ -0,0 +1,7 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
␍<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg fill="#ffffff" height="800px" width="800px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 493.583 493.583" xml:space="preserve" stroke="#ffffff">
␍<g id="SVGRepo_bgCarrier" stroke-width="0"/>
␍<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
␍<g id="SVGRepo_iconCarrier"> <g> <path d="M474.332,170.706c-3.889-49.328-26.734-94.184-64.346-126.313C376.486,15.759,333.787,0,289.761,0 c-54.305,0-105.654,23.649-140.869,64.89c-32.146,37.601-47.715,85.476-43.828,134.797c1.543,19.635,6.199,38.496,13.479,56.184 l-39.986,46.82c-9.451,11.051-8.133,27.647,2.906,37.098l4.742,4.049l-55.156,64.555c-18.525,21.684-15.953,54.283,5.73,72.809 c21.674,18.525,54.277,15.973,72.799-5.701l55.154-64.537l4.725,4.043c5.322,4.536,12.213,6.766,19.168,6.222 c6.955-0.549,13.414-3.825,17.947-9.144l40.102-46.914c13.975,3.357,28.357,5.241,42.926,5.241 c54.289,0,105.656-23.65,140.904-64.895C462.634,267.892,478.185,220.026,474.332,170.706z M392.974,273.448 c-25.869,30.253-63.527,47.605-103.375,47.605c-32.262,0-63.57-11.57-88.139-32.586c-27.602-23.551-44.359-56.455-47.201-92.635 c-2.842-36.185,8.578-71.305,32.146-98.872c25.85-30.253,63.508-47.606,103.355-47.606c32.264,0,63.59,11.566,88.176,32.57 c27.584,23.568,44.342,56.472,47.166,92.65C427.962,210.743,416.542,245.858,392.974,273.448z"/> <path d="M289.699,149.575c-19.664,0-35.654,15.988-35.654,35.617c0,19.637,15.99,35.621,35.654,35.621 c19.635,0,35.602-15.984,35.602-35.621C325.3,165.564,309.333,149.575,289.699,149.575z"/> <path d="M382.269,202.673l-12.916-7.451c0.422-3.328,1.027-6.586,1.027-10.029c0-3.436-0.605-6.695-1.027-10.022l12.916-7.468 c3.217-1.85,5.592-4.934,6.557-8.533c0.965-3.598,0.467-7.439-1.416-10.668l-17.092-29.595c-3.854-6.718-12.467-9.03-19.215-5.159 l-12.789,7.424c-5.43-4.113-11.166-7.76-17.48-10.41V96.267c0-7.775-6.295-14.054-14.07-14.054h-34.158 c-7.775,0-14.06,6.278-14.06,14.054v14.494c-6.348,2.65-12.066,6.297-17.463,10.41l-12.836-7.424 c-3.229-1.859-7.088-2.373-10.686-1.396c-3.6,0.964-6.65,3.31-8.533,6.556l-17.074,29.595c-3.889,6.717-1.578,15.323,5.141,19.201 l12.916,7.468c-0.416,3.327-1.012,6.587-1.012,10.022c0,3.443,0.596,6.701,1.012,10.029l-12.916,7.451 c-6.719,3.877-9.029,12.483-5.141,19.219l17.074,29.595c1.883,3.229,4.934,5.591,8.533,6.557c3.598,0.958,7.457,0.46,10.686-1.398 l12.836-7.423c5.396,4.112,11.115,7.758,17.463,10.426v14.479c0,7.773,6.285,14.054,14.06,14.054h34.158 c7.775,0,14.07-6.28,14.07-14.054v-14.479c6.332-2.668,12.051-6.313,17.48-10.426l12.789,7.423c3.248,1.858,7.1,2.357,10.699,1.398 c3.6-0.966,6.684-3.328,8.516-6.557l17.092-29.595C391.304,215.173,388.988,206.561,382.269,202.673z M289.699,237.265 c-28.728,0-52.105-23.356-52.105-52.072c0-28.709,23.377-52.07,52.105-52.07c28.709,0,52.053,23.361,52.053,52.07 C341.751,213.908,318.408,237.265,289.699,237.265z"/> </g> </g>
␍</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM3.00683 12C3.00683 16.9668 7.03321 20.9932 12 20.9932C16.9668 20.9932 20.9932 16.9668 20.9932 12C20.9932 7.03321 16.9668 3.00683 12 3.00683C7.03321 3.00683 3.00683 7.03321 3.00683 12Z" fill="#0F0F0F"/>
<path d="M12 5C11.4477 5 11 5.44771 11 6V12.4667C11 12.4667 11 12.7274 11.1267 12.9235C11.2115 13.0898 11.3437 13.2343 11.5174 13.3346L16.1372 16.0019C16.6155 16.278 17.2271 16.1141 17.5032 15.6358C17.7793 15.1575 17.6155 14.5459 17.1372 14.2698L13 11.8812V6C13 5.44772 12.5523 5 12 5Z" fill="#0F0F0F"/>
</svg>

After

Width:  |  Height:  |  Size: 860 B

@@ -0,0 +1,12 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Transformed by: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" stroke="#ffffff">
<g id="SVGRepo_bgCarrier" stroke-width="0"/>
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"/>
<g id="SVGRepo_iconCarrier"> <path d="M23 12C23 18.0751 18.0751 23 12 23C5.92487 23 1 18.0751 1 12C1 5.92487 5.92487 1 12 1C18.0751 1 23 5.92487 23 12ZM3.00683 12C3.00683 16.9668 7.03321 20.9932 12 20.9932C16.9668 20.9932 20.9932 16.9668 20.9932 12C20.9932 7.03321 16.9668 3.00683 12 3.00683C7.03321 3.00683 3.00683 7.03321 3.00683 12Z" fill="#ffffff"/> <path d="M12 5C11.4477 5 11 5.44771 11 6V12.4667C11 12.4667 11 12.7274 11.1267 12.9235C11.2115 13.0898 11.3437 13.2343 11.5174 13.3346L16.1372 16.0019C16.6155 16.278 17.2271 16.1141 17.5032 15.6358C17.7793 15.1575 17.6155 14.5459 17.1372 14.2698L13 11.8812V6C13 5.44772 12.5523 5 12 5Z" fill="#ffffff"/> </g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because it is too large Load Diff
+293
View File
@@ -0,0 +1,293 @@
.add-fields-card {
width: 100vw;
max-width: 100%;
display: flex;
flex-direction: column;
}
.indexDetailsContainer {
.q-table__control {
width: 100%;
}
.q-table {
td:nth-child(2) {
min-width: 15rem;
width: 15rem;
max-width: 15rem;
overflow: auto;
scrollbar-width: thin;
scrollbar-color: #999 #f0f0f0;
}
td:nth-child(3) {
padding: 4px 8px !important;
}
}
th:first-child,
td:first-child {
padding-left: 8px !important;
}
th:nth-child(5),
td:nth-child(5){
min-width: 15rem;
width: 15rem;
max-width: 15rem;
}
}
.dark-theme-table tr:hover td:nth-child(2) {
background-color: #272a2b !important;
}
.light-theme-table tr:hover td:nth-child(2) {
background-color: #f7f7f7 !important;
}
.schema-fields-tabs {
height: fit-content;
.rum-tab {
width: fit-content !important;
padding: 4px 12px !important;
border: none !important;
&.active {
background: #5960b2;
color: #ffffff !important;
}
}
}
.main-fields-tabs {
height: fit-content;
color: var(--q-light);
.rum-tab {
padding: 4px 12px !important;
&.active {
color: white !important;
border-bottom: 5px solid var(--q-primary) !important;
background-color: rgba(88, 96, 178, 0.6);
}
}
}
.floating-buttons {
position: sticky;
bottom: 0;
z-index: 1; /* Ensure it stays on top of table content */
width: 100%;
margin-top: auto; /* Push to bottom when there's less content */
}
.dark-theme-floating-buttons {
background-color: #181a1b;
}
.light-theme-floating-buttons {
background-color: #ffffff
}
.warning-text {
color: #f5a623;
border: 1px solid #f5a623;
border-radius: 10px;
padding: 6px 3px;
}
.mini-select .q-field__control {
min-height: 24px !important;
padding: 0px 4px !important;
}
.mini-select .q-field__control-container {
padding-top: 0px !important;
padding-bottom: 0px !important;
min-height: 20px !important;
}
.mini-select .q-field__control-container span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
font-size: 11px !important;
line-height: 12px !important;
}
.mini-select .q-field__marginal {
height: 20px !important;
}
.mini-select.q-field--auto-height.q-field--dense .q-field__control,
.mini-select.q-field--auto-height.q-field--dense .q-field__native {
min-height: 24px !important;
height: 24px !important;
}
.mini-select.q-field--dense .q-field__control,
.mini-select.q-field--dense .q-field__marginal {
min-height: 12px !important;
height: 12px !important;
}
.mini-select .q-field--dense .q-field__control,
.mini-select .q-field--dense .q-field__marginal {
min-height: 12px !important;
height: 12px !important;
}
/* Custom clear icon styling */
.mini-select .q-icon {
font-size: 14px !important;
width: 14px !important;
height: 14px !important;
opacity: 0.7;
font-weight: 900 !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
line-height: 1 !important;
margin-top: 16px !important;
}
.mini-select .q-icon:hover {
opacity: 1;
}
/* Move dropdown arrow down and add rotation animation */
.mini-select .q-field__append .q-icon {
margin-top: 14px;
transition: transform 0.2s ease;
}
/* Rotate arrow when dropdown is open */
.mini-select.q-field--focused .q-field__append .q-icon {
transform: rotate(180deg);
}
.schema-index-select-dropdown-light{
background-color: white !important;
border-radius: 4px !important;
border: 1px solid #C9CCD6 !important;
}
.schema-index-select-dropdown-light.q-field--focused .q-field__control {
outline: 2px solid #575FC5 !important;
box-shadow: none !important;
background-color: #FFFFFF !important;
border-radius: 4px !important;
}
.schema-index-select-dropdown-dark{
background-color: #2B2D30 !important;
border-radius: 4px !important;
border: 1px solid #4E5157 !important;
}
.schema-index-select-dropdown-dark.q-field--focused .q-field__control {
outline: 2px solid #575FC5 !important;
box-shadow: none !important;
background-color: #2B2D30 !important;
border-radius: 4px !important;
}
/* Field name ellipsis styling */
.field-name-ellipsis {
max-width: 200px;
}
.field-name-text {
display: inline-block;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.o2-schema-table{
th,td {
height: 14px !important;
min-height: 14px !important;
padding: 2px 3px !important;
}
thead {
position: sticky;
top: 0;
z-index: 1000;
}
}
.o2-schema-table-header-sticky-dark{
thead {
background-color: #181A1B;
}
}
.o2-schema-table-header-sticky-light{
thead {
background-color: #ffffff;
}
}
/* Field type badge styling */
.field-type-badge {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 8px;
border-radius: 6px;
font-size: 11px;
font-weight: 600;
}
.badge-int64 {
background: #dbeafe;
color: #1d4ed8;
}
.badge-float64 {
background: #d1fae5;
color: #065f46;
}
.badge-utf8 {
background: #fef3c7;
color: #92400e;
}
.schema-input-box{
background-color: white !important;
border-radius: 4px !important;
padding: 0px 8px !important;
border: 1px solid #C9CCD6 !important;
.q-field__control{
color: transparent !important;
}
}
.schema-input-box-light{
.q-field__control{
background-color: #ffffff !important;
outline: 0px 1px 0px 1px solid #C9CCD6 !important;
padding: 0px 6px !important;
}
}
.schema-input-box-dark{
background-color: #2B2D30 !important;
border-radius: 4px !important;
border: 1px solid #4E5157 !important;
}
.bottom-btn {
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
}
.tile-content-dark{
background-color: #181a1b;
}
.tile-content-light{
background-color: #ffffff;
}