diff --git a/src/gui/src/UI/Dashboard/TabApps.js b/src/gui/src/UI/Dashboard/TabApps.js
index 4ed478f01..2262a585b 100644
--- a/src/gui/src/UI/Dashboard/TabApps.js
+++ b/src/gui/src/UI/Dashboard/TabApps.js
@@ -54,6 +54,11 @@ const TabApps = {
html () {
let h = '
';
+ h += '
';
+ h += '';
+ h += '';
+ h += '';
+ h += '
';
h += '
';
h += '
Loading apps...
';
h += '
';
@@ -64,6 +69,46 @@ const TabApps = {
init ($el_window) {
this.loadApps($el_window);
+ const self = this;
+
+ // Toggle search/clear icons and filter
+ function updateSearch ($input) {
+ const query = $input.val().toLowerCase().trim();
+ const hasText = query.length > 0;
+ $el_window.find('.myapps-icon-search').toggle(!hasText);
+ $el_window.find('.myapps-icon-clear').toggle(hasText);
+
+ if ( ! self._apps ) return;
+
+ if ( ! query ) {
+ $el_window.find('.myapps-container').html(buildAppsGrid(self._apps));
+ return;
+ }
+
+ const filtered = self._apps.filter(app => {
+ const title = (app.title || '').toLowerCase();
+ const name = (app.name || '').toLowerCase();
+ return title.includes(query) || name.includes(query);
+ });
+
+ $el_window.find('.myapps-container').html(
+ filtered.length > 0
+ ? buildAppsGrid(filtered)
+ : '
No apps match your search
',
+ );
+ }
+
+ $el_window.on('input', '.myapps-search', function () {
+ updateSearch($(this));
+ });
+
+ // Clear search on cross click
+ $el_window.on('click', '.myapps-icon-clear', function () {
+ const $input = $el_window.find('.myapps-search');
+ $input.val('').focus();
+ updateSearch($input);
+ });
+
// Handle app tile clicks
$el_window.on('click', '.myapps-tile', function (e) {
e.preventDefault();
diff --git a/src/gui/src/css/dashboard.css b/src/gui/src/css/dashboard.css
index aa6cd8267..2e2929279 100644
--- a/src/gui/src/css/dashboard.css
+++ b/src/gui/src/css/dashboard.css
@@ -440,11 +440,52 @@ body {
padding: 32px 40px;
}
-.myapps-tab h2 {
- font-size: 26px;
- font-weight: 700;
- color: var(--dashboard-text-heading);
- margin: 0 0 24px 0;
+.myapps-search-wrap {
+ position: relative;
+ margin-bottom: 24px;
+ max-width: 360px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.myapps-search-icon {
+ position: absolute;
+ right: 12px;
+ top: 50%;
+ transform: translateY(-50%);
+ width: 16px;
+ height: 16px;
+ color: var(--dashboard-text-tertiary);
+ pointer-events: none;
+}
+
+.myapps-icon-clear {
+ pointer-events: auto;
+ cursor: pointer;
+}
+
+.myapps-icon-clear:hover {
+ color: var(--dashboard-text-primary);
+}
+
+.myapps-search {
+ width: 100%;
+ padding: 8px 36px 8px 12px;
+ font-size: 14px;
+ border: 1px solid var(--dashboard-border);
+ border-radius: 8px;
+ background: var(--dashboard-input-background);
+ color: var(--dashboard-text-primary);
+ outline: none;
+ transition: border-color 0.15s;
+}
+
+.myapps-search:focus {
+ border-color: var(--select-color);
+}
+
+.myapps-search::placeholder {
+ color: var(--dashboard-text-muted);
}
.myapps-container {