mirror of https://github.com/halo-dev/halo
parent
c27cbb5204
commit
f36531119a
|
@ -142,7 +142,7 @@ const actions: Action[] = [
|
|||
confirmText: t("core.common.buttons.confirm"),
|
||||
cancelText: t("core.common.buttons.cancel"),
|
||||
onConfirm: async () => {
|
||||
await consoleApiClient.content.indices.buildPostIndices();
|
||||
await consoleApiClient.content.indices.rebuildAllIndices();
|
||||
Toast.success(
|
||||
t(
|
||||
"core.dashboard.widgets.presets.quicklink.actions.refresh_search_engine.success_message"
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
<script lang="ts" setup>
|
||||
import StickyBlock from "@/components/sticky-block/StickyBlock.vue";
|
||||
import { useSettingFormConvert } from "@console/composables/use-setting-form";
|
||||
import { useThemeStore } from "@console/stores/theme";
|
||||
import type {
|
||||
ConfigMap,
|
||||
Setting,
|
||||
SettingForm,
|
||||
Theme,
|
||||
} from "@halo-dev/api-client";
|
||||
import type { FormKitSchemaCondition, FormKitSchemaNode } from "@formkit/core";
|
||||
import type { Setting, SettingForm, Theme } from "@halo-dev/api-client";
|
||||
import { consoleApiClient } from "@halo-dev/api-client";
|
||||
import {
|
||||
IconComputer,
|
||||
|
@ -24,7 +19,8 @@ import {
|
|||
VModal,
|
||||
VTabbar,
|
||||
} from "@halo-dev/components";
|
||||
import { useQuery } from "@tanstack/vue-query";
|
||||
import { useQuery, useQueryClient } from "@tanstack/vue-query";
|
||||
import { cloneDeep, set } from "lodash-es";
|
||||
import { OverlayScrollbarsComponent } from "overlayscrollbars-vue";
|
||||
import { storeToRefs } from "pinia";
|
||||
import { computed, markRaw, onMounted, ref, toRaw } from "vue";
|
||||
|
@ -46,6 +42,7 @@ const emit = defineEmits<{
|
|||
(event: "close"): void;
|
||||
}>();
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
const { t } = useI18n();
|
||||
|
||||
interface SettingTab {
|
||||
|
@ -132,10 +129,10 @@ const { data: setting } = useQuery<Setting>({
|
|||
enabled: computed(() => !!selectedTheme.value?.spec.settingName),
|
||||
});
|
||||
|
||||
const { data: configMap, refetch: handleFetchConfigMap } = useQuery<ConfigMap>({
|
||||
queryKey: ["theme-configMap", selectedTheme],
|
||||
const { data: configMapData } = useQuery({
|
||||
queryKey: ["core:theme:configMap:data", selectedTheme],
|
||||
queryFn: async () => {
|
||||
const { data } = await consoleApiClient.theme.theme.fetchThemeConfig({
|
||||
const { data } = await consoleApiClient.theme.theme.fetchThemeJsonConfig({
|
||||
name: selectedTheme?.value?.metadata.name as string,
|
||||
});
|
||||
return data;
|
||||
|
@ -145,34 +142,43 @@ const { data: configMap, refetch: handleFetchConfigMap } = useQuery<ConfigMap>({
|
|||
),
|
||||
});
|
||||
|
||||
const { formSchema, configMapFormData, convertToSave } = useSettingFormConvert(
|
||||
setting,
|
||||
configMap,
|
||||
activeSettingTab
|
||||
);
|
||||
const currentConfigMapGroupData = computed(() => {
|
||||
return configMapData.value?.[activeSettingTab.value];
|
||||
});
|
||||
|
||||
const formSchema = computed(() => {
|
||||
if (!setting.value) {
|
||||
return;
|
||||
}
|
||||
const { forms } = setting.value.spec;
|
||||
return forms.find((item) => item.group === activeSettingTab.value)
|
||||
?.formSchema as (FormKitSchemaCondition | FormKitSchemaNode)[];
|
||||
});
|
||||
|
||||
const handleRefresh = () => {
|
||||
previewFrame.value?.contentWindow?.location.reload();
|
||||
};
|
||||
|
||||
const handleSaveConfigMap = async () => {
|
||||
const handleSaveConfigMap = async (data: object) => {
|
||||
saving.value = true;
|
||||
|
||||
const configMapToUpdate = convertToSave();
|
||||
|
||||
if (!configMapToUpdate || !selectedTheme?.value) {
|
||||
if (!selectedTheme?.value) {
|
||||
saving.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
await consoleApiClient.theme.theme.updateThemeConfig({
|
||||
await consoleApiClient.theme.theme.updateThemeJsonConfig({
|
||||
name: selectedTheme?.value?.metadata.name,
|
||||
configMap: configMapToUpdate,
|
||||
body: set(
|
||||
cloneDeep(configMapData.value) || {},
|
||||
activeSettingTab.value,
|
||||
data
|
||||
),
|
||||
});
|
||||
|
||||
Toast.success(t("core.common.toast.save_success"));
|
||||
|
||||
await handleFetchConfigMap();
|
||||
queryClient.invalidateQueries({ queryKey: ["core:theme:configMap:data"] });
|
||||
|
||||
saving.value = false;
|
||||
|
||||
|
@ -313,28 +319,23 @@ const iframeClasses = computed(() => {
|
|||
type="outline"
|
||||
></VTabbar>
|
||||
<div class="bg-white p-3">
|
||||
<div v-for="(tab, index) in settingTabs" :key="index">
|
||||
<FormKit
|
||||
v-if="
|
||||
tab.id === activeSettingTab &&
|
||||
configMapFormData[tab.id] &&
|
||||
formSchema
|
||||
"
|
||||
:id="`preview-setting-${tab.id}`"
|
||||
:key="tab.id"
|
||||
v-model="configMapFormData[tab.id]"
|
||||
:name="tab.id"
|
||||
:actions="false"
|
||||
:preserve="true"
|
||||
type="form"
|
||||
@submit="handleSaveConfigMap"
|
||||
>
|
||||
<FormKitSchema
|
||||
:schema="toRaw(formSchema)"
|
||||
:data="configMapFormData[tab.id]"
|
||||
/>
|
||||
</FormKit>
|
||||
</div>
|
||||
<FormKit
|
||||
v-if="
|
||||
activeSettingTab && formSchema && currentConfigMapGroupData
|
||||
"
|
||||
:id="activeSettingTab"
|
||||
:key="activeSettingTab"
|
||||
:value="currentConfigMapGroupData || {}"
|
||||
:name="activeSettingTab"
|
||||
:preserve="true"
|
||||
type="form"
|
||||
@submit="handleSaveConfigMap"
|
||||
>
|
||||
<FormKitSchema
|
||||
:schema="toRaw(formSchema)"
|
||||
:data="toRaw(currentConfigMapGroupData)"
|
||||
/>
|
||||
</FormKit>
|
||||
<StickyBlock
|
||||
v-permission="['system:themes:manage']"
|
||||
class="-mx-4 -mb-4 -mr-3 rounded-b-base rounded-t-lg bg-white p-4 pt-5"
|
||||
|
@ -343,11 +344,7 @@ const iframeClasses = computed(() => {
|
|||
<VButton
|
||||
:loading="saving"
|
||||
type="secondary"
|
||||
@click="
|
||||
$formkit.submit(
|
||||
`preview-setting-${activeSettingTab}` || ''
|
||||
)
|
||||
"
|
||||
@click="$formkit.submit(activeSettingTab)"
|
||||
>
|
||||
{{ $t("core.common.buttons.save") }}
|
||||
</VButton>
|
||||
|
|
|
@ -3,6 +3,7 @@ import type { Theme } from "@halo-dev/api-client";
|
|||
import { consoleApiClient } from "@halo-dev/api-client";
|
||||
import { Dialog, Toast } from "@halo-dev/components";
|
||||
import { useFileDialog } from "@vueuse/core";
|
||||
import { merge } from "lodash-es";
|
||||
import { storeToRefs } from "pinia";
|
||||
import type { ComputedRef, Ref } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
|
@ -145,7 +146,7 @@ interface ExportData {
|
|||
version: string;
|
||||
settingName: string;
|
||||
configMapName: string;
|
||||
configs: { [key: string]: string };
|
||||
configs: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export function useThemeConfigFile(theme: Ref<Theme | undefined>) {
|
||||
|
@ -157,22 +158,25 @@ export function useThemeConfigFile(theme: Ref<Theme | undefined>) {
|
|||
return;
|
||||
}
|
||||
|
||||
const { data } = await consoleApiClient.theme.theme.fetchThemeConfig({
|
||||
const { data } = await consoleApiClient.theme.theme.fetchThemeJsonConfig({
|
||||
name: theme?.value?.metadata.name as string,
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
console.error("Failed to fetch theme config");
|
||||
return;
|
||||
}
|
||||
|
||||
const themeName = theme.value.metadata.name;
|
||||
const exportData = {
|
||||
|
||||
const exportData: ExportData = {
|
||||
themeName: themeName,
|
||||
version: theme.value.spec.version,
|
||||
settingName: theme.value.spec.settingName,
|
||||
configMapName: theme.value.spec.configMapName,
|
||||
configs: data.data,
|
||||
} as ExportData;
|
||||
version: theme.value.spec.version || "",
|
||||
settingName: theme.value.spec.settingName || "",
|
||||
configMapName: theme.value.spec.configMapName || "",
|
||||
configs: data as Record<string, unknown>,
|
||||
};
|
||||
|
||||
const exportStr = JSON.stringify(exportData, null, 2);
|
||||
const blob = new Blob([exportStr], { type: "application/json" });
|
||||
const temporaryExportUrl = URL.createObjectURL(blob);
|
||||
|
@ -203,7 +207,7 @@ export function useThemeConfigFile(theme: Ref<Theme | undefined>) {
|
|||
return;
|
||||
}
|
||||
const configText = await files[0].text();
|
||||
const configJson = JSON.parse(configText || "{}");
|
||||
const configJson = JSON.parse(configText || "{}") as ExportData;
|
||||
if (!configJson.configs) {
|
||||
return;
|
||||
}
|
||||
|
@ -246,57 +250,27 @@ export function useThemeConfigFile(theme: Ref<Theme | undefined>) {
|
|||
handleSaveConfigMap(configJson.configs);
|
||||
});
|
||||
|
||||
const handleSaveConfigMap = async (importData: Record<string, string>) => {
|
||||
const handleSaveConfigMap = async (importData: Record<string, unknown>) => {
|
||||
if (!theme.value) {
|
||||
return;
|
||||
}
|
||||
const { data } = await consoleApiClient.theme.theme.fetchThemeConfig({
|
||||
name: theme.value.metadata.name as string,
|
||||
});
|
||||
if (!data || !data.data) {
|
||||
const { data: originalData } =
|
||||
await consoleApiClient.theme.theme.fetchThemeJsonConfig({
|
||||
name: theme.value.metadata.name as string,
|
||||
});
|
||||
|
||||
if (!originalData) {
|
||||
return;
|
||||
}
|
||||
const combinedConfigData = combinedConfigMap(data.data, importData);
|
||||
await consoleApiClient.theme.theme.updateThemeConfig({
|
||||
|
||||
await consoleApiClient.theme.theme.updateThemeJsonConfig({
|
||||
name: theme.value.metadata.name,
|
||||
configMap: {
|
||||
...data,
|
||||
data: combinedConfigData,
|
||||
},
|
||||
body: merge(originalData, importData),
|
||||
});
|
||||
|
||||
Toast.success(t("core.common.toast.save_success"));
|
||||
};
|
||||
|
||||
/**
|
||||
* combined benchmark configuration and import configuration
|
||||
*
|
||||
* benchmark: { a: "{\"a\": 1}", b: "{\"b\": 2}" }
|
||||
* expand: { a: "{\"c\": 3}", b: "{\"d\": 4}" }
|
||||
* => { a: "{\"a\": 1, \"c\": 3}", b: "{\"b\": 2, \"d\": 4}" }
|
||||
*
|
||||
* benchmark: { a: "{\"a\": 1}", b: "{\"b\": 2}", d: "{\"d\": 4}"
|
||||
* expand: { a: "{\"a\": 2}", b: "{\"b\": 3, \"d\": 4}", c: "{\"c\": 5}" }
|
||||
* => { a: "{\"a\": 2}", b: "{\"b\": 3, \"d\": 4}", d: "{\"d\": 4}" }
|
||||
*
|
||||
*/
|
||||
const combinedConfigMap = (
|
||||
benchmarkConfigMap: { [key: string]: string },
|
||||
importConfigMap: { [key: string]: string }
|
||||
): { [key: string]: string } => {
|
||||
const result = benchmarkConfigMap;
|
||||
|
||||
for (const key in result) {
|
||||
const benchmarkValueJson = JSON.parse(benchmarkConfigMap[key] || "{}");
|
||||
const expandValueJson = JSON.parse(importConfigMap[key] || "{}");
|
||||
const combinedValue = {
|
||||
...benchmarkValueJson,
|
||||
...expandValueJson,
|
||||
};
|
||||
result[key] = JSON.stringify(combinedValue);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
return {
|
||||
handleExportThemeConfiguration,
|
||||
openSelectImportFileDialog,
|
||||
|
|
|
@ -47,7 +47,6 @@ import {
|
|||
ReverseProxyV1alpha1Api,
|
||||
RoleBindingV1alpha1Api,
|
||||
RoleV1alpha1Api,
|
||||
SearchEngineV1alpha1Api,
|
||||
SecretV1alpha1Api,
|
||||
SettingV1alpha1Api,
|
||||
SinglePageV1alpha1Api,
|
||||
|
@ -182,11 +181,6 @@ function createCoreApiClient(axiosInstance: AxiosInstance) {
|
|||
baseURL,
|
||||
axiosInstance
|
||||
),
|
||||
searchEngine: new SearchEngineV1alpha1Api(
|
||||
undefined,
|
||||
baseURL,
|
||||
axiosInstance
|
||||
),
|
||||
},
|
||||
|
||||
// metrics.halo.run
|
||||
|
|
Loading…
Reference in New Issue