feat: add supports for initialize preset plugins (#894)

#### What type of PR is this?

/kind feature

#### What this PR does / why we need it:

支持在初始化页面安装预设插件。适配:https://github.com/halo-dev/halo/pull/3394

#### Which issue(s) this PR fixes:

Fixes https://github.com/halo-dev/halo/issues/3120

#### Special notes for your reviewer:

测试方式:

1. Halo 需要切换到 https://github.com/halo-dev/halo/pull/3394
2. Console 需要 `pnpm build:packages`
3. 根据 https://github.com/halo-dev/halo/pull/3394 中的提示,将需要预设的插件放置到 `src/main/resources/presets/plugins`
4. 使用全新的环境进行初始化,完成之后进入插件管理检查是否正常安装了预设插件

#### Does this PR introduce a user-facing change?

```release-note
Console 端支持在初始化页面安装预设插件。
```
pull/892/head^2
Ryan Wang 2023-02-28 22:26:18 +08:00 committed by GitHub
parent de2612da27
commit 1dd0d89738
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 254 additions and 77 deletions

View File

@ -129,13 +129,18 @@ export const ApiConsoleHaloRunV1alpha1PluginApiAxiosParamCreator = function (con
},
/**
* Install a plugin by uploading a Jar file.
* @param {File} file
* @param {File} [file]
* @param {string} [source] Install source. Default is file.
* @param {string} [presetName] Plugin preset name. We will find the plugin from plugin presets
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
installPlugin: async (file: File, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'file' is not null or undefined
assertParamExists('installPlugin', 'file', file)
installPlugin: async (
file?: File,
source?: string,
presetName?: string,
options: AxiosRequestConfig = {},
): Promise<RequestArgs> => {
const localVarPath = `/apis/api.console.halo.run/v1alpha1/plugins/install`
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL)
@ -161,6 +166,14 @@ export const ApiConsoleHaloRunV1alpha1PluginApiAxiosParamCreator = function (con
localVarFormParams.append('file', file as any)
}
if (source !== undefined) {
localVarFormParams.append('source', source as any)
}
if (presetName !== undefined) {
localVarFormParams.append('presetName', presetName as any)
}
localVarHeaderParameter['Content-Type'] = 'multipart/form-data'
setSearchParams(localVarUrlObj, localVarQueryParameter)
@ -173,15 +186,50 @@ export const ApiConsoleHaloRunV1alpha1PluginApiAxiosParamCreator = function (con
options: localVarRequestOptions,
}
},
/**
* List all plugin presets in the system.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
listPluginPresets: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
const localVarPath = `/apis/api.console.halo.run/v1alpha1/plugin-presets`
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL)
let baseOptions
if (configuration) {
baseOptions = configuration.baseOptions
}
const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options }
const localVarHeaderParameter = {} as any
const localVarQueryParameter = {} as any
// authentication BasicAuth required
// http basic authentication required
setBasicAuthToObject(localVarRequestOptions, configuration)
// authentication BearerAuth required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
setSearchParams(localVarUrlObj, localVarQueryParameter)
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers }
return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
}
},
/**
* List plugins using query criteria and sort params
* @param {Array<string>} [sort] Sort property and direction of the list result. Supported fields: creationTimestamp
* @param {string} [keyword] Keyword of plugin name or description
* @param {boolean} [enabled] Whether the plugin is enabled
* @param {number} [size] Size of one page. Zero indicates no limit.
* @param {number} [page] The page number. Zero indicates no page.
* @param {Array<string>} [labelSelector] Label selector for filtering.
* @param {Array<string>} [fieldSelector] Field selector for filtering.
* @param {number} [page] The page number. Zero indicates no page.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
@ -190,9 +238,9 @@ export const ApiConsoleHaloRunV1alpha1PluginApiAxiosParamCreator = function (con
keyword?: string,
enabled?: boolean,
size?: number,
page?: number,
labelSelector?: Array<string>,
fieldSelector?: Array<string>,
page?: number,
options: AxiosRequestConfig = {},
): Promise<RequestArgs> => {
const localVarPath = `/apis/api.console.halo.run/v1alpha1/plugins`
@ -231,10 +279,6 @@ export const ApiConsoleHaloRunV1alpha1PluginApiAxiosParamCreator = function (con
localVarQueryParameter['size'] = size
}
if (page !== undefined) {
localVarQueryParameter['page'] = page
}
if (labelSelector) {
localVarQueryParameter['labelSelector'] = labelSelector
}
@ -243,6 +287,10 @@ export const ApiConsoleHaloRunV1alpha1PluginApiAxiosParamCreator = function (con
localVarQueryParameter['fieldSelector'] = fieldSelector
}
if (page !== undefined) {
localVarQueryParameter['page'] = page
}
setSearchParams(localVarUrlObj, localVarQueryParameter)
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers }
@ -347,15 +395,21 @@ export const ApiConsoleHaloRunV1alpha1PluginApiAxiosParamCreator = function (con
/**
* Upgrade a plugin by uploading a Jar file
* @param {string} name
* @param {File} file
* @param {File} [file]
* @param {string} [source] Install source. Default is file.
* @param {string} [presetName] Plugin preset name. We will find the plugin from plugin presets
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
upgradePlugin: async (name: string, file: File, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
upgradePlugin: async (
name: string,
file?: File,
source?: string,
presetName?: string,
options: AxiosRequestConfig = {},
): Promise<RequestArgs> => {
// verify required parameter 'name' is not null or undefined
assertParamExists('upgradePlugin', 'name', name)
// verify required parameter 'file' is not null or undefined
assertParamExists('upgradePlugin', 'file', file)
const localVarPath = `/apis/api.console.halo.run/v1alpha1/plugins/{name}/upgrade`.replace(
`{${'name'}}`,
encodeURIComponent(String(name)),
@ -384,6 +438,14 @@ export const ApiConsoleHaloRunV1alpha1PluginApiAxiosParamCreator = function (con
localVarFormParams.append('file', file as any)
}
if (source !== undefined) {
localVarFormParams.append('source', source as any)
}
if (presetName !== undefined) {
localVarFormParams.append('presetName', presetName as any)
}
localVarHeaderParameter['Content-Type'] = 'multipart/form-data'
setSearchParams(localVarUrlObj, localVarQueryParameter)
@ -434,15 +496,30 @@ export const ApiConsoleHaloRunV1alpha1PluginApiFp = function (configuration?: Co
},
/**
* Install a plugin by uploading a Jar file.
* @param {File} file
* @param {File} [file]
* @param {string} [source] Install source. Default is file.
* @param {string} [presetName] Plugin preset name. We will find the plugin from plugin presets
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async installPlugin(
file: File,
file?: File,
source?: string,
presetName?: string,
options?: AxiosRequestConfig,
): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Plugin>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.installPlugin(file, options)
const localVarAxiosArgs = await localVarAxiosParamCreator.installPlugin(file, source, presetName, options)
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)
},
/**
* List all plugin presets in the system.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async listPluginPresets(
options?: AxiosRequestConfig,
): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<Array<Plugin>>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.listPluginPresets(options)
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)
},
/**
@ -451,9 +528,9 @@ export const ApiConsoleHaloRunV1alpha1PluginApiFp = function (configuration?: Co
* @param {string} [keyword] Keyword of plugin name or description
* @param {boolean} [enabled] Whether the plugin is enabled
* @param {number} [size] Size of one page. Zero indicates no limit.
* @param {number} [page] The page number. Zero indicates no page.
* @param {Array<string>} [labelSelector] Label selector for filtering.
* @param {Array<string>} [fieldSelector] Field selector for filtering.
* @param {number} [page] The page number. Zero indicates no page.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
@ -462,9 +539,9 @@ export const ApiConsoleHaloRunV1alpha1PluginApiFp = function (configuration?: Co
keyword?: string,
enabled?: boolean,
size?: number,
page?: number,
labelSelector?: Array<string>,
fieldSelector?: Array<string>,
page?: number,
options?: AxiosRequestConfig,
): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<PluginList>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.listPlugins(
@ -472,9 +549,9 @@ export const ApiConsoleHaloRunV1alpha1PluginApiFp = function (configuration?: Co
keyword,
enabled,
size,
page,
labelSelector,
fieldSelector,
page,
options,
)
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)
@ -510,16 +587,20 @@ export const ApiConsoleHaloRunV1alpha1PluginApiFp = function (configuration?: Co
/**
* Upgrade a plugin by uploading a Jar file
* @param {string} name
* @param {File} file
* @param {File} [file]
* @param {string} [source] Install source. Default is file.
* @param {string} [presetName] Plugin preset name. We will find the plugin from plugin presets
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async upgradePlugin(
name: string,
file: File,
file?: File,
source?: string,
presetName?: string,
options?: AxiosRequestConfig,
): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<void>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.upgradePlugin(name, file, options)
const localVarAxiosArgs = await localVarAxiosParamCreator.upgradePlugin(name, file, source, presetName, options)
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)
},
}
@ -567,10 +648,20 @@ export const ApiConsoleHaloRunV1alpha1PluginApiFactory = function (
* @throws {RequiredError}
*/
installPlugin(
requestParameters: ApiConsoleHaloRunV1alpha1PluginApiInstallPluginRequest,
requestParameters: ApiConsoleHaloRunV1alpha1PluginApiInstallPluginRequest = {},
options?: AxiosRequestConfig,
): AxiosPromise<Plugin> {
return localVarFp.installPlugin(requestParameters.file, options).then((request) => request(axios, basePath))
return localVarFp
.installPlugin(requestParameters.file, requestParameters.source, requestParameters.presetName, options)
.then((request) => request(axios, basePath))
},
/**
* List all plugin presets in the system.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
listPluginPresets(options?: AxiosRequestConfig): AxiosPromise<Array<Plugin>> {
return localVarFp.listPluginPresets(options).then((request) => request(axios, basePath))
},
/**
* List plugins using query criteria and sort params
@ -588,9 +679,9 @@ export const ApiConsoleHaloRunV1alpha1PluginApiFactory = function (
requestParameters.keyword,
requestParameters.enabled,
requestParameters.size,
requestParameters.page,
requestParameters.labelSelector,
requestParameters.fieldSelector,
requestParameters.page,
options,
)
.then((request) => request(axios, basePath))
@ -632,7 +723,13 @@ export const ApiConsoleHaloRunV1alpha1PluginApiFactory = function (
options?: AxiosRequestConfig,
): AxiosPromise<void> {
return localVarFp
.upgradePlugin(requestParameters.name, requestParameters.file, options)
.upgradePlugin(
requestParameters.name,
requestParameters.file,
requestParameters.source,
requestParameters.presetName,
options,
)
.then((request) => request(axios, basePath))
},
}
@ -677,7 +774,21 @@ export interface ApiConsoleHaloRunV1alpha1PluginApiInstallPluginRequest {
* @type {File}
* @memberof ApiConsoleHaloRunV1alpha1PluginApiInstallPlugin
*/
readonly file: File
readonly file?: File
/**
* Install source. Default is file.
* @type {string}
* @memberof ApiConsoleHaloRunV1alpha1PluginApiInstallPlugin
*/
readonly source?: string
/**
* Plugin preset name. We will find the plugin from plugin presets
* @type {string}
* @memberof ApiConsoleHaloRunV1alpha1PluginApiInstallPlugin
*/
readonly presetName?: string
}
/**
@ -714,13 +825,6 @@ export interface ApiConsoleHaloRunV1alpha1PluginApiListPluginsRequest {
*/
readonly size?: number
/**
* The page number. Zero indicates no page.
* @type {number}
* @memberof ApiConsoleHaloRunV1alpha1PluginApiListPlugins
*/
readonly page?: number
/**
* Label selector for filtering.
* @type {Array<string>}
@ -734,6 +838,13 @@ export interface ApiConsoleHaloRunV1alpha1PluginApiListPluginsRequest {
* @memberof ApiConsoleHaloRunV1alpha1PluginApiListPlugins
*/
readonly fieldSelector?: Array<string>
/**
* The page number. Zero indicates no page.
* @type {number}
* @memberof ApiConsoleHaloRunV1alpha1PluginApiListPlugins
*/
readonly page?: number
}
/**
@ -789,7 +900,21 @@ export interface ApiConsoleHaloRunV1alpha1PluginApiUpgradePluginRequest {
* @type {File}
* @memberof ApiConsoleHaloRunV1alpha1PluginApiUpgradePlugin
*/
readonly file: File
readonly file?: File
/**
* Install source. Default is file.
* @type {string}
* @memberof ApiConsoleHaloRunV1alpha1PluginApiUpgradePlugin
*/
readonly source?: string
/**
* Plugin preset name. We will find the plugin from plugin presets
* @type {string}
* @memberof ApiConsoleHaloRunV1alpha1PluginApiUpgradePlugin
*/
readonly presetName?: string
}
/**
@ -839,11 +964,23 @@ export class ApiConsoleHaloRunV1alpha1PluginApi extends BaseAPI {
* @memberof ApiConsoleHaloRunV1alpha1PluginApi
*/
public installPlugin(
requestParameters: ApiConsoleHaloRunV1alpha1PluginApiInstallPluginRequest,
requestParameters: ApiConsoleHaloRunV1alpha1PluginApiInstallPluginRequest = {},
options?: AxiosRequestConfig,
) {
return ApiConsoleHaloRunV1alpha1PluginApiFp(this.configuration)
.installPlugin(requestParameters.file, options)
.installPlugin(requestParameters.file, requestParameters.source, requestParameters.presetName, options)
.then((request) => request(this.axios, this.basePath))
}
/**
* List all plugin presets in the system.
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ApiConsoleHaloRunV1alpha1PluginApi
*/
public listPluginPresets(options?: AxiosRequestConfig) {
return ApiConsoleHaloRunV1alpha1PluginApiFp(this.configuration)
.listPluginPresets(options)
.then((request) => request(this.axios, this.basePath))
}
@ -864,9 +1001,9 @@ export class ApiConsoleHaloRunV1alpha1PluginApi extends BaseAPI {
requestParameters.keyword,
requestParameters.enabled,
requestParameters.size,
requestParameters.page,
requestParameters.labelSelector,
requestParameters.fieldSelector,
requestParameters.page,
options,
)
.then((request) => request(this.axios, this.basePath))
@ -916,7 +1053,13 @@ export class ApiConsoleHaloRunV1alpha1PluginApi extends BaseAPI {
options?: AxiosRequestConfig,
) {
return ApiConsoleHaloRunV1alpha1PluginApiFp(this.configuration)
.upgradePlugin(requestParameters.name, requestParameters.file, options)
.upgradePlugin(
requestParameters.name,
requestParameters.file,
requestParameters.source,
requestParameters.presetName,
options,
)
.then((request) => request(this.axios, this.basePath))
}
}

View File

@ -18,7 +18,7 @@ import type { Configuration } from './configuration'
import type { AxiosPromise, AxiosInstance, AxiosRequestConfig } from 'axios'
import globalAxios from 'axios'
export const BASE_PATH = 'http://localhost:8090'.replace(/\/+$/, '')
export const BASE_PATH = 'http://127.0.0.1:8090'.replace(/\/+$/, '')
/**
*

View File

@ -58,6 +58,12 @@ export interface PluginStatus {
* @memberof PluginStatus
*/
logo?: string
/**
* Load location of the plugin, often a path.
* @type {string}
* @memberof PluginStatus
*/
loadLocation?: string
}
export const PluginStatusPhaseEnum = {

View File

@ -14,11 +14,13 @@ import menu from "./setup-data/menu.json";
import menuItems from "./setup-data/menu-items.json";
import type {
Category,
Plugin,
PostRequest,
SinglePageRequest,
Tag,
} from "@halo-dev/api-client";
import { useThemeStore } from "@/stores/theme";
import { useMutation } from "@tanstack/vue-query";
const router = useRouter();
@ -32,6 +34,24 @@ const {
const siteTitle = ref("");
const loading = ref(false);
const { mutate: pluginStartMutate } = useMutation({
mutationKey: ["plugin-start"],
mutationFn: async (plugin: Plugin) => {
const { data: pluginToUpdate } =
await apiClient.extension.plugin.getpluginHaloRunV1alpha1Plugin({
name: plugin.metadata.name,
});
pluginToUpdate.spec.enabled = true;
return apiClient.extension.plugin.updatepluginHaloRunV1alpha1Plugin({
name: plugin.metadata.name,
plugin: pluginToUpdate,
});
},
retry: 3,
});
const handleSubmit = async () => {
try {
loading.value = true;
@ -52,12 +72,7 @@ const handleSubmit = async () => {
const { data: postData } = await apiClient.post.draftPost({
postRequest: post as PostRequest,
});
try {
await apiClient.post.publishPost({ name: postData.metadata.name });
} catch (e) {
console.error("Publish post failed", e);
}
// Create singlePage
const { data: singlePageData } = await apiClient.singlePage.draftSinglePage(
@ -66,13 +81,9 @@ const handleSubmit = async () => {
}
);
try {
await apiClient.singlePage.publishSinglePage({
name: singlePageData.metadata.name,
});
} catch (e) {
console.error("Publish single page failed", e);
}
// Create menu and menu items
const menuItemPromises = menuItems.map((item) => {
@ -83,6 +94,26 @@ const handleSubmit = async () => {
await Promise.all(menuItemPromises);
await apiClient.extension.menu.createv1alpha1Menu({ menu: menu });
// Install preset plugins
const { data: presetPlugins } = await apiClient.plugin.listPluginPresets();
const installPluginResponses = await Promise.all(
presetPlugins.map((plugin) => {
return apiClient.plugin.installPlugin({
source: "PRESET",
presetName: plugin.metadata.name as string,
});
})
);
for (let i = 0; i < installPluginResponses.length; i++) {
const response = installPluginResponses[i];
pluginStartMutate(response.data);
}
} catch (error) {
console.error("Failed to initialize preset data", error);
}
// Create system-states ConfigMap
await apiClient.extension.configMap.createv1alpha1ConfigMap({
configMap: {
@ -102,14 +133,11 @@ const handleSubmit = async () => {
const themeStore = useThemeStore();
await themeStore.fetchActivatedTheme();
loading.value = false;
router.push({ name: "Dashboard" });
Toast.success("初始化成功");
} catch (error) {
console.error("Failed to setup", error);
} finally {
loading.value = false;
}
};
onMounted(async () => {