2022-08-03 03:30:13 +00:00
|
|
|
<script lang="ts" setup>
|
2023-08-30 04:54:15 +00:00
|
|
|
import { VButton, VModal, VTabbar } from "@halo-dev/components";
|
2022-08-03 03:30:13 +00:00
|
|
|
import {
|
2023-08-30 04:54:15 +00:00
|
|
|
computed,
|
|
|
|
inject,
|
|
|
|
markRaw,
|
|
|
|
nextTick,
|
|
|
|
onMounted,
|
2024-05-23 03:00:49 +00:00
|
|
|
provide,
|
|
|
|
ref,
|
2023-08-30 04:54:15 +00:00
|
|
|
type Ref,
|
2024-05-23 03:00:49 +00:00
|
|
|
watch,
|
2023-08-30 04:54:15 +00:00
|
|
|
} from "vue";
|
2022-08-03 03:30:13 +00:00
|
|
|
import type { Theme } from "@halo-dev/api-client";
|
2023-03-23 08:54:33 +00:00
|
|
|
import { useI18n } from "vue-i18n";
|
2023-05-19 02:10:24 +00:00
|
|
|
import { useRouteQuery } from "@vueuse/router";
|
2023-08-30 04:54:15 +00:00
|
|
|
import InstalledThemes from "./list-tabs/InstalledThemes.vue";
|
|
|
|
import NotInstalledThemes from "./list-tabs/NotInstalledThemes.vue";
|
|
|
|
import LocalUpload from "./list-tabs/LocalUpload.vue";
|
|
|
|
import RemoteDownload from "./list-tabs/RemoteDownload.vue";
|
|
|
|
import { usePluginModuleStore } from "@/stores/plugin";
|
|
|
|
import type { PluginModule, ThemeListTab } from "@halo-dev/console-shared";
|
2023-09-22 09:14:32 +00:00
|
|
|
import { usePermission } from "@/utils/permission";
|
2023-03-23 08:54:33 +00:00
|
|
|
|
|
|
|
const { t } = useI18n();
|
2023-09-22 09:14:32 +00:00
|
|
|
const { currentUserHasPermission } = usePermission();
|
2022-08-03 03:30:13 +00:00
|
|
|
|
2023-08-30 04:54:15 +00:00
|
|
|
const selectedTheme = inject<Ref<Theme | undefined>>("selectedTheme", ref());
|
|
|
|
|
2022-08-15 12:31:51 +00:00
|
|
|
const emit = defineEmits<{
|
|
|
|
(event: "close"): void;
|
2023-08-30 04:54:15 +00:00
|
|
|
(event: "select", theme: Theme | undefined): void;
|
2022-08-15 12:31:51 +00:00
|
|
|
}>();
|
2022-08-03 03:30:13 +00:00
|
|
|
|
2024-05-23 03:00:49 +00:00
|
|
|
const modal = ref();
|
|
|
|
|
2023-08-30 04:54:15 +00:00
|
|
|
const tabs = ref<ThemeListTab[]>([
|
|
|
|
{
|
|
|
|
id: "installed",
|
|
|
|
label: t("core.theme.list_modal.tabs.installed"),
|
|
|
|
component: markRaw(InstalledThemes),
|
|
|
|
priority: 10,
|
2023-03-27 07:56:17 +00:00
|
|
|
},
|
2023-08-30 04:54:15 +00:00
|
|
|
{
|
|
|
|
id: "local-upload",
|
|
|
|
label: t("core.theme.list_modal.tabs.local_upload"),
|
|
|
|
component: markRaw(LocalUpload),
|
|
|
|
priority: 20,
|
2023-03-27 07:56:17 +00:00
|
|
|
},
|
2023-08-30 04:54:15 +00:00
|
|
|
{
|
|
|
|
id: "remote-download",
|
|
|
|
label: t("core.theme.list_modal.tabs.remote_download.label"),
|
|
|
|
component: markRaw(RemoteDownload),
|
|
|
|
priority: 30,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "not_installed",
|
|
|
|
label: t("core.theme.list_modal.tabs.not_installed"),
|
|
|
|
component: markRaw(NotInstalledThemes),
|
|
|
|
priority: 40,
|
|
|
|
},
|
|
|
|
]);
|
2022-10-18 10:12:11 +00:00
|
|
|
|
2024-05-23 03:00:49 +00:00
|
|
|
watch(
|
|
|
|
() => selectedTheme.value,
|
|
|
|
(value, oldValue) => {
|
|
|
|
if (value && oldValue) {
|
|
|
|
emit("select", value);
|
|
|
|
modal.value.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
2023-08-30 04:54:15 +00:00
|
|
|
const activeTabId = ref();
|
2022-10-18 10:12:11 +00:00
|
|
|
|
2023-08-30 04:54:15 +00:00
|
|
|
provide<Ref<string>>("activeTabId", activeTabId);
|
2022-12-20 11:04:29 +00:00
|
|
|
|
2023-08-30 04:54:15 +00:00
|
|
|
const modalTitle = computed(() => {
|
|
|
|
const tab = tabs.value.find((tab) => tab.id === activeTabId.value);
|
|
|
|
return tab?.label;
|
|
|
|
});
|
2022-10-18 10:12:11 +00:00
|
|
|
|
2023-05-19 02:10:24 +00:00
|
|
|
// handle remote wordpress url from route
|
|
|
|
const remoteDownloadUrl = useRouteQuery<string>("remote-download-url");
|
2024-05-23 03:00:49 +00:00
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
if (remoteDownloadUrl.value) {
|
|
|
|
nextTick(() => {
|
|
|
|
activeTabId.value = "remote-download";
|
|
|
|
});
|
2023-05-19 02:10:24 +00:00
|
|
|
}
|
2024-05-23 03:00:49 +00:00
|
|
|
});
|
2023-08-30 04:54:15 +00:00
|
|
|
|
|
|
|
const { pluginModules } = usePluginModuleStore();
|
|
|
|
onMounted(() => {
|
|
|
|
const tabsFromPlugins: ThemeListTab[] = [];
|
|
|
|
pluginModules.forEach((pluginModule: PluginModule) => {
|
|
|
|
const { extensionPoints } = pluginModule;
|
|
|
|
if (!extensionPoints?.["theme:list:tabs:create"]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-22 09:14:32 +00:00
|
|
|
let items = extensionPoints["theme:list:tabs:create"]() as ThemeListTab[];
|
|
|
|
|
|
|
|
items = items.filter((item) => {
|
|
|
|
return currentUserHasPermission(item.permissions);
|
|
|
|
});
|
|
|
|
|
2023-08-30 04:54:15 +00:00
|
|
|
tabsFromPlugins.push(...items);
|
|
|
|
});
|
|
|
|
|
|
|
|
tabs.value = tabs.value.concat(tabsFromPlugins).sort((a, b) => {
|
|
|
|
return a.priority - b.priority;
|
|
|
|
});
|
|
|
|
|
|
|
|
activeTabId.value = tabs.value[0].id;
|
|
|
|
});
|
2022-08-03 03:30:13 +00:00
|
|
|
</script>
|
|
|
|
<template>
|
|
|
|
<VModal
|
2024-05-23 03:00:49 +00:00
|
|
|
ref="modal"
|
2023-08-30 04:54:15 +00:00
|
|
|
:width="920"
|
2022-09-26 06:50:00 +00:00
|
|
|
height="calc(100vh - 20px)"
|
2022-10-18 10:12:11 +00:00
|
|
|
:title="modalTitle"
|
2024-05-23 03:00:49 +00:00
|
|
|
@close="emit('close')"
|
2022-08-03 03:30:13 +00:00
|
|
|
>
|
2023-08-30 04:54:15 +00:00
|
|
|
<VTabbar
|
|
|
|
v-model:active-id="activeTabId"
|
|
|
|
:items="
|
|
|
|
tabs.map((tab) => {
|
|
|
|
return { label: tab.label, id: tab.id };
|
|
|
|
})
|
|
|
|
"
|
2022-10-18 10:12:11 +00:00
|
|
|
type="outline"
|
2023-08-30 04:54:15 +00:00
|
|
|
/>
|
|
|
|
|
|
|
|
<div class="mt-2">
|
|
|
|
<template v-for="tab in tabs" :key="tab.id">
|
|
|
|
<component
|
|
|
|
:is="tab.component"
|
|
|
|
v-bind="tab.props"
|
|
|
|
v-if="tab.id === activeTabId"
|
|
|
|
/>
|
|
|
|
</template>
|
|
|
|
</div>
|
2022-10-18 10:12:11 +00:00
|
|
|
|
2022-08-03 03:30:13 +00:00
|
|
|
<template #footer>
|
2024-05-23 03:00:49 +00:00
|
|
|
<VButton @click="modal.close()">
|
2023-08-30 04:54:15 +00:00
|
|
|
{{ $t("core.common.buttons.close") }}
|
|
|
|
</VButton>
|
2022-08-03 03:30:13 +00:00
|
|
|
</template>
|
|
|
|
</VModal>
|
|
|
|
</template>
|