mirror of
https://github.com/hexastack/hexabot
synced 2025-06-26 18:27:28 +00:00
Merge pull request #235 from Hexastack/feat/use-i18n-ns
feat(frontend): add i18n namespace + remove setting help & id
This commit is contained in:
commit
c902a8c7da
@ -130,7 +130,7 @@ export class BlockController extends BaseController<
|
|||||||
plugin: p.id,
|
plugin: p.id,
|
||||||
args: p.settings.reduce(
|
args: p.settings.reduce(
|
||||||
(acc, setting) => {
|
(acc, setting) => {
|
||||||
acc[setting.id] = setting.value;
|
acc[setting.label] = setting.value;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{} as { [key: string]: any },
|
{} as { [key: string]: any },
|
||||||
|
@ -22,7 +22,7 @@ export interface CustomBlocks {}
|
|||||||
type ChannelEvent = any;
|
type ChannelEvent = any;
|
||||||
type BlockAttrs = Partial<BlockCreateDto> & { name: string };
|
type BlockAttrs = Partial<BlockCreateDto> & { name: string };
|
||||||
|
|
||||||
export type PluginSetting = Omit<Setting, 'createdAt' | 'updatedAt'>;
|
export type PluginSetting = Omit<Setting, 'id' | 'createdAt' | 'updatedAt'>;
|
||||||
|
|
||||||
export type PluginBlockTemplate = Omit<
|
export type PluginBlockTemplate = Omit<
|
||||||
BlockAttrs,
|
BlockAttrs,
|
||||||
|
@ -6,8 +6,7 @@
|
|||||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Prop, Schema, SchemaFactory, ModelDefinition } from '@nestjs/mongoose';
|
import { ModelDefinition, Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
|
||||||
import { Transform } from 'class-transformer';
|
|
||||||
import { IsArray, IsIn } from 'class-validator';
|
import { IsArray, IsIn } from 'class-validator';
|
||||||
|
|
||||||
import { BaseSchema } from '@/utils/generics/base-schema';
|
import { BaseSchema } from '@/utils/generics/base-schema';
|
||||||
@ -46,13 +45,6 @@ export class Setting extends BaseSchema {
|
|||||||
@Prop({ type: JSON, default: {} })
|
@Prop({ type: JSON, default: {} })
|
||||||
config?: Record<string, any>;
|
config?: Record<string, any>;
|
||||||
|
|
||||||
@Prop({
|
|
||||||
type: String,
|
|
||||||
default: '',
|
|
||||||
})
|
|
||||||
@Transform(({ obj }) => obj.help || undefined)
|
|
||||||
help?: string;
|
|
||||||
|
|
||||||
@Prop({
|
@Prop({
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0,
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
"eazychart-css": "^0.2.1-alpha.0",
|
"eazychart-css": "^0.2.1-alpha.0",
|
||||||
"eazychart-react": "^0.8.0-alpha.0",
|
"eazychart-react": "^0.8.0-alpha.0",
|
||||||
"hexabot-chat-widget": "*",
|
"hexabot-chat-widget": "*",
|
||||||
|
"i18next-http-backend": "^2.6.2",
|
||||||
"next": "^14.2.13",
|
"next": "^14.2.13",
|
||||||
"next-transpile-modules": "^10.0.1",
|
"next-transpile-modules": "^10.0.1",
|
||||||
"normalizr": "^3.6.2",
|
"normalizr": "^3.6.2",
|
||||||
|
13
frontend/public/locales/en/chatbot_settings.json
Normal file
13
frontend/public/locales/en/chatbot_settings.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"chatbot_settings": "Chatbot"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"global_fallback": "Enable Global Fallback?",
|
||||||
|
"fallback_message": "Fallback Message"
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"global_fallback": "Global fallback allows you to send custom messages when user entry does not match any of the block messages.",
|
||||||
|
"fallback_message": "If no fallback block is selected, then one of these messages will be sent."
|
||||||
|
}
|
||||||
|
}
|
18
frontend/public/locales/en/contact.json
Normal file
18
frontend/public/locales/en/contact.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"contact": "Contact Infos"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"contact_email_recipient": "Contact Email Recipient",
|
||||||
|
"company_name": "Your company's name",
|
||||||
|
"company_phone": "Phone number",
|
||||||
|
"company_email": "Email address",
|
||||||
|
"company_address1": "Address",
|
||||||
|
"company_address2": "Address 2",
|
||||||
|
"company_city": "City",
|
||||||
|
"company_zipcode": "Zipcode",
|
||||||
|
"company_state": "State",
|
||||||
|
"company_country": "Country"
|
||||||
|
},
|
||||||
|
"help": {}
|
||||||
|
}
|
28
frontend/public/locales/en/live-chat-tester.json
Normal file
28
frontend/public/locales/en/live-chat-tester.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"live-chat-tester": "Live Chat Tester"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"verification_token": "Verification Token",
|
||||||
|
"allowed_domains": "Allowed Domains",
|
||||||
|
"start_button": "Enable `Get Started`",
|
||||||
|
"input_disabled": "Disable Input",
|
||||||
|
"persistent_menu": "Display Persistent Menu",
|
||||||
|
"greeting_message": "Greeting Message",
|
||||||
|
"theme_color": "Widget Theme",
|
||||||
|
"theme_color_options": {
|
||||||
|
"orange": "Orange",
|
||||||
|
"red": "Red",
|
||||||
|
"green": "Green",
|
||||||
|
"blue": "Blue",
|
||||||
|
"dark": "Dark"
|
||||||
|
},
|
||||||
|
"window_title": "Chat Window Title",
|
||||||
|
"avatar_url": "Chatbot Avatar URL",
|
||||||
|
"show_emoji": "Enable Emoji Picker",
|
||||||
|
"show_file": "Enable Attachment Uploader",
|
||||||
|
"show_location": "Enable Geolocation Share",
|
||||||
|
"allowed_upload_size": "Max Upload Size (in bytes)",
|
||||||
|
"allowed_upload_types": "Allowed Upload Mime Types (comma separated)"
|
||||||
|
}
|
||||||
|
}
|
16
frontend/public/locales/en/nlp_settings.json
Normal file
16
frontend/public/locales/en/nlp_settings.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"nlp_settings": "NLU Engine"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"provider": "Provider",
|
||||||
|
"token": "API Access Token",
|
||||||
|
"endpoint": "API Endpoint URL",
|
||||||
|
"threshold": "Fallback Threshold"
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"endpoint": "NLU (Natural Language Understanding) API URL (Depends on the provider).",
|
||||||
|
"token": "Every API request must contain an Authorize HTTP header with a token.",
|
||||||
|
"threshold": "Threshold above which the chatbot will use its prediction (min=0 & max=1)"
|
||||||
|
}
|
||||||
|
}
|
28
frontend/public/locales/en/offline.json
Normal file
28
frontend/public/locales/en/offline.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"offline": "Web Channel"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"verification_token": "Verification Token",
|
||||||
|
"allowed_domains": "Allowed Domains",
|
||||||
|
"start_button": "Enable `Get Started`",
|
||||||
|
"input_disabled": "Disable Input",
|
||||||
|
"persistent_menu": "Display Persistent Menu",
|
||||||
|
"greeting_message": "Greeting Message",
|
||||||
|
"theme_color": "Widget Theme",
|
||||||
|
"theme_color_options": {
|
||||||
|
"orange": "Orange",
|
||||||
|
"red": "Red",
|
||||||
|
"green": "Green",
|
||||||
|
"blue": "Blue",
|
||||||
|
"dark": "Dark"
|
||||||
|
},
|
||||||
|
"window_title": "Chat Window Title",
|
||||||
|
"avatar_url": "Chatbot Avatar URL",
|
||||||
|
"show_emoji": "Enable Emoji Picker",
|
||||||
|
"show_file": "Enable Attachment Uploader",
|
||||||
|
"show_location": "Enable Geolocation Share",
|
||||||
|
"allowed_upload_size": "Max Upload Size (in bytes)",
|
||||||
|
"allowed_upload_types": "Allowed Upload Mime Types (comma separated)"
|
||||||
|
}
|
||||||
|
}
|
@ -222,10 +222,6 @@
|
|||||||
"offline": "Web Channel",
|
"offline": "Web Channel",
|
||||||
"twitter": "Twitter",
|
"twitter": "Twitter",
|
||||||
"dimelo": "Dimelo",
|
"dimelo": "Dimelo",
|
||||||
"contact": "Contact Infos",
|
|
||||||
"chatbot_settings": "Chatbot",
|
|
||||||
"nlp_settings": "NLU Provider",
|
|
||||||
"contact_infos": "Contact Infos",
|
|
||||||
"event_log": "Events Log",
|
"event_log": "Events Log",
|
||||||
"log_entry": "Log entry",
|
"log_entry": "Log entry",
|
||||||
"dashboard": "Dashboard",
|
"dashboard": "Dashboard",
|
||||||
@ -471,37 +467,6 @@
|
|||||||
},
|
},
|
||||||
"languages": "Available Languages",
|
"languages": "Available Languages",
|
||||||
"default_lang": "Default Language",
|
"default_lang": "Default Language",
|
||||||
"default_lang_options": {
|
|
||||||
"fr": "Français",
|
|
||||||
"en": "English",
|
|
||||||
"ar": "Arabic",
|
|
||||||
"tn": "Tunisian"
|
|
||||||
},
|
|
||||||
"token": "API Access Token",
|
|
||||||
"endpoint": "API Endpoint URL",
|
|
||||||
"threshold": "Fallback Threshold",
|
|
||||||
"from": "Sender e-mail",
|
|
||||||
"mailer": "Mailer",
|
|
||||||
"mailer_options": {
|
|
||||||
"sendmail": "Sendmail",
|
|
||||||
"smtp": "SMTP Server"
|
|
||||||
},
|
|
||||||
"host": "SMTP Host",
|
|
||||||
"port": "Port",
|
|
||||||
"secure": "Use SSL ?",
|
|
||||||
"auth_user": "User",
|
|
||||||
"auth_pass": "Password",
|
|
||||||
"contact_email_recipient": "Contact Email Recipient",
|
|
||||||
"company_name": "Your company's name",
|
|
||||||
"company_phone": "Phone number",
|
|
||||||
"company_email": "Email address",
|
|
||||||
"company_address1": "Address",
|
|
||||||
"company_address2": "Address 2",
|
|
||||||
"company_city": "City",
|
|
||||||
"company_zipcode": "Zipcode",
|
|
||||||
"company_state": "State",
|
|
||||||
"company_country": "Country",
|
|
||||||
"global_fallback": "Enable Global Fallback?",
|
|
||||||
"secret": "Secret",
|
"secret": "Secret",
|
||||||
"verification_token": "Verification Token",
|
"verification_token": "Verification Token",
|
||||||
"allowed_domains": "Allowed Domains",
|
"allowed_domains": "Allowed Domains",
|
||||||
@ -524,21 +489,6 @@
|
|||||||
"show_location": "Enable Geolocation Share",
|
"show_location": "Enable Geolocation Share",
|
||||||
"allowed_upload_size": "Max Upload Size (in bytes)",
|
"allowed_upload_size": "Max Upload Size (in bytes)",
|
||||||
"allowed_upload_types": "Allowed Upload Mime Types (comma seperated)",
|
"allowed_upload_types": "Allowed Upload Mime Types (comma seperated)",
|
||||||
"tw_consumer_key": "Consumer Key",
|
|
||||||
"tw_consumer_secret": "Consumer Secret",
|
|
||||||
"tw_access_token": "Access Token",
|
|
||||||
"tw_access_token_secret": "Access Token Secret",
|
|
||||||
"tw_greeting_text": "Greeting Text",
|
|
||||||
"d_api_url": "API URL",
|
|
||||||
"d_access_token": "API Access Token",
|
|
||||||
"d_verify_token": "API Verify Token",
|
|
||||||
"d_attachment_fallback_id": "Attachment Fallback ID",
|
|
||||||
"d_url_fallback": "URL Fallback",
|
|
||||||
"d_supported_domain_id": "Supported Domain ID",
|
|
||||||
"d_agent_category_id": "Flow IDs when handed-over",
|
|
||||||
"d_admin_user": "On handover, assign to (admin user ID)",
|
|
||||||
"d_test_identities": "Identity IDs used for testing",
|
|
||||||
"d_supported_sources": "Supported Sources",
|
|
||||||
"channel": "Channel",
|
"channel": "Channel",
|
||||||
"entry": "Entry content",
|
"entry": "Entry content",
|
||||||
"thumbnail": "Thumbnail",
|
"thumbnail": "Thumbnail",
|
||||||
@ -673,11 +623,7 @@
|
|||||||
"composer_input_disabled": "This means your bot can only be interacted with via the persistent menu, postbacks, buttons, and webviews.",
|
"composer_input_disabled": "This means your bot can only be interacted with via the persistent menu, postbacks, buttons, and webviews.",
|
||||||
"get_started_button": "A bot's welcome screen can display a Get Started button. When this button is tapped, the Messenger Platform will send a postback event to your webhook (Payload = `GET_STARTED`).",
|
"get_started_button": "A bot's welcome screen can display a Get Started button. When this button is tapped, the Messenger Platform will send a postback event to your webhook (Payload = `GET_STARTED`).",
|
||||||
"greeting_text": "The greeting property of your bot's Messenger profile allows you to specify the greeting message people will see on the welcome screen of your bot. The welcome screen is displayed for people interacting with your bot for the first time.",
|
"greeting_text": "The greeting property of your bot's Messenger profile allows you to specify the greeting message people will see on the welcome screen of your bot. The welcome screen is displayed for people interacting with your bot for the first time.",
|
||||||
"global_fallback": "Global fallback allows you to send custom messages when user entry does not match any of the block messages.",
|
|
||||||
"fallback_message": "If no fallback block is selected, then one of these messages will be sent.",
|
"fallback_message": "If no fallback block is selected, then one of these messages will be sent.",
|
||||||
"endpoint": "URL to which HTTP NLU requests are posted and that depends on the type of provider.",
|
|
||||||
"token": "Every API request must contain an Authorize HTTP header with a token.",
|
|
||||||
"threshold": "Threshold above which the chatbot will use its prediction (min=0 & max=1)",
|
|
||||||
"app_id": "Mandatory only if you intend to use Facebook Analytics",
|
"app_id": "Mandatory only if you intend to use Facebook Analytics",
|
||||||
"page_id": "Mandatory only if you intend to use Facebook Analytics",
|
"page_id": "Mandatory only if you intend to use Facebook Analytics",
|
||||||
"nlp_train": "You can train your chatbot by adding more examples",
|
"nlp_train": "You can train your chatbot by adding more examples",
|
13
frontend/public/locales/fr/chatbot_settings.json
Normal file
13
frontend/public/locales/fr/chatbot_settings.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"chatbot_settings": "Chatbot"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"global_fallback": "Activer le message de secours global?",
|
||||||
|
"fallback_message": "Message de secours"
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"global_fallback": "Le message de secours global vous permet d'envoyer des messages personnalisés lorsque le message de l'utilisateur ne déclenche aucun bloc de message.",
|
||||||
|
"fallback_message": "Si aucun bloc de secours n'est spécifié, alors de ces messages sera envoyé."
|
||||||
|
}
|
||||||
|
}
|
18
frontend/public/locales/fr/contact.json
Normal file
18
frontend/public/locales/fr/contact.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"contact": "Contact"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"contact_email_recipient": "Email de contact du destinataire",
|
||||||
|
"company_name": "Le nom de votre entreprise",
|
||||||
|
"company_phone": "Tél.",
|
||||||
|
"company_email": "Adresse e-mail",
|
||||||
|
"company_address1": "Adresse",
|
||||||
|
"company_address2": "Adresse 2",
|
||||||
|
"company_city": "Ville",
|
||||||
|
"company_zipcode": "Code postal",
|
||||||
|
"company_state": "État/Province",
|
||||||
|
"company_country": "Pays"
|
||||||
|
},
|
||||||
|
"help": {}
|
||||||
|
}
|
28
frontend/public/locales/fr/live-chat-tester.json
Normal file
28
frontend/public/locales/fr/live-chat-tester.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"live-chat-tester": "Testeur Live Chat"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"verification_token": "Jeton de vérification",
|
||||||
|
"allowed_domains": "Domaines autorisés",
|
||||||
|
"start_button": "Activer `Démarrer`",
|
||||||
|
"input_disabled": "Désactiver la saisie",
|
||||||
|
"persistent_menu": "Afficher le menu persistent",
|
||||||
|
"greeting_message": "Message de bienvenue",
|
||||||
|
"theme_color": "Thème du widget",
|
||||||
|
"theme_color_options": {
|
||||||
|
"orange": "Orange",
|
||||||
|
"red": "Rouge",
|
||||||
|
"green": "Vert",
|
||||||
|
"blue": "Bleu",
|
||||||
|
"dark": "Sombre"
|
||||||
|
},
|
||||||
|
"window_title": "Titre de la fenêtre de chat",
|
||||||
|
"avatar_url": "Avatar du chatbot (URL)",
|
||||||
|
"show_emoji": "Activer le sélecteur d'Emojis",
|
||||||
|
"show_file": "Activer l'upload de fichiers",
|
||||||
|
"show_location": "Activer le partage de géolocalisation",
|
||||||
|
"allowed_upload_size": "Taille maximale de téléchargement (en octets)",
|
||||||
|
"allowed_upload_types": "Types MIME autorisés pour le téléchargement (séparés par des virgules)"
|
||||||
|
}
|
||||||
|
}
|
16
frontend/public/locales/fr/nlp_settings.json
Normal file
16
frontend/public/locales/fr/nlp_settings.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"nlp_settings": "Serveur NLU"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"provider": "Fournisseur",
|
||||||
|
"token": "Token d'accès à l'API",
|
||||||
|
"endpoint": "URL de l'API",
|
||||||
|
"threshold": "Seuil de repli"
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"endpoint": "URL vers laquelle les requêtes de NLU HTTP sont envoyées et qui dépend du fournisseur.",
|
||||||
|
"token": "Chaque requête vers l'API doit contenir un jeton d'authentification.",
|
||||||
|
"threshold": "Seuil en dessus duquel le chatbot va utiliser sa prediction (min=0 & max=1)"
|
||||||
|
}
|
||||||
|
}
|
28
frontend/public/locales/fr/offline.json
Normal file
28
frontend/public/locales/fr/offline.json
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"title": {
|
||||||
|
"offline": "Canal Web"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"verification_token": "Jeton de vérification",
|
||||||
|
"allowed_domains": "Domaines autorisés",
|
||||||
|
"start_button": "Activer `Démarrer`",
|
||||||
|
"input_disabled": "Désactiver la saisie",
|
||||||
|
"persistent_menu": "Afficher le menu persistent",
|
||||||
|
"greeting_message": "Message de bienvenue",
|
||||||
|
"theme_color": "Thème du widget",
|
||||||
|
"theme_color_options": {
|
||||||
|
"orange": "Orange",
|
||||||
|
"red": "Rouge",
|
||||||
|
"green": "Vert",
|
||||||
|
"blue": "Bleu",
|
||||||
|
"dark": "Sombre"
|
||||||
|
},
|
||||||
|
"window_title": "Titre de la fenêtre de chat",
|
||||||
|
"avatar_url": "Avatar du chatbot (URL)",
|
||||||
|
"show_emoji": "Activer le sélecteur d'Emojis",
|
||||||
|
"show_file": "Activer l'upload de fichiers",
|
||||||
|
"show_location": "Activer le partage de géolocalisation",
|
||||||
|
"allowed_upload_size": "Taille maximale de téléchargement (en octets)",
|
||||||
|
"allowed_upload_types": "Types MIME autorisés pour le téléchargement (séparés par des virgules)"
|
||||||
|
}
|
||||||
|
}
|
@ -222,10 +222,6 @@
|
|||||||
"offline": "Canal Web",
|
"offline": "Canal Web",
|
||||||
"twitter": "Twitter",
|
"twitter": "Twitter",
|
||||||
"dimelo": "Dimelo",
|
"dimelo": "Dimelo",
|
||||||
"contact": "Contact",
|
|
||||||
"chatbot_settings": "Paramètres du Chatbot",
|
|
||||||
"nlp_settings": "Paramètres NLU",
|
|
||||||
"contact_infos": "Informations de contact",
|
|
||||||
"event_log": "Journal des événements",
|
"event_log": "Journal des événements",
|
||||||
"log_entry": "Journal des entrées",
|
"log_entry": "Journal des entrées",
|
||||||
"dashboard": "Tableau de bord",
|
"dashboard": "Tableau de bord",
|
||||||
@ -471,36 +467,6 @@
|
|||||||
},
|
},
|
||||||
"languages": "Langues disponibles",
|
"languages": "Langues disponibles",
|
||||||
"default_lang": "Langue",
|
"default_lang": "Langue",
|
||||||
"default_lang_options": {
|
|
||||||
"fr": "Français",
|
|
||||||
"en": "English",
|
|
||||||
"ar": "Arabic",
|
|
||||||
"tn": "Tunisian"
|
|
||||||
},
|
|
||||||
"token": "Token d'accès à l'API",
|
|
||||||
"endpoint": "URL de l'API",
|
|
||||||
"threshold": "Seuil de repli",
|
|
||||||
"from": "E-mail expéditeur",
|
|
||||||
"mailer": "Mailer",
|
|
||||||
"mailer_options": {
|
|
||||||
"sendmail": "Sendmail",
|
|
||||||
"smtp": "Serveur SMTP"
|
|
||||||
},
|
|
||||||
"host": "Hôte SMTP",
|
|
||||||
"port": "Port",
|
|
||||||
"secure": "Utiliser SSL ?",
|
|
||||||
"auth_user": "Utilisateur",
|
|
||||||
"auth_pass": "Mot de passe",
|
|
||||||
"contact_email_recipient": "Email de contact du destinataire",
|
|
||||||
"company_name": "Le nom de votre entreprise",
|
|
||||||
"company_phone": "Tél.",
|
|
||||||
"company_email": "Adresse e-mail",
|
|
||||||
"company_address1": "Addresse",
|
|
||||||
"company_address2": "Addresse 2",
|
|
||||||
"company_city": "Ville",
|
|
||||||
"company_zipcode": "Code postal",
|
|
||||||
"company_state": "État/Province",
|
|
||||||
"company_country": "Pays",
|
|
||||||
"global_fallback": "Activer le message de secours global?",
|
"global_fallback": "Activer le message de secours global?",
|
||||||
"secret": "Mot de passe",
|
"secret": "Mot de passe",
|
||||||
"verification_token": "Jeton de vérification",
|
"verification_token": "Jeton de vérification",
|
||||||
@ -524,21 +490,6 @@
|
|||||||
"show_location": "Activer le partage de géolocalisation",
|
"show_location": "Activer le partage de géolocalisation",
|
||||||
"allowed_upload_size": "Taille maximale de téléchargement (en octets)",
|
"allowed_upload_size": "Taille maximale de téléchargement (en octets)",
|
||||||
"allowed_upload_types": "Types MIME autorisés pour le téléchargement (séparés par des virgules)",
|
"allowed_upload_types": "Types MIME autorisés pour le téléchargement (séparés par des virgules)",
|
||||||
"tw_consumer_key": "Clé de consommation",
|
|
||||||
"tw_consumer_secret": "Mot de pase de consommation",
|
|
||||||
"tw_access_token": "Jeton d'accès",
|
|
||||||
"tw_access_token_secret": "Mot de passe du Jeton d'accès",
|
|
||||||
"tw_greeting_text": "Text de bienvenue",
|
|
||||||
"d_api_url": "URL de l’API",
|
|
||||||
"d_access_token": "Jeton d’accès API",
|
|
||||||
"d_verify_token": "Jeton de vérification API",
|
|
||||||
"d_attachment_fallback_id": "ID Piéce jointe alternative",
|
|
||||||
"d_url_fallback": "URL alternative",
|
|
||||||
"d_supported_domain_id": "ID du domain supporté",
|
|
||||||
"d_agent_category_id": "IDs des catégories en cas de prise en charge par l’agent",
|
|
||||||
"d_admin_user": "Lors de la prise en charge par l’agent, assigner à (ID de l’administrateur)",
|
|
||||||
"d_test_identities": "IDs d'identités utilisées pour les tests",
|
|
||||||
"d_supported_sources": "Sources supportées",
|
|
||||||
"channel": "Canal",
|
"channel": "Canal",
|
||||||
"entry": "Contenu de l'entrée",
|
"entry": "Contenu de l'entrée",
|
||||||
"thumbnail": "Aperçu",
|
"thumbnail": "Aperçu",
|
||||||
@ -673,11 +624,7 @@
|
|||||||
"composer_input_disabled": "Cela signifie que votre robot ne peut interagir qu'avec le menu persistant, les valeurs de retours, les boutons et les Webviews.",
|
"composer_input_disabled": "Cela signifie que votre robot ne peut interagir qu'avec le menu persistant, les valeurs de retours, les boutons et les Webviews.",
|
||||||
"get_started_button": "L'écran de bienvenue d'un chatbot peut afficher un bouton `Démarrer`. Lorsque ce bouton est appuyé, la plate-forme Messenger envoie un événement à votre webhook (Payload = `Démarrer`).",
|
"get_started_button": "L'écran de bienvenue d'un chatbot peut afficher un bouton `Démarrer`. Lorsque ce bouton est appuyé, la plate-forme Messenger envoie un événement à votre webhook (Payload = `Démarrer`).",
|
||||||
"greeting_text": "Le texte de bienvenue de votre chatbot vous permet de spécifier le message d'accueil que les utilisateurs verront sur l'écran d'accueil de votre chatbot. L'écran de bienvenue s'affiche pour les personnes qui interagissent avec votre chatbot pour la première fois.",
|
"greeting_text": "Le texte de bienvenue de votre chatbot vous permet de spécifier le message d'accueil que les utilisateurs verront sur l'écran d'accueil de votre chatbot. L'écran de bienvenue s'affiche pour les personnes qui interagissent avec votre chatbot pour la première fois.",
|
||||||
"global_fallback": "Le message de secours global vous permet d'envoyer des messages personnalisés lorsque le message de l'utilisateur ne déclenche aucun bloc de message.",
|
|
||||||
"fallback_message": "Si aucun bloc de secours n'est spécifié, alors de ces messages sera envoyé.",
|
"fallback_message": "Si aucun bloc de secours n'est spécifié, alors de ces messages sera envoyé.",
|
||||||
"endpoint": "URL vers laquelle les requêtes de NLU HTTP sont envoyées et qui dépend du fournisseur.",
|
|
||||||
"token": "Chaque requête vers l'API doit contenir un jeton d'authentification.",
|
|
||||||
"threshold": "Seuil en dessus duquel le chatbot va utiliser sa prediction (min=0 & max=1)",
|
|
||||||
"app_id": "Obligatoire seulement si vous comptez utiliser Facebook Analytics",
|
"app_id": "Obligatoire seulement si vous comptez utiliser Facebook Analytics",
|
||||||
"page_id": "Obligatoire seulement si vous comptez utiliser Facebook Analytics",
|
"page_id": "Obligatoire seulement si vous comptez utiliser Facebook Analytics",
|
||||||
"nlp_train": "Vous pouvez entraîner votre chatbot en ajoutant plusieurs exemples",
|
"nlp_train": "Vous pouvez entraîner votre chatbot en ajoutant plusieurs exemples",
|
@ -13,8 +13,8 @@ import {
|
|||||||
DialogProps,
|
DialogProps,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { useEffect, FC } from "react";
|
import { FC, useEffect } from "react";
|
||||||
import { useForm, Controller } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
|
|
||||||
import DialogButtons from "@/app-components/buttons/DialogButtons";
|
import DialogButtons from "@/app-components/buttons/DialogButtons";
|
||||||
import { DialogTitle } from "@/app-components/dialogs/DialogTitle";
|
import { DialogTitle } from "@/app-components/dialogs/DialogTitle";
|
||||||
@ -23,7 +23,6 @@ import { ContentItem } from "@/app-components/dialogs/layouts/ContentItem";
|
|||||||
import { Input } from "@/app-components/inputs/Input";
|
import { Input } from "@/app-components/inputs/Input";
|
||||||
import { ToggleableInput } from "@/app-components/inputs/ToggleableInput";
|
import { ToggleableInput } from "@/app-components/inputs/ToggleableInput";
|
||||||
import { useTranslate } from "@/hooks/useTranslate";
|
import { useTranslate } from "@/hooks/useTranslate";
|
||||||
import { TNestedTranslation } from "@/i18n/i18n.types";
|
|
||||||
import { IMenuItem, IMenuItemAttributes, MenuType } from "@/types/menu.types";
|
import { IMenuItem, IMenuItemAttributes, MenuType } from "@/types/menu.types";
|
||||||
import { isAbsoluteUrl } from "@/utils/URL";
|
import { isAbsoluteUrl } from "@/utils/URL";
|
||||||
|
|
||||||
@ -124,11 +123,9 @@ export const MenuDialog: FC<MenuDialogProps> = ({
|
|||||||
helperText={errors.type ? errors.type.message : null}
|
helperText={errors.type ? errors.type.message : null}
|
||||||
{...rest}
|
{...rest}
|
||||||
>
|
>
|
||||||
{(
|
{Object.keys(MenuType).map((value, key) => (
|
||||||
Object.keys(MenuType) as TNestedTranslation<"label">[]
|
|
||||||
).map((value, key) => (
|
|
||||||
<MenuItem value={value} key={key}>
|
<MenuItem value={value} key={key}>
|
||||||
{t("label", value)}
|
{t(`label.${value}`)}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))}
|
))}
|
||||||
</Input>
|
</Input>
|
||||||
|
@ -36,7 +36,6 @@ import { useUpdate } from "@/hooks/crud/useUpdate";
|
|||||||
import { DialogControlProps } from "@/hooks/useDialog";
|
import { DialogControlProps } from "@/hooks/useDialog";
|
||||||
import { useToast } from "@/hooks/useToast";
|
import { useToast } from "@/hooks/useToast";
|
||||||
import { useTranslate } from "@/hooks/useTranslate";
|
import { useTranslate } from "@/hooks/useTranslate";
|
||||||
import { TNestedTranslation } from "@/i18n/i18n.types";
|
|
||||||
import { EntityType } from "@/services/types";
|
import { EntityType } from "@/services/types";
|
||||||
import {
|
import {
|
||||||
ContentField,
|
ContentField,
|
||||||
@ -71,7 +70,7 @@ const ContentFieldInput: React.FC<ContentFieldInput> = ({
|
|||||||
<Input
|
<Input
|
||||||
multiline={contentField.type === ContentFieldType.TEXTAREA}
|
multiline={contentField.type === ContentFieldType.TEXTAREA}
|
||||||
rows={contentField.type === ContentFieldType.TEXTAREA ? 5 : 1}
|
rows={contentField.type === ContentFieldType.TEXTAREA ? 5 : 1}
|
||||||
label={t("label", contentField.name as TNestedTranslation<"label">, {
|
label={t(`label.${contentField.name}`, {
|
||||||
defaultValue: contentField.label,
|
defaultValue: contentField.label,
|
||||||
})}
|
})}
|
||||||
InputProps={
|
InputProps={
|
||||||
@ -93,7 +92,7 @@ const ContentFieldInput: React.FC<ContentFieldInput> = ({
|
|||||||
case ContentFieldType.CHECKBOX:
|
case ContentFieldType.CHECKBOX:
|
||||||
return (
|
return (
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
label={t("label", contentField.name as TNestedTranslation<"label">, {
|
label={t(`label.${contentField.name}`, {
|
||||||
defaultValue: contentField.label,
|
defaultValue: contentField.label,
|
||||||
})}
|
})}
|
||||||
{...field}
|
{...field}
|
||||||
@ -103,7 +102,7 @@ const ContentFieldInput: React.FC<ContentFieldInput> = ({
|
|||||||
case ContentFieldType.FILE:
|
case ContentFieldType.FILE:
|
||||||
return (
|
return (
|
||||||
<AttachmentInput
|
<AttachmentInput
|
||||||
label={t("label", contentField.name as TNestedTranslation<"label">, {
|
label={t(`label.${contentField.name}`, {
|
||||||
defaultValue: contentField.label,
|
defaultValue: contentField.label,
|
||||||
})}
|
})}
|
||||||
{...field}
|
{...field}
|
||||||
|
@ -44,7 +44,6 @@ import { useHasPermission } from "@/hooks/useHasPermission";
|
|||||||
import { useSearch } from "@/hooks/useSearch";
|
import { useSearch } from "@/hooks/useSearch";
|
||||||
import { useToast } from "@/hooks/useToast";
|
import { useToast } from "@/hooks/useToast";
|
||||||
import { useTranslate } from "@/hooks/useTranslate";
|
import { useTranslate } from "@/hooks/useTranslate";
|
||||||
import { TNestedTranslation } from "@/i18n/i18n.types";
|
|
||||||
import { EntityType, Format } from "@/services/types";
|
import { EntityType, Format } from "@/services/types";
|
||||||
import { ILanguage } from "@/types/language.types";
|
import { ILanguage } from "@/types/language.types";
|
||||||
import {
|
import {
|
||||||
@ -321,9 +320,7 @@ export default function NlpSample() {
|
|||||||
</IconButton>
|
</IconButton>
|
||||||
),
|
),
|
||||||
}),
|
}),
|
||||||
renderValue: (value) => (
|
renderValue: (value) => <Box>{t(`label.${value}`)}</Box>,
|
||||||
<Box>{t("label", value as TNestedTranslation<"label">)}</Box>
|
|
||||||
),
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{Object.values(NlpSampleType).map((nlpSampleType, index) => (
|
{Object.values(NlpSampleType).map((nlpSampleType, index) => (
|
||||||
|
@ -17,7 +17,6 @@ import { Input } from "@/app-components/inputs/Input";
|
|||||||
import MultipleInput from "@/app-components/inputs/MultipleInput";
|
import MultipleInput from "@/app-components/inputs/MultipleInput";
|
||||||
import { PasswordInput } from "@/app-components/inputs/PasswordInput";
|
import { PasswordInput } from "@/app-components/inputs/PasswordInput";
|
||||||
import { useTranslate } from "@/hooks/useTranslate";
|
import { useTranslate } from "@/hooks/useTranslate";
|
||||||
import { TNestedTranslation } from "@/i18n/i18n.types";
|
|
||||||
import { EntityType, Format } from "@/services/types";
|
import { EntityType, Format } from "@/services/types";
|
||||||
import { IBlock } from "@/types/block.types";
|
import { IBlock } from "@/types/block.types";
|
||||||
import { ISetting } from "@/types/setting.types";
|
import { ISetting } from "@/types/setting.types";
|
||||||
@ -34,13 +33,13 @@ const SettingInput: React.FC<RenderSettingInputProps> = ({
|
|||||||
field,
|
field,
|
||||||
isDisabled = () => false,
|
isDisabled = () => false,
|
||||||
}) => {
|
}) => {
|
||||||
const { t } = useTranslate();
|
const { t } = useTranslate(setting.group);
|
||||||
const nestedLabel = setting.label as TNestedTranslation<"label">;
|
const label = t(`label.${setting.label}`, {
|
||||||
const nestedHelp = setting.help as TNestedTranslation<"help">;
|
defaultValue: setting.label,
|
||||||
const label = t("label", nestedLabel, { defaultValue: nestedLabel });
|
});
|
||||||
const helperText = nestedHelp
|
const helperText = t(`help.${setting.label}`, {
|
||||||
? t("help", nestedHelp, { defaultValue: nestedHelp })
|
defaultValue: "",
|
||||||
: "";
|
});
|
||||||
|
|
||||||
switch (setting.type) {
|
switch (setting.type) {
|
||||||
case "text":
|
case "text":
|
||||||
|
@ -24,7 +24,6 @@ import { useFind } from "@/hooks/crud/useFind";
|
|||||||
import { useUpdate } from "@/hooks/crud/useUpdate";
|
import { useUpdate } from "@/hooks/crud/useUpdate";
|
||||||
import { useToast } from "@/hooks/useToast";
|
import { useToast } from "@/hooks/useToast";
|
||||||
import { useTranslate } from "@/hooks/useTranslate";
|
import { useTranslate } from "@/hooks/useTranslate";
|
||||||
import { TNestedTranslation } from "@/i18n/i18n.types";
|
|
||||||
import { PageHeader } from "@/layout/content/PageHeader";
|
import { PageHeader } from "@/layout/content/PageHeader";
|
||||||
import { EntityType } from "@/services/types";
|
import { EntityType } from "@/services/types";
|
||||||
import { ISetting } from "@/types/setting.types";
|
import { ISetting } from "@/types/setting.types";
|
||||||
@ -70,13 +69,13 @@ function groupBy(array: ISetting[]) {
|
|||||||
export const Settings = () => {
|
export const Settings = () => {
|
||||||
const { t } = useTranslate();
|
const { t } = useTranslate();
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const [selectedTab, setSelectedTab] = useState("live-chat-tester");
|
const [selectedTab, setSelectedTab] = useState("chatbot_settings");
|
||||||
const { control, watch } = useForm();
|
const { control, watch } = useForm();
|
||||||
const { data: settings } = useFind(
|
const { data: settings } = useFind(
|
||||||
{ entity: EntityType.SETTING },
|
{ entity: EntityType.SETTING },
|
||||||
{
|
{
|
||||||
hasCount: false,
|
hasCount: false,
|
||||||
initialSortState: [{ field: "weight", sort: "desc" }],
|
initialSortState: [{ field: "weight", sort: "asc" }],
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const { mutateAsync: updateSetting } = useUpdate(EntityType.SETTING, {
|
const { mutateAsync: updateSetting } = useUpdate(EntityType.SETTING, {
|
||||||
@ -157,16 +156,16 @@ export const Settings = () => {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{(Object.keys(groups) as TNestedTranslation<"title">[]).map(
|
{Object.keys(groups)
|
||||||
(group, index) => (
|
.sort((a, b) => a.localeCompare(b))
|
||||||
|
.map((group, index) => (
|
||||||
<StyledTab
|
<StyledTab
|
||||||
value={group}
|
value={group}
|
||||||
key={group}
|
key={group}
|
||||||
label={t("title", group)}
|
label={t(`title.${group}`, { ns: group })}
|
||||||
{...a11yProps(index)}
|
{...a11yProps(index)}
|
||||||
/>
|
/>
|
||||||
),
|
))}
|
||||||
)}
|
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<StyledForm sx={{ width: "100%", px: 3, paddingY: 2 }}>
|
<StyledForm sx={{ width: "100%", px: 3, paddingY: 2 }}>
|
||||||
{Object.entries(groups).map(([group, settings]) => (
|
{Object.entries(groups).map(([group, settings]) => (
|
||||||
|
@ -25,7 +25,6 @@ import ButtonsIcon from "@/app-components/svg/toolbar/ButtonsIcon";
|
|||||||
import ListIcon from "@/app-components/svg/toolbar/ListIcon";
|
import ListIcon from "@/app-components/svg/toolbar/ListIcon";
|
||||||
import { useGet } from "@/hooks/crud/useGet";
|
import { useGet } from "@/hooks/crud/useGet";
|
||||||
import { useTranslate } from "@/hooks/useTranslate";
|
import { useTranslate } from "@/hooks/useTranslate";
|
||||||
import { TNestedTranslation } from "@/i18n/i18n.types";
|
|
||||||
import { EntityType, Format } from "@/services/types";
|
import { EntityType, Format } from "@/services/types";
|
||||||
import {
|
import {
|
||||||
ContentField,
|
ContentField,
|
||||||
@ -68,12 +67,10 @@ const ListMessageForm = () => {
|
|||||||
name="options.content.display_mode"
|
name="options.content.display_mode"
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<RadioGroup row {...field}>
|
<RadioGroup row {...field}>
|
||||||
{(
|
{[
|
||||||
[
|
OutgoingMessageFormat.list,
|
||||||
OutgoingMessageFormat.list,
|
OutgoingMessageFormat.carousel,
|
||||||
OutgoingMessageFormat.carousel,
|
].map((display) => (
|
||||||
] as TNestedTranslation<"label">[]
|
|
||||||
).map((display) => (
|
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
key={display}
|
key={display}
|
||||||
value={display}
|
value={display}
|
||||||
@ -83,7 +80,7 @@ const ListMessageForm = () => {
|
|||||||
{...register("options.content.display")}
|
{...register("options.content.display")}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
label={t("label", display)}
|
label={t(`label.${display}`)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
@ -106,7 +103,7 @@ const ListMessageForm = () => {
|
|||||||
key={style}
|
key={style}
|
||||||
value={style}
|
value={style}
|
||||||
control={<Radio />}
|
control={<Radio />}
|
||||||
label={t("label", style)}
|
label={t(`label.${style}`)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
@ -53,11 +53,11 @@ const PluginMessageForm = () => {
|
|||||||
sx={{ display: "none" }}
|
sx={{ display: "none" }}
|
||||||
/>
|
/>
|
||||||
{(settings || []).map((setting) => (
|
{(settings || []).map((setting) => (
|
||||||
<ContentItem key={setting.id}>
|
<ContentItem key={setting.label}>
|
||||||
<Controller
|
<Controller
|
||||||
name={`message.args.${setting.id}`}
|
name={`message.args.${setting.label}`}
|
||||||
control={control}
|
control={control}
|
||||||
defaultValue={message.args?.[setting.id] || setting.value}
|
defaultValue={message.args?.[setting.label] || setting.value}
|
||||||
render={({ field }) => (
|
render={({ field }) => (
|
||||||
<FormControl fullWidth sx={{ paddingTop: ".75rem" }}>
|
<FormControl fullWidth sx={{ paddingTop: ".75rem" }}>
|
||||||
<SettingInput setting={setting} field={field} />
|
<SettingInput setting={setting} field={field} />
|
||||||
|
@ -19,7 +19,6 @@ import {
|
|||||||
|
|
||||||
import { useFind } from "@/hooks/crud/useFind";
|
import { useFind } from "@/hooks/crud/useFind";
|
||||||
import { useTranslate } from "@/hooks/useTranslate";
|
import { useTranslate } from "@/hooks/useTranslate";
|
||||||
import { TNestedTranslation } from "@/i18n/i18n.types";
|
|
||||||
import { EntityType } from "@/services/types";
|
import { EntityType } from "@/services/types";
|
||||||
|
|
||||||
function ReplacementTokens() {
|
function ReplacementTokens() {
|
||||||
@ -94,13 +93,17 @@ function ReplacementTokens() {
|
|||||||
</ListItem>
|
</ListItem>
|
||||||
))}
|
))}
|
||||||
</List>
|
</List>
|
||||||
<Typography variant="h6">{t("title.contact_infos")}</Typography>
|
<Typography variant="h6">
|
||||||
|
{t("title.contact", { ns: "contact" })}
|
||||||
|
</Typography>
|
||||||
<List>
|
<List>
|
||||||
{(contactInfos || []).map((v, index) => (
|
{(contactInfos || []).map((v, index) => (
|
||||||
<ListItem key={index}>
|
<ListItem key={index}>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
primary={`{contact.${v.label}}`}
|
primary={`{contact.${v.label}}`}
|
||||||
secondary={t("label", v.label as TNestedTranslation<"label">)}
|
secondary={t(`label.${v.label}`, {
|
||||||
|
ns: "contact",
|
||||||
|
})}
|
||||||
/>
|
/>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
))}
|
))}
|
||||||
|
@ -9,13 +9,13 @@
|
|||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
TOptionsBaseExtended,
|
||||||
TTranslateProps,
|
TTranslateProps,
|
||||||
TTranslationKeys,
|
TTranslationKeys,
|
||||||
TOptionsBaseExtended,
|
|
||||||
} from "@/i18n/i18n.types";
|
} from "@/i18n/i18n.types";
|
||||||
|
|
||||||
export const useTranslate = () => {
|
export const useTranslate = (ns?: string) => {
|
||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation(ns);
|
||||||
const translate: TTranslateProps = (
|
const translate: TTranslateProps = (
|
||||||
prop1: unknown,
|
prop1: unknown,
|
||||||
prop2?: unknown,
|
prop2?: unknown,
|
||||||
|
@ -8,36 +8,40 @@
|
|||||||
|
|
||||||
// Core i18next library.
|
// Core i18next library.
|
||||||
import i18n from "i18next";
|
import i18n from "i18next";
|
||||||
|
import Backend from "i18next-http-backend";
|
||||||
// Bindings for React: allow components to
|
// Bindings for React: allow components to
|
||||||
// re-render when language changes.
|
// re-render when language changes.
|
||||||
import getConfig from "next/config";
|
import getConfig from "next/config";
|
||||||
import { initReactI18next } from "react-i18next";
|
import { initReactI18next } from "react-i18next";
|
||||||
|
|
||||||
import enTranslations from "./en/translation.json";
|
|
||||||
import frTranslations from "./fr/translation.json";
|
|
||||||
|
|
||||||
const { publicRuntimeConfig } = getConfig();
|
const { publicRuntimeConfig } = getConfig();
|
||||||
|
|
||||||
i18n.use(initReactI18next).init({
|
i18n
|
||||||
lng: publicRuntimeConfig.lang.default,
|
.use(initReactI18next)
|
||||||
fallbackLng: "en",
|
.use(Backend)
|
||||||
debug: true,
|
.init({
|
||||||
resources: {
|
lng: publicRuntimeConfig.lang.default,
|
||||||
en: {
|
fallbackLng: "en",
|
||||||
translation: enTranslations,
|
debug: process.env.NODE_ENV === "development",
|
||||||
|
backend: {
|
||||||
|
loadPath: "/locales/{{lng}}/{{ns}}.json",
|
||||||
},
|
},
|
||||||
fr: {
|
ns: [
|
||||||
translation: frTranslations,
|
"translation",
|
||||||
|
"chatbot_settings.json",
|
||||||
|
"contact",
|
||||||
|
"nlp_settings",
|
||||||
|
"offline",
|
||||||
|
"live-chat-tester",
|
||||||
|
],
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false,
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
interpolation: {
|
|
||||||
escapeValue: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
i18n.services.formatter?.add("dateFormat", (value, lng, options) =>
|
i18n.services.formatter?.add("dateFormat", (value, lng, options) =>
|
||||||
new Intl.DateTimeFormat(lng, options?.formatParams?.val).format(
|
new Intl.DateTimeFormat(lng, options?.formatParams?.val).format(
|
||||||
new Date(options?.date || value),
|
new Date(options?.date || value),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
export default i18n;
|
export default i18n;
|
@ -8,16 +8,27 @@ import { TOptionsBase } from "i18next";
|
|||||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { translations } from ".";
|
|
||||||
|
|
||||||
import { TFilterNestedKeysOfType } from "@/types/common/object.types";
|
import { TFilterNestedKeysOfType } from "@/types/common/object.types";
|
||||||
|
|
||||||
type TEnTranslation = (typeof translations)["en"];
|
export type TTranslation = string;
|
||||||
type TFrTranslation = (typeof translations)["fr"];
|
|
||||||
|
|
||||||
export type TTranslation = TEnTranslation & TFrTranslation;
|
export type TTranslationPrefix =
|
||||||
export type TTranslationKeys = TFilterNestedKeysOfType<TEnTranslation> &
|
| "message"
|
||||||
TFilterNestedKeysOfType<TFrTranslation>;
|
| "menu"
|
||||||
|
| "title"
|
||||||
|
| "label"
|
||||||
|
| "placeholder"
|
||||||
|
| "button"
|
||||||
|
| "input"
|
||||||
|
| "link"
|
||||||
|
| "help"
|
||||||
|
| "charts"
|
||||||
|
| "datetime"
|
||||||
|
| "visual_editor";
|
||||||
|
|
||||||
|
export type TTranslationKeys =
|
||||||
|
| `${TTranslationPrefix}`
|
||||||
|
| `${TTranslationPrefix}.${TTranslation}`;
|
||||||
|
|
||||||
export type TNestedTranslation<T extends keyof TTranslation> =
|
export type TNestedTranslation<T extends keyof TTranslation> =
|
||||||
TFilterNestedKeysOfType<TTranslation[T]>;
|
TFilterNestedKeysOfType<TTranslation[T]>;
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2024 Hexastack. All rights reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
|
||||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
|
||||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
|
||||||
*/
|
|
||||||
|
|
||||||
import en from "@/i18n/en/translation.json";
|
|
||||||
import fr from "@/i18n/fr/translation.json";
|
|
||||||
|
|
||||||
export const translations = { en, fr } as const;
|
|
@ -276,7 +276,7 @@ export const CustomBlockSettingEntity = new schema.Entity(
|
|||||||
EntityType.CUSTOM_BLOCK_SETTINGS,
|
EntityType.CUSTOM_BLOCK_SETTINGS,
|
||||||
undefined,
|
undefined,
|
||||||
{
|
{
|
||||||
idAttribute: ({ id }) => id,
|
idAttribute: ({ id, label }) => id || label,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -92,8 +92,6 @@ export interface ISettingAttributes {
|
|||||||
options?: string[];
|
options?: string[];
|
||||||
config?: Record<string, any>;
|
config?: Record<string, any>;
|
||||||
weight?: number;
|
weight?: number;
|
||||||
title?: string;
|
|
||||||
help?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISettingStub extends IBaseSchema, ISettingAttributes {}
|
export interface ISettingStub extends IBaseSchema, ISettingAttributes {}
|
||||||
|
55
package-lock.json
generated
55
package-lock.json
generated
@ -64,6 +64,7 @@
|
|||||||
"eazychart-css": "^0.2.1-alpha.0",
|
"eazychart-css": "^0.2.1-alpha.0",
|
||||||
"eazychart-react": "^0.8.0-alpha.0",
|
"eazychart-react": "^0.8.0-alpha.0",
|
||||||
"hexabot-chat-widget": "*",
|
"hexabot-chat-widget": "*",
|
||||||
|
"i18next-http-backend": "^2.6.2",
|
||||||
"next": "^14.2.13",
|
"next": "^14.2.13",
|
||||||
"next-transpile-modules": "^10.0.1",
|
"next-transpile-modules": "^10.0.1",
|
||||||
"normalizr": "^3.6.2",
|
"normalizr": "^3.6.2",
|
||||||
@ -4167,6 +4168,14 @@
|
|||||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-fetch": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
|
||||||
|
"dependencies": {
|
||||||
|
"node-fetch": "^2.6.12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
@ -6440,6 +6449,14 @@
|
|||||||
"@babel/runtime": "^7.23.2"
|
"@babel/runtime": "^7.23.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/i18next-http-backend": {
|
||||||
|
"version": "2.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-2.6.2.tgz",
|
||||||
|
"integrity": "sha512-Hp/kd8/VuoxIHmxsknJXjkTYYHzivAyAF15pzliKzk2TiXC25rZCEerb1pUFoxz4IVrG3fCvQSY51/Lu4ECV4A==",
|
||||||
|
"dependencies": {
|
||||||
|
"cross-fetch": "4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ignore": {
|
"node_modules/ignore": {
|
||||||
"version": "5.3.2",
|
"version": "5.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||||
@ -7633,6 +7650,25 @@
|
|||||||
"enhanced-resolve": "^5.10.0"
|
"enhanced-resolve": "^5.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/node-fetch": {
|
||||||
|
"version": "2.7.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
|
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.18",
|
"version": "2.0.18",
|
||||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
|
||||||
@ -9173,6 +9209,11 @@
|
|||||||
"node": ">=8.0"
|
"node": ">=8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/tr46": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||||
|
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||||
|
},
|
||||||
"node_modules/ts-api-utils": {
|
"node_modules/ts-api-utils": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
|
||||||
@ -9665,6 +9706,20 @@
|
|||||||
"vscode-uri": "^3.0.8"
|
"vscode-uri": "^3.0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/webidl-conversions": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||||
|
},
|
||||||
|
"node_modules/whatwg-url": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||||
|
"dependencies": {
|
||||||
|
"tr46": "~0.0.3",
|
||||||
|
"webidl-conversions": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/which": {
|
"node_modules/which": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||||
|
Loading…
Reference in New Issue
Block a user