🔨(frontend) email invitation in invited user's language
- language for invitation emails => language saved on the invited user - if invited user does not exist yet => language of the sending user - if for some reason no sending user => system default language
This commit is contained in:
@@ -32,6 +32,7 @@ and this project adheres to
|
|||||||
|
|
||||||
- 🐛(backend) allow any type of extensions for media download #671
|
- 🐛(backend) allow any type of extensions for media download #671
|
||||||
- ♻️(frontend) improve table pdf rendering
|
- ♻️(frontend) improve table pdf rendering
|
||||||
|
- 🐛(email) invitation emails in receivers language
|
||||||
|
|
||||||
|
|
||||||
## [2.2.0] - 2025-02-10
|
## [2.2.0] - 2025-02-10
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import {
|
|||||||
Role,
|
Role,
|
||||||
} from '@/features/docs/doc-management';
|
} from '@/features/docs/doc-management';
|
||||||
import { KEY_LIST_DOC_ACCESSES } from '@/features/docs/doc-share';
|
import { KEY_LIST_DOC_ACCESSES } from '@/features/docs/doc-share';
|
||||||
import { ContentLanguage } from '@/i18n/types';
|
|
||||||
import { useBroadcastStore } from '@/stores';
|
import { useBroadcastStore } from '@/stores';
|
||||||
|
|
||||||
import { OptionType } from '../types';
|
import { OptionType } from '../types';
|
||||||
@@ -21,20 +20,15 @@ interface CreateDocAccessParams {
|
|||||||
role: Role;
|
role: Role;
|
||||||
docId: Doc['id'];
|
docId: Doc['id'];
|
||||||
memberId: User['id'];
|
memberId: User['id'];
|
||||||
contentLanguage: ContentLanguage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createDocAccess = async ({
|
export const createDocAccess = async ({
|
||||||
memberId,
|
memberId,
|
||||||
role,
|
role,
|
||||||
docId,
|
docId,
|
||||||
contentLanguage,
|
|
||||||
}: CreateDocAccessParams): Promise<Access> => {
|
}: CreateDocAccessParams): Promise<Access> => {
|
||||||
const response = await fetchAPI(`documents/${docId}/accesses/`, {
|
const response = await fetchAPI(`documents/${docId}/accesses/`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
|
||||||
'Content-Language': contentLanguage,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
user_id: memberId,
|
user_id: memberId,
|
||||||
role,
|
role,
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { APIError, errorCauses, fetchAPI } from '@/api';
|
|||||||
import { User } from '@/features/auth';
|
import { User } from '@/features/auth';
|
||||||
import { Doc, Role } from '@/features/docs/doc-management';
|
import { Doc, Role } from '@/features/docs/doc-management';
|
||||||
import { Invitation, OptionType } from '@/features/docs/doc-share/types';
|
import { Invitation, OptionType } from '@/features/docs/doc-share/types';
|
||||||
import { ContentLanguage } from '@/i18n/types';
|
|
||||||
|
|
||||||
import { KEY_LIST_DOC_INVITATIONS } from './useDocInvitations';
|
import { KEY_LIST_DOC_INVITATIONS } from './useDocInvitations';
|
||||||
|
|
||||||
@@ -12,20 +11,15 @@ interface CreateDocInvitationParams {
|
|||||||
email: User['email'];
|
email: User['email'];
|
||||||
role: Role;
|
role: Role;
|
||||||
docId: Doc['id'];
|
docId: Doc['id'];
|
||||||
contentLanguage: ContentLanguage;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createDocInvitation = async ({
|
export const createDocInvitation = async ({
|
||||||
email,
|
email,
|
||||||
role,
|
role,
|
||||||
docId,
|
docId,
|
||||||
contentLanguage,
|
|
||||||
}: CreateDocInvitationParams): Promise<Invitation> => {
|
}: CreateDocInvitationParams): Promise<Invitation> => {
|
||||||
const response = await fetchAPI(`documents/${docId}/invitations/`, {
|
const response = await fetchAPI(`documents/${docId}/invitations/`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
|
||||||
'Content-Language': contentLanguage,
|
|
||||||
},
|
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
email,
|
email,
|
||||||
role,
|
role,
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { Box } from '@/components';
|
|||||||
import { useCunninghamTheme } from '@/cunningham';
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
import { User } from '@/features/auth';
|
import { User } from '@/features/auth';
|
||||||
import { Doc, Role } from '@/features/docs';
|
import { Doc, Role } from '@/features/docs';
|
||||||
import { useLanguage } from '@/i18n/hooks/useLanguage';
|
|
||||||
|
|
||||||
import { useCreateDocAccess, useCreateDocInvitation } from '../api';
|
import { useCreateDocAccess, useCreateDocInvitation } from '../api';
|
||||||
import { OptionType } from '../types';
|
import { OptionType } from '../types';
|
||||||
@@ -42,7 +41,6 @@ export const DocShareAddMemberList = ({
|
|||||||
const { toast } = useToastProvider();
|
const { toast } = useToastProvider();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const { spacingsTokens, colorsTokens } = useCunninghamTheme();
|
const { spacingsTokens, colorsTokens } = useCunninghamTheme();
|
||||||
const { contentLanguage } = useLanguage();
|
|
||||||
const [invitationRole, setInvitationRole] = useState<Role>(Role.EDITOR);
|
const [invitationRole, setInvitationRole] = useState<Role>(Role.EDITOR);
|
||||||
const canShare = doc.abilities.accesses_manage;
|
const canShare = doc.abilities.accesses_manage;
|
||||||
const spacing = spacingsTokens();
|
const spacing = spacingsTokens();
|
||||||
@@ -90,7 +88,6 @@ export const DocShareAddMemberList = ({
|
|||||||
const payload = {
|
const payload = {
|
||||||
role: invitationRole,
|
role: invitationRole,
|
||||||
docId: doc.id,
|
docId: doc.id,
|
||||||
contentLanguage,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return isInvitationMode
|
return isInvitationMode
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { Box, Text } from '@/components';
|
|||||||
import { useCunninghamTheme } from '@/cunningham';
|
import { useCunninghamTheme } from '@/cunningham';
|
||||||
import { Footer } from '@/features/footer';
|
import { Footer } from '@/features/footer';
|
||||||
import { LeftPanel } from '@/features/left-panel';
|
import { LeftPanel } from '@/features/left-panel';
|
||||||
import { useLanguage } from '@/i18n/hooks/useLanguage';
|
|
||||||
import { useResponsiveStore } from '@/stores';
|
import { useResponsiveStore } from '@/stores';
|
||||||
|
|
||||||
import SC1ResponsiveEn from '../assets/SC1-responsive-en.png';
|
import SC1ResponsiveEn from '../assets/SC1-responsive-en.png';
|
||||||
@@ -28,11 +27,10 @@ import { HomeHeader, getHeaderHeight } from './HomeHeader';
|
|||||||
import { HomeSection } from './HomeSection';
|
import { HomeSection } from './HomeSection';
|
||||||
|
|
||||||
export function HomeContent() {
|
export function HomeContent() {
|
||||||
const { t } = useTranslation();
|
const { i18n, t } = useTranslation();
|
||||||
const { colorsTokens } = useCunninghamTheme();
|
const { colorsTokens } = useCunninghamTheme();
|
||||||
const { isMobile, isSmallMobile, isTablet } = useResponsiveStore();
|
const { isMobile, isSmallMobile, isTablet } = useResponsiveStore();
|
||||||
const lang = useLanguage();
|
const isFrLanguage = i18n.resolvedLanguage === 'fr';
|
||||||
const isFrLanguage = lang.language === 'fr';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box as="main">
|
<Box as="main">
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
|
|
||||||
import { ContentLanguage } from '../types';
|
|
||||||
|
|
||||||
export const useLanguage = (): {
|
|
||||||
language: string;
|
|
||||||
contentLanguage: ContentLanguage;
|
|
||||||
} => {
|
|
||||||
const { i18n } = useTranslation();
|
|
||||||
|
|
||||||
return {
|
|
||||||
language: i18n.language,
|
|
||||||
contentLanguage: i18n.language === 'fr' ? 'fr-fr' : 'en-us',
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
// See: https://github.com/numerique-gouv/impress/blob/ac58341984c99c10ebfac7f8bbe1e8756c48e4d4/src/backend/impress/settings.py#L156-L161
|
|
||||||
export type ContentLanguage = 'en-us' | 'fr-fr';
|
|
||||||
Reference in New Issue
Block a user