mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2025-04-27 15:39:54 +03:00
feat(search-bar): add search bar to catalog, this will filter images
This commit is contained in:
parent
263584fc43
commit
a2b3c592df
4 changed files with 75 additions and 7 deletions
|
@ -16,7 +16,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
-->
|
||||
<catalog-element>
|
||||
<!-- Begin of tag -->
|
||||
<div class="content">
|
||||
<div class="content"
|
||||
if="{!props.filterResults || state.nImages > 0 || matchSearch(props.filterResults, state.image)}">
|
||||
<material-card class="list highlight" expanded="{state.expanded}" onclick="{ onClick }">
|
||||
<material-waves onmousedown="{this.triggerLaunch}" center="true" color="#ddd"
|
||||
setLaunchListener="{ setLaunchListener }" />
|
||||
|
@ -24,17 +25,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<i class="material-icons">send</i>
|
||||
{ state.image || state.repo }
|
||||
<div if="{state.images}" class="item-count right">
|
||||
{ state.images.length } images
|
||||
{ state.nImages } images
|
||||
<i class="material-icons animated {state.expanded ? 'expanded' : ''}">expand_more</i>
|
||||
</div>
|
||||
</span>
|
||||
</material-card>
|
||||
<catalog-element if="{ state.images }"
|
||||
class="animated {!state.expanded ? 'hide' : ''} {state.expanding ? 'expanding' : ''}"
|
||||
<catalog-element if="{ state.images }" filter-results="{ props.filterResults }"
|
||||
class="animated {!state.expanded && !props.filterResults ? 'hide' : ''} {state.expanding ? 'expanding' : ''}"
|
||||
each="{item in state.images}" item="{ item }" />
|
||||
</div>
|
||||
<script>
|
||||
import router from '../../scripts/router';
|
||||
import {
|
||||
matchSearch
|
||||
} from '../search-bar.riot';
|
||||
|
||||
export default {
|
||||
onBeforeMount(props, state) {
|
||||
|
@ -45,6 +49,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
} else if (props.item.images && props.item.repo) {
|
||||
state.images = props.item.images;
|
||||
state.repo = props.item.repo;
|
||||
state.nImages = props.item.images.length;
|
||||
}
|
||||
},
|
||||
onBeforeUpdate(props, state) {
|
||||
if (props.filterResults && state.images) {
|
||||
state.nImages = state.images.filter(image => matchSearch(props.filterResults, image)).length;
|
||||
} else {
|
||||
state.nImages = state.images && state.images.length;
|
||||
}
|
||||
},
|
||||
onClick() {
|
||||
|
@ -65,7 +77,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
},
|
||||
setLaunchListener(cb) {
|
||||
this.triggerLaunch = cb;
|
||||
}
|
||||
},
|
||||
matchSearch
|
||||
}
|
||||
</script>
|
||||
<!-- End of tag -->
|
||||
|
|
|
@ -26,7 +26,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<div if="{ !state.loadend }" class="spinner-wrapper">
|
||||
<material-spinner></material-spinner>
|
||||
</div>
|
||||
<catalog-element each="{ item in state.repositories }" item="{ item }" />
|
||||
<catalog-element each="{ item in state.repositories }" item="{ item }" filter-results="{ props.filterResults }"/>
|
||||
<script>
|
||||
import CatalogElement from './catalog-element.riot'
|
||||
import {
|
||||
|
|
|
@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<header>
|
||||
<material-navbar>
|
||||
<div class="logo">Docker Registry UI</div>
|
||||
<search-bar on-search="{ onSearch }"></search-bar>
|
||||
<dialogs-menu if="{props.singleRegistry !== 'true'}" on-notify="{ notifySnackbar }"
|
||||
on-server-change="{ onServerChange }"></dialogs-menu>
|
||||
</material-navbar>
|
||||
|
@ -26,7 +27,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
<router base="#!">
|
||||
<route path="{baseRoute}">
|
||||
<catalog registry-url="{ state.registryUrl }" registry-name="{ state.name }"
|
||||
catalog-elements-limit="{ state.catalogElementsLimit }" on-notify="{ notifySnackbar }" />
|
||||
catalog-elements-limit="{ state.catalogElementsLimit }" on-notify="{ notifySnackbar }"
|
||||
filter-results="{ state.filter }" />
|
||||
</route>
|
||||
<route path="{baseRoute}taglist/(.*)">
|
||||
<tag-list registry-url="{ state.registryUrl }" registry-name="{ state.name }" pull-url="{ state.pullUrl }"
|
||||
|
@ -66,6 +68,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
import TagList from './tag-list/tag-list.riot';
|
||||
import TagHistory from './tag-history/tag-history.riot';
|
||||
import DialogsMenu from './dialogs/dialogs-menu.riot';
|
||||
import SearchBar from './search-bar.riot'
|
||||
import {
|
||||
stripHttps,
|
||||
getRegistryServers
|
||||
|
@ -78,6 +81,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
TagList,
|
||||
TagHistory,
|
||||
DialogsMenu,
|
||||
SearchBar,
|
||||
Router,
|
||||
Route
|
||||
},
|
||||
|
@ -121,6 +125,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
});
|
||||
}
|
||||
},
|
||||
onSearch(value) {
|
||||
this.update({ filter: value })
|
||||
},
|
||||
baseRoute: '([^#]*?)/(\\?[^#]*?)?(#!)?(/?)',
|
||||
router,
|
||||
version
|
||||
|
|
48
src/components/search-bar.riot
Normal file
48
src/components/search-bar.riot
Normal file
|
@ -0,0 +1,48 @@
|
|||
<search-bar>
|
||||
<material-input placeholder="Search in page"></material-input>
|
||||
<script>
|
||||
import {
|
||||
router
|
||||
} from '@riotjs/route';
|
||||
|
||||
export default {
|
||||
onMounted(props, state) {
|
||||
const input = this.$('input');
|
||||
let value = '';
|
||||
const notify = () => {
|
||||
if (value !== input.value) {
|
||||
props.onSearch(input.value.toLowerCase())
|
||||
}
|
||||
value = input.value;
|
||||
}
|
||||
input.addEventListener('keyup', notify);
|
||||
router.on.value(() => {
|
||||
input.value = '';
|
||||
notify();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function matchSearch(search, value) {
|
||||
return !search || (value && value.toLowerCase().indexOf(search) >= 0);
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
:host material-input {
|
||||
position: absolute;
|
||||
top: 0em;
|
||||
right: 64px;
|
||||
max-width: 20%;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 400px) {
|
||||
:host material-input {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
:host material-input input {
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
</search-bar>
|
Loading…
Add table
Add a link
Reference in a new issue