Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Translate PWA (backport #1856) #2330

Merged
merged 11 commits into from
Oct 23, 2024
15 changes: 13 additions & 2 deletions frontend/src/components/AttendanceCalendar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
<div v-for="status in summaryStatuses" class="flex flex-col gap-1">
<div class="flex flex-row gap-1 items-center">
<span class="rounded full h-3 w-3" :class="`bg-${colorMap[status]}`" />
<span class="text-gray-600 text-sm font-medium leading-5"> {{ status }} </span>
<span class="text-gray-600 text-sm font-medium leading-5"> {{ __(status) }} </span>
</div>
<span class="text-gray-800 text-base font-semibold leading-6 mx-auto">
{{ summary[status] || 0 }}
Expand Down Expand Up @@ -76,6 +76,7 @@ const colorMap = {
Holiday: "gray-100",
}

// __("Present"), __("Half Day"), __("Absent"), __("On Leave"), __("Work From Home")
const summaryStatuses = ["Present", "Half Day", "Absent", "On Leave"]

const summary = computed(() => {
Expand Down Expand Up @@ -104,7 +105,17 @@ const getEventOnDate = (date) => {
return calendarEvents.data[firstOfMonth.value.date(date).format("YYYY-MM-DD")]
}

const DAYS = ["S", "M", "T", "W", "T", "F", "S"]
const getFirstLetter = (s) => Array.from(s.trim())[0] // Unicode

const DAYS = [
getFirstLetter(__("Sunday")),
getFirstLetter(__("Monday")),
getFirstLetter(__("Tuesday")),
getFirstLetter(__("Wednesday")),
getFirstLetter(__("Thursday")),
getFirstLetter(__("Friday")),
getFirstLetter(__("Saturday")),
]

//resources
const calendarEvents = createResource({
Expand Down
6 changes: 2 additions & 4 deletions frontend/src/components/AttendanceRequestItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@
<span>{{ props.doc.attendance_dates || getDates(props.doc) }}</span>
<span v-if="props.doc.to_date">
<span class="whitespace-pre"> &middot; </span>
<span class="whitespace-nowrap">{{
`${props.doc.total_attendance_days || getTotalDays(props.doc)}d`
}}</span>
<span class="whitespace-nowrap">{{ __("{0}d", [props.doc.total_attendance_days]) }}</span>
</span>
</div>
</div>
</template>
<template #right>
<Badge variant="outline" :theme="colorMap[status]" :label="status" size="md" />
<Badge variant="outline" :theme="colorMap[status]" :label="__(status)" size="md" />
<FeatherIcon name="chevron-right" class="h-5 w-5 text-gray-500" />
</template>
</ListItem>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/BaseLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<div class="flex flex-row justify-between items-center">
<div class="flex flex-row items-center gap-2">
<h2 class="text-xl font-bold text-gray-900">
{{ props.pageTitle }}
{{ props.pageTitle || __("Frappe HR") }}
</h2>
</div>
<div class="flex flex-row items-center gap-3 ml-auto">
Expand Down Expand Up @@ -62,7 +62,7 @@ const props = defineProps({
pageTitle: {
type: String,
required: false,
default: "Frappe HR",
default: "",
},
})
</script>
13 changes: 8 additions & 5 deletions frontend/src/components/BottomTabs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,33 +31,36 @@ import LeaveIcon from "@/components/icons/LeaveIcon.vue"
import ExpenseIcon from "@/components/icons/ExpenseIcon.vue"
import SalaryIcon from "@/components/icons/SalaryIcon.vue"
import AttendanceIcon from "@/components/icons/AttendanceIcon.vue"
import { inject } from "vue"

const __ = inject("$translate")

const route = useRoute()

const tabItems = [
{
icon: HomeIcon,
title: "Home",
title: __("Home"),
route: "/home",
},
{
icon: AttendanceIcon,
title: "Attendance",
title: __("Attendance"),
route: "/dashboard/attendance",
},
{
icon: LeaveIcon,
title: "Leaves",
title: __("Leaves"),
route: "/dashboard/leaves",
},
{
icon: ExpenseIcon,
title: "Expenses",
title: __("Expenses"),
route: "/dashboard/expense-claims",
},
{
icon: SalaryIcon,
title: "Salary",
title: __("Salary"),
route: "/dashboard/salary-slips",
},
]
Expand Down
35 changes: 19 additions & 16 deletions frontend/src/components/CheckInPanel.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
<template>
<div class="flex flex-col bg-white rounded w-full py-6 px-4 border-none">
<h2 class="text-lg font-bold text-gray-900">Hey, {{ employee?.data?.first_name }} 👋</h2>
<h2 class="text-lg font-bold text-gray-900">
{{ __("Hey, {0} 👋", [employee?.data?.first_name]) }}
</h2>

<template v-if="settings.data?.allow_employee_checkin_from_mobile_app">
<div class="font-medium text-sm text-gray-500 mt-1.5" v-if="lastLog">
<span>Last {{ lastLogType }} was at {{ formatTimestamp(lastLog.time) }}</span>
<span>{{ __("Last {0} was at {1}", [__(lastLogType), formatTimestamp(lastLog.time)]) }}</span>
<span class="whitespace-pre"> &middot; </span>
<router-link :to="{ name: 'EmployeeCheckinListView' }" v-slot="{ navigate }">
<span @click="navigate" class="underline">View List</span>
Expand Down Expand Up @@ -68,7 +70,7 @@
</template>

<Button variant="solid" class="w-full py-5 text-sm" @click="submitLog(nextAction.action)">
Confirm {{ nextAction.label }}
{{ __("Confirm {0}", [nextAction.label]) }}
</Button>
</div>
</ion-modal>
Expand All @@ -86,6 +88,7 @@ const DOCTYPE = "Employee Checkin"
const socket = inject("$socket")
const employee = inject("$employee")
const dayjs = inject("$dayjs")
const __ = inject("$translate")
const checkinTimestamp = ref(null)
const latitude = ref(0)
const longitude = ref(0)
Expand Down Expand Up @@ -117,18 +120,18 @@ const lastLogType = computed(() => {

const nextAction = computed(() => {
return lastLog?.value?.log_type === "IN"
? { action: "OUT", label: "Check Out" }
: { action: "IN", label: "Check In" }
? { action: "OUT", label: __("Check Out") }
: { action: "IN", label: __("Check In") }
})

function handleLocationSuccess(position) {
latitude.value = position.coords.latitude
longitude.value = position.coords.longitude

locationStatus.value = `
Latitude: ${Number(latitude.value).toFixed(5),
Longitude: ${Number(longitude.value).toFixed(5)
`
locationStatus.value = [
__("Latitude: {0}°", [Number(latitude.value).toFixed(5)]),
__("Longitude: {0}°", [Number(longitude.value).toFixed(5)]),
].join(", ")
}

function handleLocationError(error) {
Expand All @@ -138,9 +141,9 @@ function handleLocationError(error) {

const fetchLocation = () => {
if (!navigator.geolocation) {
locationStatus.value = "Geolocation is not supported by your current browser"
locationStatus.value = __("Geolocation is not supported by your current browser")
} else {
locationStatus.value = "Locating..."
locationStatus.value = __("Locating...")
navigator.geolocation.getCurrentPosition(handleLocationSuccess, handleLocationError)
}
}
Expand All @@ -154,7 +157,7 @@ const handleEmployeeCheckin = () => {
}

const submitLog = (logType) => {
const action = logType === "IN" ? "Check-in" : "Check-out"
const actionLabel = logType === "IN" ? __("Check-in") : __("Check-out")

checkins.insert.submit(
{
Expand All @@ -168,17 +171,17 @@ const submitLog = (logType) => {
onSuccess() {
modalController.dismiss()
toast({
title: "Success",
text: `${action} successful!`,
title: __("Success"),
text: __("{0} successful!", [actionLabel]),
icon: "check-circle",
position: "bottom-center",
iconClasses: "text-green-500",
})
},
onError() {
toast({
title: "Error",
text: `${action} failed!`,
title: __("Error"),
text: __("{0} failed!", [actionLabel]),
icon: "alert-circle",
position: "bottom-center",
iconClasses: "text-red-500",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/EmployeeAdvanceBalance.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
>
<div class="flex flex-col bg-white w-full py-5 px-3.5 mt-0 border-none">
<Button @click="navigate" variant="subtle" class="py-5 text-base">
Request an Advance
{{ __("Request an Advance") }}
</Button>
</div>
</router-link>
Expand Down
16 changes: 7 additions & 9 deletions frontend/src/components/EmployeeAdvanceItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@
<EmployeeAdvanceIcon class="h-5 w-5 mt-[3px] text-gray-500" />
<div class="flex flex-col items-start gap-1">
<div v-if="props.doc.balance_amount" class="text-lg font-bold text-gray-800 leading-6">
{{ `${currency} ${props.doc.balance_amount} /` }}
{{ formatCurrency(props.doc.balance_amount, props.doc.currency) }}
/
<span class="text-gray-600">
{{ `${currency} ${props.doc.paid_amount}` }}
{{ formatCurrency(props.doc.paid_amount, props.doc.currency) }}
</span>
</div>
<div v-else class="text-lg font-bold text-gray-800 leading-6">
{{ `${currency} ${props.doc.advance_amount}` }}
{{ formatCurrency(props.doc.advance_amount, props.doc.currency) }}
</div>
<div class="text-xs font-normal text-gray-500">
<span>
{{ props.doc.purpose }}
{{ __(props.doc.purpose) }}
</span>
<span class="whitespace-pre"> &middot; </span>
<span class="whitespace-nowrap">
Expand All @@ -28,7 +29,7 @@
</div>
</template>
<template #right>
<Badge variant="outline" :theme="colorMap[status]" :label="status" size="md" />
<Badge variant="outline" :theme="colorMap[status]" :label="__(status, null, 'Employee Advance')" size="md" />
<FeatherIcon name="chevron-right" class="h-5 w-5 text-gray-500" />
</template>
</ListItem>
Expand All @@ -38,10 +39,9 @@
import { FeatherIcon, Badge } from "frappe-ui"
import { computed, inject } from "vue"

import { getCurrencySymbol } from "@/data/currencies"

import ListItem from "@/components/ListItem.vue"
import EmployeeAdvanceIcon from "@/components/icons/EmployeeAdvanceIcon.vue"
import { formatCurrency } from "@/utils/formatters";

const dayjs = inject("$dayjs")
const props = defineProps({
Expand All @@ -66,8 +66,6 @@ const colorMap = {
"Partly Claimed and Returned": "orange",
}

const currency = computed(() => getCurrencySymbol(props.doc.currency))

const postingDate = computed(() => {
return dayjs(props.doc.posting_date).format("D MMM")
})
Expand Down
10 changes: 6 additions & 4 deletions frontend/src/components/ExpenseAdvancesTable.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="flex flex-row justify-between items-center">
<h2 class="text-base font-semibold text-gray-800">
Settle against Advances
{{ __("Settle against Advances") }}
</h2>
</div>

Expand Down Expand Up @@ -32,8 +32,10 @@
</div>
<div class="flex flex-row items-center gap-3 justify-between">
<div class="text-xs font-normal text-gray-500">
Unclaimed Amount:
{{ formatCurrency(advance.unclaimed_amount, currency) }}
{{ __("{0}: {1}", [
__("Unclaimed Amount"),
formatCurrency(advance.unclaimed_amount, currency),
]) }}
</div>
</div>
</div>
Expand All @@ -58,7 +60,7 @@
</div>
</div>

<EmptyState v-else message="No advances found" :isTableField="true" />
<EmptyState v-else :message="__('No advances found')" :isTableField="true" />
</template>

<script setup>
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/ExpenseClaimItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</div>
</template>
<template #right>
<Badge variant="outline" :theme="statusMap[status]" :label="status" size="md" />
<Badge variant="outline" :theme="statusMap[status]" :label="__(status, null, 'Expense Claim')" size="md" />
<FeatherIcon name="chevron-right" class="h-5 w-5 text-gray-500" />
</template>
</ListItem>
Expand All @@ -39,6 +39,7 @@ import { getCompanyCurrency } from "@/data/currencies"
import { formatCurrency } from "@/utils/formatters"

const dayjs = inject("$dayjs")
const __ = inject("$translate")
const props = defineProps({
doc: {
type: Object,
Expand Down Expand Up @@ -80,11 +81,10 @@ const status = computed(() => {
})

const claimTitle = computed(() => {
let title = props.doc.expense_type
let title = __(props.doc.expense_type)
if (props.doc.total_expenses > 1) {
title += ` & ${props.doc.total_expenses - 1} more`
title = __("{0} & {1} more", [title, props.doc.total_expenses - 1])
}

return title
})

Expand Down
10 changes: 5 additions & 5 deletions frontend/src/components/ExpenseClaimSummary.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<template>
<div class="flex flex-col w-full gap-5" v-if="summary.data">
<div class="text-lg text-gray-800 font-bold">Expense Claim Summary</div>
<div class="text-lg text-gray-800 font-bold">{{ __("Expense Claim Summary") }}</div>
<div
class="flex flex-col gap-4 bg-white py-3 px-3.5 rounded-lg border-none"
>
<div class="flex flex-col gap-1.5">
<span class="text-gray-600 text-base font-medium leading-5">
Total Expense Amount
{{ __("Total Expense Amount") }}
</span>
<span class="text-gray-800 text-lg font-bold leading-6">
{{ formatCurrency(total_claimed_amount, company_currency) }}
Expand All @@ -17,7 +17,7 @@
<div class="flex flex-col gap-1">
<div class="flex flex-row gap-1 items-center">
<span class="text-gray-600 text-sm font-medium leading-5">
Pending
{{ __("Pending") }}
</span>
<FeatherIcon name="alert-circle" class="text-yellow-500 h-3 w-3" />
</div>
Expand All @@ -33,7 +33,7 @@
<div class="flex flex-col gap-1">
<div class="flex flex-row gap-1 items-center">
<span class="text-gray-600 text-sm font-medium leading-5">
Approved
{{ __("Approved") }}
</span>
<FeatherIcon name="check-circle" class="text-green-500 h-3 w-3" />
</div>
Expand All @@ -50,7 +50,7 @@
<div class="flex flex-col gap-1">
<div class="flex flex-row gap-1 items-center">
<span class="text-gray-600 text-sm font-medium leading-5">
Rejected
{{ __("Rejected") }}
</span>
<FeatherIcon name="x-circle" class="text-red-500 h-3 w-3" />
</div>
Expand Down
Loading
Loading