Add barcode search field [SCI-8283]

This commit is contained in:
Anton 2023-05-11 11:21:50 +02:00
parent 4737a2d4bc
commit 8f5560b016
8 changed files with 137 additions and 3 deletions

View file

@ -430,6 +430,13 @@ var RepositoryDatatable = (function(global) {
});
}
function addRepositorySearch() {
$(`<div id="inventorySearchComponent">
<repository_search_container/>
</div>`).appendTo('.repository-search-container');
initRepositorySearch();
}
function dataTableInit() {
TABLE = $(TABLE_ID).DataTable({
dom: "R<'repository-toolbar hidden'<'repository-search-container'f>>t<'pagination-row hidden'<'pagination-info'li><'pagination-actions'p>>",
@ -643,8 +650,8 @@ var RepositoryDatatable = (function(global) {
initBSTooltips();
DataTableHelpers.initLengthAppearance($(TABLE_ID).closest('.dataTables_wrapper'));
$('<img class="barcode-scanner" src="/images/icon_small/barcode.png"></img>').appendTo($('.search-container'));
$('.dataTables_filter').addClass('hidden');
addRepositorySearch();
if ($('.repository-show').length) {
$('.dataTables_scrollBody, .dataTables_scrollHead').css('overflow', '');
}

View file

@ -186,6 +186,10 @@
.fas {
margin: 0;
}
img {
margin: 0;
}
}
&.btn-large {

View file

@ -71,7 +71,7 @@ module Navigator
end
current_team.projects
.where(project_folder_id: folder)
.viewable_by_user(current_user, current_team)
.visible_to(current_user, current_team)
.with_children_viewable_by_user(current_user)
.where('
projects.archived = :archived OR

View file

@ -0,0 +1,16 @@
import TurbolinksAdapter from 'vue-turbolinks';
import Vue from 'vue/dist/vue.esm';
import RepositorySearchContainer from '../../vue/repository_search/container.vue';
Vue.use(TurbolinksAdapter);
Vue.prototype.i18n = window.I18n;
window.initRepositorySearch = () => {
window.RepositorySearchComponent = new Vue({
el: '#inventorySearchComponent',
name: 'RepositorySearchComponent',
components: {
'repository_search_container': RepositorySearchContainer
}
});
}

View file

@ -0,0 +1,104 @@
<template>
<div class="flex items-center">
<button v-if="!searchOpened" class="btn btn-light icon-btn" @click="openSearch">
<i class="fas fa-search"></i>
</button>
<div v-if="searchOpened || barcodeSearchOpened" class="w-52">
<div v-if="searchOpened" class="sci-input-container right-icon">
<input
ref="searchInput"
class="sci-input-field"
type="text"
:placeholder="i18n.t('repositories.show.filter_inventory_items')"
@keyup="setValue"
@blur="closeSearch"
/>
<i class="fas fa-search"></i>
</div>
<div v-if="barcodeSearchOpened" class="sci-input-container right-icon ml-2">
<input
ref="barcodeSearchInput"
class="sci-input-field"
type="text"
:placeholder="i18n.t('repositories.show.filter_inventory_items_with_ean')"
@change="setBarcodeValue"
@blur="closeBarcodeSearch"
/>
<img class="barcode-scanner" src="/images/icon_small/barcode.png"/>
</div>
</div>
<button v-if="!barcodeSearchOpened" class="btn btn-light icon-btn ml-2" @click="openBarcodeSearch">
<img class="barcode-scanner" src="/images/icon_small/barcode.png"/>
</button>
</div>
</template>
<script>
export default {
name: 'RepositorySearchContainer',
data() {
return {
barcodeSearchOpened: false,
barcodeValue: '',
searchOpened: false,
value: ''
}
},
watch: {
barcodeValue() {
this.updateRepositoySearch();
},
value() {
this.updateRepositoySearch();
}
},
computed: {
activeValue() {
return this.value.length > 0 ? this.value : this.barcodeValue;
}
},
methods: {
setValue(e) {
this.value = e.target.value;
},
setBarcodeValue(e) {
this.barcodeValue = e.target.value;
},
openBarcodeSearch() {
this.clearValues();
this.closeSearch();
this.barcodeSearchOpened = true;
this.$nextTick(() => {
this.$refs.barcodeSearchInput.focus();
});
},
openSearch() {
this.clearValues();
this.closeBarcodeSearch();
this.searchOpened = true;
this.$nextTick(() => {
this.$refs.searchInput.focus();
});
},
closeBarcodeSearch() {
if (this.barcodeValue.length == 0) {
this.barcodeSearchOpened = false;
}
},
closeSearch() {
if (this.value.length == 0) {
this.searchOpened = false;
}
},
updateRepositoySearch() {
$('.dataTables_filter input').val(this.activeValue).trigger('keyup');
},
clearValues() {
this.value = '';
this.barcodeValue = '';
if (this.$refs.searchInput) this.$refs.searchInput.value = '';
if (this.$refs.barcodeSearchInput) this.$refs.barcodeSearchInput.value = '';
}
}
}
</script>

View file

@ -89,6 +89,7 @@
<%= render partial: 'save_repository_filter_modal' %>
<% end %>
<%= javascript_include_tag 'vue_repository_search' %>
<%= javascript_include_tag 'repositories/edit' %>
<%= javascript_include_tag 'repositories/repository_datatable' %>
<%= javascript_include_tag "repositories/show" %>

View file

@ -1735,6 +1735,7 @@ en:
archived_on: "Inventory archived on"
archived_by: "by"
filter_inventory_items: "Filter items"
filter_inventory_items_with_ean: "Search with EAN code"
no_items: "No items here"
no_items_matched: "No items here"
no_archived_items: "No archived items here"

View file

@ -30,6 +30,7 @@ const entryList = {
vue_label_template: './app/javascript/packs/vue/label_template.js',
vue_protocol: './app/javascript/packs/vue/protocol.js',
vue_repository_filter: './app/javascript/packs/vue/repository_filter.js',
vue_repository_search: './app/javascript/packs/vue/repository_search.js',
vue_repository_print_modal: './app/javascript/packs/vue/repository_print_modal.js',
vue_navigation_top_menu: './app/javascript/packs/vue/navigation/top_menu.js',
vue_navigation_navigator: './app/javascript/packs/vue/navigation/navigator.js',