Skip to content

Commit 66ea94f

Browse files
Merge pull request #6982 from christianbeeznest/fixes-updates173
Admin: Translate Settings breadcrumb section label
2 parents 8019350 + b9a8b62 commit 66ea94f

File tree

2 files changed

+92
-7
lines changed

2 files changed

+92
-7
lines changed

assets/vue/components/Breadcrumb.vue

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,20 @@
2828
</template>
2929

3030
<script setup>
31-
import { computed, ref, watch, watchEffect } from "vue"
31+
import { computed, ref, watch, watchEffect, onMounted } from "vue"
3232
import { useRoute, useRouter } from "vue-router"
3333
import { useI18n } from "vue-i18n"
3434
import Breadcrumb from "primevue/breadcrumb"
3535
import { useCidReqStore } from "../store/cidReq"
3636
import { storeToRefs } from "pinia"
3737
import { useStore } from "vuex"
3838
39-
const legacyItems = ref(window.breadcrumb)
39+
const legacyItems = ref([])
4040
4141
const cidReqStore = useCidReqStore()
4242
const route = useRoute()
4343
const router = useRouter()
44-
const { t } = useI18n()
44+
const { t, te } = useI18n()
4545
4646
const { course, session } = storeToRefs(cidReqStore)
4747
const store = useStore()
@@ -61,6 +61,13 @@ const specialRouteNames = [
6161
6262
const itemList = ref([])
6363
64+
onMounted(() => {
65+
const wb = (window && window.breadcrumb) || []
66+
if (Array.isArray(wb) && wb.length > 0) {
67+
legacyItems.value = wb
68+
}
69+
})
70+
6471
const formatToolName = (name) => {
6572
if (!name) return ""
6673
return name
@@ -189,6 +196,35 @@ function addDocumentBreadcrumb() {
189196
}
190197
}
191198
199+
/**
200+
* Resolve translated label for /admin/settings/:namespace
201+
*/
202+
function resolveSettingsSectionLabel(nsRaw) {
203+
const ns = String(nsRaw || "").trim()
204+
// Safer because it's already translated server-side.
205+
try {
206+
const current = document.querySelector(".list-group a.bg-gray-25")
207+
const domText = current?.textContent?.trim()
208+
if (domText) {
209+
return domText
210+
}
211+
} catch (e) {}
212+
213+
// i18n candidates
214+
const candidates = [
215+
`settings_section.${ns}`,
216+
`settings_section.${ns.replace(/-/g, "_")}`,
217+
ns,
218+
ns.replace(/[-_]/g, " "),
219+
]
220+
for (const key of candidates) {
221+
const has = typeof te === "function" && te(key)
222+
if (has) return t(key)
223+
}
224+
225+
return ns.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())
226+
}
227+
192228
// Watch route changes to dynamically rebuild the breadcrumb trail
193229
watchEffect(() => {
194230
if ("/" === route.fullPath) return
@@ -220,10 +256,10 @@ watchEffect(() => {
220256
const mainUrl = window.location.href
221257
const mainPath = mainUrl.indexOf("main/")
222258
legacyItems.value.forEach((item) => {
223-
let newUrl = item.url.toString()
259+
let newUrl = (item.url || "").toString()
224260
if (newUrl.indexOf("main/") > 0) newUrl = "/" + newUrl.substring(mainPath)
225261
if (newUrl === "/") newUrl = "#"
226-
itemList.value.push({ label: item.name, url: newUrl })
262+
itemList.value.push({ label: item.name, url: newUrl || undefined })
227263
})
228264
legacyItems.value = []
229265
} else if (course.value && route.name !== "CourseHome") {
@@ -268,7 +304,7 @@ watchEffect(() => {
268304
if (mainToolName === "ccalendarevent") {
269305
const cid = Number(route.query?.cid || 0)
270306
const gid = Number(route.query?.gid || 0)
271-
toolLabel = gid > 0 ? "Group agenda" : (cid > 0 ? "Agenda" : "Personal agenda")
307+
toolLabel = gid > 0 ? "Group agenda" : cid > 0 ? "Agenda" : "Personal agenda"
272308
}
273309
itemList.value.push({
274310
label: t(toolLabel),
@@ -300,10 +336,24 @@ watchResourceNodeLoader()
300336
function cleanIdParam(id) {
301337
if (!id) return undefined
302338
const match = id.toString().match(/(\d+)$/)
303-
return match ? match[1] : id
339+
return match ? id.toString().match(/(\d+)$/)[1] : id
304340
}
305341
306342
function buildManualBreadcrumbIfNeeded() {
343+
// If server already injected legacy breadcrumbs, use them.
344+
if (Array.isArray(legacyItems.value) && legacyItems.value.length > 0) {
345+
const mainUrl = window.location.href
346+
const mainPath = mainUrl.indexOf("main/")
347+
legacyItems.value.forEach((item) => {
348+
let newUrl = (item.url || "").toString()
349+
if (newUrl.indexOf("main/") > 0) newUrl = "/" + newUrl.substring(mainPath)
350+
if (newUrl === "/") newUrl = "#"
351+
itemList.value.push({ label: item.name, url: newUrl || undefined })
352+
})
353+
legacyItems.value = []
354+
return true
355+
}
356+
307357
const whitelist = ["admin"]
308358
const overrides = {
309359
admin: "AdminIndex",
@@ -316,6 +366,24 @@ function buildManualBreadcrumbIfNeeded() {
316366
return false
317367
}
318368
369+
// /admin/settings/<namespace>
370+
const isAdminSettings = pathSegments[1] === "settings"
371+
if (isAdminSettings) {
372+
const ns = pathSegments[2] || route.params?.namespace || route.query?.namespace || ""
373+
const adminLabel = t("Admin")
374+
itemList.value.push({
375+
label: adminLabel,
376+
route: { name: overrides.admin, params: route.params, query: route.query },
377+
})
378+
itemList.value.push({
379+
label: t("Settings"),
380+
route: { path: "/admin/settings" },
381+
})
382+
const section = resolveSettingsSectionLabel(ns)
383+
itemList.value.push({ label: section })
384+
return true
385+
}
386+
319387
const fullPath = "/" + pathSegments.join("/")
320388
const hasMatchedRoute = router.getRoutes().some((r) => r.path === fullPath)
321389

src/CoreBundle/Resources/views/Admin/Settings/default.html.twig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,3 +205,20 @@
205205
});
206206
</script>
207207
{% endblock %}
208+
{% block javascripts %}
209+
{% set ns = app.request.get('namespace')|default('') %}
210+
{% set sectionLabel =
211+
(namespace_labels is defined and namespace_labels[ns] is defined)
212+
? namespace_labels[ns]
213+
: (ns == 'cas' ? 'CAS' : (ns == 'lp' ? 'Learning path'|trans : (ns|capitalize)|trans))
214+
%}
215+
<script>
216+
window.breadcrumb = [
217+
{ name: "{{ 'Admin'|trans|e('js') }}", url: "/admin" },
218+
{ name: "{{ 'Settings'|trans|e('js') }}", url: "/admin/settings" },
219+
{ name: "{{ sectionLabel|e('js') }}" }
220+
];
221+
</script>
222+
223+
{{ parent() }}
224+
{% endblock %}

0 commit comments

Comments
 (0)