feat(): Translation settings + user configuration + admin hook and js sdk + dashboard (#14355)
* feat(): Translation settings + user configuration * feat(): Translation settings + user configuration * Create gentle-bees-grow.md * add entities end point * add entities end point * add admin hook and js sdk method * update changeset * fix tests * fix tests * rm unnecessary copy * update dashboard to use the new resources * update dashboard to use the new resources * update dashboard to use the new resources * allow type inference through interface augmentation in the defineConfig of medusa-config * allow type inference through interface augmentation in the defineConfig of medusa-config * exclude id and _id props --------- Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
co-authored by
Oli Juhl
parent
797878af26
commit
b21a599d11
@@ -0,0 +1,90 @@
|
||||
import {
|
||||
AuthenticatedMedusaRequest,
|
||||
MedusaResponse,
|
||||
} from "@medusajs/framework/http"
|
||||
import { ContainerRegistrationKeys } from "@medusajs/framework/utils"
|
||||
import { HttpTypes } from "@medusajs/types"
|
||||
|
||||
export const GET = async (
|
||||
req: AuthenticatedMedusaRequest<
|
||||
undefined,
|
||||
HttpTypes.AdminTranslationEntitiesParams
|
||||
>,
|
||||
res: MedusaResponse<HttpTypes.AdminTranslationEntitiesResponse>
|
||||
) => {
|
||||
const query = req.scope.resolve(ContainerRegistrationKeys.QUERY)
|
||||
const { type, id } = req.validatedQuery
|
||||
|
||||
const {
|
||||
data: [translationSettings],
|
||||
} = await query.graph(
|
||||
{
|
||||
entity: "translation_settings",
|
||||
fields: ["*"],
|
||||
filters: {
|
||||
entity_type: type,
|
||||
},
|
||||
},
|
||||
{
|
||||
cache: { enable: true },
|
||||
}
|
||||
)
|
||||
|
||||
const translatableFields = translationSettings?.fields ?? []
|
||||
|
||||
const filters: Record<string, unknown> = {}
|
||||
if (id) {
|
||||
filters.id = id
|
||||
}
|
||||
|
||||
const { data: entities = [], metadata } = await query
|
||||
.graph(
|
||||
{
|
||||
entity: type,
|
||||
fields: ["id", ...translatableFields],
|
||||
filters,
|
||||
pagination: req.queryConfig.pagination,
|
||||
},
|
||||
{
|
||||
cache: { enable: true },
|
||||
}
|
||||
)
|
||||
.catch((e) => {
|
||||
const normalizedMessage = e.message.toLowerCase()
|
||||
if (
|
||||
normalizedMessage.includes("service with alias") &&
|
||||
normalizedMessage.includes("was not found")
|
||||
) {
|
||||
return { data: [], metadata: { count: 0, skip: 0, take: 0 } }
|
||||
}
|
||||
throw e
|
||||
})
|
||||
|
||||
let aggregatedData =
|
||||
entities as HttpTypes.AdminTranslationEntitiesResponse["data"]
|
||||
|
||||
if (aggregatedData.length) {
|
||||
const { data: translations } = await query.graph({
|
||||
entity: "translations",
|
||||
fields: ["*"],
|
||||
filters: {
|
||||
reference_id: aggregatedData.map((entity) => entity.id),
|
||||
},
|
||||
})
|
||||
|
||||
// aggregate data - include all translations for all locales
|
||||
aggregatedData = aggregatedData.map((entity) => {
|
||||
entity.translations = translations.filter(
|
||||
(translation) => translation.reference_id === entity.id
|
||||
)
|
||||
return entity
|
||||
})
|
||||
}
|
||||
|
||||
return res.json({
|
||||
data: aggregatedData,
|
||||
count: metadata?.count ?? 0,
|
||||
offset: metadata?.skip ?? 0,
|
||||
limit: metadata?.take ?? 0,
|
||||
})
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
import {
|
||||
AdminBatchTranslations,
|
||||
AdminGetTranslationsParams,
|
||||
AdminTranslationEntitiesParams,
|
||||
AdminTranslationSettingsParams,
|
||||
AdminTranslationStatistics,
|
||||
} from "./validators"
|
||||
@@ -43,4 +44,14 @@ export const adminTranslationsRoutesMiddlewares: MiddlewareRoute[] = [
|
||||
validateAndTransformQuery(AdminTranslationSettingsParams, {}),
|
||||
],
|
||||
},
|
||||
{
|
||||
method: ["GET"],
|
||||
matcher: "/admin/translations/entities",
|
||||
middlewares: [
|
||||
validateAndTransformQuery(
|
||||
AdminTranslationEntitiesParams,
|
||||
QueryConfig.listTransformQueryConfig
|
||||
),
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -25,12 +25,12 @@ export const GET = async (
|
||||
const translationService = req.scope.resolve<ITranslationModuleService>(
|
||||
Modules.TRANSLATION
|
||||
)
|
||||
const translatable_fields = translationService.getTranslatableFields(
|
||||
const translatableFields = await translationService.getTranslatableFields(
|
||||
req.validatedQuery.entity_type
|
||||
)
|
||||
|
||||
res.json({
|
||||
translatable_fields,
|
||||
translatable_fields: translatableFields,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -71,3 +71,16 @@ export type AdminTranslationSettingsParamsType = z.infer<
|
||||
export const AdminTranslationSettingsParams = z.object({
|
||||
entity_type: z.string().optional(),
|
||||
})
|
||||
|
||||
export type AdminTranslationEntitiesParamsType = z.infer<
|
||||
typeof AdminTranslationEntitiesParams
|
||||
>
|
||||
export const AdminTranslationEntitiesParams = createFindParams({
|
||||
limit: 20,
|
||||
offset: 0,
|
||||
}).merge(
|
||||
z.object({
|
||||
type: z.string(),
|
||||
id: z.union([z.string(), z.array(z.string())]).optional(),
|
||||
})
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user