move isoModal to vue component

This commit is contained in:
Miao Wang 2024-04-08 10:09:29 +08:00
parent 998fe8f9fa
commit 6307b5bba7
4 changed files with 102 additions and 88 deletions

View File

@ -172,49 +172,8 @@
{% unless page.legacy or site.issue %}
<!-- iso download wizard modal -->
<!-- Modal -->
{% raw %}
<div class="modal fade" id="isoModal" tabindex="-1" role="dialog" aria-labelledby="isoModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="isoModalLabel">获取安装镜像</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
</button>
</div>
<div class="modal-body">
<div class="row" v-if="availableCategories.length > 0">
<div class="col-lg-12">
<ul class="nav nav-tabs">
<li class="nav-item" role="presentation" v-for="cat in availableCategories">
<a
:class="[curCategory === cat ? 'active' : '', 'nav-link']"
@click="switchCategory(cat)"
href="#"
>{{ knownCategories[cat] ? knownCategories[cat] : cat }}</a>
</li>
</ul>
</div>
<div class="col-lg-3">
<ul class="nav nav-pills flex-column">
<li class="nav-item" v-for="distro in curDistroList">
<a href="#" @click="switchDistro(distro)" :class="[selected.distro == distro.distro ? 'active' : '', 'nav-link']">{{ distro.distro }}</a>
</li>
</ul>
</div>
<div class="col-lg-9">
<h3>{{selected.distro}}</h3>
<ul>
<template v-for="url in selected.urls">
<li><a :href="url.url">{{url.name}}</a></li>
</template>
</ul>
</div>
</div>
</div>
</div>
</div>
</div><!-- /iso download wizard modal -->
{% endraw %}
{% endunless %}
</body>
{% raw %}

View File

@ -0,0 +1,90 @@
<script setup>
import { ref, defineEmits, computed, onMounted, nextTick } from "vue";
const distroList = ref([]);
const selected = ref({});
const curCategory = ref("");
const availableCategories = ref([]);
const knownCategories = {
os: "操作系统",
app: "应用软件",
font: "字体",
};
const emit = defineEmits(["ready"]);
fetch("/static/status/isoinfo.json").then((res) => res.json()).then((isoinfo) => {
distroList.value = isoinfo;
availableCategories.value = [...new Set(isoinfo.map((x) => x.category))];
curCategory.value = availableCategories.value[0];
selected.value = curDistroList.value[0];
});
onMounted(async () => {
await nextTick();
emit("ready");
});
const curDistroList = computed(() => {
return distroList.value
.filter((x) => x.category === curCategory.value)
.sort(function (a, b) {
return a.distro.localeCompare(b.distro);
});
});
const switchDistro = (distro) => {
selected.value = distro;
};
const switchCategory = (category) => {
curCategory.value = category;
selected.value = curDistroList.value[0];
};
</script>
<template>
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="isoModalLabel">获取安装镜像</h4>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
</button>
</div>
<div class="modal-body">
<div class="row" v-if="availableCategories.length > 0">
<div class="col-lg-12">
<ul class="nav nav-tabs">
<li class="nav-item" role="presentation" v-for="cat in availableCategories">
<a
:class="[curCategory === cat ? 'active' : '', 'nav-link']"
@click="switchCategory(cat)"
href="#"
>{{ knownCategories[cat] ? knownCategories[cat] : cat }}</a>
</li>
</ul>
</div>
<div class="col-lg-3">
<ul class="nav nav-pills flex-column">
<li class="nav-item" v-for="distro in curDistroList">
<a
href="#"
@click="switchDistro(distro)"
:class="[selected.distro == distro.distro ? 'active' : '', 'nav-link']"
>{{ distro.distro }}</a>
</li>
</ul>
</div>
<div class="col-lg-9">
<h3>{{selected.distro}}</h3>
<ul>
<template v-for="url in selected.urls">
<li><a :href="url.url">{{url.name}}</a></li>
</template>
</ul>
</div>
</div>
</div>
</div>
</div>
</template>

View File

@ -1,5 +1,16 @@
import Empty from '../components/Empty.vue'
import IsoModal from '../components/IsoModal.vue'
import { createApp } from 'vue';
const empty = createApp(Empty);
empty.mount("#upgrade-mask");
const isoModalEl = document.getElementById('isoModal');
createApp(IsoModal, {
onReady: async function() {
if (window.location.hash.match(/#iso-download(\?.*)?/)) {
new bootstrap.Modal(isoModalEl).show();
}
},
}).mount(isoModalEl);

View File

@ -195,53 +195,7 @@ const processMirrorItem = (d) => {
[d.last_started, d.last_started_ago] = stringifyTime(d.last_started_ts);
[d.next_schedule, d.next_schedule_ago] = stringifyTime(d.next_schedule_ts);
return d;
}
var vmIso = new Vue({
el: "#isoModal",
data: {
distroList: [],
selected: {},
curCategory: "",
knownCategories: {
os: "操作系统",
app: "应用软件",
font: "字体",
},
availableCategories: []
},
created: function() {
var self = this;
fetch("/static/status/isoinfo.json").then((res)=>res.json()).then((isoinfo) => {
self.distroList = isoinfo;
self.availableCategories = [... new Set(isoinfo.map((x) => x.category))]
self.curCategory = self.availableCategories[0];
self.selected = self.curDistroList[0];
if (window.location.hash.match(/#iso-download(\?.*)?/)) {
new bootstrap.Modal(document.getElementById('isoModal')).show();
}
});
},
computed: {
curDistroList() {
return this.distroList
.filter((x) => x.category === this.curCategory)
.sort(function (a, b) {
return a.distro.localeCompare(b.distro);
});
},
},
methods: {
switchDistro (distro) {
this.selected = distro;
},
switchCategory (category) {
this.curCategory = category;
this.selected = this.curDistroList[0];
}
}
});
};
});
// vim: ts=2 sts=2 sw=2 noexpandtab