mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-21 13:23:07 +01:00
* WIP vue3 * WIP vue3 * WIP vue3 * Migrates to vitejs * Fixes js tests and removes not needed modules * Fixes unmount * Updates to use css instead for space * Fixes tests and rebases one more time * Uses orgua * Fixes migrations bugs with oruga and fixes scroll * Fixes v-deep * Fixes icons to prod * Fixes icons to prod * Adds favicon back * Transitions some to composition api * Updates another component to comp api * Cleans defineProps * Updates log messages * Moves more to compose api * Cleans up styles and rewrites event source * Tries to fix DOMPurify * Removes postcss * WIP typescript * Improves importing * Converts all to ts * Converts main to ts * Makes changes for tsconfig * Moves more to ts * Adds typing to store * More typing * Updates to ts * Updates the rest to ts * Fixes computes * Fixes unmount * Adds cypress with custom base fixed * Fixes jest tests * Fixes golang tests * Adds gitignore for cypress * Removes int in favor of e2e with cypress * Tries to fix int tests again * Adds title * Updates e2e tests * Uses vue for isMobile * Removes app spec * Cleans up docker * Adds drop down for settings * Fixes bug with restart * Fixes scroll up bug * Adds tests for light mode
136 lines
2.8 KiB
Vue
136 lines
2.8 KiB
Vue
<template>
|
|
<div class="panel">
|
|
<o-autocomplete
|
|
ref="autocomplete"
|
|
v-model="query"
|
|
placeholder="Search containers using ⌘ + k or ctrl + k"
|
|
field="name"
|
|
open-on-focus
|
|
keep-first
|
|
expanded
|
|
:data="results"
|
|
@select="selected"
|
|
>
|
|
<template v-slot="props">
|
|
<div class="media">
|
|
<div class="media-left">
|
|
<span class="icon is-small" :class="props.option.state">
|
|
<octicon-container-24 />
|
|
</span>
|
|
</div>
|
|
<div class="media-content">
|
|
{{ props.option.name }}
|
|
</div>
|
|
<div class="media-right">
|
|
<span class="icon is-small column-icon" @click.stop.prevent="addColumn(props.option)" title="Pin as column">
|
|
<cil-columns />
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</o-autocomplete>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { mapState, mapActions } from "vuex";
|
|
import fuzzysort from "fuzzysort";
|
|
|
|
export default {
|
|
props: {
|
|
maxResults: {
|
|
default: 20,
|
|
type: Number,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
query: "",
|
|
};
|
|
},
|
|
name: "FuzzySearchModal",
|
|
|
|
mounted() {
|
|
this.$nextTick(() => this.$refs.autocomplete.focus());
|
|
},
|
|
watch: {},
|
|
methods: {
|
|
...mapActions({
|
|
appendActiveContainer: "APPEND_ACTIVE_CONTAINER",
|
|
}),
|
|
selected(item) {
|
|
this.$router.push({ name: "container", params: { id: item.id, name: item.name } });
|
|
this.$emit("close");
|
|
},
|
|
addColumn(container) {
|
|
this.appendActiveContainer(container);
|
|
this.$emit("close");
|
|
},
|
|
},
|
|
computed: {
|
|
...mapState(["containers"]),
|
|
preparedContainers() {
|
|
return this.containers.map((c) => ({
|
|
name: c.name,
|
|
id: c.id,
|
|
created: c.created,
|
|
state: c.state,
|
|
preparedName: fuzzysort.prepare(c.name),
|
|
}));
|
|
},
|
|
results() {
|
|
const options = {
|
|
limit: this.maxResults,
|
|
key: "preparedName",
|
|
};
|
|
if (this.query) {
|
|
const results = fuzzysort.go(this.query, this.preparedContainers, options);
|
|
results.forEach((result) => {
|
|
if (result.obj.state === "running") {
|
|
result.score += 1;
|
|
}
|
|
});
|
|
return results.sort((a, b) => b.score - a.score).map((i) => i.obj);
|
|
} else {
|
|
return [...this.containers].sort((a, b) => b.created - a.created);
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.panel {
|
|
min-height: 400px;
|
|
width: 580px;
|
|
}
|
|
|
|
.running {
|
|
color: var(--primary-color);
|
|
}
|
|
|
|
.exited {
|
|
color: var(--scheme-main-ter);
|
|
}
|
|
|
|
.column-icon {
|
|
&:hover {
|
|
color: var(--secondary-color);
|
|
}
|
|
}
|
|
|
|
:deep(a.dropdown-item) {
|
|
padding-right: 1em;
|
|
.media-right {
|
|
visibility: hidden;
|
|
}
|
|
&:hover .media-right {
|
|
visibility: visible;
|
|
}
|
|
}
|
|
|
|
.icon {
|
|
vertical-align: middle;
|
|
}
|
|
</style>
|