Browse Source

Merge pull request #1143 from colinin/fix-component-not-registed

Fix component not registed
pull/1149/head
yx lin 1 year ago
committed by GitHub
parent
commit
a97de4cacc
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      apps/vben5/apps/app-antd/package.json
  2. 49
      apps/vben5/apps/app-antd/src/adapter/form.ts
  3. 23
      apps/vben5/apps/app-antd/src/api/core/useAbpConfigApi.ts
  4. 2
      apps/vben5/apps/app-antd/src/bootstrap.ts
  5. 5
      apps/vben5/apps/app-antd/src/locales/index.ts
  6. 6
      apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json
  7. 6
      apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json
  8. 39
      apps/vben5/apps/app-antd/src/router/routes/modules/abp.ts
  9. 15
      apps/vben5/apps/app-antd/src/views/localization/languages/index.vue
  10. 15
      apps/vben5/apps/app-antd/src/views/localization/resources/index.vue
  11. 15
      apps/vben5/apps/app-antd/src/views/localization/texts/index.vue
  12. 8
      apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue
  13. 2
      apps/vben5/packages/@abp/core/src/constants/events.ts
  14. 4
      apps/vben5/packages/@abp/features/src/components/definitions/features/FeatureDefinitionModal.vue
  15. 6
      apps/vben5/packages/@abp/features/src/components/definitions/features/FeatureDefinitionTable.vue
  16. 4
      apps/vben5/packages/@abp/features/src/components/definitions/groups/FeatureGroupDefinitionModal.vue
  17. 6
      apps/vben5/packages/@abp/features/src/components/definitions/groups/FeatureGroupDefinitionTable.vue
  18. 2
      apps/vben5/packages/@abp/gdpr/src/components/GdprTable.vue
  19. 2
      apps/vben5/packages/@abp/identity/src/api/useOrganizationUnitsApi.ts
  20. 4
      apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeModal.vue
  21. 6
      apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeTable.vue
  22. 4
      apps/vben5/packages/@abp/identity/src/components/claims/ClaimModal.vue
  23. 2
      apps/vben5/packages/@abp/identity/src/components/claims/ClaimTable.vue
  24. 15
      apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitModal.vue
  25. 14
      apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitRoleTable.vue
  26. 2
      apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue
  27. 6
      apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitUserTable.vue
  28. 4
      apps/vben5/packages/@abp/identity/src/components/organization-units/SelectMemberModal.vue
  29. 12
      apps/vben5/packages/@abp/identity/src/components/organization-units/SelectRoleModal.vue
  30. 4
      apps/vben5/packages/@abp/identity/src/components/roles/RoleModal.vue
  31. 18
      apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue
  32. 8
      apps/vben5/packages/@abp/identity/src/components/security-logs/SecurityLogTable.vue
  33. 4
      apps/vben5/packages/@abp/identity/src/components/sessions/SessionTable.vue
  34. 8
      apps/vben5/packages/@abp/identity/src/components/users/UserLockModal.vue
  35. 8
      apps/vben5/packages/@abp/identity/src/components/users/UserModal.vue
  36. 4
      apps/vben5/packages/@abp/identity/src/components/users/UserPasswordModal.vue
  37. 6
      apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue
  38. 1
      apps/vben5/packages/@abp/identity/src/constants/index.ts
  39. 2
      apps/vben5/packages/@abp/identity/src/index.ts
  40. 40
      apps/vben5/packages/@abp/localization/package.json
  41. 3
      apps/vben5/packages/@abp/localization/src/api/index.ts
  42. 89
      apps/vben5/packages/@abp/localization/src/api/useLanguagesApi.ts
  43. 28
      apps/vben5/packages/@abp/localization/src/api/useLocalizationsApi.ts
  44. 89
      apps/vben5/packages/@abp/localization/src/api/useResourcesApi.ts
  45. 62
      apps/vben5/packages/@abp/localization/src/api/useTextsApi.ts
  46. 3
      apps/vben5/packages/@abp/localization/src/components/index.ts
  47. 115
      apps/vben5/packages/@abp/localization/src/components/languages/LocalizationLanguageModal.vue
  48. 234
      apps/vben5/packages/@abp/localization/src/components/languages/LocalizationLanguageTable.vue
  49. 125
      apps/vben5/packages/@abp/localization/src/components/resources/LocalizationResourceModal.vue
  50. 225
      apps/vben5/packages/@abp/localization/src/components/resources/LocalizationResourceTable.vue
  51. 196
      apps/vben5/packages/@abp/localization/src/components/texts/LocalizationTextModal.vue
  52. 319
      apps/vben5/packages/@abp/localization/src/components/texts/LocalizationTextTable.vue
  53. 30
      apps/vben5/packages/@abp/localization/src/constants/permissions.ts
  54. 3
      apps/vben5/packages/@abp/localization/src/index.ts
  55. 2
      apps/vben5/packages/@abp/localization/src/types/index.ts
  56. 30
      apps/vben5/packages/@abp/localization/src/types/languages.ts
  57. 33
      apps/vben5/packages/@abp/localization/src/types/resources.ts
  58. 51
      apps/vben5/packages/@abp/localization/src/types/texts.ts
  59. 6
      apps/vben5/packages/@abp/localization/tsconfig.json
  60. 4
      apps/vben5/packages/@abp/notifications/src/components/definitions/groups/NotificationGroupDefinitionModal.vue
  61. 12
      apps/vben5/packages/@abp/notifications/src/components/definitions/groups/NotificationGroupDefinitionTable.vue
  62. 6
      apps/vben5/packages/@abp/notifications/src/components/definitions/notifications/NotificationDefinitionTable.vue
  63. 6
      apps/vben5/packages/@abp/notifications/src/components/my-notifilers/MyNotificationTable.vue
  64. 4
      apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationModal.vue
  65. 19
      apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationSecretModal.vue
  66. 6
      apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationTable.vue
  67. 6
      apps/vben5/packages/@abp/openiddict/src/components/authorizations/AuthorizationTable.vue
  68. 4
      apps/vben5/packages/@abp/openiddict/src/components/scopes/ScopeModal.vue
  69. 6
      apps/vben5/packages/@abp/openiddict/src/components/scopes/ScopeTable.vue
  70. 6
      apps/vben5/packages/@abp/openiddict/src/components/tokens/TokenTable.vue
  71. 1
      apps/vben5/packages/@abp/openiddict/src/constants/index.ts
  72. 1
      apps/vben5/packages/@abp/openiddict/src/index.ts
  73. 4
      apps/vben5/packages/@abp/permissions/src/components/definitions/groups/PermissionGroupDefinitionModal.vue
  74. 6
      apps/vben5/packages/@abp/permissions/src/components/definitions/groups/PermissionGroupDefinitionTable.vue
  75. 4
      apps/vben5/packages/@abp/permissions/src/components/definitions/permissions/PermissionDefinitionModal.vue
  76. 6
      apps/vben5/packages/@abp/permissions/src/components/definitions/permissions/PermissionDefinitionTable.vue
  77. 17
      apps/vben5/packages/@abp/permissions/src/components/permissions/PermissionModal.vue
  78. 1
      apps/vben5/packages/@abp/permissions/src/constants/index.ts
  79. 6
      apps/vben5/packages/@abp/platform/src/components/messages/email/EmailMessageTable.vue
  80. 6
      apps/vben5/packages/@abp/platform/src/components/messages/sms/SmsMessageTable.vue
  81. 1
      apps/vben5/packages/@abp/platform/src/constants/index.ts
  82. 1
      apps/vben5/packages/@abp/platform/src/index.ts
  83. 3
      apps/vben5/packages/@abp/saas/src/components/editions/EditionModal.vue
  84. 6
      apps/vben5/packages/@abp/saas/src/components/editions/EditionTable.vue
  85. 6
      apps/vben5/packages/@abp/saas/src/components/tenants/TenantTable.vue
  86. 1
      apps/vben5/packages/@abp/saas/src/constants/index.ts
  87. 1
      apps/vben5/packages/@abp/saas/src/index.ts
  88. 77
      apps/vben5/packages/@abp/settings/src/api/definitions.ts
  89. 4
      apps/vben5/packages/@abp/settings/src/api/index.ts
  90. 84
      apps/vben5/packages/@abp/settings/src/api/settings.ts
  91. 99
      apps/vben5/packages/@abp/settings/src/api/useDefinitionsApi.ts
  92. 103
      apps/vben5/packages/@abp/settings/src/api/useSettingsApi.ts
  93. 8
      apps/vben5/packages/@abp/settings/src/components/definitions/SettingDefinitionModal.vue
  94. 9
      apps/vben5/packages/@abp/settings/src/components/definitions/SettingDefinitionTable.vue
  95. 15
      apps/vben5/packages/@abp/settings/src/components/settings/SystemSetting.vue
  96. 4
      apps/vben5/packages/@abp/settings/src/components/settings/UserSetting.vue
  97. 1
      apps/vben5/packages/@abp/settings/src/constants/index.ts
  98. 1
      apps/vben5/packages/@abp/settings/src/index.ts
  99. 172
      apps/vben5/packages/@abp/ui/src/adapter/component/index.ts
  100. 47
      apps/vben5/packages/@abp/ui/src/adapter/form.ts

1
apps/vben5/apps/app-antd/package.json

@ -31,6 +31,7 @@
"@abp/core": "workspace:*",
"@abp/features": "workspace:*",
"@abp/identity": "workspace:*",
"@abp/localization": "workspace:*",
"@abp/notifications": "workspace:*",
"@abp/openiddict": "workspace:*",
"@abp/permissions": "workspace:*",

49
apps/vben5/apps/app-antd/src/adapter/form.ts

@ -0,0 +1,49 @@
import type {
VbenFormSchema as FormSchema,
VbenFormProps,
} from '@vben/common-ui';
import type { ComponentType } from './component';
import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';
async function initVbenForm() {
setupVbenForm<ComponentType>({
config: {
// ant design vue组件库默认都是 v-model:value
baseModelPropName: 'value',
// 一些组件是 v-model:checked 或者 v-model:fileList
modelPropNameMap: {
Checkbox: 'checked',
Radio: 'checked',
Switch: 'checked',
Upload: 'fileList',
},
},
defineRules: {
// 输入项目必填国际化适配
required: (value, _params, ctx) => {
if (value === undefined || value === null || value.length === 0) {
return $t('ui.formRules.required', [ctx.label]);
}
return true;
},
// 选择项目必填国际化适配
selectRequired: (value, _params, ctx) => {
if (value === undefined || value === null) {
return $t('ui.formRules.selectRequired', [ctx.label]);
}
return true;
},
},
});
}
const useVbenForm = useForm<ComponentType>;
export { initVbenForm, useVbenForm, z };
export type VbenFormSchema = FormSchema<ComponentType>;
export type { VbenFormProps };

23
apps/vben5/apps/app-antd/src/api/core/useAbpConfigApi.ts

@ -1,7 +1,4 @@
import type {
ApplicationConfigurationDto,
ApplicationLocalizationDto,
} from '@abp/core';
import type { ApplicationConfigurationDto } from '@abp/core';
import { useRequest } from '@abp/request';
@ -23,26 +20,8 @@ export function useAbpConfigApi() {
);
}
/**
*
* @returns
*/
function getLocalizationApi(options: {
cultureName: string;
onlyDynamics?: boolean;
}): Promise<ApplicationLocalizationDto> {
return request<ApplicationLocalizationDto>(
'/api/abp/application-localization',
{
params: options,
method: 'GET',
},
);
}
return {
cancel,
getConfigApi,
getLocalizationApi,
};
}

2
apps/vben5/apps/app-antd/src/bootstrap.ts

@ -12,6 +12,7 @@ import { useTitle } from '@vueuse/core';
import { $t, setupI18n } from '#/locales';
import { initComponentAdapter } from './adapter/component';
import { initVbenForm } from './adapter/form';
import { initRequestClient } from './adapter/request';
import App from './app.vue';
import { router } from './router';
@ -19,6 +20,7 @@ import { router } from './router';
async function bootstrap(namespace: string) {
// 初始化组件适配器
await initComponentAdapter();
await initVbenForm();
initRequestClient();
const app = createApp(App);

5
apps/vben5/apps/app-antd/src/locales/index.ts

@ -14,13 +14,12 @@ import {
import { preferences } from '@vben/preferences';
import { useAbpStore } from '@abp/core';
import { useLocalizationsApi } from '@abp/localization';
import antdEnLocale from 'ant-design-vue/es/locale/en_US';
import antdDefaultLocale from 'ant-design-vue/es/locale/zh_CN';
import dayjs from 'dayjs';
import localizedFormat from 'dayjs/plugin/localizedFormat';
import { useAbpConfigApi } from '#/api/core/useAbpConfigApi';
const antdLocale = ref<Locale>(antdDefaultLocale);
const modules = import.meta.glob('./langs/**/*.json');
@ -106,7 +105,7 @@ async function loadAntdLocale(lang: SupportedLanguagesType) {
*/
async function loadAbpLocale(lang: SupportedLanguagesType) {
const abpStore = useAbpStore();
const { getLocalizationApi } = useAbpConfigApi();
const { getLocalizationApi } = useLocalizationsApi();
let localization = abpStore.localization;
if (lang !== localization?.currentCulture.cultureName) {

6
apps/vben5/apps/app-antd/src/locales/langs/en-US/abp.json

@ -45,6 +45,12 @@
"myNotifilers": "My Notifilers",
"groups": "Groups",
"definitions": "Definitions"
},
"localization": {
"title": "Localization",
"resources": "Resources",
"languages": "Languages",
"texts": "Texts"
}
},
"openiddict": {

6
apps/vben5/apps/app-antd/src/locales/langs/zh-CN/abp.json

@ -45,6 +45,12 @@
"myNotifilers": "我的通知",
"groups": "通知分组",
"definitions": "通知定义"
},
"localization": {
"title": "本地化管理",
"resources": "资源管理",
"languages": "语言管理",
"texts": "文档管理"
}
},
"openiddict": {

39
apps/vben5/apps/app-antd/src/router/routes/modules/abp.ts

@ -175,6 +175,45 @@ const routes: RouteRecordRaw[] = [
},
],
},
{
meta: {
title: $t('abp.manage.localization.title'),
icon: 'ion:globe-outline',
},
name: 'LocalizationManagement',
path: '/manage/localization',
children: [
{
meta: {
title: $t('abp.manage.localization.resources'),
icon: 'grommet-icons:resources',
},
name: 'LocalizationResources',
path: '/manage/localization/resources',
component: () =>
import('#/views/localization/resources/index.vue'),
},
{
meta: {
title: $t('abp.manage.localization.languages'),
icon: 'cil:language',
},
name: 'LocalizationLanguages',
path: '/manage/localization/languages',
component: () =>
import('#/views/localization/languages/index.vue'),
},
{
meta: {
title: $t('abp.manage.localization.texts'),
icon: 'mi:text',
},
name: 'LocalizationTexts',
path: '/manage/localization/texts',
component: () => import('#/views/localization/texts/index.vue'),
},
],
},
{
meta: {
title: $t('abp.manage.identity.auditLogs'),

15
apps/vben5/apps/app-antd/src/views/localization/languages/index.vue

@ -0,0 +1,15 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { LocalizationLanguageTable } from '@abp/localization';
defineOptions({
name: 'LocalizationLanguages',
});
</script>
<template>
<Page>
<LocalizationLanguageTable />
</Page>
</template>

15
apps/vben5/apps/app-antd/src/views/localization/resources/index.vue

@ -0,0 +1,15 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { LocalizationResourceTable } from '@abp/localization';
defineOptions({
name: 'LocalizationResources',
});
</script>
<template>
<Page>
<LocalizationResourceTable />
</Page>
</template>

15
apps/vben5/apps/app-antd/src/views/localization/texts/index.vue

@ -0,0 +1,15 @@
<script lang="ts" setup>
import { Page } from '@vben/common-ui';
import { LocalizationTextTable } from '@abp/localization';
defineOptions({
name: 'LocalizationTexts',
});
</script>
<template>
<Page>
<LocalizationTextTable />
</Page>
</template>

8
apps/vben5/packages/@abp/auditing/src/components/audit-logs/AuditLogTable.vue

@ -1,6 +1,8 @@
<script setup lang="ts">
import type { SortOrder } from '@abp/core';
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { AuditLogDto } from '../../types/audit-logs';
@ -273,7 +275,7 @@ async function onDelete(row: AuditLogDto) {
content: $t('AbpUi.ItemWillBeDeletedMessage'),
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
gridApi.query();
},
title: $t('AbpUi.AreYouSure'),
@ -289,7 +291,7 @@ function onBulkDelete() {
ids: toValue(selectedKeys),
});
selectedKeys.value = [];
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
gridApi.query();
},
title: $t('AbpUi.AreYouSure'),

2
apps/vben5/packages/@abp/core/src/constants/events.ts

@ -3,6 +3,8 @@ export const Events = {
GetNotification: 'get-notification',
/** 新通知消息 */
NotificationRecevied: 'sys_notifications_recevied',
/** 权限变更事件 */
PermissionChange: 'sys_permission_change',
/** 用户登录事件 */
UserLogin: 'sys_user_login',
/** 用户登出事件 */

4
apps/vben5/packages/@abp/features/src/components/definitions/features/FeatureDefinitionModal.vue

@ -165,7 +165,7 @@ const [Modal, modalApi] = useVbenModal({
const api = isEditModel.value
? updateApi(formModel.value.name, input)
: createApi(input);
modalApi.setState({ confirmLoading: true, loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.SavedSuccessfully'));
@ -173,7 +173,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ confirmLoading: false, loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

6
apps/vben5/packages/@abp/features/src/components/definitions/features/FeatureDefinitionTable.vue

@ -1,5 +1,7 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { FeatureDefinitionDto } from '../../../types/definitions';
import type { FeatureGroupDefinitionDto } from '../../../types/groups';
@ -263,7 +265,7 @@ function onDelete(row: FeatureDefinitionDto) {
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.name])}`,
onOk: async () => {
await deleteApi(row.name);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
onGet();
},
title: $t('AbpUi.AreYouSure'),

4
apps/vben5/packages/@abp/features/src/components/definitions/groups/FeatureGroupDefinitionModal.vue

@ -50,7 +50,7 @@ const [Modal, modalApi] = useVbenModal({
const api = isEditModel.value
? updateApi(formModel.value.name, toValue(formModel))
: createApi(toValue(formModel));
modalApi.setState({ confirmLoading: true, loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.SavedSuccessfully'));
@ -58,7 +58,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ confirmLoading: false, loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

6
apps/vben5/packages/@abp/features/src/components/definitions/groups/FeatureGroupDefinitionTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { FeatureGroupDefinitionDto } from '../../../types/groups';
import { defineAsyncComponent, h, onMounted, reactive, ref } from 'vue';
@ -193,7 +195,7 @@ function onDelete(row: FeatureGroupDefinitionDto) {
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.name])}`,
onOk: async () => {
await deleteApi(row.name);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
onGet();
},
title: $t('AbpUi.AreYouSure'),

2
apps/vben5/packages/@abp/gdpr/src/components/GdprTable.vue

@ -161,7 +161,7 @@ const onDelete = (row: GdprRequestDto) => {
gridApi.setLoading(true);
try {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
await gridApi.query();
} finally {
gridApi.setLoading(false);

2
apps/vben5/packages/@abp/identity/src/api/useOrganizationUnitsApi.ts

@ -30,7 +30,7 @@ export function useOrganizationUnitsApi() {
): Promise<OrganizationUnitDto> {
return request<OrganizationUnitDto>('/api/identity/organization-units', {
data: input,
method: 'GET',
method: 'POST',
});
}

4
apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeModal.vue

@ -70,7 +70,7 @@ const [Modal, modalApi] = useVbenModal({
const api = formModel.value.id
? updateApi(formModel.value.id, toValue(formModel))
: createApi(toValue(formModel));
modalApi.setState({ loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.Success'));
@ -78,7 +78,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

6
apps/vben5/packages/@abp/identity/src/components/claim-types/ClaimTypeTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { IdentityClaimTypeDto } from '../../types/claim-types';
import { defineAsyncComponent, h } from 'vue';
@ -184,7 +186,7 @@ const onDelete = (row: IdentityClaimTypeDto) => {
},
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
query();
},
title: $t('AbpUi.AreYouSure'),

4
apps/vben5/packages/@abp/identity/src/components/claims/ClaimModal.vue

@ -93,7 +93,7 @@ async function initAssignableClaims() {
/** 提交声明类型变更 */
async function onSubmit(values: Record<string, any>) {
try {
modalApi.setState({ confirmLoading: true });
modalApi.setState({ submitting: true });
const claimDto = modalApi.getData<IdentityClaimDto>();
const api = claimDto.id
? updateApi({
@ -109,7 +109,7 @@ async function onSubmit(values: Record<string, any>) {
emits('change', values as IdentityClaimDto);
modalApi.close();
} finally {
modalApi.setState({ confirmLoading: false });
modalApi.setState({ submitting: false });
}
}
</script>

2
apps/vben5/packages/@abp/identity/src/components/claims/ClaimTable.vue

@ -91,7 +91,7 @@ async function onDelete(row: IdentityClaimDto) {
claimType: row.claimType,
claimValue: row.claimValue,
});
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
query();
emits('onDelete');
}

15
apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitModal.vue

@ -5,11 +5,9 @@ import type {
OrganizationUnitUpdateDto,
} from '../../types/organization-units';
import { useVbenModal } from '@vben/common-ui';
import { useVbenForm, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useVbenForm } from '@abp/ui';
import { useOrganizationUnitsApi } from '../../api/useOrganizationUnitsApi';
defineOptions({
@ -103,17 +101,16 @@ const [Modal, modalApi] = useVbenModal({
async function onSubmit(input: Record<string, any>) {
try {
modalApi.setState({
confirmLoading: true,
submitting: true,
});
const api = input.id
? updateApi(input.id, input as OrganizationUnitUpdateDto)
: createApi(input as OrganizationUnitCreateDto);
const dto = await api;
const dto = input.id
? await updateApi(input.id, input as OrganizationUnitUpdateDto)
: await createApi(input as OrganizationUnitCreateDto);
emits('change', dto);
modalApi.close();
} finally {
modalApi.setState({
confirmLoading: false,
submitting: false,
});
}
}

14
apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitRoleTable.vue

@ -1,4 +1,6 @@
<script setup lang="ts">
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { IdentityRoleDto } from '../../types/roles';
import { computed, defineAsyncComponent, h, nextTick, watch } from 'vue';
@ -7,11 +9,7 @@ import { useAccess } from '@vben/access';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import {
useVbenVxeGrid,
type VxeGridListeners,
type VxeGridProps,
} from '@abp/ui';
import { useVbenVxeGrid } from '@abp/ui';
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { Button, Modal } from 'ant-design-vue';
@ -137,8 +135,7 @@ const onShowRole = () => {
const onCreateRole = async (roles: IdentityRoleDto[]) => {
try {
roleModalApi.setState({
closable: false,
confirmLoading: true,
submitting: true,
});
await addRoles(props.selectedKey!, {
roleIds: roles.map((item) => item.id),
@ -147,8 +144,7 @@ const onCreateRole = async (roles: IdentityRoleDto[]) => {
await query();
} finally {
roleModalApi.setState({
closable: true,
confirmLoading: false,
submitting: false,
});
}
};

2
apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitTree.vue

@ -137,7 +137,7 @@ function onDelete(id: string) {
maskClosable: false,
onOk: async () => {
await deleteApi(id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
onRefresh();
},
title: $t('AbpUi.AreYouSure'),

6
apps/vben5/packages/@abp/identity/src/components/organization-units/OrganizationUnitUserTable.vue

@ -135,8 +135,7 @@ const onShowMember = () => {
const onCreateMember = (users: IdentityUserDto[]) => {
userModalApi.setState({
closable: false,
confirmLoading: true,
submitting: true,
});
addMembers(props.selectedKey!, {
userIds: users.map((item) => item.id),
@ -147,8 +146,7 @@ const onCreateMember = (users: IdentityUserDto[]) => {
})
.finally(() => {
userModalApi.setState({
closable: true,
confirmLoading: false,
submitting: false,
});
});
};

4
apps/vben5/packages/@abp/identity/src/components/organization-units/SelectMemberModal.vue

@ -1,11 +1,13 @@
<script setup lang="ts">
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { IdentityUserDto } from '../../types/users';
import { defineEmits, defineOptions, nextTick, ref, toValue } from 'vue';
import { useVbenModal, type VbenFormProps } from '@vben/common-ui';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useVbenVxeGrid } from '@abp/ui';

12
apps/vben5/packages/@abp/identity/src/components/organization-units/SelectRoleModal.vue

@ -1,16 +1,16 @@
<script setup lang="ts">
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { IdentityRoleDto } from '../../types/roles';
import { defineEmits, defineOptions, nextTick, ref, toValue } from 'vue';
import { useVbenModal, type VbenFormProps } from '@vben/common-ui';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import {
useVbenVxeGrid,
type VxeGridListeners,
type VxeGridProps,
} from '@abp/ui';
import { useVbenVxeGrid } from '@abp/ui';
import { useOrganizationUnitsApi } from '../../api/useOrganizationUnitsApi';

4
apps/vben5/packages/@abp/identity/src/components/roles/RoleModal.vue

@ -45,7 +45,7 @@ const [Modal, modalApi] = useVbenModal({
const api = formModel.value.id
? updateApi(formModel.value.id, toValue(formModel))
: createApi(toValue(formModel));
modalApi.setState({ loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.Success'));
@ -53,7 +53,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

18
apps/vben5/packages/@abp/identity/src/components/roles/RoleTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { IdentityRoleDto } from '../../types/roles';
import { defineAsyncComponent, h } from 'vue';
@ -12,7 +14,7 @@ import { createIconifyIcon } from '@vben/icons';
import { $t } from '@vben/locales';
import { AuditLogPermissions, EntityChangeDrawer } from '@abp/auditing';
import { useAbpStore, useFeatures } from '@abp/core';
import { Events, useAbpStore, useEventBus, useFeatures } from '@abp/core';
import { PermissionModal } from '@abp/permissions';
import { useVbenVxeGrid } from '@abp/ui';
import {
@ -39,6 +41,7 @@ const RoleModal = defineAsyncComponent(() => import('./RoleModal.vue'));
const ClaimModal = defineAsyncComponent(() => import('./RoleClaimModal.vue'));
const abpStore = useAbpStore();
const { publish } = useEventBus();
const { isEnabled } = useFeatures();
const { hasAccessByCodes } = useAccess();
const { cancel, deleteApi, getPagedListApi } = useRolesApi();
@ -143,7 +146,7 @@ const handleDelete = (row: IdentityRoleDto) => {
},
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
query();
},
title: $t('AbpUi.AreYouSure'),
@ -179,6 +182,13 @@ const handleMenuClick = async (row: IdentityRoleDto, info: MenuInfo) => {
}
}
};
function onPermissionChange(_name: string, key: string) {
const roles = abpStore.application?.currentUser.roles ?? [];
if (roles.includes(key)) {
publish(Events.PermissionChange);
}
}
</script>
<template>
@ -271,7 +281,7 @@ const handleMenuClick = async (row: IdentityRoleDto, info: MenuInfo) => {
</Grid>
<RoleEditModal @change="() => query()" />
<RoleClaimModal @change="query" />
<RolePermissionModal />
<RolePermissionModal @change="onPermissionChange" />
<RoleChangeDrawer />
</template>

8
apps/vben5/packages/@abp/identity/src/components/security-logs/SecurityLogTable.vue

@ -1,6 +1,8 @@
<script setup lang="ts">
import type { SortOrder } from '@abp/core';
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { SecurityLogDto } from '../../types/security-logs';
@ -223,7 +225,7 @@ function onDelete(row: SecurityLogDto) {
},
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
gridApi.query();
},
title: $t('AbpUi.AreYouSure'),
@ -239,7 +241,7 @@ function onBulkDelete() {
ids: toValue(selectedKeys),
});
selectedKeys.value = [];
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
gridApi.query();
},
title: $t('AbpUi.AreYouSure'),

4
apps/vben5/packages/@abp/identity/src/components/sessions/SessionTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { SelectValue } from 'ant-design-vue/es/select';
import type { VbenFormProps } from '@vben/common-ui';
import type { IdentityUserDto } from '../../types';
import type { IdentitySessionDto } from '../../types/sessions';

8
apps/vben5/packages/@abp/identity/src/components/users/UserLockModal.vue

@ -2,11 +2,9 @@
<script setup lang="ts">
import type { IdentityUserDto } from '../../types/users';
import { useVbenModal } from '@vben/common-ui';
import { useVbenForm, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useVbenForm } from '@abp/ui';
import { useUsersApi } from '../../api/useUsersApi';
defineOptions({
@ -109,7 +107,7 @@ const [Modal, modalApi] = useVbenModal({
async function onSubmit(input: Record<string, any>) {
try {
modalApi.setState({
confirmLoading: true,
submitting: true,
});
const lockSeconds = input.type * input.seconds;
await lockApi(input.userId, lockSeconds);
@ -117,7 +115,7 @@ async function onSubmit(input: Record<string, any>) {
modalApi.close();
} finally {
modalApi.setState({
confirmLoading: false,
submitting: false,
});
}
}

8
apps/vben5/packages/@abp/identity/src/components/users/UserModal.vue

@ -79,7 +79,7 @@ const [Modal, modalApi] = useVbenModal({
const api = formModel.value.id
? updateApi(formModel.value.id, toValue(formModel))
: createApi(toValue(formModel));
modalApi.setState({ confirmLoading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.SavedSuccessfully'));
@ -87,7 +87,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ confirmLoading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {
@ -291,8 +291,8 @@ async function onLoadOuChildren(node: EventDataNode) {
}"
:render="(item) => item.title"
:titles="[
$t('AbpIdentityServer.Assigned'),
$t('AbpIdentityServer.Available'),
$t('AbpOpenIddict.Assigned'),
$t('AbpOpenIddict.Available'),
]"
class="tree-transfer"
/>

4
apps/vben5/packages/@abp/identity/src/components/users/UserPasswordModal.vue

@ -70,10 +70,10 @@ const [Modal, modalApi] = useVbenModal({
},
onConfirm: async () => {
try {
modalApi.setState({ confirmLoading: true });
modalApi.setState({ submitting: true });
await formApi.validateAndSubmitForm();
} finally {
modalApi.setState({ confirmLoading: false });
modalApi.setState({ submitting: false });
}
},
onOpenChange(isOpen) {

6
apps/vben5/packages/@abp/identity/src/components/users/UserTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { IdentityUserDto } from '../../types/users';
import { computed, defineAsyncComponent, h } from 'vue';
@ -200,7 +202,7 @@ const handleDelete = (row: IdentityUserDto) => {
},
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
query();
},
title: $t('AbpUi.AreYouSure'),

1
apps/vben5/packages/@abp/identity/src/constants/index.ts

@ -1 +0,0 @@
export * from './permissions';

2
apps/vben5/packages/@abp/identity/src/index.ts

@ -1,4 +1,4 @@
export * from './api';
export * from './components';
export * from './constants';
export { UserLookupPermissions } from './constants/permissions';
export * from './types';

40
apps/vben5/packages/@abp/localization/package.json

@ -0,0 +1,40 @@
{
"name": "@abp/localization",
"version": "9.0.4",
"homepage": "https://github.com/colinin/abp-next-admin",
"bugs": "https://github.com/colinin/abp-next-admin/issues",
"repository": {
"type": "git",
"url": "git+https://github.com/colinin/abp-next-admin.git",
"directory": "packages/@abp/localization"
},
"license": "MIT",
"type": "module",
"sideEffects": [
"**/*.css"
],
"exports": {
".": {
"types": "./src/index.ts",
"default": "./src/index.ts"
}
},
"dependencies": {
"@abp/components": "workspace:*",
"@abp/core": "workspace:*",
"@abp/request": "workspace:*",
"@abp/signalr": "workspace:*",
"@abp/ui": "workspace:*",
"@ant-design/icons-vue": "catalog:",
"@vben/access": "workspace:*",
"@vben/common-ui": "workspace:*",
"@vben/hooks": "workspace:*",
"@vben/icons": "workspace:*",
"@vben/layouts": "workspace:*",
"@vben/locales": "workspace:*",
"ant-design-vue": "catalog:",
"dayjs": "catalog:",
"vue": "catalog:*",
"vxe-table": "catalog:"
}
}

3
apps/vben5/packages/@abp/localization/src/api/index.ts

@ -0,0 +1,3 @@
export { useLanguagesApi } from './useLanguagesApi';
export { useLocalizationsApi } from './useLocalizationsApi';
export { useResourcesApi } from './useResourcesApi';

89
apps/vben5/packages/@abp/localization/src/api/useLanguagesApi.ts

@ -0,0 +1,89 @@
import type { ListResultDto } from '@abp/core';
import type {
LanguageCreateDto,
LanguageDto,
LanguageGetListInput,
LanguageUpdateDto,
} from '../types/languages';
import { useRequest } from '@abp/request';
export function useLanguagesApi() {
const { cancel, request } = useRequest();
/**
*
* @param input
* @returns
*/
function getListApi(
input?: LanguageGetListInput,
): Promise<ListResultDto<LanguageDto>> {
return request<ListResultDto<LanguageDto>>(
'/api/abp/localization/languages',
{
method: 'GET',
params: input,
},
);
}
/**
*
* @param name
* @returns
*/
function getApi(name: string): Promise<LanguageDto> {
return request<LanguageDto>(`/api/localization/languages/${name}`, {
method: 'GET',
});
}
/**
*
* @param name
*/
function deleteApi(name: string): Promise<void> {
return request(`/api/localization/languages/${name}`, {
method: 'DELETE',
});
}
/**
*
* @param input
* @returns
*/
function createApi(input: LanguageCreateDto): Promise<LanguageDto> {
return request<LanguageDto>(`/api/localization/languages`, {
data: input,
method: 'POST',
});
}
/**
*
* @param name
* @param input
* @returns
*/
function updateApi(
name: string,
input: LanguageUpdateDto,
): Promise<LanguageDto> {
return request<LanguageDto>(`/api/localization/languages/${name}`, {
data: input,
method: 'PUT',
});
}
return {
cancel,
createApi,
deleteApi,
getApi,
getListApi,
updateApi,
};
}

28
apps/vben5/packages/@abp/localization/src/api/useLocalizationsApi.ts

@ -0,0 +1,28 @@
import type { ApplicationLocalizationDto } from '@abp/core';
import { useRequest } from '@abp/request';
export function useLocalizationsApi() {
const { cancel, request } = useRequest();
/**
*
* @returns
*/
function getLocalizationApi(options: {
cultureName: string;
onlyDynamics?: boolean;
}): Promise<ApplicationLocalizationDto> {
return request<ApplicationLocalizationDto>(
'/api/abp/application-localization',
{
method: 'GET',
params: options,
},
);
}
return {
cancel,
getLocalizationApi,
};
}

89
apps/vben5/packages/@abp/localization/src/api/useResourcesApi.ts

@ -0,0 +1,89 @@
import type { ListResultDto } from '@abp/core';
import type {
ResourceCreateDto,
ResourceDto,
ResourceGetListInput,
ResourceUpdateDto,
} from '../types/resources';
import { useRequest } from '@abp/request';
export function useResourcesApi() {
const { cancel, request } = useRequest();
/**
*
* @param input
* @returns
*/
function getListApi(
input?: ResourceGetListInput,
): Promise<ListResultDto<ResourceDto>> {
return request<ListResultDto<ResourceDto>>(
'/api/abp/localization/resources',
{
method: 'GET',
params: input,
},
);
}
/**
*
* @param name
* @returns
*/
function getApi(name: string): Promise<ResourceDto> {
return request<ResourceDto>(`/api/localization/resources/${name}`, {
method: 'GET',
});
}
/**
*
* @param name
*/
function deleteApi(name: string): Promise<void> {
return request(`/api/localization/resources/${name}`, {
method: 'DELETE',
});
}
/**
*
* @param input
* @returns
*/
function createApi(input: ResourceCreateDto): Promise<ResourceDto> {
return request<ResourceDto>(`/api/localization/resources`, {
data: input,
method: 'POST',
});
}
/**
*
* @param name
* @param input
* @returns
*/
function updateApi(
name: string,
input: ResourceUpdateDto,
): Promise<ResourceDto> {
return request<ResourceDto>(`/api/localization/resources/${name}`, {
data: input,
method: 'PUT',
});
}
return {
cancel,
createApi,
deleteApi,
getApi,
getListApi,
updateApi,
};
}

62
apps/vben5/packages/@abp/localization/src/api/useTextsApi.ts

@ -0,0 +1,62 @@
import type { ListResultDto } from '@abp/core';
import type {
GetTextByKeyInput,
GetTextsInput,
SetTextInput,
TextDifferenceDto,
TextDto,
} from '../types/texts';
import { useRequest } from '@abp/request';
export function useTextsApi() {
const { cancel, request } = useRequest();
/**
*
* @param input
* @returns
*/
function getListApi(
input: GetTextsInput,
): Promise<ListResultDto<TextDifferenceDto>> {
return request<ListResultDto<TextDifferenceDto>>(
'/api/abp/localization/texts',
{
method: 'GET',
params: input,
},
);
}
/**
*
* @param input
* @returns
*/
function getApi(input: GetTextByKeyInput): Promise<TextDto> {
return request<TextDto>('/api/abp/localization/texts/by-culture-key', {
method: 'GET',
params: input,
});
}
/**
*
* @param input
*/
function setApi(input: SetTextInput): Promise<void> {
return request('/api/localization/texts', {
data: input,
method: 'PUT',
});
}
return {
cancel,
getApi,
getListApi,
setApi,
};
}

3
apps/vben5/packages/@abp/localization/src/components/index.ts

@ -0,0 +1,3 @@
export { default as LocalizationLanguageTable } from './languages/LocalizationLanguageTable.vue';
export { default as LocalizationResourceTable } from './resources/LocalizationResourceTable.vue';
export { default as LocalizationTextTable } from './texts/LocalizationTextTable.vue';

115
apps/vben5/packages/@abp/localization/src/components/languages/LocalizationLanguageModal.vue

@ -0,0 +1,115 @@
<script setup lang="ts">
import type { FormInstance } from 'ant-design-vue';
import type { LanguageDto } from '../../types/languages';
import { defineEmits, defineOptions, ref, toValue, useTemplateRef } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { Form, Input, message } from 'ant-design-vue';
import { useLanguagesApi } from '../../api/useLanguagesApi';
defineOptions({
name: 'LocalizationLanguageModal',
});
const emits = defineEmits<{
(event: 'change', data: LanguageDto): void;
}>();
const FormItem = Form.Item;
const defaultModel = {} as LanguageDto;
const form = useTemplateRef<FormInstance>('form');
const formModel = ref<LanguageDto>({ ...defaultModel });
const { cancel, createApi, getApi, updateApi } = useLanguagesApi();
const [Modal, modalApi] = useVbenModal({
class: 'w-1/2',
draggable: true,
fullscreenButton: false,
onCancel() {
modalApi.close();
},
onClosed() {
cancel('LocalizationLanguageModal has closed!');
},
onConfirm: onSubmit,
onOpenChange: async (isOpen: boolean) => {
if (isOpen) {
formModel.value = { ...defaultModel };
modalApi.setState({
title: $t('LocalizationManagement.Language:AddNew'),
});
const { cultureName } = modalApi.getData<LanguageDto>();
cultureName && (await onGet(cultureName));
}
},
title: $t('LocalizationManagement.Language:AddNew'),
});
async function onGet(name: string) {
try {
modalApi.setState({ loading: true });
const dto = await getApi(name);
formModel.value = dto;
modalApi.setState({
title: `${$t('AbpLocalization.Languages')} - ${dto.cultureName}`,
});
} finally {
modalApi.setState({ loading: false });
}
}
async function onSubmit() {
await form.value?.validate();
try {
modalApi.setState({ submitting: true });
const input = toValue(formModel);
const api = input.id
? updateApi(input.cultureName, input)
: createApi(input);
const dto = await api;
message.success($t('AbpUi.SavedSuccessfully'));
emits('change', dto);
modalApi.close();
} finally {
modalApi.setState({ submitting: false });
}
}
</script>
<template>
<Modal>
<Form
ref="form"
:label-col="{ span: 6 }"
:model="formModel"
:wrapper-col="{ span: 18 }"
>
<FormItem
:label="$t('AbpLocalization.DisplayName:CultureName')"
name="cultureName"
required
>
<Input v-model:value="formModel.cultureName" autocomplete="off" />
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:UiCultureName')"
name="uiCultureName"
>
<Input v-model:value="formModel.uiCultureName" autocomplete="off" />
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:DisplayName')"
name="displayName"
required
>
<Input v-model:value="formModel.displayName" autocomplete="off" />
</FormItem>
</Form>
</Modal>
</template>
<style scoped></style>

234
apps/vben5/packages/@abp/localization/src/components/languages/LocalizationLanguageTable.vue

@ -0,0 +1,234 @@
<script setup lang="ts">
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { LanguageDto } from '../../types/languages';
import { defineAsyncComponent, h, onMounted, reactive, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useAbpStore } from '@abp/core';
import { useVbenVxeGrid } from '@abp/ui';
import {
DeleteOutlined,
EditOutlined,
PlusOutlined,
} from '@ant-design/icons-vue';
import { Button, message, Modal } from 'ant-design-vue';
import { useLanguagesApi } from '../../api/useLanguagesApi';
import { useLocalizationsApi } from '../../api/useLocalizationsApi';
import { LanguagesPermissions } from '../../constants/permissions';
defineOptions({
name: 'LocalizationLanguageTable',
});
const dataSource = ref<LanguageDto[]>([]);
const pageState = reactive({
current: 1,
size: 10,
total: 0,
});
const abpStore = useAbpStore();
const { deleteApi, getListApi } = useLanguagesApi();
const { getLocalizationApi } = useLocalizationsApi();
const formOptions: VbenFormProps = {
//
collapsed: false,
handleReset: onReset,
async handleSubmit(params) {
pageState.current = 1;
await onGet(params);
},
schema: [
{
component: 'Input',
fieldName: 'filter',
formItemClass: 'col-span-2 items-baseline',
label: $t('AbpUi.Search'),
},
],
//
showCollapseButton: true,
//
submitOnEnter: true,
};
const gridOptions: VxeGridProps<LanguageDto> = {
columns: [
{
align: 'left',
field: 'cultureName',
minWidth: 150,
title: $t('AbpLocalization.DisplayName:CultureName'),
},
{
align: 'left',
field: 'displayName',
minWidth: 150,
title: $t('AbpLocalization.DisplayName:DisplayName'),
},
{
align: 'left',
field: 'uiCultureName',
minWidth: 150,
title: $t('AbpLocalization.DisplayName:UiCultureName'),
},
{
field: 'action',
fixed: 'right',
slots: { default: 'action' },
title: $t('AbpUi.Actions'),
width: 220,
},
],
exportConfig: {},
keepSource: true,
toolbarConfig: {
custom: true,
export: true,
refresh: false,
zoom: true,
},
};
const gridEvents: VxeGridListeners<LanguageDto> = {
pageChange(params) {
pageState.current = params.currentPage;
pageState.size = params.pageSize;
onPageChange();
},
};
const [LocalizationLanguageModal, modalApi] = useVbenModal({
connectedComponent: defineAsyncComponent(
() => import('./LocalizationLanguageModal.vue'),
),
});
const [Grid, gridApi] = useVbenVxeGrid({
formOptions,
gridEvents,
gridOptions,
});
async function onGet(input?: Record<string, string>) {
try {
gridApi.setLoading(true);
const { items } = await getListApi(input);
pageState.total = items.length;
dataSource.value = items;
onPageChange();
} finally {
gridApi.setLoading(false);
}
}
async function onReset() {
await gridApi.formApi.resetForm();
const input = await gridApi.formApi.getValues();
await onGet(input);
}
function onPageChange() {
const items = dataSource.value.slice(
(pageState.current - 1) * pageState.size,
pageState.current * pageState.size,
);
gridApi.setGridOptions({
data: items,
pagerConfig: {
currentPage: pageState.current,
pageSize: pageState.size,
total: pageState.total,
},
});
}
function onCreate() {
modalApi.setData({});
modalApi.open();
}
function onUpdate(row: LanguageDto) {
modalApi.setData(row);
modalApi.open();
}
function onDelete(row: LanguageDto) {
Modal.confirm({
centered: true,
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.cultureName])}`,
onOk: async () => {
await deleteApi(row.cultureName);
message.success($t('AbpUi.DeletedSuccessfully'));
onChange(row);
},
title: $t('AbpUi.AreYouSure'),
});
}
async function onChange(data: LanguageDto) {
const input = await gridApi.formApi.getValues();
onGet(input);
//
const cultureName =
abpStore.application!.localization.currentCulture.cultureName;
if (data.cultureName === cultureName) {
const localization = await getLocalizationApi({
cultureName,
});
abpStore.setLocalization(localization);
}
}
onMounted(onGet);
</script>
<template>
<Grid :table-title="$t('AbpLocalization.Languages')">
<template #toolbar-tools>
<Button
:icon="h(PlusOutlined)"
type="primary"
v-access:code="[LanguagesPermissions.Create]"
@click="onCreate"
>
{{ $t('LocalizationManagement.Language:AddNew') }}
</Button>
</template>
<template #action="{ row }">
<div class="flex flex-row">
<Button
:icon="h(EditOutlined)"
block
type="link"
v-access:code="[LanguagesPermissions.Update]"
@click="onUpdate(row)"
>
{{ $t('AbpUi.Edit') }}
</Button>
<Button
v-if="!row.isStatic"
:icon="h(DeleteOutlined)"
block
danger
type="link"
v-access:code="[LanguagesPermissions.Delete]"
@click="onDelete(row)"
>
{{ $t('AbpUi.Delete') }}
</Button>
</div>
</template>
</Grid>
<LocalizationLanguageModal @change="onChange" />
</template>
<style scoped></style>

125
apps/vben5/packages/@abp/localization/src/components/resources/LocalizationResourceModal.vue

@ -0,0 +1,125 @@
<script setup lang="ts">
import type { FormInstance } from 'ant-design-vue';
import type { ResourceDto } from '../../types/resources';
import { defineEmits, defineOptions, ref, toValue, useTemplateRef } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { Checkbox, Form, Input, message } from 'ant-design-vue';
import { useResourcesApi } from '../../api/useResourcesApi';
defineOptions({
name: 'LocalizationResourceModal',
});
const emits = defineEmits<{
(event: 'change', data: ResourceDto): void;
}>();
const FormItem = Form.Item;
const defaultModel = {
displayName: '',
enable: true,
name: '',
} as ResourceDto;
const form = useTemplateRef<FormInstance>('form');
const formModel = ref<ResourceDto>({ ...defaultModel });
const { cancel, createApi, getApi, updateApi } = useResourcesApi();
const [Modal, modalApi] = useVbenModal({
class: 'w-1/2',
draggable: true,
fullscreenButton: false,
onCancel() {
modalApi.close();
},
onClosed() {
cancel('LocalizationResourceModal has closed!');
},
onConfirm: onSubmit,
onOpenChange: async (isOpen: boolean) => {
if (isOpen) {
formModel.value = { ...defaultModel };
modalApi.setState({
title: $t('LocalizationManagement.Resource:AddNew'),
});
const { name } = modalApi.getData<ResourceDto>();
name && (await onGet(name));
}
},
title: $t('LocalizationManagement.Resource:AddNew'),
});
async function onGet(name: string) {
try {
modalApi.setState({ loading: true });
const dto = await getApi(name);
formModel.value = dto;
modalApi.setState({
title: `${$t('AbpLocalization.Resources')} - ${dto.name}`,
});
} finally {
modalApi.setState({ loading: false });
}
}
async function onSubmit() {
await form.value?.validate();
try {
modalApi.setState({ submitting: true });
const input = toValue(formModel);
const api = input.id ? updateApi(input.name, input) : createApi(input);
const dto = await api;
message.success($t('AbpUi.SavedSuccessfully'));
emits('change', dto);
modalApi.close();
} finally {
modalApi.setState({ submitting: false });
}
}
</script>
<template>
<Modal>
<Form
ref="form"
:label-col="{ span: 6 }"
:model="formModel"
:wrapper-col="{ span: 18 }"
>
<FormItem
:label="$t('LocalizationManagement.DisplayName:Enable')"
name="enable"
>
<Checkbox v-model:checked="formModel.enable">
{{ $t('LocalizationManagement.DisplayName:Enable') }}
</Checkbox>
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:ResourceName')"
name="name"
required
>
<Input v-model:value="formModel.name" autocomplete="off" />
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:DisplayName')"
name="displayName"
required
>
<Input v-model:value="formModel.displayName" autocomplete="off" />
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:Description')"
name="description"
>
<Input v-model:value="formModel.description" autocomplete="off" />
</FormItem>
</Form>
</Modal>
</template>
<style scoped></style>

225
apps/vben5/packages/@abp/localization/src/components/resources/LocalizationResourceTable.vue

@ -0,0 +1,225 @@
<script setup lang="ts">
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { ResourceDto } from '../../types/resources';
import { defineAsyncComponent, h, onMounted, reactive, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useAbpStore } from '@abp/core';
import { useVbenVxeGrid } from '@abp/ui';
import {
DeleteOutlined,
EditOutlined,
PlusOutlined,
} from '@ant-design/icons-vue';
import { Button, message, Modal } from 'ant-design-vue';
import { useLocalizationsApi } from '../../api/useLocalizationsApi';
import { useResourcesApi } from '../../api/useResourcesApi';
import { ResourcesPermissions } from '../../constants/permissions';
defineOptions({
name: 'LocalizationResourceTable',
});
const dataSource = ref<ResourceDto[]>([]);
const pageState = reactive({
current: 1,
size: 10,
total: 0,
});
const abpStore = useAbpStore();
const { deleteApi, getListApi } = useResourcesApi();
const { getLocalizationApi } = useLocalizationsApi();
const formOptions: VbenFormProps = {
//
collapsed: false,
handleReset: onReset,
async handleSubmit(params) {
pageState.current = 1;
await onGet(params);
},
schema: [
{
component: 'Input',
fieldName: 'filter',
formItemClass: 'col-span-2 items-baseline',
label: $t('AbpUi.Search'),
},
],
//
showCollapseButton: true,
//
submitOnEnter: true,
};
const gridOptions: VxeGridProps<ResourceDto> = {
columns: [
{
align: 'left',
field: 'name',
minWidth: 150,
title: $t('AbpFeatureManagement.DisplayName:Name'),
},
{
align: 'left',
field: 'displayName',
minWidth: 150,
title: $t('AbpFeatureManagement.DisplayName:DisplayName'),
},
{
field: 'action',
fixed: 'right',
slots: { default: 'action' },
title: $t('AbpUi.Actions'),
width: 220,
},
],
exportConfig: {},
keepSource: true,
toolbarConfig: {
custom: true,
export: true,
refresh: false,
zoom: true,
},
};
const gridEvents: VxeGridListeners<ResourceDto> = {
pageChange(params) {
pageState.current = params.currentPage;
pageState.size = params.pageSize;
onPageChange();
},
};
const [LocalizationResourceModal, modalApi] = useVbenModal({
connectedComponent: defineAsyncComponent(
() => import('./LocalizationResourceModal.vue'),
),
});
const [Grid, gridApi] = useVbenVxeGrid({
formOptions,
gridEvents,
gridOptions,
});
async function onGet(input?: Record<string, string>) {
try {
gridApi.setLoading(true);
const { items } = await getListApi(input);
pageState.total = items.length;
dataSource.value = items;
onPageChange();
} finally {
gridApi.setLoading(false);
}
}
async function onReset() {
await gridApi.formApi.resetForm();
const input = await gridApi.formApi.getValues();
await onGet(input);
}
function onPageChange() {
const items = dataSource.value.slice(
(pageState.current - 1) * pageState.size,
pageState.current * pageState.size,
);
gridApi.setGridOptions({
data: items,
pagerConfig: {
currentPage: pageState.current,
pageSize: pageState.size,
total: pageState.total,
},
});
}
function onCreate() {
modalApi.setData({});
modalApi.open();
}
function onUpdate(row: ResourceDto) {
modalApi.setData(row);
modalApi.open();
}
function onDelete(row: ResourceDto) {
Modal.confirm({
centered: true,
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.name])}`,
onOk: async () => {
await deleteApi(row.name);
message.success($t('AbpUi.DeletedSuccessfully'));
onChange();
},
title: $t('AbpUi.AreYouSure'),
});
}
async function onChange() {
const input = await gridApi.formApi.getValues();
onGet(input);
//
const cultureName = abpStore.localization!.currentCulture.cultureName;
const localization = await getLocalizationApi({
cultureName,
});
abpStore.setLocalization(localization);
}
onMounted(onGet);
</script>
<template>
<Grid :table-title="$t('AbpLocalization.Resources')">
<template #toolbar-tools>
<Button
:icon="h(PlusOutlined)"
type="primary"
v-access:code="[ResourcesPermissions.Create]"
@click="onCreate"
>
{{ $t('LocalizationManagement.Resource:AddNew') }}
</Button>
</template>
<template #action="{ row }">
<div class="flex flex-row">
<Button
:icon="h(EditOutlined)"
block
type="link"
v-access:code="[ResourcesPermissions.Update]"
@click="onUpdate(row)"
>
{{ $t('AbpUi.Edit') }}
</Button>
<Button
v-if="!row.isStatic"
:icon="h(DeleteOutlined)"
block
danger
type="link"
v-access:code="[ResourcesPermissions.Delete]"
@click="onDelete(row)"
>
{{ $t('AbpUi.Delete') }}
</Button>
</div>
</template>
</Grid>
<LocalizationResourceModal @change="onChange" />
</template>
<style scoped></style>

196
apps/vben5/packages/@abp/localization/src/components/texts/LocalizationTextModal.vue

@ -0,0 +1,196 @@
<script setup lang="ts">
import type { FormInstance } from 'ant-design-vue';
import type { LanguageDto } from '../../types/languages';
import type { ResourceDto } from '../../types/resources';
import type {
GetTextByKeyInput,
TextDifferenceDto,
TextDto,
} from '../../types/texts';
import {
defineEmits,
defineOptions,
onMounted,
ref,
toValue,
useTemplateRef,
} from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { Form, Input, message, Select, Textarea } from 'ant-design-vue';
import { useLanguagesApi } from '../../api/useLanguagesApi';
import { useResourcesApi } from '../../api/useResourcesApi';
import { useTextsApi } from '../../api/useTextsApi';
defineOptions({
name: 'LocalizationTextModal',
});
const emits = defineEmits<{
(event: 'change', data: TextDto): void;
}>();
const FormItem = Form.Item;
const defaultModel = {} as TextDto;
const isEditModal = ref(false);
const form = useTemplateRef<FormInstance>('form');
const formModel = ref<TextDto>({ ...defaultModel });
const resources = ref<ResourceDto[]>([]);
const languages = ref<LanguageDto[]>([]);
const { getListApi: getLanguagesApi } = useLanguagesApi();
const { getListApi: getResourcesApi } = useResourcesApi();
const { cancel, getApi, setApi } = useTextsApi();
const [Modal, modalApi] = useVbenModal({
class: 'w-1/2',
draggable: true,
fullscreenButton: false,
onCancel() {
modalApi.close();
},
onClosed() {
cancel('LocalizationTextModal has closed!');
},
onConfirm: onSubmit,
onOpenChange: async (isOpen: boolean) => {
if (isOpen) {
isEditModal.value = false;
modalApi.setState({
title: $t('LocalizationManagement.Text:AddNew'),
});
const modalData = modalApi.getData<TextDifferenceDto>();
formModel.value = { ...modalData };
await onGet();
}
},
title: $t('LocalizationManagement.Text:AddNew'),
});
async function onInit() {
const [languageRes, resourceRes] = await Promise.all([
getLanguagesApi(),
getResourcesApi(),
]);
languages.value = languageRes.items;
resources.value = resourceRes.items;
}
async function onGet() {
const dto = modalApi.getData<TextDifferenceDto>();
if (dto.targetCultureName) {
isEditModal.value = true;
await onLoad({
cultureName: dto.targetCultureName,
key: dto.key,
resourceName: dto.resourceName,
});
}
}
async function onLanguageChange(value: string) {
const dto = modalApi.getData<TextDifferenceDto>();
if (dto.targetCultureName) {
await onLoad({
cultureName: value,
key: dto.key,
resourceName: dto.resourceName,
});
}
}
async function onLoad(input: GetTextByKeyInput) {
try {
modalApi.setState({ loading: true });
const textDto = await getApi(input);
formModel.value = textDto;
modalApi.setState({
title: `${$t('AbpLocalization.Texts')} - ${textDto.key}`,
});
} finally {
modalApi.setState({ loading: false });
}
}
async function onSubmit() {
await form.value?.validate();
try {
modalApi.setState({ submitting: true });
const input = toValue(formModel);
await setApi(input);
message.success($t('AbpUi.SavedSuccessfully'));
emits('change', input);
modalApi.close();
} finally {
modalApi.setState({ submitting: false });
}
}
onMounted(onInit);
</script>
<template>
<Modal>
<Form
ref="form"
:label-col="{ span: 6 }"
:model="formModel"
:wrapper-col="{ span: 18 }"
>
<FormItem
:label="$t('AbpLocalization.DisplayName:CultureName')"
name="cultureName"
required
>
<Select
v-model:value="formModel.cultureName"
:options="languages"
:field-names="{ label: 'displayName', value: 'cultureName' }"
@change="(value) => onLanguageChange(value!.toString())"
/>
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:ResourceName')"
name="resourceName"
required
>
<Select
v-model:value="formModel.resourceName"
:options="resources"
:disabled="isEditModal"
:field-names="{ label: 'displayName', value: 'name' }"
/>
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:Key')"
name="key"
required
>
<Input
:disabled="isEditModal"
v-model:value="formModel.key"
autocomplete="off"
/>
</FormItem>
<FormItem
:label="$t('AbpLocalization.DisplayName:Value')"
name="value"
required
>
<Textarea
:auto-size="{ minRows: 3 }"
v-model:value="formModel.value"
autocomplete="off"
/>
</FormItem>
</Form>
</Modal>
</template>
<style scoped></style>

319
apps/vben5/packages/@abp/localization/src/components/texts/LocalizationTextTable.vue

@ -0,0 +1,319 @@
<script setup lang="ts">
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { LanguageDto, ResourceDto } from '../../types';
import type { TextDifferenceDto, TextDto } from '../../types/texts';
import { defineAsyncComponent, h, onMounted, reactive, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useAbpStore } from '@abp/core';
import { useVbenVxeGrid } from '@abp/ui';
import { EditOutlined, PlusOutlined } from '@ant-design/icons-vue';
import { Button, Select } from 'ant-design-vue';
import { useLanguagesApi } from '../../api/useLanguagesApi';
import { useLocalizationsApi } from '../../api/useLocalizationsApi';
import { useResourcesApi } from '../../api/useResourcesApi';
import { useTextsApi } from '../../api/useTextsApi';
import { TextsPermissions } from '../../constants/permissions';
defineOptions({
name: 'LocalizationTextTable',
});
const dataSource = ref<TextDifferenceDto[]>([]);
const resources = ref<ResourceDto[]>([]);
const languages = ref<LanguageDto[]>([]);
const targetValueOptions = reactive([
{
label: $t('AbpLocalization.DisplayName:Any'),
value: 'false',
},
{
label: $t('AbpLocalization.DisplayName:OnlyNull'),
value: 'true',
},
]);
const pageState = reactive({
current: 1,
size: 10,
total: 0,
});
const abpStore = useAbpStore();
const { getListApi } = useTextsApi();
const { getListApi: getLanguagesApi } = useLanguagesApi();
const { getListApi: getResourcesApi } = useResourcesApi();
const { getLocalizationApi } = useLocalizationsApi();
const formOptions: VbenFormProps = {
//
collapsed: false,
collapsedRows: 2,
commonConfig: {
//
componentProps: {
class: 'w-full',
},
},
compact: false,
handleReset: onReset,
async handleSubmit(params) {
pageState.current = 1;
await onGet(params);
},
schema: [
{
component: 'Input',
fieldName: 'cultureName',
formItemClass: 'items-baseline',
label: $t('AbpLocalization.DisplayName:CultureName'),
rules: 'selectRequired',
},
{
component: 'Input',
fieldName: 'targetCultureName',
formItemClass: 'items-baseline',
label: $t('AbpLocalization.DisplayName:TargetCultureName'),
rules: 'selectRequired',
},
{
component: 'Input',
fieldName: 'resourceName',
label: $t('AbpLocalization.DisplayName:ResourceName'),
},
{
component: 'Input',
fieldName: 'onlyNull',
label: $t('AbpLocalization.DisplayName:TargetValue'),
},
{
component: 'Input',
fieldName: 'filter',
formItemClass: 'col-span-2 items-baseline',
label: $t('AbpUi.Search'),
},
],
//
showCollapseButton: true,
//
submitOnEnter: true,
};
const gridOptions: VxeGridProps<TextDifferenceDto> = {
columns: [
{
align: 'left',
field: 'key',
minWidth: 150,
title: $t('AbpLocalization.DisplayName:Key'),
},
{
align: 'left',
field: 'value',
minWidth: 150,
title: $t('AbpLocalization.DisplayName:Value'),
},
{
align: 'left',
field: 'targetValue',
minWidth: 150,
title: $t('AbpLocalization.DisplayName:TargetValue'),
},
{
align: 'left',
field: 'resourceName',
minWidth: 150,
title: $t('AbpLocalization.DisplayName:ResourceName'),
},
{
field: 'action',
fixed: 'right',
slots: { default: 'action' },
title: $t('AbpUi.Actions'),
width: 220,
},
],
exportConfig: {},
keepSource: true,
toolbarConfig: {
custom: true,
export: true,
refresh: false,
zoom: true,
},
};
const gridEvents: VxeGridListeners<TextDifferenceDto> = {
pageChange(params) {
pageState.current = params.currentPage;
pageState.size = params.pageSize;
onPageChange();
},
};
const [Grid, gridApi] = useVbenVxeGrid({
formOptions,
gridEvents,
gridOptions,
});
const [LocalizationTextModal, modalApi] = useVbenModal({
connectedComponent: defineAsyncComponent(
() => import('./LocalizationTextModal.vue'),
),
});
async function onInit() {
const [languageRes, resourceRes] = await Promise.all([
getLanguagesApi(),
getResourcesApi(),
]);
languages.value = languageRes.items;
resources.value = resourceRes.items;
}
function onFieldChange(fieldName: string, value?: string) {
gridApi.formApi.setFieldValue(fieldName, value);
}
async function onGet(input: Record<string, string>) {
try {
gridApi.setLoading(true);
const { items } = await getListApi(input as any);
pageState.total = items.length;
dataSource.value = items;
onPageChange();
} finally {
gridApi.setLoading(false);
}
}
async function onReset() {
await gridApi.formApi.resetForm();
const input = await gridApi.formApi.getValues();
await onGet(input);
}
function onPageChange() {
const items = dataSource.value.slice(
(pageState.current - 1) * pageState.size,
pageState.current * pageState.size,
);
gridApi.setGridOptions({
data: items,
pagerConfig: {
currentPage: pageState.current,
pageSize: pageState.size,
total: pageState.total,
},
});
}
async function onCreate() {
const input = await gridApi.formApi.getValues();
modalApi.setData({
cultureName: input.targetCultureName,
resourceName: input.resourceName,
});
modalApi.open();
}
function onUpdate(row: TextDifferenceDto) {
modalApi.setData(row);
modalApi.open();
}
async function onChange(data: TextDto) {
const input = await gridApi.formApi.getValues();
onGet(input);
//
const cultureName =
abpStore.application!.localization.currentCulture.cultureName;
if (data.cultureName === cultureName) {
const localization = await getLocalizationApi({
cultureName,
});
abpStore.setLocalization(localization);
}
}
onMounted(onInit);
</script>
<template>
<Grid :table-title="$t('AbpLocalization.Texts')">
<template #form-cultureName="{ modelValue }">
<Select
class="w-full"
allow-clear
:options="languages"
:value="modelValue"
:field-names="{ label: 'displayName', value: 'cultureName' }"
@change="(value) => onFieldChange('cultureName', value?.toString())"
/>
</template>
<template #form-targetCultureName="{ modelValue }">
<Select
class="w-full"
allow-clear
:options="languages"
:value="modelValue"
:field-names="{ label: 'displayName', value: 'cultureName' }"
@change="
(value) => onFieldChange('targetCultureName', value?.toString())
"
/>
</template>
<template #form-resourceName="{ modelValue }">
<Select
class="w-full"
allow-clear
:options="resources"
:value="modelValue"
:field-names="{ label: 'displayName', value: 'name' }"
@change="(value) => onFieldChange('resourceName', value?.toString())"
/>
</template>
<template #form-onlyNull="{ modelValue }">
<Select
class="w-full"
allow-clear
:options="targetValueOptions"
:value="modelValue"
@change="(value) => onFieldChange('onlyNull', value?.toString())"
/>
</template>
<template #toolbar-tools>
<Button
:icon="h(PlusOutlined)"
type="primary"
v-access:code="[TextsPermissions.Create]"
@click="onCreate"
>
{{ $t('LocalizationManagement.Text:AddNew') }}
</Button>
</template>
<template #action="{ row }">
<div class="flex flex-row">
<Button
:icon="h(EditOutlined)"
block
type="link"
v-access:code="[TextsPermissions.Update]"
@click="onUpdate(row)"
>
{{ $t('AbpUi.Edit') }}
</Button>
</div>
</template>
</Grid>
<LocalizationTextModal @change="onChange" />
</template>
<style scoped></style>

30
apps/vben5/packages/@abp/localization/src/constants/permissions.ts

@ -0,0 +1,30 @@
/** 资源管理权限 */
export const ResourcesPermissions = {
/** 新增 */
Create: 'LocalizationManagement.Resource.Create',
Default: 'LocalizationManagement.Resource',
/** 删除 */
Delete: 'LocalizationManagement.Resource.Delete',
/** 更新 */
Update: 'LocalizationManagement.Resource.Update',
};
/** 语言管理权限 */
export const LanguagesPermissions = {
/** 新增 */
Create: 'LocalizationManagement.Language.Create',
Default: 'LocalizationManagement.Language',
/** 删除 */
Delete: 'LocalizationManagement.Language.Delete',
/** 更新 */
Update: 'LocalizationManagement.Language.Update',
};
/** 文本管理权限 */
export const TextsPermissions = {
/** 新增 */
Create: 'LocalizationManagement.Text.Create',
Default: 'LocalizationManagement.Text',
/** 删除 */
Delete: 'LocalizationManagement.Text.Delete',
/** 更新 */
Update: 'LocalizationManagement.Text.Update',
};

3
apps/vben5/packages/@abp/localization/src/index.ts

@ -0,0 +1,3 @@
export * from './api';
export * from './components';
export * from './types';

2
apps/vben5/packages/@abp/localization/src/types/index.ts

@ -0,0 +1,2 @@
export * from './languages';
export * from './resources';

30
apps/vben5/packages/@abp/localization/src/types/languages.ts

@ -0,0 +1,30 @@
import type { AuditedEntityDto } from '@abp/core';
interface LanguageDto extends AuditedEntityDto<string> {
cultureName: string;
displayName: string;
twoLetterISOLanguageName?: string;
uiCultureName: string;
}
interface LanguageGetListInput {
filter?: string;
}
interface LanguageCreateOrUpdateDto {
displayName: string;
}
interface LanguageCreateDto extends LanguageCreateOrUpdateDto {
cultureName: string;
uiCultureName?: string;
}
type LanguageUpdateDto = LanguageCreateOrUpdateDto;
export type {
LanguageCreateDto,
LanguageDto,
LanguageGetListInput,
LanguageUpdateDto,
};

33
apps/vben5/packages/@abp/localization/src/types/resources.ts

@ -0,0 +1,33 @@
import type { AuditedEntityDto } from '@abp/core';
interface ResourceDto extends AuditedEntityDto<string> {
defaultCultureName?: string;
description?: string;
displayName: string;
enable: boolean;
name: string;
}
interface ResourceCreateOrUpdateDto {
defaultCultureName?: string;
description?: string;
displayName: string;
enable: boolean;
}
interface ResourceCreateDto extends ResourceCreateOrUpdateDto {
name: string;
}
type ResourceUpdateDto = ResourceCreateOrUpdateDto;
interface ResourceGetListInput {
filter?: string;
}
export type {
ResourceCreateDto,
ResourceDto,
ResourceGetListInput,
ResourceUpdateDto,
};

51
apps/vben5/packages/@abp/localization/src/types/texts.ts

@ -0,0 +1,51 @@
interface GetTextByKeyInput {
cultureName: string;
key: string;
resourceName: string;
}
interface GetTextsInput {
cultureName: string;
filter?: string;
onlyNull?: boolean;
resourceName?: string;
targetCultureName: string;
}
interface SetTextInput {
cultureName: string;
key: string;
resourceName: string;
value: string;
}
interface RestoreDefaultTextInput {
cultureName: string;
key: string;
resourceName: string;
}
interface TextDifferenceDto {
cultureName: string;
key: string;
resourceName: string;
targetCultureName: string;
targetValue: string;
value: string;
}
interface TextDto {
cultureName: string;
key: string;
resourceName: string;
value: string;
}
export type {
GetTextByKeyInput,
GetTextsInput,
RestoreDefaultTextInput,
SetTextInput,
TextDifferenceDto,
TextDto,
};

6
apps/vben5/packages/@abp/localization/tsconfig.json

@ -0,0 +1,6 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/tsconfig/web.json",
"include": ["src"],
"exclude": ["node_modules"]
}

4
apps/vben5/packages/@abp/notifications/src/components/definitions/groups/NotificationGroupDefinitionModal.vue

@ -51,7 +51,7 @@ const [Modal, modalApi] = useVbenModal({
const api = isEditModel.value
? updateApi(formModel.value.name, input)
: createApi(input);
modalApi.setState({ confirmLoading: true, loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.SavedSuccessfully'));
@ -59,7 +59,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ confirmLoading: false, loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

12
apps/vben5/packages/@abp/notifications/src/components/definitions/groups/NotificationGroupDefinitionTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { NotificationGroupDefinitionDto } from '../../../types/groups';
import { defineAsyncComponent, h, onMounted, reactive, ref } from 'vue';
@ -34,7 +36,7 @@ defineOptions({
const MenuItem = Menu.Item;
const DefinitionIcon = createIconifyIcon('nimbus:notification');
const permissionGroups = ref<NotificationGroupDefinitionDto[]>([]);
const dataSource = ref<NotificationGroupDefinitionDto[]>([]);
const pageState = reactive({
current: 1,
size: 10,
@ -130,7 +132,7 @@ async function onGet(input?: Record<string, string>) {
gridApi.setLoading(true);
const { items } = await getListApi(input);
pageState.total = items.length;
permissionGroups.value = items.map((item) => {
dataSource.value = items.map((item) => {
const localizableString = deserialize(item.displayName);
return {
...item,
@ -150,7 +152,7 @@ async function onReset() {
}
function onPageChange() {
const items = permissionGroups.value.slice(
const items = dataSource.value.slice(
(pageState.current - 1) * pageState.size,
pageState.current * pageState.size,
);
@ -180,7 +182,7 @@ function onDelete(row: NotificationGroupDefinitionDto) {
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.name])}`,
onOk: async () => {
await deleteApi(row.name);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
onGet();
},
title: $t('AbpUi.AreYouSure'),

6
apps/vben5/packages/@abp/notifications/src/components/definitions/notifications/NotificationDefinitionTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { NotificationDefinitionDto } from '../../../types/definitions';
import type { NotificationGroupDefinitionDto } from '../../../types/groups';
@ -317,7 +319,7 @@ function onDelete(row: NotificationDefinitionDto) {
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.name])}`,
onOk: async () => {
await deleteApi(row.name);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
onGet();
},
title: $t('AbpUi.AreYouSure'),

6
apps/vben5/packages/@abp/notifications/src/components/my-notifilers/MyNotificationTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { Notification } from '../../types/notifications';
import { defineAsyncComponent, h, ref } from 'vue';
@ -252,7 +254,7 @@ const onDelete = (row: Notification) => {
},
onOk: async () => {
await deleteMyNotifilerApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
await gridApi.query();
},
title: $t('AbpUi.AreYouSure'),

4
apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationModal.vue

@ -159,7 +159,7 @@ const [Modal, modalApi] = useVbenModal({
const api = formModel.value.id
? updateApi(formModel.value.id, toValue(formModel))
: createApi(toValue(formModel));
modalApi.setState({ confirmLoading: true, loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.SavedSuccessfully'));
@ -167,7 +167,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ confirmLoading: false, loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

19
apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationSecretModal.vue

@ -71,13 +71,18 @@ async function onGet(id: string) {
applicationModel.value = dto;
}
async function onSubmit(input: Record<string, any>) {
const dto = await updateApi(applicationModel.value!.id, {
...applicationModel.value!,
clientSecret: input.clientSecret,
});
message.success($t('AbpUi.SavedSuccessfully'));
emits('change', dto);
modalApi.close();
try {
modalApi.setState({ submitting: true });
const dto = await updateApi(applicationModel.value!.id, {
...applicationModel.value!,
clientSecret: input.clientSecret,
});
message.success($t('AbpUi.SavedSuccessfully'));
emits('change', dto);
modalApi.close();
} finally {
modalApi.setState({ submitting: false });
}
}
</script>

6
apps/vben5/packages/@abp/openiddict/src/components/applications/ApplicationTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridProps } from '@abp/ui';
import type { VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { OpenIddictApplicationDto } from '../../types/applications';
import { defineAsyncComponent, h } from 'vue';
@ -178,7 +180,7 @@ const onDelete = (row: OpenIddictApplicationDto) => {
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.clientId])}`,
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
query();
},
title: $t('AbpUi.AreYouSure'),

6
apps/vben5/packages/@abp/openiddict/src/components/authorizations/AuthorizationTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridProps } from '@abp/ui';
import type { VxeGridProps } from '@abp/ui';
import type { SelectValue } from 'ant-design-vue/es/select';
import type { VbenFormProps } from '@vben/common-ui';
import type { OpenIddictApplicationDto } from '../../types';
import type { OpenIddictAuthorizationDto } from '../../types/authorizations';
@ -198,7 +200,7 @@ function onDelete(row: OpenIddictAuthorizationDto) {
content: `${$t('AbpUi.ItemWillBeDeletedMessage')}`,
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
gridApi.query();
},
title: $t('AbpUi.AreYouSure'),

4
apps/vben5/packages/@abp/openiddict/src/components/scopes/ScopeModal.vue

@ -71,7 +71,7 @@ const [Modal, modalApi] = useVbenModal({
const api = formModel.value.id
? updateApi(formModel.value.id, toValue(formModel))
: createApi(toValue(formModel));
modalApi.setState({ confirmLoading: true, loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.SavedSuccessfully'));
@ -79,7 +79,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ confirmLoading: false, loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

6
apps/vben5/packages/@abp/openiddict/src/components/scopes/ScopeTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridProps } from '@abp/ui';
import type { VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { OpenIddictScopeDto } from '../../types/scopes';
import { defineAsyncComponent, h } from 'vue';
@ -146,7 +148,7 @@ const onDelete = (row: OpenIddictScopeDto) => {
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.name])}`,
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
query();
},
title: $t('AbpUi.AreYouSure'),

6
apps/vben5/packages/@abp/openiddict/src/components/tokens/TokenTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridProps } from '@abp/ui';
import type { VxeGridProps } from '@abp/ui';
import type { SelectValue } from 'ant-design-vue/es/select';
import type { VbenFormProps } from '@vben/common-ui';
import type { OpenIddictApplicationDto } from '../../types';
import type { OpenIddictTokenDto } from '../../types/tokens';
@ -222,7 +224,7 @@ function onDelete(row: OpenIddictTokenDto) {
content: `${$t('AbpUi.ItemWillBeDeletedMessage')}`,
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
gridApi.query();
},
title: $t('AbpUi.AreYouSure'),

1
apps/vben5/packages/@abp/openiddict/src/constants/index.ts

@ -1 +0,0 @@
export * from './permissions';

1
apps/vben5/packages/@abp/openiddict/src/index.ts

@ -1,4 +1,3 @@
export * from './api';
export * from './components';
export * from './constants';
export * from './types';

4
apps/vben5/packages/@abp/permissions/src/components/definitions/groups/PermissionGroupDefinitionModal.vue

@ -50,7 +50,7 @@ const [Modal, modalApi] = useVbenModal({
const api = isEditModel.value
? updateApi(formModel.value.name, toValue(formModel))
: createApi(toValue(formModel));
modalApi.setState({ confirmLoading: true, loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.SavedSuccessfully'));
@ -58,7 +58,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ confirmLoading: false, loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

6
apps/vben5/packages/@abp/permissions/src/components/definitions/groups/PermissionGroupDefinitionTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { PermissionGroupDefinitionDto } from '../../../types/groups';
import { defineAsyncComponent, h, onMounted, reactive, ref } from 'vue';
@ -193,7 +195,7 @@ function onDelete(row: PermissionGroupDefinitionDto) {
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.name])}`,
onOk: async () => {
await deleteApi(row.name);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
onGet();
},
title: $t('AbpUi.AreYouSure'),

4
apps/vben5/packages/@abp/permissions/src/components/definitions/permissions/PermissionDefinitionModal.vue

@ -82,7 +82,7 @@ const [Modal, modalApi] = useVbenModal({
const api = isEditModel.value
? updateApi(formModel.value.name, toValue(formModel))
: createApi(toValue(formModel));
modalApi.setState({ confirmLoading: true, loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.SavedSuccessfully'));
@ -90,7 +90,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ confirmLoading: false, loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

6
apps/vben5/packages/@abp/permissions/src/components/definitions/permissions/PermissionDefinitionTable.vue

@ -1,5 +1,7 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { PermissionDefinitionDto } from '../../../types/definitions';
import type { PermissionGroupDefinitionDto } from '../../../types/groups';
@ -259,7 +261,7 @@ function onDelete(row: PermissionDefinitionDto) {
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.name])}`,
onOk: async () => {
await deleteApi(row.name);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
onGet();
},
title: $t('AbpUi.AreYouSure'),

17
apps/vben5/packages/@abp/permissions/src/components/permissions/PermissionModal.vue

@ -31,6 +31,10 @@ defineOptions({
name: 'PermissionModal',
});
const emits = defineEmits<{
(event: 'change', name: string, key?: string): void;
}>();
const TabPane = Tabs.TabPane;
interface ModalState {
@ -92,13 +96,14 @@ const [Modal, modalApi] = useVbenModal({
const permissions = toPermissionList(permissionTree.value);
try {
modalApi.setState({
closable: false,
confirmLoading: true,
submitting: true,
});
const providerName = modelState.value!.providerName;
const providerKey = modelState.value!.providerKey;
await updateApi(
{
providerKey: modelState.value!.providerKey,
providerName: modelState.value!.providerName,
providerKey,
providerName,
},
{
permissions,
@ -106,10 +111,10 @@ const [Modal, modalApi] = useVbenModal({
);
message.success($t('AbpUi.SavedSuccessfully'));
modalApi.close();
emits('change', providerName, providerKey);
} finally {
modalApi.setState({
closable: true,
confirmLoading: false,
submitting: false,
});
}
},

1
apps/vben5/packages/@abp/permissions/src/constants/index.ts

@ -1 +0,0 @@
export * from './permissions';

6
apps/vben5/packages/@abp/platform/src/components/messages/email/EmailMessageTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridProps } from '@abp/ui';
import type { VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { EmailMessageDto } from '../../../types/messages';
import { defineAsyncComponent, h } from 'vue';
@ -226,7 +228,7 @@ function onDelete(row: EmailMessageDto) {
try {
gridApi.setLoading(true);
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
gridApi.query();
} finally {
gridApi.setLoading(false);

6
apps/vben5/packages/@abp/platform/src/components/messages/sms/SmsMessageTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridProps } from '@abp/ui';
import type { VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { SmsMessageDto } from '../../../types/messages';
import { h } from 'vue';
@ -198,7 +200,7 @@ function onDelete(row: SmsMessageDto) {
try {
gridApi.setLoading(true);
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
gridApi.query();
} finally {
gridApi.setLoading(false);

1
apps/vben5/packages/@abp/platform/src/constants/index.ts

@ -1 +0,0 @@
export * from './permissions';

1
apps/vben5/packages/@abp/platform/src/index.ts

@ -1,4 +1,3 @@
export * from './api';
export * from './components';
export * from './constants';
export * from './types';

3
apps/vben5/packages/@abp/saas/src/components/editions/EditionModal.vue

@ -3,10 +3,9 @@ import type { EditionDto } from '../../types';
import { ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { useVbenForm, useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { useVbenForm } from '@abp/ui';
import { message } from 'ant-design-vue';
import { useEditionsApi } from '../../api';

6
apps/vben5/packages/@abp/saas/src/components/editions/EditionTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { EditionDto } from '../../types/editions';
import { defineAsyncComponent, h } from 'vue';
@ -142,7 +144,7 @@ const onDelete = (row: EditionDto) => {
},
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
query();
},
title: $t('AbpUi.AreYouSure'),

6
apps/vben5/packages/@abp/saas/src/components/tenants/TenantTable.vue

@ -1,7 +1,9 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import type { VbenFormProps } from '@vben/common-ui';
import type { TenantDto } from '../../types/tenants';
import { defineAsyncComponent, h } from 'vue';
@ -161,7 +163,7 @@ const onDelete = (row: TenantDto) => {
},
onOk: async () => {
await deleteApi(row.id);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
query();
},
title: $t('AbpUi.AreYouSure'),

1
apps/vben5/packages/@abp/saas/src/constants/index.ts

@ -1 +0,0 @@
export * from './permissions';

1
apps/vben5/packages/@abp/saas/src/index.ts

@ -1,4 +1,3 @@
export * from './api';
export * from './components';
export * from './constants';
export * from './types';

77
apps/vben5/packages/@abp/settings/src/api/definitions.ts

@ -1,77 +0,0 @@
import type { ListResultDto } from '@abp/core';
import type {
SettingDefinitionCreateDto,
SettingDefinitionDto,
SettingDefinitionGetListInput,
SettingDefinitionUpdateDto,
} from '../types/definitions';
import { requestClient } from '@abp/request';
/**
*
* @param name
*/
export function deleteApi(name: string): Promise<void> {
return requestClient.delete(
`/api/setting-management/settings/definitions/${name}`,
);
}
/**
*
* @param name
* @returns
*/
export function getApi(name: string): Promise<SettingDefinitionDto> {
return requestClient.get<SettingDefinitionDto>(
`/api/setting-management/settings/definitions/${name}`,
);
}
/**
*
* @param input
* @returns
*/
export function getListApi(
input?: SettingDefinitionGetListInput,
): Promise<ListResultDto<SettingDefinitionDto>> {
return requestClient.get<ListResultDto<SettingDefinitionDto>>(
`/api/setting-management/settings/definitions`,
{
params: input,
},
);
}
/**
*
* @param input
* @returns
*/
export function createApi(
input: SettingDefinitionCreateDto,
): Promise<SettingDefinitionDto> {
return requestClient.post<SettingDefinitionDto>(
'/api/setting-management/settings/definitions',
input,
);
}
/**
*
* @param name
* @param input
* @returns
*/
export function updateApi(
name: string,
input: SettingDefinitionUpdateDto,
): Promise<SettingDefinitionDto> {
return requestClient.put<SettingDefinitionDto>(
`/api/setting-management/settings/definitions/${name}`,
input,
);
}

4
apps/vben5/packages/@abp/settings/src/api/index.ts

@ -1,2 +1,2 @@
export * as settingDefinitionsApi from './definitions';
export * as settingsApi from './settings';
export { useDefinitionsApi } from './useDefinitionsApi';
export { useSettingsApi } from './useSettingsApi';

84
apps/vben5/packages/@abp/settings/src/api/settings.ts

@ -1,84 +0,0 @@
import type { ListResultDto } from '@abp/core';
import type { SettingGroup, SettingsUpdateInput } from '../types/settings';
import { requestClient } from '@abp/request';
/**
*
* @returns
*/
export function getGlobalSettingsApi(): Promise<ListResultDto<SettingGroup>> {
return requestClient.get<ListResultDto<SettingGroup>>(
`/api/setting-management/settings/by-global`,
);
}
/**
*
* @returns
*/
export function setGlobalSettingsApi(
input: SettingsUpdateInput,
): Promise<void> {
return requestClient.put(
`/api/setting-management/settings/change-global`,
input,
);
}
/**
*
* @returns
*/
export function getTenantSettingsApi(): Promise<ListResultDto<SettingGroup>> {
return requestClient.get<ListResultDto<SettingGroup>>(
`/api/setting-management/settings/by-current-tenant`,
);
}
/**
*
* @returns
*/
export function setTenantSettingsApi(
input: SettingsUpdateInput,
): Promise<void> {
return requestClient.put(
`/api/setting-management/settings/change-current-tenant`,
input,
);
}
/**
*
* @returns
*/
export function getUserSettingsApi(): Promise<ListResultDto<SettingGroup>> {
return requestClient.get<ListResultDto<SettingGroup>>(
`/api/setting-management/settings/by-current-user`,
);
}
/**
*
* @returns
*/
export function setUserSettingsApi(input: SettingsUpdateInput): Promise<void> {
return requestClient.put(
`/api/setting-management/settings/change-current-user`,
input,
);
}
/**
*
* @param emailAddress
*/
export const sendTestEmailApi = (emailAddress: string) => {
return requestClient.post(
`/api/setting-management/settings/send-test-email`,
{
emailAddress,
},
);
};

99
apps/vben5/packages/@abp/settings/src/api/useDefinitionsApi.ts

@ -0,0 +1,99 @@
import type { ListResultDto } from '@abp/core';
import type {
SettingDefinitionCreateDto,
SettingDefinitionDto,
SettingDefinitionGetListInput,
SettingDefinitionUpdateDto,
} from '../types';
import { useRequest } from '@abp/request';
export function useDefinitionsApi() {
const { cancel, request } = useRequest();
/**
*
* @param name
*/
function deleteApi(name: string): Promise<void> {
return request(`/api/setting-management/settings/definitions/${name}`, {
method: 'DELETE',
});
}
/**
*
* @param name
* @returns
*/
function getApi(name: string): Promise<SettingDefinitionDto> {
return request<SettingDefinitionDto>(
`/api/setting-management/settings/definitions/${name}`,
{
method: 'GET',
},
);
}
/**
*
* @param input
* @returns
*/
function getListApi(
input?: SettingDefinitionGetListInput,
): Promise<ListResultDto<SettingDefinitionDto>> {
return request<ListResultDto<SettingDefinitionDto>>(
`/api/setting-management/settings/definitions`,
{
method: 'GET',
params: input,
},
);
}
/**
*
* @param input
* @returns
*/
function createApi(
input: SettingDefinitionCreateDto,
): Promise<SettingDefinitionDto> {
return request<SettingDefinitionDto>(
'/api/setting-management/settings/definitions',
{
data: input,
method: 'POST',
},
);
}
/**
*
* @param name
* @param input
* @returns
*/
function updateApi(
name: string,
input: SettingDefinitionUpdateDto,
): Promise<SettingDefinitionDto> {
return request<SettingDefinitionDto>(
`/api/setting-management/settings/definitions/${name}`,
{
data: input,
method: 'PUT',
},
);
}
return {
cancel,
createApi,
deleteApi,
getApi,
getListApi,
updateApi,
};
}

103
apps/vben5/packages/@abp/settings/src/api/useSettingsApi.ts

@ -0,0 +1,103 @@
import type { ListResultDto } from '@abp/core';
import type { SettingGroup, SettingsUpdateInput } from '../types';
import { useRequest } from '@abp/request';
export function useSettingsApi() {
const { cancel, request } = useRequest();
/**
*
* @returns
*/
function getGlobalSettingsApi(): Promise<ListResultDto<SettingGroup>> {
return request<ListResultDto<SettingGroup>>(
`/api/setting-management/settings/by-global`,
{
method: 'GET',
},
);
}
/**
*
* @returns
*/
function setGlobalSettingsApi(input: SettingsUpdateInput): Promise<void> {
return request(`/api/setting-management/settings/change-global`, {
data: input,
method: 'PUT',
});
}
/**
*
* @returns
*/
function getTenantSettingsApi(): Promise<ListResultDto<SettingGroup>> {
return request<ListResultDto<SettingGroup>>(
`/api/setting-management/settings/by-current-tenant`,
{
method: 'GET',
},
);
}
/**
*
* @returns
*/
function setTenantSettingsApi(input: SettingsUpdateInput): Promise<void> {
return request(`/api/setting-management/settings/change-current-tenant`, {
data: input,
method: 'PUT',
});
}
/**
*
* @returns
*/
function getUserSettingsApi(): Promise<ListResultDto<SettingGroup>> {
return request<ListResultDto<SettingGroup>>(
`/api/setting-management/settings/by-current-user`,
{
method: 'GET',
},
);
}
/**
*
* @returns
*/
function setUserSettingsApi(input: SettingsUpdateInput): Promise<void> {
return request(`/api/setting-management/settings/change-current-user`, {
data: input,
method: 'PUT',
});
}
/**
*
* @param emailAddress
*/
const sendTestEmailApi = (emailAddress: string) => {
return request(`/api/setting-management/settings/send-test-email`, {
data: {
emailAddress,
},
method: 'POST',
});
};
return {
cancel,
getGlobalSettingsApi,
getTenantSettingsApi,
getUserSettingsApi,
sendTestEmailApi,
setGlobalSettingsApi,
setTenantSettingsApi,
setUserSettingsApi,
};
}

8
apps/vben5/packages/@abp/settings/src/components/definitions/SettingDefinitionModal.vue

@ -27,7 +27,7 @@ import {
Textarea,
} from 'ant-design-vue';
import { createApi, getApi, updateApi } from '../../api/definitions';
import { useDefinitionsApi } from '../../api/useDefinitionsApi';
defineOptions({
name: 'SettingDefinitionModal',
@ -55,6 +55,8 @@ const providerOptions = reactive([
{ label: $t('AbpSettingManagement.Providers:User'), value: 'U' },
]);
const { createApi, getApi, updateApi } = useDefinitionsApi();
const [Modal, modalApi] = useVbenModal({
class: 'w-1/2',
draggable: true,
@ -67,7 +69,7 @@ const [Modal, modalApi] = useVbenModal({
const api = isEditModel.value
? updateApi(formModel.value.name, toValue(formModel))
: createApi(toValue(formModel));
modalApi.setState({ confirmLoading: true, loading: true });
modalApi.setState({ submitting: true });
api
.then((res) => {
message.success($t('AbpUi.SavedSuccessfully'));
@ -75,7 +77,7 @@ const [Modal, modalApi] = useVbenModal({
modalApi.close();
})
.finally(() => {
modalApi.setState({ confirmLoading: false, loading: false });
modalApi.setState({ submitting: false });
});
},
onOpenChange: async (isOpen: boolean) => {

9
apps/vben5/packages/@abp/settings/src/components/definitions/SettingDefinitionTable.vue

@ -1,5 +1,7 @@
<script setup lang="ts">
import type { VbenFormProps, VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VxeGridListeners, VxeGridProps } from '@abp/ui';
import type { VbenFormProps } from '@vben/common-ui';
import type { SettingDefinitionDto } from '../../types/definitions';
@ -17,7 +19,7 @@ import {
} from '@ant-design/icons-vue';
import { Button, message, Modal } from 'ant-design-vue';
import { deleteApi, getListApi } from '../../api/definitions';
import { useDefinitionsApi } from '../../api/useDefinitionsApi';
import { SettingDefinitionsPermissions } from '../../constants/permissions';
defineOptions({
@ -33,6 +35,7 @@ const pageState = reactive({
const { Lr } = useLocalization();
const { deserialize } = useLocalizationSerializer();
const { deleteApi, getListApi } = useDefinitionsApi();
const formOptions: VbenFormProps = {
//
@ -163,7 +166,7 @@ function onDelete(row: SettingDefinitionDto) {
content: `${$t('AbpUi.ItemWillBeDeletedMessageWithFormat', [row.name])}`,
onOk: async () => {
await deleteApi(row.name);
message.success($t('AbpUi.SuccessfullyDeleted'));
message.success($t('AbpUi.DeletedSuccessfully'));
onGet();
},
title: $t('AbpUi.AreYouSure'),

15
apps/vben5/packages/@abp/settings/src/components/settings/SystemSetting.vue

@ -10,13 +10,7 @@ import { isEmail, useAbpStore } from '@abp/core';
import { FeatureModal } from '@abp/features';
import { Button, Form, InputSearch, message, Modal } from 'ant-design-vue';
import {
getGlobalSettingsApi,
getTenantSettingsApi,
sendTestEmailApi,
setGlobalSettingsApi,
setTenantSettingsApi,
} from '../../api/settings';
import { useSettingsApi } from '../../api/useSettingsApi';
import SettingForm from './SettingForm.vue';
defineOptions({
@ -26,6 +20,13 @@ defineOptions({
const FormItem = Form.Item;
const abpStore = useAbpStore();
const {
getGlobalSettingsApi,
getTenantSettingsApi,
sendTestEmailApi,
setGlobalSettingsApi,
setTenantSettingsApi,
} = useSettingsApi();
const [HostFeatureModal, featureModalApi] = useVbenModal({
connectedComponent: FeatureModal,
});

4
apps/vben5/packages/@abp/settings/src/components/settings/UserSetting.vue

@ -1,13 +1,15 @@
<script setup lang="ts">
import type { SettingsUpdateInput } from '../../types';
import { getUserSettingsApi, setUserSettingsApi } from '../../api/settings';
import { useSettingsApi } from '../../api/useSettingsApi';
import SettingForm from './SettingForm.vue';
defineOptions({
name: 'UserSettingForm',
});
const { getUserSettingsApi, setUserSettingsApi } = useSettingsApi();
async function onGet() {
const { items } = await getUserSettingsApi();
return items;

1
apps/vben5/packages/@abp/settings/src/constants/index.ts

@ -1 +0,0 @@
export * from './permissions';

1
apps/vben5/packages/@abp/settings/src/index.ts

@ -1,4 +1,3 @@
export * from './api';
export * from './components';
export * from './constants';
export * from './types';

172
apps/vben5/packages/@abp/ui/src/adapter/component/index.ts

@ -1,172 +0,0 @@
/**
* 使 adapter/form 使便使
* vben-formvben-modalvben-drawer 使,
*/
import type { Component, SetupContext } from 'vue';
import type { BaseFormComponentType } from '@vben/common-ui';
import { h } from 'vue';
import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui';
import { $t } from '@vben/locales';
import {
AutoComplete,
Button,
Checkbox,
CheckboxGroup,
DatePicker,
Divider,
Input,
InputNumber,
InputPassword,
InputSearch,
Mentions,
notification,
Radio,
RadioGroup,
RangePicker,
Rate,
Select,
Space,
Switch,
Textarea,
TimePicker,
TreeSelect,
Upload,
} from 'ant-design-vue';
const withDefaultPlaceholder = <T extends Component>(
component: T,
type: 'input' | 'select',
) => {
return (props: any, { attrs, slots }: Omit<SetupContext, 'expose'>) => {
const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`);
return h(component, { ...props, ...attrs, placeholder }, slots);
};
};
// 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
export type ComponentType =
| 'ApiSelect'
| 'ApiTreeSelect'
| 'AutoComplete'
| 'Checkbox'
| 'CheckboxGroup'
| 'DatePicker'
| 'DefaultButton'
| 'Divider'
| 'IconPicker'
| 'Input'
| 'InputNumber'
| 'InputPassword'
| 'InputSearch'
| 'Mentions'
| 'PrimaryButton'
| 'Radio'
| 'RadioGroup'
| 'RangePicker'
| 'Rate'
| 'Select'
| 'Space'
| 'Switch'
| 'Textarea'
| 'TimePicker'
| 'TreeSelect'
| 'Upload'
| BaseFormComponentType;
async function initComponentAdapter() {
const components: Partial<Record<ComponentType, Component>> = {
// 如果你的组件体积比较大,可以使用异步加载
// Button: () =>
// import('xxx').then((res) => res.Button),
ApiSelect: (props, { attrs, slots }) => {
return h(
ApiComponent,
{
placeholder: $t('ui.placeholder.select'),
...props,
...attrs,
component: Select,
loadingSlot: 'suffixIcon',
modelPropName: 'value',
visibleEvent: 'onDropdownVisibleChange',
},
slots,
);
},
ApiTreeSelect: (props, { attrs, slots }) => {
return h(
ApiComponent,
{
placeholder: $t('ui.placeholder.select'),
...props,
...attrs,
component: TreeSelect,
fieldNames: { label: 'label', value: 'value', children: 'children' },
loadingSlot: 'suffixIcon',
modelPropName: 'value',
optionsPropName: 'treeData',
visibleEvent: 'onVisibleChange',
},
slots,
);
},
AutoComplete,
Checkbox,
CheckboxGroup,
DatePicker,
// 自定义默认按钮
DefaultButton: (props, { attrs, slots }) => {
return h(Button, { ...props, attrs, type: 'default' }, slots);
},
Divider,
IconPicker: (props, { attrs, slots }) => {
return h(
IconPicker,
{ iconSlot: 'addonAfter', inputComponent: Input, ...props, ...attrs },
slots,
);
},
Input: withDefaultPlaceholder(Input, 'input'),
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
InputSearch: withDefaultPlaceholder(InputSearch, 'input'),
Mentions: withDefaultPlaceholder(Mentions, 'input'),
// 自定义主要按钮
PrimaryButton: (props, { attrs, slots }) => {
return h(Button, { ...props, attrs, type: 'primary' }, slots);
},
Radio,
RadioGroup,
RangePicker,
Rate,
Select: withDefaultPlaceholder(Select, 'select'),
Space,
Switch,
Textarea: withDefaultPlaceholder(Textarea, 'input'),
TimePicker,
TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'),
Upload,
};
// 将组件注册到全局共享状态中
globalShareState.setComponents(components);
// 定义全局共享状态中的消息提示
globalShareState.defineMessage({
// 复制成功消息提示
copyPreferencesSuccess: (title, content) => {
notification.success({
description: content,
message: title,
placement: 'bottomRight',
});
},
});
}
export { initComponentAdapter };

47
apps/vben5/packages/@abp/ui/src/adapter/form.ts

@ -1,47 +0,0 @@
import type {
VbenFormSchema as FormSchema,
VbenFormProps,
} from '@vben/common-ui';
import type { ComponentType } from './component';
import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';
setupVbenForm<ComponentType>({
config: {
// ant design vue组件库默认都是 v-model:value
baseModelPropName: 'value',
// 一些组件是 v-model:checked 或者 v-model:fileList
modelPropNameMap: {
Checkbox: 'checked',
Radio: 'checked',
Switch: 'checked',
Upload: 'fileList',
},
},
defineRules: {
// 输入项目必填国际化适配
required: (value, _params, ctx) => {
if (value === undefined || value === null || value.length === 0) {
return $t('ui.formRules.required', [ctx.label]);
}
return true;
},
// 选择项目必填国际化适配
selectRequired: (value, _params, ctx) => {
if (value === undefined || value === null) {
return $t('ui.formRules.selectRequired', [ctx.label]);
}
return true;
},
},
});
const useVbenForm = useForm<ComponentType>;
export { useVbenForm, z };
export type VbenFormSchema = FormSchema<ComponentType>;
export type { VbenFormProps };

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save