From 71a2672a73321ad0de40feadff855c252cea439a Mon Sep 17 00:00:00 2001
From: Carl Schwan
Date: Sat, 8 Aug 2026 16:08:26 +0200
Subject: [PATCH] feat: Port UI to vue
Signed-off-by: Carl Schwan
---
css/navigate.css | 83 ----
js/navigate.js | 495 ------------------------
lib/Controller/NavigationController.php | 12 +-
lib/Service/ConfigService.php | 2 +-
src/Navigate.vue | 374 ++++++++++++++++++
src/navigate.ts | 10 +
src/types.d.ts | 68 ++++
templates/navigate.php | 47 +--
vite.config.ts | 1 +
9 files changed, 462 insertions(+), 630 deletions(-)
delete mode 100644 css/navigate.css
delete mode 100644 js/navigate.js
create mode 100644 src/Navigate.vue
create mode 100644 src/navigate.ts
diff --git a/css/navigate.css b/css/navigate.css
deleted file mode 100644
index 5f5c9d7b..00000000
--- a/css/navigate.css
+++ /dev/null
@@ -1,83 +0,0 @@
-/**
- * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-#search_header {
- width: 100%;
- position: absolute;
-}
-
-#search_header div {
- left: 0;
- right: 0;
- top: 0;
- margin: 5px;
-}
-
-#search_input {
- width: 100%;
-}
-
-#search_error {
- text-align: center;
- color: #f00;
- margin: 20px;
-}
-
-.search_checkbox {
- margin-right: 10px !important;
- opacity: 0.8;
-}
-
-.search_checkbox_sub {
- margin-right: 10px !important;
- opacity: 0.65;
-}
-
-.search_input_sub {
- margin-right: 10px !important;
- opacity: 0.65;
-}
-
-.search_tags_sub {
- margin-right: 10px !important;
- width: 200px;
- opacity: 0.65;
-}
-
-.search_input_sub_small {
- width: 70px;
-}
-
-.search_icon {
- background-image: url('/apps/fulltextsearch/img/fulltextsearch_black.svg');
-}
-
-A.icon-fts {
- text-indent: 25px;
-}
-
-a.ulsub {
- padding: 0px 12px 0 12px !important;
-}
-
-/**
-
-*/
-#search_result {
-}
-
-.provider_header {
- margin-bottom: 35px;
-}
-
-.provider_result {
-}
-
-#noresult {
- font-style: italic;
- position: absolute;
- left: 100px;
-}
-
diff --git a/js/navigate.js b/js/navigate.js
deleted file mode 100644
index 3ac1f049..00000000
--- a/js/navigate.js
+++ /dev/null
@@ -1,495 +0,0 @@
-/**
- * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
- * SPDX-License-Identifier: AGPL-3.0-or-later
- */
-
-
-/** global: OCA */
-/** global: _ */
-
-var fullTextSearch = OCA.FullTextSearch.api;
-
-
-var elements = {
- searchTimeout: null,
- search_input: null,
- search_submit: null,
- search_result: null,
- search_json: null
-};
-
-var Navigate = function () {
- this.init();
-};
-
-Navigate.prototype = {
-
- currentTagsResult: {},
- selectedTags: {},
-
- init: function () {
- var self = this;
-
- elements.search_input = $('#search_input');
- elements.search_submit = $('#search_submit');
- elements.search_result = $('#search_result');
- elements.search_panels = $('#search_navigation');
-// elements.search_json = $('#search_json');
- elements.divHeader = $('#search_header');
- box_elements.searchError = $('#search_error');
-
- // fullTextSearch.setEntryTemplate($('#template_entry'), self);
- fullTextSearch.setResultContainer(elements.search_result);
-
- elements.search_input.on('input', this.navigateTimedSearch);
- // function () {
- // self.resetSearch();
- // if (elements.searchTimeout === null && self.initSearch()) {
- // elements.searchTimeout = _.delay(function () {
- // self.initSearch();
- // elements.searchTimeout = null;
- // }, 3000);
- // }
- // });
-
- //
- // $(document).keypress(function (e) {
- // if (e.which === 13) {
- // self.initSearch(true);
- // }
- // });
-
- self.initPanels();
- },
-
-
- navigateTimedSearch: function () {
-
- if (curr.lastSearchTimer !== null) {
- window.clearTimeout(curr.lastSearchTimer);
- }
-
- curr.lastSearchTimer = window.setTimeout(function () {
- OCA.FullTextSearch.navigate.initSearch();
- }, settings.searchEntryTimer);
-
- if (curr.lastRequestTimer === null) {
- curr.lastRequestTimer = window.setTimeout(function () {
- OCA.FullTextSearch.navigate.initSearch();
- }, settings.searchRequestTimer);
- }
- },
-
-
- initPanels: function () {
- var self = this;
- $.ajax({
- method: 'GET',
- url: OC.generateUrl('/apps/fulltextsearch/navigation/panels')
- }).done(function (res) {
- self.displayPanels(res);
- });
- },
-
-
- displayPanels: function (data) {
- var self = this;
-
- var ak = Object.keys(data);
- for (var i = 0; i < ak.length; i++) {
- var providerAppId = ak[i];
- var title = data[ak[i]]['title'];
- var options = data[ak[i]]['options'];
- var css = data[ak[i]]['css'];
- var icon = data[ak[i]]['icon'];
- var providerId = data[ak[i]]['provider'];
-
- if (css !== '') {
- OC.addStyle(providerAppId, css);
- }
-
- var li = $('', {class: (nav.options !== undefined) ? 'collapsible open' : ''});
- var aIcon = $('', {
- href: '#',
- class: (icon !== undefined) ? icon : 'search_icon'
- });
- aIcon.addClass('icon-fts').text(title);
-
- var ul = $('
-
-
- }
- // }
-
- li.append(aIcon);
- var aInput = $('', {
- class: 'search_checkbox',
- type: 'checkbox',
- 'data-provider': ak[i],
- 'data-provider-id': providerId
- });
- aInput.change(function () {
- self.initSearch();
- });
-
- li.append(aInput);
- li.append(ul);
-
- elements.search_panels.append(li);
- }
-
- },
-
-
- displayPanelOptionTitle: function (sub) {
- return $('', {
- href: '#',
- class: 'ulsub',
- text: sub.title
- });
- },
-
-
- displayPanelCheckbox: function (ul, sub) {
-
- if (sub.type !== 'checkbox') {
- return;
- }
-
- var self = this;
- var subA = this.displayPanelOptionTitle(sub);
- var subAInput = $('', {
- class: 'search_checkbox_sub',
- type: 'checkbox',
- 'data-option': sub.name
- });
- subAInput.change(function () {
- self.initSearch();
- });
-
- ul.append($('').append(subA).append(subAInput));
- },
-
-
- displayPanelInput: function (ul, sub) {
- if (sub.type !== 'input') {
- return;
- }
-
- var self = this;
- var subA = this.displayPanelOptionTitle(sub);
- var subAInput = $('', {
- class: 'search_input_sub search_input_sub_' + sub.size,
- type: 'text',
- placeholder: sub.placeholder,
- 'data-option': sub.name
- });
- subAInput.on('input', function () {
- self.initSearch();
- });
-
- ul.append($('').append(subA).append(subAInput));
- },
-
-
- displayPanelTags: function (ul, sub) {
- if (sub.type !== 'tags') {
- return;
- }
-
- var self = this;
- var subAInput = $('', {
- id: sub.name,
- class: 'search_tags_sub',
- type: 'text',
- placeholder: sub.title,
- list: sub.name + '_datalist',
- 'data-option': sub.name
- });
-
- var subADataList = $('