UBERF-10248: Fix timezone loading (#8586)

* UBERF-10248: Fix local timezone

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-10248: Remove unused import

Signed-off-by: Artem Savchenko <armisav@gmail.com>

* UBERF-10248: Remove redundant arg

Signed-off-by: Artem Savchenko <armisav@gmail.com>

---------

Signed-off-by: Artem Savchenko <armisav@gmail.com>
This commit is contained in:
Artyom Savchenko 2025-04-16 20:30:05 +07:00 committed by GitHub
parent 45aaa26011
commit c370fdb1a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 43 additions and 32 deletions

View File

@ -111,6 +111,7 @@
"ViberPlaceholder": "Viber", "ViberPlaceholder": "Viber",
"UserProfile": "Uživatelský profil", "UserProfile": "Uživatelský profil",
"DeactivatedAccount": "Deaktivovaný účet", "DeactivatedAccount": "Deaktivovaný účet",
"LocalTime": "místní čas" "LocalTime": "místní čas",
"LocalTimeNotSet": "Místní čas není nastaven"
} }
} }

View File

@ -111,6 +111,7 @@
"ViberPlaceholder": "Viber", "ViberPlaceholder": "Viber",
"UserProfile": "Benutzerprofil", "UserProfile": "Benutzerprofil",
"DeactivatedAccount": "Deaktivierter Account", "DeactivatedAccount": "Deaktivierter Account",
"LocalTime": "Ortszeit" "LocalTime": "Ortszeit",
"LocalTimeNotSet": "Ortszeit nicht festgelegt"
} }
} }

View File

@ -115,6 +115,7 @@
"Confirmed": "Confirmed", "Confirmed": "Confirmed",
"UserProfile": "User profile", "UserProfile": "User profile",
"DeactivatedAccount": "Deactivated account", "DeactivatedAccount": "Deactivated account",
"LocalTime": "local time" "LocalTime": "local time",
"LocalTimeNotSet": "Local time not set"
} }
} }

View File

@ -115,6 +115,7 @@
"Confirmed": "Confirmado", "Confirmed": "Confirmado",
"UserProfile": "Perfil de usuario", "UserProfile": "Perfil de usuario",
"DeactivatedAccount": "Cuenta desactivada", "DeactivatedAccount": "Cuenta desactivada",
"LocalTime": "hora local" "LocalTime": "hora local",
"LocalTimeNotSet": "Hora local no establecida"
} }
} }

View File

@ -115,6 +115,7 @@
"Confirmed": "Confirmé", "Confirmed": "Confirmé",
"UserProfile": "Profil utilisateur", "UserProfile": "Profil utilisateur",
"DeactivatedAccount": "Compte désactivé", "DeactivatedAccount": "Compte désactivé",
"LocalTime": "heure locale" "LocalTime": "heure locale",
"LocalTimeNotSet": "Heure locale non définie"
} }
} }

View File

@ -115,6 +115,7 @@
"Confirmed": "Confermato", "Confirmed": "Confermato",
"UserProfile": "Profilo utente", "UserProfile": "Profilo utente",
"DeactivatedAccount": "Account disattivato", "DeactivatedAccount": "Account disattivato",
"LocalTime": "ora locale" "LocalTime": "ora locale",
"LocalTimeNotSet": "Ora locale non impostata"
} }
} }

View File

@ -115,6 +115,7 @@
"Confirmed": "Confirmado", "Confirmed": "Confirmado",
"UserProfile": "Perfil do usuário", "UserProfile": "Perfil do usuário",
"DeactivatedAccount": "Conta desativada", "DeactivatedAccount": "Conta desativada",
"LocalTime": "hora local" "LocalTime": "hora local",
"LocalTimeNotSet": "Hora local não definida"
} }
} }

View File

@ -115,6 +115,7 @@
"Confirmed": "Подтвержден", "Confirmed": "Подтвержден",
"UserProfile": "Профиль пользователя", "UserProfile": "Профиль пользователя",
"DeactivatedAccount": "Деактивированный аккаунт", "DeactivatedAccount": "Деактивированный аккаунт",
"LocalTime": "местного времени" "LocalTime": "местного времени",
"LocalTimeNotSet": "Местное время не задано"
} }
} }

View File

@ -115,6 +115,7 @@
"Confirmed": "已确认", "Confirmed": "已确认",
"UserProfile": "用户资料", "UserProfile": "用户资料",
"DeactivatedAccount": "已停用账户", "DeactivatedAccount": "已停用账户",
"LocalTime": "当地时间" "LocalTime": "当地时间",
"LocalTimeNotSet": "未设置当地时间"
} }
} }

View File

@ -15,7 +15,7 @@
<script lang="ts"> <script lang="ts">
import { Employee } from '@hcengineering/contact' import { Employee } from '@hcengineering/contact'
import { AccountUuid, Class, Doc, Ref } from '@hcengineering/core' import { AccountUuid, Class, Doc, Ref } from '@hcengineering/core'
import { ButtonIcon, Loading, navigate } from '@hcengineering/ui' import { ButtonIcon, navigate } from '@hcengineering/ui'
import view from '@hcengineering/view' import view from '@hcengineering/view'
import { getObjectLinkFragment } from '@hcengineering/view-resources' import { getObjectLinkFragment } from '@hcengineering/view-resources'
import { ComponentExtensions, getClient } from '@hcengineering/presentation' import { ComponentExtensions, getClient } from '@hcengineering/presentation'
@ -97,11 +97,7 @@
<div class="flex-col flex-gap-0-5"> <div class="flex-col flex-gap-0-5">
<EmployeePresenter value={employee} shouldShowAvatar={false} showPopup={false} compact accent /> <EmployeePresenter value={employee} shouldShowAvatar={false} showPopup={false} compact accent />
<span class="flex-presenter cursor-default"> <span class="flex-presenter cursor-default">
{#if isTimezoneLoading} <TimePresenter {timezone} {isTimezoneLoading} />
<Loading size="small" />
{:else if timezone != null}
<TimePresenter {timezone} />
{/if}
</span> </span>
</div> </div>
</div> </div>

View File

@ -16,8 +16,10 @@
import { Icon, Label } from '@hcengineering/ui' import { Icon, Label } from '@hcengineering/ui'
import contact from '@hcengineering/contact' import contact from '@hcengineering/contact'
import view from '@hcengineering/view'
export let timezone: string export let timezone: string | undefined
export let isTimezoneLoading: boolean
function displayTimeInTimezone (timezone: string): string { function displayTimeInTimezone (timezone: string): string {
const options: Intl.DateTimeFormatOptions = { const options: Intl.DateTimeFormatOptions = {
@ -34,10 +36,16 @@
<div class="time-container"> <div class="time-container">
<div class="clock-icon"> <div class="clock-icon">
<Icon icon={contact.icon.Clock} size={'x-small'} /> <Icon icon={contact.icon.Clock} size={'smaller'} />
</div> </div>
<div class="text-normal font-normal content-color select-text"> <div class="text-normal font-normal content-color select-text">
{#if isTimezoneLoading}
<span class="time-text-span"><Label label={view.string.Loading} /></span>
{:else if timezone != null}
<span class="time-text-span">{displayTimeInTimezone(timezone)} <Label label={contact.string.LocalTime} /></span> <span class="time-text-span">{displayTimeInTimezone(timezone)} <Label label={contact.string.LocalTime} /></span>
{:else}
<span class="time-text-span"><Label label={contact.string.LocalTimeNotSet} /></span>
{/if}
</div> </div>
</div> </div>

View File

@ -336,7 +336,8 @@ export const contactPlugin = plugin(contactId, {
Confirmed: '' as IntlString, Confirmed: '' as IntlString,
UserProfile: '' as IntlString, UserProfile: '' as IntlString,
DeactivatedAccount: '' as IntlString, DeactivatedAccount: '' as IntlString,
LocalTime: '' as IntlString LocalTime: '' as IntlString,
LocalTimeNotSet: '' as IntlString
}, },
viewlet: { viewlet: {
TableMember: '' as Ref<Viewlet>, TableMember: '' as Ref<Viewlet>,

View File

@ -117,8 +117,7 @@ export async function login (
params: { params: {
email: string email: string
password: string password: string
}, }
meta?: Meta
): Promise<LoginInfo> { ): Promise<LoginInfo> {
const { email, password } = params const { email, password } = params
const normalizedEmail = cleanEmail(email) const normalizedEmail = cleanEmail(email)
@ -149,7 +148,6 @@ export async function login (
const extraToken: Record<string, string> = isAdminEmail(email) ? { admin: 'true' } : {} const extraToken: Record<string, string> = isAdminEmail(email) ? { admin: 'true' } : {}
ctx.info('Login succeeded', { email, normalizedEmail, isConfirmed, emailSocialId, ...extraToken }) ctx.info('Login succeeded', { email, normalizedEmail, isConfirmed, emailSocialId, ...extraToken })
void setTimezoneIfNotDefined(ctx, db, existingAccount.uuid, existingAccount, meta)
return { return {
account: existingAccount.uuid, account: existingAccount.uuid,
@ -172,8 +170,7 @@ export async function loginOtp (
db: AccountDB, db: AccountDB,
branding: Branding | null, branding: Branding | null,
token: string, token: string,
params: { email: string }, params: { email: string }
meta?: Meta
): Promise<OtpInfo> { ): Promise<OtpInfo> {
const { email } = params const { email } = params
@ -191,8 +188,6 @@ export async function loginOtp (
throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, {})) throw new PlatformError(new Status(Severity.ERROR, platform.status.AccountNotFound, {}))
} }
void setTimezoneIfNotDefined(ctx, db, account.uuid, account, meta)
return await sendOtp(ctx, db, branding, emailSocialId) return await sendOtp(ctx, db, branding, emailSocialId)
} }
@ -287,8 +282,7 @@ export async function validateOtp (
params: { params: {
email: string email: string
code: string code: string
}, }
meta?: Meta
): Promise<LoginInfo> { ): Promise<LoginInfo> {
const { email, code } = params const { email, code } = params
@ -326,8 +320,6 @@ export async function validateOtp (
ctx.info('OTP login success', emailSocialId) ctx.info('OTP login success', emailSocialId)
} }
void setTimezoneIfNotDefined(ctx, db, emailSocialId.personUuid as AccountUuid, account, meta)
const person = await db.person.findOne({ uuid: emailSocialId.personUuid }) const person = await db.person.findOne({ uuid: emailSocialId.personUuid })
if (person == null) { if (person == null) {
throw new PlatformError(new Status(Severity.ERROR, platform.status.InternalServerError, {})) throw new PlatformError(new Status(Severity.ERROR, platform.status.InternalServerError, {}))
@ -667,7 +659,7 @@ export async function join (
ctx.info('Joining a workspace using invite', { email, normalizedEmail, ...invite }) ctx.info('Joining a workspace using invite', { email, normalizedEmail, ...invite })
const { token, account } = await login(ctx, db, branding, _token, { email: normalizedEmail, password }, meta) const { token, account } = await login(ctx, db, branding, _token, { email: normalizedEmail, password })
if (token == null) { if (token == null) {
return { return {
@ -1258,7 +1250,8 @@ export async function getLoginInfoByToken (
ctx: MeasureContext, ctx: MeasureContext,
db: AccountDB, db: AccountDB,
branding: Branding | null, branding: Branding | null,
token: string token: string,
meta?: Meta
): Promise<LoginInfo | WorkspaceLoginInfo> { ): Promise<LoginInfo | WorkspaceLoginInfo> {
let accountUuid: AccountUuid let accountUuid: AccountUuid
let workspaceUuid: WorkspaceUuid let workspaceUuid: WorkspaceUuid
@ -1317,6 +1310,10 @@ export async function getLoginInfoByToken (
token token
} }
if (!isSystem) {
void setTimezoneIfNotDefined(ctx, db, accountUuid, null, meta)
}
if (workspaceUuid != null && workspaceUuid !== '') { if (workspaceUuid != null && workspaceUuid !== '') {
const workspace = await getWorkspaceById(db, workspaceUuid) const workspace = await getWorkspaceById(db, workspaceUuid)