@nocobase/portal-template-default 1.0.12 → 1.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/build-html.mjs +14 -0
- package/src/extensions/nocobase-auth-cas/README.md +6 -0
- package/src/extensions/nocobase-auth-cas/cas-sign-in-button.tsx +41 -0
- package/src/extensions/nocobase-auth-cas/demo.tsx +20 -0
- package/src/extensions/nocobase-auth-cas/extension.tsx +48 -0
- package/src/extensions/nocobase-auth-cas/index.ts +1 -0
- package/src/extensions/nocobase-auth-cas/use-cas-sign-in.ts +31 -0
- package/src/extensions/nocobase-auth-dingtalk/README.md +7 -0
- package/src/extensions/nocobase-auth-dingtalk/auto-login-provider.tsx +185 -0
- package/src/extensions/nocobase-auth-dingtalk/demo.tsx +23 -0
- package/src/extensions/nocobase-auth-dingtalk/dingtalk-sign-in-button.tsx +45 -0
- package/src/extensions/nocobase-auth-dingtalk/extension.tsx +53 -0
- package/src/extensions/nocobase-auth-dingtalk/index.ts +4 -0
- package/src/extensions/nocobase-auth-dingtalk/use-dingtalk-sign-in.ts +66 -0
- package/src/extensions/nocobase-auth-ldap/README.md +6 -0
- package/src/extensions/nocobase-auth-ldap/demo.tsx +21 -0
- package/src/extensions/nocobase-auth-ldap/extension.tsx +48 -0
- package/src/extensions/nocobase-auth-ldap/index.ts +1 -0
- package/src/extensions/nocobase-auth-ldap/ldap-sign-in-form.tsx +69 -0
- package/src/extensions/nocobase-auth-ldap/use-ldap-sign-in.ts +5 -0
- package/src/extensions/nocobase-auth-oidc/README.md +11 -0
- package/src/extensions/nocobase-auth-oidc/auto-redirect-provider.tsx +13 -0
- package/src/extensions/nocobase-auth-oidc/demo.tsx +20 -0
- package/src/extensions/nocobase-auth-oidc/extension.tsx +51 -0
- package/src/extensions/nocobase-auth-oidc/index.ts +1 -0
- package/src/extensions/nocobase-auth-oidc/oidc-sign-in-button.tsx +44 -0
- package/src/extensions/nocobase-auth-oidc/use-oidc-sign-in.ts +60 -0
- package/src/extensions/nocobase-auth-saml/README.md +6 -0
- package/src/extensions/nocobase-auth-saml/auto-redirect-provider.tsx +13 -0
- package/src/extensions/nocobase-auth-saml/demo.tsx +20 -0
- package/src/extensions/nocobase-auth-saml/extension.tsx +51 -0
- package/src/extensions/nocobase-auth-saml/index.ts +1 -0
- package/src/extensions/nocobase-auth-saml/saml-sign-in-button.tsx +43 -0
- package/src/extensions/nocobase-auth-saml/use-saml-sign-in.ts +53 -0
- package/src/extensions/nocobase-auth-sms/README.md +7 -0
- package/src/extensions/nocobase-auth-sms/demo.tsx +25 -0
- package/src/extensions/nocobase-auth-sms/extension.tsx +48 -0
- package/src/extensions/nocobase-auth-sms/index.ts +1 -0
- package/src/extensions/nocobase-auth-sms/sms-sign-in-form.tsx +107 -0
- package/src/extensions/nocobase-auth-sms/use-sms-sign-in.ts +88 -0
- package/src/extensions/nocobase-auth-wecom/README.md +6 -0
- package/src/extensions/nocobase-auth-wecom/auto-login-provider.tsx +21 -0
- package/src/extensions/nocobase-auth-wecom/demo.tsx +23 -0
- package/src/extensions/nocobase-auth-wecom/extension.tsx +51 -0
- package/src/extensions/nocobase-auth-wecom/index.ts +1 -0
- package/src/extensions/nocobase-auth-wecom/use-wecom-sign-in.ts +64 -0
- package/src/extensions/nocobase-auth-wecom/wecom-sign-in-button.tsx +70 -0
- package/src/extensions/nocobase-i18n/README.md +44 -0
- package/src/extensions/nocobase-i18n/components/index.ts +1 -0
- package/src/extensions/nocobase-i18n/components/language-switcher.tsx +138 -0
- package/src/extensions/nocobase-i18n/demo/index.tsx +209 -0
- package/src/extensions/nocobase-i18n/demo/prompt-generator.tsx +132 -0
- package/src/extensions/nocobase-i18n/extension.tsx +48 -0
- package/src/extensions/nocobase-i18n/index.ts +7 -0
- package/src/extensions/nocobase-i18n/locales/en-US.ts +39 -0
- package/src/extensions/nocobase-i18n/locales/index.ts +8 -0
- package/src/extensions/nocobase-i18n/locales/zh-CN.ts +35 -0
- package/src/extensions/nocobase-i18n/provider.tsx +44 -0
- package/src/extensions/nocobase-i18n/server-resources.ts +166 -0
- package/src/extensions/nocobase-i18n/tests/i18n-regression.mjs +51 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { nocobaseClient } from "@/lib/nocobase/client";
|
|
2
|
+
import {
|
|
3
|
+
type LocaleSystemSettings,
|
|
4
|
+
applyDocumentLocale,
|
|
5
|
+
getCurrentLocale,
|
|
6
|
+
i18n,
|
|
7
|
+
registerLocale,
|
|
8
|
+
setEnabledLocales,
|
|
9
|
+
} from "@/providers/i18n";
|
|
10
|
+
|
|
11
|
+
type ServerLanguagePayload = {
|
|
12
|
+
lang?: string;
|
|
13
|
+
resources?: Record<string, Record<string, string>>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const serverResourceNamespaces = new Set(["lm-collections"]);
|
|
17
|
+
const loadedServerResourceNamespaces = new Set<string>();
|
|
18
|
+
const namespaceLoadPromises = new Map<string, Promise<void>>();
|
|
19
|
+
let cachedServerResources: ServerLanguagePayload["resources"] = {};
|
|
20
|
+
let serverResourcesPromise: Promise<void> | undefined;
|
|
21
|
+
let bootstrapStarted = false;
|
|
22
|
+
let bootstrapComplete = false;
|
|
23
|
+
|
|
24
|
+
function mergeNamespace(namespace: string, locale?: string) {
|
|
25
|
+
const resource = cachedServerResources?.[namespace];
|
|
26
|
+
if (!locale || !resource) return false;
|
|
27
|
+
i18n.addResourceBundle(locale, namespace, resource, true, false);
|
|
28
|
+
loadedServerResourceNamespaces.add(namespace);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function requestServerResources(
|
|
33
|
+
namespaces: string[],
|
|
34
|
+
requestedLocale?: string
|
|
35
|
+
) {
|
|
36
|
+
const payload = await nocobaseClient.action<ServerLanguagePayload>(
|
|
37
|
+
"app",
|
|
38
|
+
"getLang",
|
|
39
|
+
{
|
|
40
|
+
method: "GET",
|
|
41
|
+
query: {
|
|
42
|
+
...(requestedLocale ? { locale: requestedLocale } : {}),
|
|
43
|
+
...(namespaces.length ? { ns: namespaces.join(",") } : {}),
|
|
44
|
+
},
|
|
45
|
+
includeRole: false,
|
|
46
|
+
withAclMeta: false,
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
cachedServerResources = {
|
|
51
|
+
...cachedServerResources,
|
|
52
|
+
...payload.resources,
|
|
53
|
+
};
|
|
54
|
+
for (const namespace of namespaces) {
|
|
55
|
+
mergeNamespace(namespace, payload.lang);
|
|
56
|
+
loadedServerResourceNamespaces.add(namespace);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return payload;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function ensureServerResourceNamespaces(namespaces: string[]) {
|
|
63
|
+
const pending: Promise<void>[] = [];
|
|
64
|
+
const missing: string[] = [];
|
|
65
|
+
|
|
66
|
+
for (const namespace of namespaces) {
|
|
67
|
+
if (loadedServerResourceNamespaces.has(namespace)) continue;
|
|
68
|
+
if (mergeNamespace(namespace, getCurrentLocale())) continue;
|
|
69
|
+
const existing = namespaceLoadPromises.get(namespace);
|
|
70
|
+
if (existing) pending.push(existing);
|
|
71
|
+
else missing.push(namespace);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (missing.length) {
|
|
75
|
+
const request = requestServerResources(
|
|
76
|
+
missing,
|
|
77
|
+
nocobaseClient.getStoredLocale() ?? getCurrentLocale()
|
|
78
|
+
).then(() => undefined);
|
|
79
|
+
for (const namespace of missing) {
|
|
80
|
+
namespaceLoadPromises.set(namespace, request);
|
|
81
|
+
}
|
|
82
|
+
const cleanup = () => {
|
|
83
|
+
for (const namespace of missing) {
|
|
84
|
+
if (namespaceLoadPromises.get(namespace) === request) {
|
|
85
|
+
namespaceLoadPromises.delete(namespace);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
void request.then(cleanup, cleanup);
|
|
90
|
+
pending.push(request);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
await Promise.all(pending);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function registerServerResourceNamespace(namespace: string) {
|
|
97
|
+
if (!namespace) return;
|
|
98
|
+
serverResourceNamespaces.add(namespace);
|
|
99
|
+
|
|
100
|
+
if (
|
|
101
|
+
mergeNamespace(namespace, getCurrentLocale()) ||
|
|
102
|
+
!bootstrapStarted ||
|
|
103
|
+
!bootstrapComplete
|
|
104
|
+
) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
void ensureServerResourceNamespaces([namespace]).catch((error) => {
|
|
109
|
+
console.warn(
|
|
110
|
+
`Unable to load NocoBase locale namespace ${namespace}`,
|
|
111
|
+
error
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function getServerResourceNamespaces() {
|
|
117
|
+
return [...serverResourceNamespaces];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function loadServerLocaleResources(settings?: LocaleSystemSettings) {
|
|
121
|
+
if (serverResourcesPromise) return serverResourcesPromise;
|
|
122
|
+
|
|
123
|
+
bootstrapStarted = true;
|
|
124
|
+
const requestedLocale = nocobaseClient.getStoredLocale();
|
|
125
|
+
const initialNamespaces = [...serverResourceNamespaces];
|
|
126
|
+
const configuredLocales = Array.isArray(settings?.enabledLanguages)
|
|
127
|
+
? settings.enabledLanguages
|
|
128
|
+
: [];
|
|
129
|
+
if (configuredLocales.length) setEnabledLocales(configuredLocales);
|
|
130
|
+
const languagePromise = requestServerResources(
|
|
131
|
+
initialNamespaces,
|
|
132
|
+
requestedLocale
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
serverResourcesPromise = languagePromise
|
|
136
|
+
.then(async (payload) => {
|
|
137
|
+
const serverLocale = payload.lang;
|
|
138
|
+
|
|
139
|
+
if (!configuredLocales.length && serverLocale) {
|
|
140
|
+
setEnabledLocales([serverLocale]);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (serverLocale) {
|
|
144
|
+
registerLocale({ locale: serverLocale, label: serverLocale });
|
|
145
|
+
nocobaseClient.setLocale(serverLocale);
|
|
146
|
+
await i18n.changeLanguage(serverLocale);
|
|
147
|
+
applyDocumentLocale(serverLocale);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
bootstrapComplete = true;
|
|
151
|
+
const lateNamespaces = [...serverResourceNamespaces].filter(
|
|
152
|
+
(namespace) => !loadedServerResourceNamespaces.has(namespace)
|
|
153
|
+
);
|
|
154
|
+
if (lateNamespaces.length) {
|
|
155
|
+
await ensureServerResourceNamespaces(lateNamespaces);
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
.catch((error) => {
|
|
159
|
+
bootstrapComplete = true;
|
|
160
|
+
if (!configuredLocales.length) setEnabledLocales([getCurrentLocale()]);
|
|
161
|
+
serverResourcesPromise = undefined;
|
|
162
|
+
throw error;
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
return serverResourcesPromise;
|
|
166
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { createServer } from "vite";
|
|
3
|
+
|
|
4
|
+
const server = await createServer({
|
|
5
|
+
appType: "custom",
|
|
6
|
+
logLevel: "silent",
|
|
7
|
+
server: { middlewareMode: true },
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
try {
|
|
11
|
+
await server.ssrLoadModule("/src/locales/index.ts");
|
|
12
|
+
const {
|
|
13
|
+
applySystemLocale,
|
|
14
|
+
getCurrentLocale,
|
|
15
|
+
i18n,
|
|
16
|
+
registerLocaleResources,
|
|
17
|
+
translate,
|
|
18
|
+
} = await server.ssrLoadModule("/src/providers/i18n/runtime.ts");
|
|
19
|
+
const { resolveTranslatableText } =
|
|
20
|
+
await server.ssrLoadModule("/src/lib/i18n.ts");
|
|
21
|
+
|
|
22
|
+
await i18n.changeLanguage("en-US");
|
|
23
|
+
assert.equal(translate("buttons.create", { ns: "starter" }, "Create"), "Create");
|
|
24
|
+
|
|
25
|
+
await i18n.changeLanguage("zh-CN");
|
|
26
|
+
assert.equal(translate("buttons.create", { ns: "starter" }, "Create"), "新建");
|
|
27
|
+
assert.equal(resolveTranslatableText('{{t("Admin")}}'), "管理员");
|
|
28
|
+
assert.equal(
|
|
29
|
+
resolveTranslatableText("Full permissions", { ns: "starter" }),
|
|
30
|
+
"全部权限"
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
registerLocaleResources("example-feature", {
|
|
34
|
+
"en-US": { title: "Example" },
|
|
35
|
+
"zh-CN": { title: "示例" },
|
|
36
|
+
});
|
|
37
|
+
assert.equal(
|
|
38
|
+
translate("title", { ns: "example-feature" }, "Example"),
|
|
39
|
+
"示例"
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
await applySystemLocale({
|
|
43
|
+
appLang: "en-US",
|
|
44
|
+
enabledLanguages: ["en-US", "zh-CN"],
|
|
45
|
+
});
|
|
46
|
+
assert.equal(getCurrentLocale(), "en-US");
|
|
47
|
+
|
|
48
|
+
console.log("NocoBase i18n regression tests passed");
|
|
49
|
+
} finally {
|
|
50
|
+
await server.close();
|
|
51
|
+
}
|