i18n: add missing __() calls to complete French translation

This commit is contained in:
Youssef
2025-08-15 19:51:10 -04:00
parent cf5cc19fd5
commit 16afb24276
14 changed files with 210 additions and 27 deletions

View File

@@ -157,7 +157,7 @@
v-model="showHelpModal"
v-model:articles="articles"
appName="learning"
title="Frappe Learning"
:title="__('Frappe Learning')"
:logo="LMSLogo"
:afterSkip="(step) => capture('onboarding_step_skipped_' + step)"
:afterSkipAll="() => capture('onboarding_steps_skipped')"
@@ -303,7 +303,7 @@ const unreadNotifications = createResource({
const addNotifications = () => {
if (user) {
sidebarLinks.value.push({
label: 'Notifications',
label: __('Notifications'),
icon: 'Bell',
to: 'Notifications',
activeFor: ['Notifications'],
@@ -315,7 +315,7 @@ const addNotifications = () => {
const addQuizzes = () => {
if (isInstructor.value || isModerator.value) {
sidebarLinks.value.splice(4, 0, {
label: 'Quizzes',
label: __('Quizzes'),
icon: 'CircleHelp',
to: 'Quizzes',
activeFor: [
@@ -331,7 +331,7 @@ const addQuizzes = () => {
const addAssignments = () => {
if (isInstructor.value || isModerator.value) {
sidebarLinks.value.splice(5, 0, {
label: 'Assignments',
label: __('Assignments'),
icon: 'Pencil',
to: 'Assignments',
activeFor: [
@@ -347,7 +347,7 @@ const addAssignments = () => {
const addProgrammingExercises = () => {
if (isInstructor.value || isModerator.value) {
sidebarLinks.value.splice(3, 0, {
label: 'Programming Exercises',
label: __('Programming Exercises'),
icon: 'Code',
to: 'ProgrammingExercises',
activeFor: [
@@ -383,7 +383,7 @@ const addPrograms = () => {
if (canAddProgram) {
sidebarLinks.value.splice(index, 0, {
label: 'Programs',
label: __('Programs'),
icon: 'Route',
to: 'Programs',
activeFor: activeFor,

View File

@@ -102,7 +102,7 @@ const props = defineProps({
},
emptyStateText: {
type: String,
default: 'Start a discussion',
default: __('Start a discussion'),
},
singleThread: {
type: Boolean,

View File

@@ -2,6 +2,7 @@
<div class="flex flex-col items-center justify-center mt-60">
<GraduationCap class="size-10 mx-auto stroke-1 text-ink-gray-5" />
<div class="text-lg font-semibold text-ink-gray-7 mb-2.5">
{{ __('No {0}').format(props.type) }}
</div>
<div

View File

@@ -0,0 +1,70 @@
<template>
<div
v-if="!isSidebarCollapsed"
class="flex flex-col gap-3 shadow-sm rounded-lg py-2.5 px-3 bg-surface-modal text-base"
>
<div v-if="stepsCompleted != totalSteps" class="inline-flex text-ink-gray-9 gap-2">
<StepsIcon class="h-4 my-0.5 shrink-0" />
<div class="flex flex-col text-p-sm gap-0.5">
<div class="font-medium">
{{ __('Getting started') }}
</div>
<div class="text-ink-gray-7">
{{ __('{0}/{1} steps').format(stepsCompleted, totalSteps) }}
</div>
</div>
</div>
<div v-else class="flex flex-col gap-1">
<div class="flex items-center justify-between gap-1">
<div class="flex items-center gap-2 shrink-0">
<StepsIcon class="h-4 my-0.5" />
<div class="text-ink-gray-9 font-medium">
{{ __('You are all set') }}
</div>
</div>
<FeatherIcon
name="x"
class="h-4 cursor-pointer"
@click="() => { showHelpCenter = true; isOnboardingStepsCompleted = true }"
/>
</div>
<div class="text-p-sm text-ink-gray-7">
{{ __('All steps are completed successfully') }}
</div>
</div>
<Button
v-if="stepsCompleted != totalSteps"
:label="stepsCompleted == 0 ? __('Start now') : __('Continue')"
theme="blue"
@click="openOnboarding"
>
<template #prefix>
<FeatherIcon name="chevrons-right" class="size-4" />
</template>
</Button>
</div>
<Button v-else-if="stepsCompleted != totalSteps" @click="openOnboarding">
<StepsIcon class="h-4 my-0.5 shrink-0" />
</Button>
</template>
<script setup>
import StepsIcon from 'frappe-ui/frappe/Icons/StepsIcon.vue'
import Button from 'frappe-ui/src/components/Button/Button.vue'
import FeatherIcon from 'frappe-ui/src/components/FeatherIcon.vue'
import { useOnboarding } from 'frappe-ui/frappe/Onboarding/onboarding'
import { showHelpCenter } from 'frappe-ui/frappe/HelpCenter/helpCenter'
import { showHelpModal, minimize } from 'frappe-ui/frappe/Help/help'
const props = defineProps({
isSidebarCollapsed: { type: Boolean, default: false },
appName: { type: String, default: 'frappecrm' },
})
const { stepsCompleted, totalSteps, isOnboardingStepsCompleted } = useOnboarding(props.appName)
const openOnboarding = () => {
minimize.value = false
showHelpModal.value = true
}
</script>

View File

@@ -0,0 +1,112 @@
<template>
<div class="flex flex-col justify-center items-center gap-1 mt-4 mb-7">
<component :is="logo" class="size-10 shrink-0 rounded mb-4" />
<div class="text-base font-medium">
{{ __('Welcome to {0}').format(title) }}
</div>
<div class="text-p-base font-normal">
{{ __('{0}/{1} steps completed').format(stepsCompleted, totalSteps) }}
</div>
</div>
<div class="flex flex-col gap-2.5 overflow-hidden">
<div class="flex justify-between items-center py-0.5">
<Badge
:label="__('{0}% completed').format(completedPercentage)"
:theme="completedPercentage == 100 ? 'green' : 'orange'"
size="lg"
/>
<div class="flex">
<Button
v-if="completedPercentage != 0"
variant="ghost"
:label="__('Reset all')"
@click="() => resetAll(afterResetAll)"
/>
<Button
v-if="completedPercentage != 100"
variant="ghost"
:label="__('Skip all')"
@click="() => skipAll(afterSkipAll)"
/>
</div>
</div>
<div class="flex flex-col gap-1.5 overflow-y-auto">
<div
v-for="step in steps"
:key="step.title"
class="group w-full flex gap-2 justify-between items-center hover:bg-surface-gray-1 rounded px-2 py-1.5 cursor-pointer"
@click.stop="() => !step.completed && !isDependent(step) && step.onClick()"
>
<component :is="isDependent(step) ? Tooltip : 'div'" :text="dependsOnTooltip(step)">
<div
class="flex gap-2 items-center"
:class="[
step.completed
? 'text-ink-gray-5'
: isDependent(step)
? 'text-ink-gray-4'
: 'text-ink-gray-8',
]"
>
<component :is="step.icon" class="h-4" />
<div class="text-base" :class="{ 'line-through': step.completed }">
{{ step.title }}
</div>
</div>
</component>
<Button
v-if="!step.completed && !isDependent(step)"
:label="__('Skip')"
class="!h-4 text-xs !text-ink-gray-6 hidden group-hover:flex"
@click="() => skip(step.name, afterSkip)"
/>
<Button
v-else-if="!isDependent(step)"
:label="__('Reset')"
class="!h-4 text-xs !text-ink-gray-6 hidden group-hover:flex"
@click.stop="() => reset(step.name, afterReset)"
/>
</div>
</div>
</div>
</template>
<script setup>
import { useOnboarding } from 'frappe-ui/frappe/Onboarding/onboarding'
import Tooltip from 'frappe-ui/src/components/Tooltip/Tooltip.vue'
import Button from 'frappe-ui/src/components/Button/Button.vue'
import Badge from 'frappe-ui/src/components/Badge/Badge.vue'
const props = defineProps({
appName: { type: String, default: 'frappecrm' },
title: { type: String, default: 'Frappe CRM' },
logo: { type: Object, required: true },
afterSkip: { type: Function, default: () => {} },
afterSkipAll: { type: Function, default: () => {} },
afterReset: { type: Function, default: () => {} },
afterResetAll: { type: Function, default: () => {} },
})
function isDependent(step) {
if (step.dependsOn && !step.completed) {
const dependsOnStep = steps.find((s) => s.name === step.dependsOn)
if (dependsOnStep && !dependsOnStep.completed) {
return true
}
}
return false
}
function dependsOnTooltip(step) {
if (step.dependsOn && !step.completed) {
const dependsOnStep = steps.find((s) => s.name === step.dependsOn)
if (dependsOnStep && !dependsOnStep.completed) {
return `You need to complete "${dependsOnStep.title}" first.`
}
}
return ''
}
const { steps, stepsCompleted, totalSteps, completedPercentage, skip, skipAll, reset, resetAll } =
useOnboarding(props.appName)
</script>

View File

@@ -57,7 +57,7 @@
}"
>
</ListView>
<EmptyState v-else type="Assignments" />
<EmptyState v-else :type="__('Assignments').toLowerCase()" />
<div
v-if="assignments.data && assignments.hasNextPage"
class="flex justify-center my-5"
@@ -198,7 +198,7 @@ const assignmentTypes = computed(() => {
const breadcrumbs = computed(() => [
{
label: 'Assignments',
label: __('Assignments'),
route: { name: 'Assignments' },
},
])

View File

@@ -70,7 +70,7 @@
<BatchCard :batch="batch" />
</router-link>
</div>
<EmptyState v-else-if="!batches.list.loading" type="Batches" />
<EmptyState v-else-if="!batches.list.loading" :type="__('Batches').toLowerCase()" />
<div
v-if="!batches.list.loading && batches.hasNextPage"

View File

@@ -81,7 +81,7 @@
</router-link>
</div>
</div>
<EmptyState v-else type="Job Openings" />
<EmptyState v-else :type="__('Job Openings').toLowerCase()" />
</div>
</div>
</template>

View File

@@ -214,7 +214,7 @@
<div class="mt-20" ref="discussionsContainer">
<Discussions
v-if="allowDiscussions"
:title="'Questions'"
:title="__('Questions')"
:doctype="'Course Lesson'"
:docname="lesson.data.name"
:key="lesson.data.name"

View File

@@ -144,7 +144,7 @@ onUnmounted(() => {
const breadcrumbs = computed(() => {
let crumbs = [
{
label: 'Notifications',
label: __('Notifications'),
route: {
name: 'Notifications',
},
@@ -155,7 +155,7 @@ const breadcrumbs = computed(() => {
usePageMeta(() => {
return {
title: 'Notifications',
title: __('Notifications'),
icon: brand.favicon,
}
})

View File

@@ -323,12 +323,12 @@ const saveProgram = () => {
const courseColumns = computed(() => {
return [
{
label: 'Title',
label: __('Title'),
key: 'course_title',
width: 3,
},
{
label: 'ID',
label: __('ID'),
key: 'course',
width: 3,
},
@@ -338,19 +338,19 @@ const courseColumns = computed(() => {
const memberColumns = computed(() => {
return [
{
label: 'Member',
label: __('Member'),
key: 'member',
width: 3,
align: 'left',
},
{
label: 'Full Name',
label: __('Full Name'),
key: 'full_name',
width: 3,
align: 'left',
},
{
label: 'Progress (%)',
label: __('Progress (%)'),
key: 'progress',
width: 3,
align: 'right',
@@ -361,11 +361,11 @@ const memberColumns = computed(() => {
const breadbrumbs = computed(() => {
return [
{
label: 'Programs',
label: __('Programs'),
route: { name: 'Programs' },
},
{
label: props.programName === 'new' ? 'New Program' : props.programName,
label: props.programName === 'new' ? __('New Program') : props.programName,
},
]
})

View File

@@ -82,7 +82,7 @@
</div>
</div>
</div>
<EmptyState v-else type="Programs" />
<EmptyState v-else :type="__('Programs').toLowerCase()" />
<Dialog
v-model="showDialog"

View File

@@ -19,7 +19,7 @@
: __('No Quizzes')
}}
</div>
<FormControl v-model="search" type="text" placeholder="Search">
<FormControl v-model="search" type="text" :placeholder="__('Search')">
<template #prefix>
<FeatherIcon name="search" class="size-4 text-ink-gray-5" />
</template>
@@ -88,7 +88,7 @@
</template>
</ListSelectBanner>
</ListView>
<EmptyState v-else type="Quizzes" />
<EmptyState v-else :type="__('Quizzes').toLowerCase()" />
<div v-if="quizzes.hasNextPage" class="flex justify-center my-5">
<Button @click="quizzes.next()">
{{ __('Load More') }}

View File

@@ -16,14 +16,14 @@
<Tooltip :text="__('Active Members')">
<NumberChart
class="border rounded-md"
:config="{ title: 'Signups', value: chartDetails.data.users }"
:config="{ title: __('Signups'), value: chartDetails.data.users }"
/>
</Tooltip>
<Tooltip :text="__('Course Enrollments')">
<NumberChart
class="border rounded-md"
:config="{
title: 'Enrollments',
title: __('Enrollments'),
value: chartDetails.data.enrollments,
}"
/>
@@ -122,7 +122,7 @@
:config="{
data: courseCompletion.data,
title: __('Completions'),
subtitle: 'Course Completion',
subtitle: __('Course Completion'),
categoryColumn: 'label',
valueColumn: 'value',
}"