@liujitcn/kratos-admin-system 0.0.54 → 0.0.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/package/declarations/src/api/system/admin/v1/base_redact_storage_policy.d.ts +3 -1
  2. package/dist/package/declarations/src/locales/generated.d.ts +0 -4
  3. package/dist/package/declarations/src/rpc/base/v1/ai_session.d.ts +4 -0
  4. package/dist/package/declarations/src/rpc/base/v1/config.d.ts +11 -1
  5. package/dist/package/declarations/src/rpc/base/v1/notification.d.ts +2 -0
  6. package/dist/package/declarations/src/rpc/system/admin/v1/base_api.d.ts +4 -0
  7. package/dist/package/declarations/src/rpc/system/admin/v1/base_file.d.ts +2 -4
  8. package/dist/package/declarations/src/rpc/system/admin/v1/base_i18n_custom.d.ts +6 -0
  9. package/dist/package/declarations/src/rpc/system/admin/v1/base_message.d.ts +2 -0
  10. package/dist/package/declarations/src/rpc/system/admin/v1/base_redact_output_policy.d.ts +6 -0
  11. package/dist/package/declarations/src/rpc/system/admin/v1/base_redact_storage_policy.d.ts +27 -2
  12. package/dist/package/declarations/src/rpc/system/admin/v1/base_third_account.d.ts +2 -0
  13. package/dist/package/declarations/src/rpc/system/admin/v1/oauth_client.d.ts +2 -0
  14. package/dist/package/src/api/system/admin/v1/base_redact_storage_policy.ts +7 -0
  15. package/dist/package/src/locales/en-US.json +0 -1
  16. package/dist/package/src/locales/ja-JP.json +0 -1
  17. package/dist/package/src/locales/zh-CN.json +0 -1
  18. package/dist/package/src/locales/zh-TW.json +0 -1
  19. package/dist/package/src/rpc/base/v1/ai_session.ts +4 -0
  20. package/dist/package/src/rpc/base/v1/config.ts +13 -1
  21. package/dist/package/src/rpc/base/v1/notification.ts +2 -0
  22. package/dist/package/src/rpc/system/admin/v1/base_api.ts +7 -1
  23. package/dist/package/src/rpc/system/admin/v1/base_file.ts +2 -4
  24. package/dist/package/src/rpc/system/admin/v1/base_i18n_custom.ts +8 -0
  25. package/dist/package/src/rpc/system/admin/v1/base_message.ts +2 -0
  26. package/dist/package/src/rpc/system/admin/v1/base_redact_output_policy.ts +8 -0
  27. package/dist/package/src/rpc/system/admin/v1/base_redact_storage_policy.ts +34 -4
  28. package/dist/package/src/rpc/system/admin/v1/base_third_account.ts +2 -0
  29. package/dist/package/src/rpc/system/admin/v1/oauth_client.ts +2 -0
  30. package/dist/package/src/views/ai/chat/message.ts +3 -0
  31. package/dist/package/src/views/base/api-log/index.vue +3 -0
  32. package/dist/package/src/views/base/area/index.vue +6 -2
  33. package/dist/package/src/views/base/config/index.vue +14 -1
  34. package/dist/package/src/views/base/data-access-log/index.vue +4 -1
  35. package/dist/package/src/views/base/file/index.vue +1 -1
  36. package/dist/package/src/views/base/i18n-custom/index.vue +32 -4
  37. package/dist/package/src/views/base/job/log.vue +0 -1
  38. package/dist/package/src/views/base/login-log/index.vue +2 -9
  39. package/dist/package/src/views/base/menu/index.vue +0 -1
  40. package/dist/package/src/views/base/operation-log/index.vue +5 -2
  41. package/dist/package/src/views/base/permission-log/index.vue +3 -0
  42. package/dist/package/src/views/base/policy-evaluation-log/index.vue +3 -0
  43. package/dist/package/src/views/base/redact-output-policy/index.vue +30 -9
  44. package/dist/package/src/views/base/redact-storage-policy/index.vue +19 -11
  45. package/dist/package/src/views/base/tenant/index.vue +5 -0
  46. package/dist/package/src/views/profile/components/login-log.vue +0 -1
  47. package/dist/package/src/views/profile/components/session.vue +18 -12
  48. package/package.json +2 -2
@@ -84,7 +84,7 @@
84
84
  </template>
85
85
 
86
86
  <script setup lang="ts">
87
- import { computed, defineComponent, h, reactive, ref } from "vue";
87
+ import { computed, defineComponent, h, onMounted, reactive, ref } from "vue";
88
88
  import type { FormRules } from "element-plus";
89
89
  import type { ColumnProps, HeaderActionProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
90
90
  import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
@@ -92,12 +92,11 @@ import FormDialog from "@liujitcn/kratos-admin-core/components/Dialog/FormDialog
92
92
  import type { ProFormField, ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
93
93
  import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
94
94
  import { buildPageRequest, normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
95
+ import { useTenantScope } from "@liujitcn/kratos-admin-core/tenant";
95
96
  import { t } from "@liujitcn/kratos-admin-core";
96
97
  import { defBaseTableSourceService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_table_source";
97
- import { defCodeGenTableService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/code_gen_table";
98
98
  import { defBaseRedactRuleService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_redact_rule";
99
99
  import { defBaseRedactStoragePolicyService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_redact_storage_policy";
100
- import type { CodeGenDatabaseTable } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_table";
101
100
  import type { BaseRedactRule } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_redact_rule";
102
101
  import type { BaseRedactStoragePolicy, BaseRedactStoragePolicyForm, PageBaseRedactStoragePolicyRequest } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_redact_storage_policy";
103
102
  import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
@@ -140,8 +139,10 @@ interface StorageColumnRow extends ProFormOption {
140
139
  rule_params: string;
141
140
  }
142
141
 
143
- /** 入库脱敏表单状态。 */
144
- interface StorageFormState extends BaseRedactStoragePolicyForm {
142
+ /** 入库脱敏表单状态,新增时租户保持未选择。 */
143
+ interface StorageFormState extends Omit<BaseRedactStoragePolicyForm, "tenant_id"> {
144
+ /** 租户ID。 */
145
+ tenant_id?: number;
145
146
  /** 当前选择的字段表格。 */
146
147
  column_rows: StorageColumnRow[];
147
148
  }
@@ -179,6 +180,10 @@ const ParameterNumber = defineComponent({
179
180
 
180
181
  defineOptions({ name: "BaseRedactStoragePolicy", inheritAttrs: false });
181
182
  const { BUTTONS } = useAuthButtons();
183
+ const { isDefaultTenant, tenantColumns, tenantFormField, toRequestTenantId, loadTenantOptions } = useTenantScope();
184
+ onMounted(() => {
185
+ void loadTenantOptions();
186
+ });
182
187
  const table = ref<ProTableInstance>();
183
188
  const dialogRef = ref<InstanceType<typeof FormDialog>>();
184
189
  const sourceOptions = ref<ProFormOption[]>([]);
@@ -192,6 +197,7 @@ let columnsRequestRevision = 0;
192
197
  const statusOptions = computed<ProFormOption[]>(() => [{ label: t("common.status.enabled"), value: Status.STATUS_ENABLE }, { label: t("common.status.disabled"), value: Status.STATUS_DISABLE }]);
193
198
  const configuredFieldCount = computed(() => form.column_rows.filter(row => Boolean(row.rule_id)).length);
194
199
  const fields = computed<ProFormField[]>(() => [
200
+ tenantFormField({ label: t("common.field.tenant"), disabledOnEdit: true }),
195
201
  { prop: "source_name", label: t("system.base.redact_storage_policy.field.source_name"), component: "select", props: { filterable: true, disabled: Boolean(form.id), onChange: handleSourceChange }, options: sourceOptions.value },
196
202
  { prop: "table_name", label: t("system.base.redact_storage_policy.field.table_name"), component: "select", props: { filterable: true, disabled: Boolean(form.id) || !form.source_name, onChange: handleTableChange }, options: tableOptions.value },
197
203
  { prop: "column_rows", label: t("system.base.redact_storage_policy.field.column_name"), component: "slot", slotName: "column_rows", colSpan: 24, visible: () => Boolean(form.table_name) },
@@ -199,12 +205,14 @@ const fields = computed<ProFormField[]>(() => [
199
205
  { prop: "remark", label: t("common.field.remark"), component: "textarea" }
200
206
  ]);
201
207
  const rules = computed<FormRules>(() => ({
208
+ tenant_id: [{ required: isDefaultTenant.value, message: t("common.validation.required_select", { field: t("common.field.tenant") }), trigger: "change" }],
202
209
  source_name: [{ required: true, message: t("system.base.redact_storage_policy.validation.source_name"), trigger: "change" }],
203
210
  table_name: [{ required: true, message: t("system.base.redact_storage_policy.validation.table_name"), trigger: "change" }],
204
211
  column_rows: [{ validator: (_rule, value: StorageColumnRow[], callback) => value?.some(row => Boolean(row.rule_id)) ? callback() : callback(new Error(t("system.base.redact_storage_policy.validation.configured_fields"))), trigger: "change" }]
205
212
  }));
206
213
  const columns = computed<ColumnProps[]>(() => [
207
214
  { type: "selection", width: 55 },
215
+ ...tenantColumns({ label: t("common.field.tenant"), order: 1 }),
208
216
  { prop: "source_name", label: t("system.base.redact_storage_policy.field.source_name"), minWidth: 130, search: { el: "input" } },
209
217
  { prop: "table_name", label: t("system.base.redact_storage_policy.field.table_name"), minWidth: 180, search: { el: "input" }, render: scope => tableLabel(scope.row as BaseRedactStoragePolicy) },
210
218
  { prop: "column_name", label: t("system.base.redact_storage_policy.field.column_name"), minWidth: 150, search: { el: "input" } },
@@ -215,7 +223,7 @@ const columns = computed<ColumnProps[]>(() => [
215
223
  const headerActions = computed<HeaderActionProps[]>(() => [{ label: t("common.action.create"), type: "success", icon: CirclePlus, hidden: () => !BUTTONS.value["base:redact-storage-policy:create"], onClick: () => openDialog() }, { label: t("common.action.delete"), type: "danger", icon: Delete, hidden: () => !BUTTONS.value["base:redact-storage-policy:delete"], disabled: scope => !scope.selectedList.length, onClick: scope => deleteItems(scope.selectedList as BaseRedactStoragePolicy[]) }]);
216
224
 
217
225
  /** 请求入库脱敏策略分页列表。 */
218
- async function requestTable(params: PageBaseRedactStoragePolicyRequest) { const data = await defBaseRedactStoragePolicyService.PageBaseRedactStoragePolicy(buildPageRequest(params)); return { data: { list: data.base_redact_storage_policies ?? [], total: data.total } }; }
226
+ async function requestTable(params: PageBaseRedactStoragePolicyRequest) { const data = await defBaseRedactStoragePolicyService.PageBaseRedactStoragePolicy({ ...buildPageRequest(params), tenant_id: toRequestTenantId(params.tenant_id) }); return { data: { list: data.base_redact_storage_policies ?? [], total: data.total } }; }
219
227
  /** 加载脱敏规则选项。 */
220
228
  async function loadRules() { const rules = await requestRules(); ruleCatalog.value = rules.catalog; ruleOptions.value = rules.options; }
221
229
  /** 请求脱敏规则选项。 */
@@ -231,15 +239,15 @@ async function requestSourceOptions() { const data = await defBaseTableSourceSer
231
239
  /** 加载指定数据源的数据表选项。 */
232
240
  async function loadTables(sourceName = form.source_name) { tableOptions.value = await requestTables(sourceName); }
233
241
  /** 请求指定数据源的数据表选项。 */
234
- async function requestTables(sourceName: string) { if (!sourceName) return []; const data = await defCodeGenTableService.ListCodeGenDatabaseTable({ source_name: sourceName }); return (data.tables ?? []).map((item: CodeGenDatabaseTable) => ({ label: item.comment ? `${item.comment}(${item.name})` : item.name, value: item.name })); }
242
+ async function requestTables(sourceName: string) { if (!sourceName) return []; const data = await defBaseRedactStoragePolicyService.ListBaseRedactStorageTable({ source_name: sourceName }); return (data.tables ?? []).map(item => ({ label: item.comment && item.comment !== item.name ? `${item.comment}(${item.name})` : item.name, value: item.name })); }
235
243
  /** 预加载数据表中文注释,供列表显示。 */
236
- async function loadTableComments() { await loadSourceOptions(); const comments = new Map<string, string>(); await Promise.all(sourceOptions.value.map(async option => { const sourceName = String(option.value); const data = await defCodeGenTableService.ListCodeGenDatabaseTable({ source_name: sourceName }); for (const item of data.tables ?? []) { if (item.comment) comments.set(`${sourceName}\x00${item.name}`, item.comment); } })); tableCommentMap.value = comments; }
244
+ async function loadTableComments() { await loadSourceOptions(); const comments = new Map<string, string>(); await Promise.all(sourceOptions.value.map(async option => { const sourceName = String(option.value); const data = await defBaseRedactStoragePolicyService.ListBaseRedactStorageTable({ source_name: sourceName }); for (const item of data.tables ?? []) { if (item.comment) comments.set(`${sourceName}\x00${item.name}`, item.comment); } })); tableCommentMap.value = comments; }
237
245
  /** 加载并过滤数据库字段。 */
238
246
  async function loadColumns() { const revision = ++columnsRequestRevision; const rows = await requestColumns(form.source_name, form.table_name); if (revision === columnsRequestRevision) form.column_rows = rows; }
239
247
  /** 请求并转换数据库字段。 */
240
248
  async function requestColumns(sourceName: string, tableName: string) { if (!sourceName || !tableName) return []; const data = await defBaseRedactStoragePolicyService.ListBaseRedactStorageColumn({ source_name: sourceName, table_name: tableName }); return (data.columns ?? []).filter(item => !STORAGE_AUDIT_COLUMN_NAMES.has(item.name.toLowerCase())).map(item => createColumnRow({ label: item.name, value: item.name, name: item.name, comment: item.comment, db_type: item.db_type })); }
241
249
  /** 打开新增或编辑弹窗。 */
242
- async function openDialog(id?: number) { await dialogRef.value?.open({ load: async () => { const [sources, rules, data] = await Promise.all([requestSourceOptions(), requestRules(), id !== undefined ? defBaseRedactStoragePolicyService.GetBaseRedactStoragePolicy({ id }) : Promise.resolve(undefined)]); const sourceName = data?.source_name ?? ""; const tables = await requestTables(sourceName); const columns = data ? await requestColumns(sourceName, data.table_name) : []; return { sources, rules, data, tables, columns }; }, commit: ({ sources, rules, data, tables, columns }) => { resetForm(); sourceOptions.value = sources; tableOptions.value = tables; ruleCatalog.value = rules.catalog; ruleOptions.value = rules.options; if (data) { Object.assign(form, data); form.column_rows = columns; const row = form.column_rows.find(item => item.name === data.column_name); if (row) applyPolicy(row, data); } dialog.titleKey = id !== undefined ? "common.action.edit_resource" : "common.action.create_resource"; } }); }
250
+ async function openDialog(id?: number) { await dialogRef.value?.open({ load: async () => { await loadTenantOptions(); const [sources, rules, data] = await Promise.all([requestSourceOptions(), requestRules(), id !== undefined ? defBaseRedactStoragePolicyService.GetBaseRedactStoragePolicy({ id }) : Promise.resolve(undefined)]); const sourceName = data?.source_name ?? ""; const tables = await requestTables(sourceName); const columns = data ? await requestColumns(sourceName, data.table_name) : []; return { sources, rules, data, tables, columns }; }, commit: ({ sources, rules, data, tables, columns }) => { resetForm(); sourceOptions.value = sources; tableOptions.value = tables; ruleCatalog.value = rules.catalog; ruleOptions.value = rules.options; if (data) { Object.assign(form, data); form.column_rows = columns; const row = form.column_rows.find(item => item.name === data.column_name); if (row) applyPolicy(row, data); } dialog.titleKey = id !== undefined ? "common.action.edit_resource" : "common.action.create_resource"; } }); }
243
251
  /** 重置弹窗表单。 */
244
252
  function resetForm() { dialog.visible = false; dialogRef.value?.resetFields(); Object.assign(form, defaultForm()); sourceOptions.value = []; tableOptions.value = []; }
245
253
  /** 保存表格中已配置的全部字段。 */
@@ -260,7 +268,7 @@ async function submit() {
260
268
  table.value?.getTableList();
261
269
  }
262
270
  /** 将表格行转换为入库策略请求。 */
263
- function buildPayload(row: StorageColumnRow): BaseRedactStoragePolicyForm { syncRowParams(row); return { id: row.id, source_name: form.source_name, table_name: form.table_name, column_name: row.name, rule_id: row.rule_id ?? 0, rule_params: row.rule_params, status: form.status, remark: form.remark }; }
271
+ function buildPayload(row: StorageColumnRow): BaseRedactStoragePolicyForm { syncRowParams(row); return { id: row.id, tenant_id: form.tenant_id ?? 0, source_name: form.source_name, table_name: form.table_name, column_name: row.name, rule_id: row.rule_id ?? 0, rule_params: row.rule_params, status: form.status, remark: form.remark }; }
264
272
  /** 将已保存的策略回填到对应字段行。 */
265
273
  function applyPolicy(row: StorageColumnRow, data: BaseRedactStoragePolicyForm) { row.id = data.id; row.rule_id = data.rule_id || undefined; row.rule_params = data.rule_params; if (row.rule_id) { const rule = ruleCatalog.value.find(item => item.id === row.rule_id); row.rule_type = rule?.rule_type ?? ""; row.params = rule ? parseParams(row.rule_type, row.rule_params, rule.rule) : {}; } }
266
274
  /** 处理行规则变更。 */
@@ -288,7 +296,7 @@ async function changeStatus(row: BaseRedactStoragePolicy) { const next = row.sta
288
296
  /** 删除选中的入库策略。 */
289
297
  function deleteItems(selected?: BaseRedactStoragePolicy | BaseRedactStoragePolicy[] | number | string | Array<number | string>) { const items = Array.isArray(selected) ? selected.filter((item): item is BaseRedactStoragePolicy => typeof item === "object") : selected && typeof selected === "object" ? [selected] : []; const ids = items.length ? items.map(item => item.id) : normalizeSelectedIds(selected as number | string | Array<number | string>); if (!ids.length) { ElMessage.warning(t("common.message.select_delete_item")); return; } ElMessageBox.confirm(t("common.dialog.delete_selected", { resource: t("system.base.redact_storage_policy.title") }), t("common.title.warning"), { type: "warning" }).then(async () => { await defBaseRedactStoragePolicyService.DeleteBaseRedactStoragePolicy({ id: ids.join(",") }); ElMessage.success(t("common.message.delete_success", { resource: t("system.base.redact_storage_policy.title") })); table.value?.getTableList(); }); }
290
298
  /** 创建默认入库表单。 */
291
- function defaultForm(): StorageFormState { return { id: 0, source_name: "", table_name: "", column_name: "", column_rows: [], rule_id: 0, rule_params: "{}", status: Status.STATUS_ENABLE, remark: "" }; }
299
+ function defaultForm(): StorageFormState { return { id: 0, tenant_id: undefined, source_name: "", table_name: "", column_name: "", column_rows: [], rule_id: 0, rule_params: "{}", status: Status.STATUS_ENABLE, remark: "" }; }
292
300
 
293
301
  /** 格式化列表中的数据表名称。 */
294
302
  function tableLabel(row: BaseRedactStoragePolicy) { const comment = tableCommentMap.value.get(`${row.source_name}\x00${row.table_name}`); return comment && comment !== row.table_name ? `${comment}(${row.table_name})` : row.table_name; }
@@ -105,6 +105,7 @@ import type {
105
105
  import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
106
106
  import { buildPageRequest, normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
107
107
  import { copyText } from "@liujitcn/kratos-admin-core/security";
108
+ import { invalidateTenantOptions } from "@liujitcn/kratos-admin-core/tenant";
108
109
  import { t } from "@liujitcn/kratos-admin-core";
109
110
 
110
111
  defineOptions({
@@ -370,9 +371,11 @@ async function handleSubmit() {
370
371
  const submitData = JSON.parse(JSON.stringify(formData)) as BaseTenantForm;
371
372
  if (submitData.id) {
372
373
  await defBaseTenantService.UpdateBaseTenant({ base_tenant: submitData });
374
+ invalidateTenantOptions();
373
375
  ElMessage.success(t("common.message.update_success", { resource: t("common.field.tenant") }));
374
376
  } else {
375
377
  const response = await defBaseTenantService.CreateBaseTenant({ base_tenant: submitData });
378
+ invalidateTenantOptions();
376
379
  ElMessage.success(t("common.message.create_success", { resource: t("common.field.tenant") }));
377
380
  handleCloseDialog();
378
381
  refreshTable();
@@ -436,6 +439,7 @@ async function handleBeforeSetStatus(row: BaseTenant) {
436
439
  }
437
440
  );
438
441
  await defBaseTenantService.SetBaseTenantStatus({ id: row.id, status: nextStatus });
442
+ invalidateTenantOptions();
439
443
  ElMessage.success(t("common.message.status_success", { action: text }));
440
444
  refreshTable();
441
445
  return true;
@@ -481,6 +485,7 @@ function handleDelete(selected?: number | string | Array<number | string> | Base
481
485
  }).then(
482
486
  () => {
483
487
  defBaseTenantService.DeleteBaseTenant({ id: tenantIds }).then(() => {
488
+ invalidateTenantOptions();
484
489
  ElMessage.success(t("common.message.delete_success", { resource: t("common.field.tenant") }));
485
490
  refreshTable();
486
491
  });
@@ -69,7 +69,6 @@ const columns = computed<ColumnProps[]>(() => [
69
69
  prop: "device_id",
70
70
  label: t("system.profile.login_log.field.device_id"),
71
71
  minWidth: 160,
72
- align: "left",
73
72
  render: scope => (scope.row as BaseLoginLog).device_id || (scope.row as BaseLoginLog).user_agent || "--"
74
73
  },
75
74
  { prop: "reason", label: t("system.profile.login_log.field.reason"), minWidth: 180 }
@@ -13,20 +13,21 @@
13
13
  </div>
14
14
  </template>
15
15
 
16
- <ProTable ref="proTable" row-key="session_id" :columns="columns" :request-api="requestSessionTable" :pagination="false" />
17
- <div class="session-actions">
18
- <el-button type="danger" plain :disabled="!hasSessions" @click="revokeAll">
19
- <el-icon><SwitchButton /></el-icon>
20
- {{ t("system.profile.session.action.revoke_all") }}
21
- </el-button>
22
- </div>
16
+ <ProTable
17
+ ref="proTable"
18
+ row-key="session_id"
19
+ :columns="columns"
20
+ :header-actions="headerActions"
21
+ :request-api="requestSessionTable"
22
+ :pagination="false"
23
+ />
23
24
  </el-card>
24
25
  </template>
25
26
 
26
27
  <script setup lang="ts">
27
28
  import { computed, ref } from "vue";
28
29
  import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
29
- import type { ColumnProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
30
+ import type { ColumnProps, HeaderActionProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
30
31
  import { useRouter } from "vue-router";
31
32
  import { t } from "@liujitcn/kratos-admin-core";
32
33
  import { LOGIN_URL } from "@liujitcn/kratos-admin-core/config";
@@ -38,6 +39,15 @@ import type { BaseSession } from "@liujitcn/kratos-admin-system/rpc/system/admin
38
39
  const loading = ref(false);
39
40
  const proTable = ref<ProTableInstance>();
40
41
  const hasSessions = ref(false);
42
+ const headerActions = computed<HeaderActionProps[]>(() => [
43
+ {
44
+ label: t("system.profile.session.action.revoke_all"),
45
+ type: "danger",
46
+ icon: SwitchButton,
47
+ disabled: () => !hasSessions.value,
48
+ onClick: () => revokeAll()
49
+ }
50
+ ]);
41
51
  const columns = computed<ColumnProps[]>(() => [
42
52
  {
43
53
  prop: "current",
@@ -140,10 +150,6 @@ function formatExpires(seconds: number) {
140
150
  color: var(--el-text-color-secondary);
141
151
  font-size: 13px;
142
152
  }
143
- .session-actions {
144
- justify-content: flex-end;
145
- margin-top: 20px;
146
- }
147
153
  @media screen and (width <= 640px) {
148
154
  .session-header {
149
155
  align-items: flex-start;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@liujitcn/kratos-admin-system",
3
3
  "private": false,
4
- "version": "0.0.54",
4
+ "version": "0.0.56",
5
5
  "type": "module",
6
6
  "description": "kratos-admin system management module",
7
7
  "license": "MIT",
@@ -16,7 +16,7 @@
16
16
  "sortablejs": "^1.15.2",
17
17
  "swagger-ui-dist": "^5.32.15",
18
18
  "vue-element-plus-x": "^2.0.3",
19
- "@liujitcn/kratos-admin-core": "0.0.54"
19
+ "@liujitcn/kratos-admin-core": "0.0.56"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "@element-plus/icons-vue": "^2.3.1",