Update ui

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/7469/head
Ryan Wang 2025-05-26 22:09:34 +08:00
parent c27cbb5204
commit f36531119a
4 changed files with 72 additions and 107 deletions

View File

@ -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"

View File

@ -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>

View File

@ -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,

View File

@ -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