mirror of https://github.com/halo-dev/halo
feat: api supports field filtering (halo-dev/console#591)
Signed-off-by: Ryan Wang <i@ryanc.cc> <!-- Thanks for sending a pull request! Here are some tips for you: 1. 如果这是你的第一次,请阅读我们的贡献指南:<https://github.com/halo-dev/halo/blob/master/CONTRIBUTING.md>。 1. If this is your first time, please read our contributor guidelines: <https://github.com/halo-dev/halo/blob/master/CONTRIBUTING.md>. 2. 请根据你解决问题的类型为 Pull Request 添加合适的标签。 2. Please label this pull request according to what type of issue you are addressing, especially if this is a release targeted pull request. 3. 请确保你已经添加并运行了适当的测试。 3. Ensure you have added or ran the appropriate tests for your PR. --> #### What type of PR is this? /kind feature /milestone 2.0 <!-- 添加其中一个类别: Add one of the following kinds: /kind bug /kind cleanup /kind documentation /kind feature /kind optimization 适当添加其中一个或多个类别(可选): Optionally add one or more of the following kinds if applicable: /kind api-change /kind deprecation /kind failing-test /kind flake /kind regression --> #### What this PR does / why we need it: 适配 https://github.com/halo-dev/halo/pull/2279 接口支持通过参数筛选数据。 #### Which issue(s) this PR fixes: <!-- PR 合并时自动关闭 issue。 Automatically closes linked issue when PR is merged. 用法:`Fixes #<issue 号>`,或者 `Fixes (粘贴 issue 完整链接)` Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`. --> None #### Screenshots: <!-- 如果此 PR 有 UI 的改动,最好截图说明这个 PR 的改动。 If there are UI changes to this PR, it is best to take a screenshot to illustrate the changes to this PR. eg. Before: ![screenshot-before](https://user-images.githubusercontent.com/screenshot.png) After: ![screenshot-after](https://user-images.githubusercontent.com/screenshot.png) --> None #### Special notes for your reviewer: /hold until https://github.com/halo-dev/halo/pull/2279 merge #### Does this PR introduce a user-facing change? <!-- 如果当前 Pull Request 的修改不会造成用户侧的任何变更,在 `release-note` 代码块儿中填写 `NONE`。 否则请填写用户侧能够理解的 Release Note。如果当前 Pull Request 包含破坏性更新(Break Change), Release Note 需要以 `action required` 开头。 If no, just write "NONE" in the release-note block below. If yes, a release note is required: Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required". --> ```release-note None ```pull/3445/head
parent
5d84e4de1c
commit
325525c07c
|
@ -34,7 +34,7 @@
|
|||
"@formkit/vue": "1.0.0-beta.9",
|
||||
"@halo-dev/admin-api": "^1.1.0",
|
||||
"@halo-dev/admin-shared": "workspace:*",
|
||||
"@halo-dev/api-client": "^0.0.5",
|
||||
"@halo-dev/api-client": "^0.0.6",
|
||||
"@halo-dev/components": "workspace:*",
|
||||
"@vueuse/components": "^8.9.4",
|
||||
"@vueuse/core": "^8.9.4",
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
"homepage": "https://github.com/halo-dev/halo-admin/tree/next/shared/components#readme",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@halo-dev/api-client": "^0.0.5",
|
||||
"@halo-dev/api-client": "^0.0.6",
|
||||
"@halo-dev/components": "workspace:*",
|
||||
"axios": "^0.27.2"
|
||||
},
|
||||
|
|
|
@ -14,7 +14,7 @@ importers:
|
|||
'@formkit/vue': 1.0.0-beta.9
|
||||
'@halo-dev/admin-api': ^1.1.0
|
||||
'@halo-dev/admin-shared': workspace:*
|
||||
'@halo-dev/api-client': ^0.0.5
|
||||
'@halo-dev/api-client': ^0.0.6
|
||||
'@halo-dev/components': workspace:*
|
||||
'@rushstack/eslint-patch': ^1.1.4
|
||||
'@tailwindcss/aspect-ratio': ^0.4.0
|
||||
|
@ -84,7 +84,7 @@ importers:
|
|||
'@formkit/vue': 1.0.0-beta.9_jly5jqkcc2zgnt3crhnp3znzv4
|
||||
'@halo-dev/admin-api': 1.1.0
|
||||
'@halo-dev/admin-shared': link:packages/shared
|
||||
'@halo-dev/api-client': 0.0.5
|
||||
'@halo-dev/api-client': 0.0.6
|
||||
'@halo-dev/components': link:packages/components
|
||||
'@vueuse/components': 8.9.4_vue@3.2.37
|
||||
'@vueuse/core': 8.9.4_vue@3.2.37
|
||||
|
@ -176,12 +176,12 @@ importers:
|
|||
|
||||
packages/shared:
|
||||
specifiers:
|
||||
'@halo-dev/api-client': ^0.0.5
|
||||
'@halo-dev/api-client': ^0.0.6
|
||||
'@halo-dev/components': workspace:*
|
||||
axios: ^0.27.2
|
||||
vite-plugin-dts: ^1.3.1
|
||||
dependencies:
|
||||
'@halo-dev/api-client': 0.0.5
|
||||
'@halo-dev/api-client': 0.0.6
|
||||
'@halo-dev/components': link:../components
|
||||
axios: 0.27.2
|
||||
devDependencies:
|
||||
|
@ -1873,8 +1873,8 @@ packages:
|
|||
- debug
|
||||
dev: false
|
||||
|
||||
/@halo-dev/api-client/0.0.5:
|
||||
resolution: {integrity: sha512-UqT6svy1nEVGF1swZXJgvu9iy6gQhaJ/o8lY5736Q4BbW8pYrqQBEQYNv8ySRBQr762/Cy7wDFijAGlPod7tDw==}
|
||||
/@halo-dev/api-client/0.0.6:
|
||||
resolution: {integrity: sha512-JDWGlTq+pHVrZsmqDCXAowZQFcNL3M6+guL37yrKbhylUgIutYpCMU/d2Qogc+c43FzFBq84igP84T5XtuknjQ==}
|
||||
dev: false
|
||||
|
||||
/@halo-dev/logger/1.1.0:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts" setup>
|
||||
import { VSwitch, VTag } from "@halo-dev/components";
|
||||
import type { Ref } from "vue";
|
||||
import { computed, inject, onMounted, ref } from "vue";
|
||||
import { computed, inject, ref, watchEffect } from "vue";
|
||||
import { apiClient } from "@halo-dev/admin-shared";
|
||||
import type { Plugin, Role } from "@halo-dev/api-client";
|
||||
import { pluginLabels } from "@/constants/labels";
|
||||
|
@ -11,31 +11,24 @@ import { usePluginLifeCycle } from "./composables/use-plugin";
|
|||
const plugin = inject<Ref<Plugin>>("plugin", ref({} as Plugin));
|
||||
const { changeStatus, isStarted } = usePluginLifeCycle(plugin);
|
||||
|
||||
// TODO 临时解决方案
|
||||
interface RoleTemplateGroup {
|
||||
module: string | null | undefined;
|
||||
roles: Role[];
|
||||
}
|
||||
|
||||
const roles = ref<Role[]>([]);
|
||||
const pluginRoleTemplates = ref<Role[]>([]);
|
||||
|
||||
const handleFetchRoles = async () => {
|
||||
try {
|
||||
const { data } = await apiClient.extension.role.listv1alpha1Role();
|
||||
roles.value = data.items;
|
||||
const { data } = await apiClient.extension.role.listv1alpha1Role(0, 0, [
|
||||
`${pluginLabels.NAME}=${plugin.value.metadata.name}`,
|
||||
]);
|
||||
pluginRoleTemplates.value = data.items;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
const pluginRoleTemplates = computed(() => {
|
||||
return roles.value.filter((item) => {
|
||||
return (
|
||||
item.metadata.labels?.[pluginLabels.NAME] === plugin.value.metadata?.name
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const pluginRoleTemplateGroups = computed<RoleTemplateGroup[]>(() => {
|
||||
const groups: RoleTemplateGroup[] = [];
|
||||
pluginRoleTemplates.value.forEach((role) => {
|
||||
|
@ -55,8 +48,10 @@ const pluginRoleTemplateGroups = computed<RoleTemplateGroup[]>(() => {
|
|||
return groups;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
watchEffect(() => {
|
||||
if (plugin.value.metadata?.name) {
|
||||
handleFetchRoles();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
|
|
@ -12,23 +12,42 @@ import {
|
|||
} from "@halo-dev/components";
|
||||
import PluginListItem from "./components/PluginListItem.vue";
|
||||
import PluginInstallModal from "./components/PluginInstallModal.vue";
|
||||
import { onMounted, ref } from "vue";
|
||||
import { onMounted, ref, watch } from "vue";
|
||||
import { apiClient } from "@halo-dev/admin-shared";
|
||||
import type { Plugin } from "@halo-dev/api-client";
|
||||
|
||||
const plugins = ref<Plugin[]>([] as Plugin[]);
|
||||
const pluginInstall = ref(false);
|
||||
const keyword = ref("");
|
||||
|
||||
const handleFetchPlugins = async () => {
|
||||
try {
|
||||
const fieldSelector: Array<string> = [];
|
||||
|
||||
if (keyword.value) {
|
||||
fieldSelector.push(`name=${keyword.value}`);
|
||||
}
|
||||
|
||||
const { data } =
|
||||
await apiClient.extension.plugin.listpluginHaloRunV1alpha1Plugin();
|
||||
await apiClient.extension.plugin.listpluginHaloRunV1alpha1Plugin(
|
||||
0,
|
||||
0,
|
||||
[],
|
||||
fieldSelector
|
||||
);
|
||||
plugins.value = data.items;
|
||||
} catch (e) {
|
||||
console.error("Fail to fetch plugins", e);
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => keyword.value,
|
||||
() => {
|
||||
handleFetchPlugins();
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(handleFetchPlugins);
|
||||
</script>
|
||||
<template>
|
||||
|
@ -64,7 +83,11 @@ onMounted(handleFetchPlugins);
|
|||
class="relative flex flex-col items-start sm:flex-row sm:items-center"
|
||||
>
|
||||
<div class="flex w-full flex-1 sm:w-auto">
|
||||
<FormKit placeholder="输入关键词搜索" type="text"></FormKit>
|
||||
<FormKit
|
||||
v-model="keyword"
|
||||
placeholder="输入关键词搜索"
|
||||
type="text"
|
||||
></FormKit>
|
||||
</div>
|
||||
<div class="mt-4 flex sm:mt-0">
|
||||
<VSpace spacing="lg">
|
||||
|
|
|
@ -12,7 +12,7 @@ import {
|
|||
VTag,
|
||||
} from "@halo-dev/components";
|
||||
import RoleEditingModal from "./components/RoleEditingModal.vue";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { onMounted, ref } from "vue";
|
||||
import type { Role } from "@halo-dev/api-client";
|
||||
import { apiClient } from "@halo-dev/admin-shared";
|
||||
import { roleLabels } from "@/constants/labels";
|
||||
|
@ -22,15 +22,11 @@ const roles = ref<Role[]>([]);
|
|||
const editingModal = ref<boolean>(false);
|
||||
const selectedRole = ref<Role | null>(null);
|
||||
|
||||
const basicRoles = computed(() => {
|
||||
return roles.value.filter(
|
||||
(role) => role.metadata?.labels?.[roleLabels.TEMPLATE] !== "true"
|
||||
);
|
||||
});
|
||||
|
||||
const handleFetchRoles = async () => {
|
||||
try {
|
||||
const { data } = await apiClient.extension.role.listv1alpha1Role();
|
||||
const { data } = await apiClient.extension.role.listv1alpha1Role(0, 0, [
|
||||
`!${roleLabels.TEMPLATE}`,
|
||||
]);
|
||||
roles.value = data.items;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
|
@ -169,7 +165,7 @@ onMounted(() => {
|
|||
</div>
|
||||
</template>
|
||||
<ul class="box-border h-full w-full divide-y divide-gray-100" role="list">
|
||||
<li v-for="(role, index) in basicRoles" :key="index">
|
||||
<li v-for="(role, index) in roles" :key="index">
|
||||
<div
|
||||
class="relative block cursor-pointer px-4 py-3 transition-all hover:bg-gray-50"
|
||||
>
|
||||
|
|
|
@ -59,21 +59,13 @@ export function useRoleForm() {
|
|||
}
|
||||
|
||||
export function useRoleTemplateSelection() {
|
||||
const rawRoles = ref<Role[]>([] as Role[]);
|
||||
const roleTemplates = ref<Role[]>([] as Role[]);
|
||||
const selectedRoleTemplates = ref<Set<string>>(new Set());
|
||||
|
||||
// Get all role templates based on the condition that `metadata.labels.[halo.run/role-template] === 'true'`
|
||||
const roleTemplates = computed<Role[]>(() => {
|
||||
return rawRoles.value.filter(
|
||||
(role) =>
|
||||
role.metadata.labels?.[roleLabels.TEMPLATE] === "true" &&
|
||||
role.metadata.labels?.["halo.run/hidden"] !== "true"
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Grouping role templates by module
|
||||
* Grouping role templates by module <br />
|
||||
* Example:
|
||||
* ```json
|
||||
* {
|
||||
* "module": "Users Management",
|
||||
* "roles": [
|
||||
|
@ -151,6 +143,7 @@ export function useRoleTemplateSelection() {
|
|||
* }
|
||||
* ]
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
const roleTemplateGroups = computed<RoleTemplateGroup[]>(() => {
|
||||
const groups: RoleTemplateGroup[] = [];
|
||||
|
@ -171,10 +164,16 @@ export function useRoleTemplateSelection() {
|
|||
return groups;
|
||||
});
|
||||
|
||||
/**
|
||||
* Get all role templates based on the condition that `metadata.labels.[halo.run/role-template] = 'true'` and `!halo.run/hidden`
|
||||
*/
|
||||
const handleFetchRoles = async () => {
|
||||
try {
|
||||
const { data } = await apiClient.extension.role.listv1alpha1Role();
|
||||
rawRoles.value = data.items;
|
||||
const { data } = await apiClient.extension.role.listv1alpha1Role(0, 0, [
|
||||
`${roleLabels.TEMPLATE}=true`,
|
||||
"!halo.run/hidden",
|
||||
]);
|
||||
roleTemplates.value = data.items;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
@ -185,7 +184,9 @@ export function useRoleTemplateSelection() {
|
|||
if (!checked) {
|
||||
return;
|
||||
}
|
||||
const role = rawRoles.value.find((role) => role.metadata.name === value);
|
||||
const role = roleTemplates.value.find(
|
||||
(role) => role.metadata.name === value
|
||||
);
|
||||
const dependencies =
|
||||
role?.metadata.annotations?.[rbacAnnotations.DEPENDENCIES];
|
||||
if (!dependencies) {
|
||||
|
@ -200,7 +201,6 @@ export function useRoleTemplateSelection() {
|
|||
onMounted(handleFetchRoles);
|
||||
|
||||
return {
|
||||
rawRoles,
|
||||
selectedRoleTemplates,
|
||||
roleTemplates,
|
||||
roleTemplateGroups,
|
||||
|
|
Loading…
Reference in New Issue