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 = $('
      '); - // if (nav.options !== undefined) { - - aIcon.on('click', function () { - var li = $(this).closest('li'); - if (li.hasClass('open')) { - li.removeClass('open'); - } else { - li.addClass('open'); - } - }); - - for (var j = 0; j < options.length; j++) { - var sub = options[j]; - self.displayPanelCheckbox(ul, sub); - self.displayPanelInput(ul, sub); - self.displayPanelTags(ul, sub); - self.displayPanelSearch(providerAppId, ul, sub); - // - //

      - // - //

      - - - } - // } - - 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 = $('', { - id: sub.name + '_datalist' - }); - - sub.list.forEach(function (item) { - subADataList.append($(' - */ - // subAInput.on('change', function (e) { - // var div = $(this); - // if (e.which === 13 && div.val() !== '') { - // self.selectPanelTags($(this).attr('id')); - // } - // - // - // var url = '/apps/' + div.attr('data-provider'); - // var route = JSON.parse(div.attr('data-route')); - // - // route.url = url + route.url; - // self.quickSearch(route, div.val(), function (res) { - // self.resultTagsSearch(div, res); - // }); - // }); - - ul.append($('
    • ').append(subAInput).append(subADataList)); - }, - - displayPanelSearch: function (appId, ul, sub) { - var self = this; - - if (sub.type !== 'search') { - return; - } - - var subAInput = $('', { - id: sub.name, - class: 'search_tags_sub', - type: 'text', - placeholder: sub.title, - list: sub.name + '_datalist', - 'data-option': sub.name, - 'data-provider': appId, - 'data-route': JSON.stringify(sub.route) - }); - - var subADataList = $('', { - id: sub.name + '_datalist' - }); - - - subAInput.on('keypress', function (e) { - var div = $(this); - if (e.which === 13 && div.val() !== '') { - self.selectPanelTags($(this).attr('id')); - } - - - var url = '/apps/' + div.attr('data-provider'); - var route = JSON.parse(div.attr('data-route')); - - route.url = url + route.url; - self.quickSearch(route, div.val(), function (res) { - self.resultTagsSearch(div, res); - }); - }); - - ul.append($('
    • ').append(subAInput).append(subADataList)); - }, - - - // selectPanelTags: function (panelId) { - // if (this.currentTagsResult === undefined) { - // return; - // } - // - // var tags = this.currentTagsResult[panelId]; - // if (tags.length === 0) { - // return; - // } - // - // if (this.selectedTags[panelId] === undefined) - // this.selectedTags[panelId] = []; - // this.selectedTags[panelId].push(tags[0]); - // - // console.log('etntree' + JSON.stringify(this.selectedTags[panelId])); - // }, - // - // - // resultTagsSearch: function (div, res) { - // this.currentTagsResult[div.attr('id')] = res; - // var datalistId = div.attr('data-option') + '_datalist'; - // var datalist = $('#' + datalistId); - // - // datalist.empty(); - // res.forEach(function (item) { - // datalist.append($('