Browse Source

UI to update about information.

pull/1016/head
Sebastian 3 years ago
parent
commit
23fd8c91c1
  1. 6
      backend/i18n/frontend_en.json
  2. 6
      backend/i18n/frontend_fr.json
  3. 6
      backend/i18n/frontend_it.json
  4. 6
      backend/i18n/frontend_nl.json
  5. 6
      backend/i18n/frontend_pt.json
  6. 6
      backend/i18n/frontend_zh.json
  7. 25
      backend/i18n/source/backend_en.json
  8. 6
      backend/i18n/source/frontend_en.json
  9. 2
      backend/src/Squidex.Domain.Users/UserValues.cs
  10. 15
      backend/src/Squidex.Shared/Identity/SquidexClaimsExtensions.cs
  11. 69
      backend/src/Squidex.Shared/Texts.fr.resx
  12. 69
      backend/src/Squidex.Shared/Texts.it.resx
  13. 69
      backend/src/Squidex.Shared/Texts.nl.resx
  14. 69
      backend/src/Squidex.Shared/Texts.pt.resx
  15. 71
      backend/src/Squidex.Shared/Texts.resx
  16. 69
      backend/src/Squidex.Shared/Texts.zh.resx
  17. 2
      backend/src/Squidex/Areas/Api/Controllers/Users/Models/UpdateProfileDto.cs
  18. 32
      backend/src/Squidex/Areas/IdentityServer/Controllers/Profile/ChangeAboutModel.cs
  19. 14
      backend/src/Squidex/Areas/IdentityServer/Controllers/Profile/ProfileController.cs
  20. 8
      backend/src/Squidex/Areas/IdentityServer/Controllers/Profile/ProfileVM.cs
  21. 68
      backend/src/Squidex/Areas/IdentityServer/Views/Profile/Profile.cshtml
  22. 2
      backend/src/Squidex/Config/MyIdentityOptions.cs
  23. 14
      backend/src/Squidex/Startup.cs
  24. 4
      frontend/src/app/features/apps/pages/onboarding-dialog.component.html

6
backend/i18n/frontend_en.json

@ -1069,8 +1069,8 @@
"tour.projectCommerce": "E-Commerce Solution", "tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning", "tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App", "tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "", "tour.projectNewsMagazine": "News Magazine",
"tour.projectPersonalBlog": "News Magazine", "tour.projectPersonalBlog": "Personal Blog",
"tour.projectSmallBusiness": "Website for Small Business", "tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst", "tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner", "tour.roleBusinessOwner": "Business Owner",
@ -1090,10 +1090,10 @@
"tour.stepAssetsText": "The assets contains all files that can also be linked to your content. For example images, videos or documents.\n\nYou can upload the assets here and use them later or also upload them directly when you create a new content item with an asset field.", "tour.stepAssetsText": "The assets contains all files that can also be linked to your content. For example images, videos or documents.\n\nYou can upload the assets here and use them later or also upload them directly when you create a new content item with an asset field.",
"tour.stepContentNext": "Almost there!", "tour.stepContentNext": "Almost there!",
"tour.stepContentText": "Content is the actual data in your app which is grouped by the schema.\n\nSelect a published schema first, then add content for this schema.", "tour.stepContentText": "Content is the actual data in your app which is grouped by the schema.\n\nSelect a published schema first, then add content for this schema.",
"tour.stepDataCompanyRole": "What is your role?",
"tour.stepDataCompanySize": "How many people work in a company?", "tour.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue", "tour.stepDataNext": "Continue",
"tour.stepDataProject": "What kind of project do you realize?", "tour.stepDataProject": "What kind of project do you realize?",
"tour.stepDataRole": "What is your role?",
"tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.", "tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.",
"tour.stepDataTitle": "About You", "tour.stepDataTitle": "About You",
"tour.stepIntroNext": "Let's take a look around", "tour.stepIntroNext": "Let's take a look around",

6
backend/i18n/frontend_fr.json

@ -1069,8 +1069,8 @@
"tour.projectCommerce": "E-Commerce Solution", "tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning", "tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App", "tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "", "tour.projectNewsMagazine": "News Magazine",
"tour.projectPersonalBlog": "News Magazine", "tour.projectPersonalBlog": "Personal Blog",
"tour.projectSmallBusiness": "Website for Small Business", "tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst", "tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner", "tour.roleBusinessOwner": "Business Owner",
@ -1090,10 +1090,10 @@
"tour.stepAssetsText": "Les actifs contiennent tous les fichiers qui peuvent également être liés à votre contenu. Par exemple des images, des vidéos ou des documents. Vous pouvez télécharger les actifs ici et les utiliser plus tard ou également les télécharger directement lorsque vous créez un nouvel élément de contenu avec un champ d'actif.", "tour.stepAssetsText": "Les actifs contiennent tous les fichiers qui peuvent également être liés à votre contenu. Par exemple des images, des vidéos ou des documents. Vous pouvez télécharger les actifs ici et les utiliser plus tard ou également les télécharger directement lorsque vous créez un nouvel élément de contenu avec un champ d'actif.",
"tour.stepContentNext": "Presque là!", "tour.stepContentNext": "Presque là!",
"tour.stepContentText": "Le contenu est les données réelles de votre application qui sont regroupées par le schéma. Sélectionnez d'abord un schéma publié, puis ajoutez du contenu pour ce schéma.", "tour.stepContentText": "Le contenu est les données réelles de votre application qui sont regroupées par le schéma. Sélectionnez d'abord un schéma publié, puis ajoutez du contenu pour ce schéma.",
"tour.stepDataCompanyRole": "What is your role?",
"tour.stepDataCompanySize": "How many people work in a company?", "tour.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue", "tour.stepDataNext": "Continue",
"tour.stepDataProject": "What kind of project do you realize?", "tour.stepDataProject": "What kind of project do you realize?",
"tour.stepDataRole": "What is your role?",
"tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.", "tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.",
"tour.stepDataTitle": "About You", "tour.stepDataTitle": "About You",
"tour.stepIntroNext": "Jetons un coup d'œil autour", "tour.stepIntroNext": "Jetons un coup d'œil autour",

6
backend/i18n/frontend_it.json

@ -1069,8 +1069,8 @@
"tour.projectCommerce": "E-Commerce Solution", "tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning", "tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App", "tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "", "tour.projectNewsMagazine": "News Magazine",
"tour.projectPersonalBlog": "News Magazine", "tour.projectPersonalBlog": "Personal Blog",
"tour.projectSmallBusiness": "Website for Small Business", "tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst", "tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner", "tour.roleBusinessOwner": "Business Owner",
@ -1090,10 +1090,10 @@
"tour.stepAssetsText": "Le risorse contengono tutti i file che tu puoi collegare ai tuoi contenuti. Per esempio immagini, video o documenti.\n\nPuoi caricare qui le risorse e usarle successivamente oppure caricarle direttamente quando stai creando un contenuto utilizzando un campo risorse.", "tour.stepAssetsText": "Le risorse contengono tutti i file che tu puoi collegare ai tuoi contenuti. Per esempio immagini, video o documenti.\n\nPuoi caricare qui le risorse e usarle successivamente oppure caricarle direttamente quando stai creando un contenuto utilizzando un campo risorse.",
"tour.stepContentNext": "Ci siamo quasi!", "tour.stepContentNext": "Ci siamo quasi!",
"tour.stepContentText": "I contenuti della tua app sono raggruppati tramite gli schemi.\n\nSeleziona uno schema pubblicato e poi crea il relativo contenuto.", "tour.stepContentText": "I contenuti della tua app sono raggruppati tramite gli schemi.\n\nSeleziona uno schema pubblicato e poi crea il relativo contenuto.",
"tour.stepDataCompanyRole": "What is your role?",
"tour.stepDataCompanySize": "How many people work in a company?", "tour.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue", "tour.stepDataNext": "Continue",
"tour.stepDataProject": "What kind of project do you realize?", "tour.stepDataProject": "What kind of project do you realize?",
"tour.stepDataRole": "What is your role?",
"tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.", "tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.",
"tour.stepDataTitle": "About You", "tour.stepDataTitle": "About You",
"tour.stepIntroNext": "Guardiamoci intorno", "tour.stepIntroNext": "Guardiamoci intorno",

6
backend/i18n/frontend_nl.json

@ -1069,8 +1069,8 @@
"tour.projectCommerce": "E-Commerce Solution", "tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning", "tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App", "tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "", "tour.projectNewsMagazine": "News Magazine",
"tour.projectPersonalBlog": "News Magazine", "tour.projectPersonalBlog": "Personal Blog",
"tour.projectSmallBusiness": "Website for Small Business", "tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst", "tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner", "tour.roleBusinessOwner": "Business Owner",
@ -1090,10 +1090,10 @@
"tour.stepAssetsText": "De mappen bevatten alle bestanden die ook aan uw inhoud kunnen worden gekoppeld. Bijvoorbeeld afbeeldingen, video's of documenten. \n \n Je kunt de bestanden hier uploaden en later gebruiken of ze direct uploaden wanneer je een nieuw contentitem met een bestandveld maakt. ", "tour.stepAssetsText": "De mappen bevatten alle bestanden die ook aan uw inhoud kunnen worden gekoppeld. Bijvoorbeeld afbeeldingen, video's of documenten. \n \n Je kunt de bestanden hier uploaden en later gebruiken of ze direct uploaden wanneer je een nieuw contentitem met een bestandveld maakt. ",
"tour.stepContentNext": "Bijna klaar!", "tour.stepContentNext": "Bijna klaar!",
"tour.stepContentText": "Inhoud zijn de feitelijke gegevens in uw app die zijn gegroepeerd op basis van het schema. \n \n Selecteer eerst een gepubliceerd schema en voeg vervolgens inhoud toe voor dit schema.", "tour.stepContentText": "Inhoud zijn de feitelijke gegevens in uw app die zijn gegroepeerd op basis van het schema. \n \n Selecteer eerst een gepubliceerd schema en voeg vervolgens inhoud toe voor dit schema.",
"tour.stepDataCompanyRole": "What is your role?",
"tour.stepDataCompanySize": "How many people work in a company?", "tour.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue", "tour.stepDataNext": "Continue",
"tour.stepDataProject": "What kind of project do you realize?", "tour.stepDataProject": "What kind of project do you realize?",
"tour.stepDataRole": "What is your role?",
"tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.", "tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.",
"tour.stepDataTitle": "About You", "tour.stepDataTitle": "About You",
"tour.stepIntroNext": "Laten we eens rondkijken", "tour.stepIntroNext": "Laten we eens rondkijken",

6
backend/i18n/frontend_pt.json

@ -1069,8 +1069,8 @@
"tour.projectCommerce": "E-Commerce Solution", "tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning", "tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App", "tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "", "tour.projectNewsMagazine": "News Magazine",
"tour.projectPersonalBlog": "News Magazine", "tour.projectPersonalBlog": "Personal Blog",
"tour.projectSmallBusiness": "Website for Small Business", "tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst", "tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner", "tour.roleBusinessOwner": "Business Owner",
@ -1090,10 +1090,10 @@
"tour.stepAssetsText": "Os ativos contêm todos os ficheiros que também podem estar ligados ao seu conteúdo. Por exemplo, imagens, vídeos ou documentos.\n\nPode fazer o upload dos ativos aqui e usá-los mais tarde ou também carregá-los diretamente quando criar um novo item de conteúdo com um campo de ativos.", "tour.stepAssetsText": "Os ativos contêm todos os ficheiros que também podem estar ligados ao seu conteúdo. Por exemplo, imagens, vídeos ou documentos.\n\nPode fazer o upload dos ativos aqui e usá-los mais tarde ou também carregá-los diretamente quando criar um novo item de conteúdo com um campo de ativos.",
"tour.stepContentNext": "Está quase!", "tour.stepContentNext": "Está quase!",
"tour.stepContentText": "O conteúdo é o dado real da sua app que é agrupado pelo esquema.\n\nSelecione primeiro um esquema publicado e, em seguida, adicione conteúdo para este esquema.", "tour.stepContentText": "O conteúdo é o dado real da sua app que é agrupado pelo esquema.\n\nSelecione primeiro um esquema publicado e, em seguida, adicione conteúdo para este esquema.",
"tour.stepDataCompanyRole": "What is your role?",
"tour.stepDataCompanySize": "How many people work in a company?", "tour.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue", "tour.stepDataNext": "Continue",
"tour.stepDataProject": "What kind of project do you realize?", "tour.stepDataProject": "What kind of project do you realize?",
"tour.stepDataRole": "What is your role?",
"tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.", "tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.",
"tour.stepDataTitle": "About You", "tour.stepDataTitle": "About You",
"tour.stepIntroNext": "Vamos dar uma vista de olhos.", "tour.stepIntroNext": "Vamos dar uma vista de olhos.",

6
backend/i18n/frontend_zh.json

@ -1069,8 +1069,8 @@
"tour.projectCommerce": "E-Commerce Solution", "tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning", "tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App", "tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "", "tour.projectNewsMagazine": "News Magazine",
"tour.projectPersonalBlog": "News Magazine", "tour.projectPersonalBlog": "Personal Blog",
"tour.projectSmallBusiness": "Website for Small Business", "tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst", "tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner", "tour.roleBusinessOwner": "Business Owner",
@ -1090,10 +1090,10 @@
"tour.stepAssetsText": "资源包含所有也可以链接到您的内容的文件。例如图像、视频或文档。\n\n您可以在此处上传资源供以后使用,也可以在创建时直接上传带有资源字段的新内容项。", "tour.stepAssetsText": "资源包含所有也可以链接到您的内容的文件。例如图像、视频或文档。\n\n您可以在此处上传资源供以后使用,也可以在创建时直接上传带有资源字段的新内容项。",
"tour.stepContentNext": "快到了!", "tour.stepContentNext": "快到了!",
"tour.stepContentText": "内容是您的应用程序中按Schemas分组的实际数据。\n\n首先选择一个已发布的Schemas,然后为此Schemas添加内容。", "tour.stepContentText": "内容是您的应用程序中按Schemas分组的实际数据。\n\n首先选择一个已发布的Schemas,然后为此Schemas添加内容。",
"tour.stepDataCompanyRole": "What is your role?",
"tour.stepDataCompanySize": "How many people work in a company?", "tour.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue", "tour.stepDataNext": "Continue",
"tour.stepDataProject": "What kind of project do you realize?", "tour.stepDataProject": "What kind of project do you realize?",
"tour.stepDataRole": "What is your role?",
"tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.", "tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.",
"tour.stepDataTitle": "About You", "tour.stepDataTitle": "About You",
"tour.stepIntroNext": "我们看看周围", "tour.stepIntroNext": "我们看看周围",

25
backend/i18n/source/backend_en.json

@ -350,11 +350,15 @@
"users.logout.text": "!Please close this popup.", "users.logout.text": "!Please close this popup.",
"users.logout.title": "Logout", "users.logout.title": "Logout",
"users.noEmailAddress": "We cannot get the email address from authentication provider.", "users.noEmailAddress": "We cannot get the email address from authentication provider.",
"users.profile.aboutHint": "Please share some information about your. It helps us to get an understanding about our users and to improve the product.",
"users.profile.aboutTitle": "About You",
"users.profile.addLoginDone": "Login added successfully.", "users.profile.addLoginDone": "Login added successfully.",
"users.profile.changePassword": "Change Password", "users.profile.changePassword": "Change Password",
"users.profile.changePasswordDone": "Password changed successfully.", "users.profile.changePasswordDone": "Password changed successfully.",
"users.profile.clientHint": "Use the client credentials to access the API with your profile information and permissions", "users.profile.clientHint": "Use the client credentials to access the API with your profile information and personal permissions, for example to create apps.",
"users.profile.clientTitle": "Client", "users.profile.clientTitle": "Client",
"users.profile.companyRole": "What is your role?",
"users.profile.companySize": "How many people work in a company?",
"users.profile.confirmPassword": "Confirm", "users.profile.confirmPassword": "Confirm",
"users.profile.generateClient": "Generate", "users.profile.generateClient": "Generate",
"users.profile.generateClientDone": "Client secret generated successfully.", "users.profile.generateClientDone": "Client secret generated successfully.",
@ -363,12 +367,31 @@
"users.profile.loginsTitle": "Logins", "users.profile.loginsTitle": "Logins",
"users.profile.passwordTitle": "Password", "users.profile.passwordTitle": "Password",
"users.profile.pii": "Personal Information", "users.profile.pii": "Personal Information",
"users.profile.project": "What kind of project do you realize?",
"users.profile.projectBackend": "Backend Data Management",
"users.profile.projectCommerce": "E-Commerce Solution",
"users.profile.projectLearning": "None, I am just here for learning",
"users.profile.projectMobileApp": "Mobile App",
"users.profile.projectNewsMagazine": "News Magazine",
"users.profile.projectPersonalBlog": "Personal Blog",
"users.profile.projectSmallBusiness": "Website for Small Business",
"users.profile.propertiesHint": "Use custom properties for rules and scripts.", "users.profile.propertiesHint": "Use custom properties for rules and scripts.",
"users.profile.propertiesTitle": "Properties", "users.profile.propertiesTitle": "Properties",
"users.profile.propertyAdd": "Add Property", "users.profile.propertyAdd": "Add Property",
"users.profile.removeLoginDone": "Login provider removed successfully.", "users.profile.removeLoginDone": "Login provider removed successfully.",
"users.profile.roleBusinessAnalyst": "Business Analyst",
"users.profile.roleBusinessOwner": "Business Owner",
"users.profile.roleContentCreator": "Content Creator",
"users.profile.roleEmployee": "Work at a company",
"users.profile.roleProductManager": "Product Manager",
"users.profile.roleSoftwareDeveloper": "Business Owner",
"users.profile.setPassword": "Set Password", "users.profile.setPassword": "Set Password",
"users.profile.setPasswordDone": "Password set successfully.", "users.profile.setPasswordDone": "Password set successfully.",
"users.profile.sizeLarge": "101-1000",
"users.profile.sizeMedium": "51-100",
"users.profile.sizeSingle": "1",
"users.profile.sizeSmall": "2-10",
"users.profile.sizeVeryLarge": "1000+",
"users.profile.title": "Profile", "users.profile.title": "Profile",
"users.profile.updateProfileDone": "Account updated successfully.", "users.profile.updateProfileDone": "Account updated successfully.",
"users.profile.updatePropertiesDone": "Account updated successfully.", "users.profile.updatePropertiesDone": "Account updated successfully.",

6
backend/i18n/source/frontend_en.json

@ -1069,8 +1069,8 @@
"tour.projectCommerce": "E-Commerce Solution", "tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning", "tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App", "tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "", "tour.projectNewsMagazine": "News Magazine",
"tour.projectPersonalBlog": "News Magazine", "tour.projectPersonalBlog": "Personal Blog",
"tour.projectSmallBusiness": "Website for Small Business", "tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst", "tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner", "tour.roleBusinessOwner": "Business Owner",
@ -1090,10 +1090,10 @@
"tour.stepAssetsText": "The assets contains all files that can also be linked to your content. For example images, videos or documents.\n\nYou can upload the assets here and use them later or also upload them directly when you create a new content item with an asset field.", "tour.stepAssetsText": "The assets contains all files that can also be linked to your content. For example images, videos or documents.\n\nYou can upload the assets here and use them later or also upload them directly when you create a new content item with an asset field.",
"tour.stepContentNext": "Almost there!", "tour.stepContentNext": "Almost there!",
"tour.stepContentText": "Content is the actual data in your app which is grouped by the schema.\n\nSelect a published schema first, then add content for this schema.", "tour.stepContentText": "Content is the actual data in your app which is grouped by the schema.\n\nSelect a published schema first, then add content for this schema.",
"tour.stepDataCompanyRole": "What is your role?",
"tour.stepDataCompanySize": "How many people work in a company?", "tour.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue", "tour.stepDataNext": "Continue",
"tour.stepDataProject": "What kind of project do you realize?", "tour.stepDataProject": "What kind of project do you realize?",
"tour.stepDataRole": "What is your role?",
"tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.", "tour.stepDataText": "Before we continue we would like to learn a little bit about you to improve to user experience.",
"tour.stepDataTitle": "About You", "tour.stepDataTitle": "About You",
"tour.stepIntroNext": "Let's take a look around", "tour.stepIntroNext": "Let's take a look around",

2
backend/src/Squidex.Domain.Users/UserValues.cs

@ -36,5 +36,5 @@ public sealed class UserValues
public List<(string Name, string Value)>? Properties { get; set; } public List<(string Name, string Value)>? Properties { get; set; }
public Dictionary<string, string>? Answers { get; set; } public Dictionary<string, string?>? Answers { get; set; }
} }

15
backend/src/Squidex.Shared/Identity/SquidexClaimsExtensions.cs

@ -76,6 +76,21 @@ namespace Squidex.Shared.Identity
return user.GetClaimValue(SquidexClaimTypes.DisplayName); return user.GetClaimValue(SquidexClaimTypes.DisplayName);
} }
public static string? Answer(this IEnumerable<Claim> user, string name)
{
var prefix = $"{name}=";
foreach (var claim in user)
{
if (claim.Type == SquidexClaimTypes.Answer && claim.Value.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
return claim.Value[prefix.Length..];
}
}
return null;
}
public static int GetTotalApps(this IEnumerable<Claim> user) public static int GetTotalApps(this IEnumerable<Claim> user)
{ {
var value = user.GetClaimValue(SquidexClaimTypes.TotalApps); var value = user.GetClaimValue(SquidexClaimTypes.TotalApps);

69
backend/src/Squidex.Shared/Texts.fr.resx

@ -1135,6 +1135,12 @@
<data name="users.noEmailAddress" xml:space="preserve"> <data name="users.noEmailAddress" xml:space="preserve">
<value>Nous ne pouvons pas obtenir l'adresse e-mail du fournisseur d'authentification.</value> <value>Nous ne pouvons pas obtenir l'adresse e-mail du fournisseur d'authentification.</value>
</data> </data>
<data name="users.profile.aboutHint" xml:space="preserve">
<value>Please share some information about your. It helps us to get an understanding about our users and to improve the product.</value>
</data>
<data name="users.profile.aboutTitle" xml:space="preserve">
<value>About You</value>
</data>
<data name="users.profile.addLoginDone" xml:space="preserve"> <data name="users.profile.addLoginDone" xml:space="preserve">
<value>Connexion ajoutée avec succès.</value> <value>Connexion ajoutée avec succès.</value>
</data> </data>
@ -1150,6 +1156,12 @@
<data name="users.profile.clientTitle" xml:space="preserve"> <data name="users.profile.clientTitle" xml:space="preserve">
<value>Client</value> <value>Client</value>
</data> </data>
<data name="users.profile.companyRole" xml:space="preserve">
<value>What is your role?</value>
</data>
<data name="users.profile.companySize" xml:space="preserve">
<value>How many people work in a company?</value>
</data>
<data name="users.profile.confirmPassword" xml:space="preserve"> <data name="users.profile.confirmPassword" xml:space="preserve">
<value>Confirmer</value> <value>Confirmer</value>
</data> </data>
@ -1174,6 +1186,30 @@
<data name="users.profile.pii" xml:space="preserve"> <data name="users.profile.pii" xml:space="preserve">
<value>Informations personnelles</value> <value>Informations personnelles</value>
</data> </data>
<data name="users.profile.project" xml:space="preserve">
<value>What kind of project do you realize?</value>
</data>
<data name="users.profile.projectBackend" xml:space="preserve">
<value>Backend Data Management</value>
</data>
<data name="users.profile.projectCommerce" xml:space="preserve">
<value>E-Commerce Solution</value>
</data>
<data name="users.profile.projectLearning" xml:space="preserve">
<value>None, I am just here for learning</value>
</data>
<data name="users.profile.projectMobileApp" xml:space="preserve">
<value>Mobile App</value>
</data>
<data name="users.profile.projectNewsMagazine" xml:space="preserve">
<value>News Magazine</value>
</data>
<data name="users.profile.projectPersonalBlog" xml:space="preserve">
<value>Personal Blog</value>
</data>
<data name="users.profile.projectSmallBusiness" xml:space="preserve">
<value>Website for Small Business</value>
</data>
<data name="users.profile.propertiesHint" xml:space="preserve"> <data name="users.profile.propertiesHint" xml:space="preserve">
<value>Utilisez des propriétés personnalisées pour les règles et les scripts.</value> <value>Utilisez des propriétés personnalisées pour les règles et les scripts.</value>
</data> </data>
@ -1186,12 +1222,45 @@
<data name="users.profile.removeLoginDone" xml:space="preserve"> <data name="users.profile.removeLoginDone" xml:space="preserve">
<value>Fournisseur de connexion supprimé avec succès.</value> <value>Fournisseur de connexion supprimé avec succès.</value>
</data> </data>
<data name="users.profile.roleBusinessAnalyst" xml:space="preserve">
<value>Business Analyst</value>
</data>
<data name="users.profile.roleBusinessOwner" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.roleContentCreator" xml:space="preserve">
<value>Content Creator</value>
</data>
<data name="users.profile.roleEmployee" xml:space="preserve">
<value>Work at a company</value>
</data>
<data name="users.profile.roleProductManager" xml:space="preserve">
<value>Product Manager</value>
</data>
<data name="users.profile.roleSoftwareDeveloper" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.setPassword" xml:space="preserve"> <data name="users.profile.setPassword" xml:space="preserve">
<value>Définir le mot de passe</value> <value>Définir le mot de passe</value>
</data> </data>
<data name="users.profile.setPasswordDone" xml:space="preserve"> <data name="users.profile.setPasswordDone" xml:space="preserve">
<value>Mot de passe défini avec succès.</value> <value>Mot de passe défini avec succès.</value>
</data> </data>
<data name="users.profile.sizeLarge" xml:space="preserve">
<value>101-1000</value>
</data>
<data name="users.profile.sizeMedium" xml:space="preserve">
<value>51-100</value>
</data>
<data name="users.profile.sizeSingle" xml:space="preserve">
<value>1</value>
</data>
<data name="users.profile.sizeSmall" xml:space="preserve">
<value>2-10</value>
</data>
<data name="users.profile.sizeVeryLarge" xml:space="preserve">
<value>1000+</value>
</data>
<data name="users.profile.title" xml:space="preserve"> <data name="users.profile.title" xml:space="preserve">
<value>Profil</value> <value>Profil</value>
</data> </data>

69
backend/src/Squidex.Shared/Texts.it.resx

@ -1135,6 +1135,12 @@
<data name="users.noEmailAddress" xml:space="preserve"> <data name="users.noEmailAddress" xml:space="preserve">
<value>We cannot get the email address from authentication provider.</value> <value>We cannot get the email address from authentication provider.</value>
</data> </data>
<data name="users.profile.aboutHint" xml:space="preserve">
<value>Please share some information about your. It helps us to get an understanding about our users and to improve the product.</value>
</data>
<data name="users.profile.aboutTitle" xml:space="preserve">
<value>About You</value>
</data>
<data name="users.profile.addLoginDone" xml:space="preserve"> <data name="users.profile.addLoginDone" xml:space="preserve">
<value>La login è stata aggiunta con successo.</value> <value>La login è stata aggiunta con successo.</value>
</data> </data>
@ -1150,6 +1156,12 @@
<data name="users.profile.clientTitle" xml:space="preserve"> <data name="users.profile.clientTitle" xml:space="preserve">
<value>Client</value> <value>Client</value>
</data> </data>
<data name="users.profile.companyRole" xml:space="preserve">
<value>What is your role?</value>
</data>
<data name="users.profile.companySize" xml:space="preserve">
<value>How many people work in a company?</value>
</data>
<data name="users.profile.confirmPassword" xml:space="preserve"> <data name="users.profile.confirmPassword" xml:space="preserve">
<value>Confermare</value> <value>Confermare</value>
</data> </data>
@ -1174,6 +1186,30 @@
<data name="users.profile.pii" xml:space="preserve"> <data name="users.profile.pii" xml:space="preserve">
<value>Informazioni personali</value> <value>Informazioni personali</value>
</data> </data>
<data name="users.profile.project" xml:space="preserve">
<value>What kind of project do you realize?</value>
</data>
<data name="users.profile.projectBackend" xml:space="preserve">
<value>Backend Data Management</value>
</data>
<data name="users.profile.projectCommerce" xml:space="preserve">
<value>E-Commerce Solution</value>
</data>
<data name="users.profile.projectLearning" xml:space="preserve">
<value>None, I am just here for learning</value>
</data>
<data name="users.profile.projectMobileApp" xml:space="preserve">
<value>Mobile App</value>
</data>
<data name="users.profile.projectNewsMagazine" xml:space="preserve">
<value>News Magazine</value>
</data>
<data name="users.profile.projectPersonalBlog" xml:space="preserve">
<value>Personal Blog</value>
</data>
<data name="users.profile.projectSmallBusiness" xml:space="preserve">
<value>Website for Small Business</value>
</data>
<data name="users.profile.propertiesHint" xml:space="preserve"> <data name="users.profile.propertiesHint" xml:space="preserve">
<value>Utilizza proprietà personalizzate per regole e script.</value> <value>Utilizza proprietà personalizzate per regole e script.</value>
</data> </data>
@ -1186,12 +1222,45 @@
<data name="users.profile.removeLoginDone" xml:space="preserve"> <data name="users.profile.removeLoginDone" xml:space="preserve">
<value>Il provider per l'autenticazione è stato rimosso correttamente.</value> <value>Il provider per l'autenticazione è stato rimosso correttamente.</value>
</data> </data>
<data name="users.profile.roleBusinessAnalyst" xml:space="preserve">
<value>Business Analyst</value>
</data>
<data name="users.profile.roleBusinessOwner" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.roleContentCreator" xml:space="preserve">
<value>Content Creator</value>
</data>
<data name="users.profile.roleEmployee" xml:space="preserve">
<value>Work at a company</value>
</data>
<data name="users.profile.roleProductManager" xml:space="preserve">
<value>Product Manager</value>
</data>
<data name="users.profile.roleSoftwareDeveloper" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.setPassword" xml:space="preserve"> <data name="users.profile.setPassword" xml:space="preserve">
<value>Imposta la Password</value> <value>Imposta la Password</value>
</data> </data>
<data name="users.profile.setPasswordDone" xml:space="preserve"> <data name="users.profile.setPasswordDone" xml:space="preserve">
<value>Password impostata con successo.</value> <value>Password impostata con successo.</value>
</data> </data>
<data name="users.profile.sizeLarge" xml:space="preserve">
<value>101-1000</value>
</data>
<data name="users.profile.sizeMedium" xml:space="preserve">
<value>51-100</value>
</data>
<data name="users.profile.sizeSingle" xml:space="preserve">
<value>1</value>
</data>
<data name="users.profile.sizeSmall" xml:space="preserve">
<value>2-10</value>
</data>
<data name="users.profile.sizeVeryLarge" xml:space="preserve">
<value>1000+</value>
</data>
<data name="users.profile.title" xml:space="preserve"> <data name="users.profile.title" xml:space="preserve">
<value>Profilo</value> <value>Profilo</value>
</data> </data>

69
backend/src/Squidex.Shared/Texts.nl.resx

@ -1135,6 +1135,12 @@
<data name="users.noEmailAddress" xml:space="preserve"> <data name="users.noEmailAddress" xml:space="preserve">
<value>We cannot get the email address from authentication provider.</value> <value>We cannot get the email address from authentication provider.</value>
</data> </data>
<data name="users.profile.aboutHint" xml:space="preserve">
<value>Please share some information about your. It helps us to get an understanding about our users and to improve the product.</value>
</data>
<data name="users.profile.aboutTitle" xml:space="preserve">
<value>About You</value>
</data>
<data name="users.profile.addLoginDone" xml:space="preserve"> <data name="users.profile.addLoginDone" xml:space="preserve">
<value>Login succesvol toegevoegd.</value> <value>Login succesvol toegevoegd.</value>
</data> </data>
@ -1150,6 +1156,12 @@
<data name="users.profile.clientTitle" xml:space="preserve"> <data name="users.profile.clientTitle" xml:space="preserve">
<value>Client</value> <value>Client</value>
</data> </data>
<data name="users.profile.companyRole" xml:space="preserve">
<value>What is your role?</value>
</data>
<data name="users.profile.companySize" xml:space="preserve">
<value>How many people work in a company?</value>
</data>
<data name="users.profile.confirmPassword" xml:space="preserve"> <data name="users.profile.confirmPassword" xml:space="preserve">
<value>Bevestigen</value> <value>Bevestigen</value>
</data> </data>
@ -1174,6 +1186,30 @@
<data name="users.profile.pii" xml:space="preserve"> <data name="users.profile.pii" xml:space="preserve">
<value>Persoonlijke informatie</value> <value>Persoonlijke informatie</value>
</data> </data>
<data name="users.profile.project" xml:space="preserve">
<value>What kind of project do you realize?</value>
</data>
<data name="users.profile.projectBackend" xml:space="preserve">
<value>Backend Data Management</value>
</data>
<data name="users.profile.projectCommerce" xml:space="preserve">
<value>E-Commerce Solution</value>
</data>
<data name="users.profile.projectLearning" xml:space="preserve">
<value>None, I am just here for learning</value>
</data>
<data name="users.profile.projectMobileApp" xml:space="preserve">
<value>Mobile App</value>
</data>
<data name="users.profile.projectNewsMagazine" xml:space="preserve">
<value>News Magazine</value>
</data>
<data name="users.profile.projectPersonalBlog" xml:space="preserve">
<value>Personal Blog</value>
</data>
<data name="users.profile.projectSmallBusiness" xml:space="preserve">
<value>Website for Small Business</value>
</data>
<data name="users.profile.propertiesHint" xml:space="preserve"> <data name="users.profile.propertiesHint" xml:space="preserve">
<value>Gebruik aangepaste eigenschappen voor regels en scripts.</value> <value>Gebruik aangepaste eigenschappen voor regels en scripts.</value>
</data> </data>
@ -1186,12 +1222,45 @@
<data name="users.profile.removeLoginDone" xml:space="preserve"> <data name="users.profile.removeLoginDone" xml:space="preserve">
<value>Login provider succesvol verwijderd.</value> <value>Login provider succesvol verwijderd.</value>
</data> </data>
<data name="users.profile.roleBusinessAnalyst" xml:space="preserve">
<value>Business Analyst</value>
</data>
<data name="users.profile.roleBusinessOwner" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.roleContentCreator" xml:space="preserve">
<value>Content Creator</value>
</data>
<data name="users.profile.roleEmployee" xml:space="preserve">
<value>Work at a company</value>
</data>
<data name="users.profile.roleProductManager" xml:space="preserve">
<value>Product Manager</value>
</data>
<data name="users.profile.roleSoftwareDeveloper" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.setPassword" xml:space="preserve"> <data name="users.profile.setPassword" xml:space="preserve">
<value>Wachtwoord instellen</value> <value>Wachtwoord instellen</value>
</data> </data>
<data name="users.profile.setPasswordDone" xml:space="preserve"> <data name="users.profile.setPasswordDone" xml:space="preserve">
<value>Wachtwoord succesvol ingesteld.</value> <value>Wachtwoord succesvol ingesteld.</value>
</data> </data>
<data name="users.profile.sizeLarge" xml:space="preserve">
<value>101-1000</value>
</data>
<data name="users.profile.sizeMedium" xml:space="preserve">
<value>51-100</value>
</data>
<data name="users.profile.sizeSingle" xml:space="preserve">
<value>1</value>
</data>
<data name="users.profile.sizeSmall" xml:space="preserve">
<value>2-10</value>
</data>
<data name="users.profile.sizeVeryLarge" xml:space="preserve">
<value>1000+</value>
</data>
<data name="users.profile.title" xml:space="preserve"> <data name="users.profile.title" xml:space="preserve">
<value>Profiel</value> <value>Profiel</value>
</data> </data>

69
backend/src/Squidex.Shared/Texts.pt.resx

@ -1135,6 +1135,12 @@
<data name="users.noEmailAddress" xml:space="preserve"> <data name="users.noEmailAddress" xml:space="preserve">
<value>Não podemos obter o endereço de e-mail do provedor de autenticação.</value> <value>Não podemos obter o endereço de e-mail do provedor de autenticação.</value>
</data> </data>
<data name="users.profile.aboutHint" xml:space="preserve">
<value>Please share some information about your. It helps us to get an understanding about our users and to improve the product.</value>
</data>
<data name="users.profile.aboutTitle" xml:space="preserve">
<value>About You</value>
</data>
<data name="users.profile.addLoginDone" xml:space="preserve"> <data name="users.profile.addLoginDone" xml:space="preserve">
<value>Login adicionado com sucesso.</value> <value>Login adicionado com sucesso.</value>
</data> </data>
@ -1150,6 +1156,12 @@
<data name="users.profile.clientTitle" xml:space="preserve"> <data name="users.profile.clientTitle" xml:space="preserve">
<value>cliente</value> <value>cliente</value>
</data> </data>
<data name="users.profile.companyRole" xml:space="preserve">
<value>What is your role?</value>
</data>
<data name="users.profile.companySize" xml:space="preserve">
<value>How many people work in a company?</value>
</data>
<data name="users.profile.confirmPassword" xml:space="preserve"> <data name="users.profile.confirmPassword" xml:space="preserve">
<value>Confirmar</value> <value>Confirmar</value>
</data> </data>
@ -1174,6 +1186,30 @@
<data name="users.profile.pii" xml:space="preserve"> <data name="users.profile.pii" xml:space="preserve">
<value>Informação pessoal</value> <value>Informação pessoal</value>
</data> </data>
<data name="users.profile.project" xml:space="preserve">
<value>What kind of project do you realize?</value>
</data>
<data name="users.profile.projectBackend" xml:space="preserve">
<value>Backend Data Management</value>
</data>
<data name="users.profile.projectCommerce" xml:space="preserve">
<value>E-Commerce Solution</value>
</data>
<data name="users.profile.projectLearning" xml:space="preserve">
<value>None, I am just here for learning</value>
</data>
<data name="users.profile.projectMobileApp" xml:space="preserve">
<value>Mobile App</value>
</data>
<data name="users.profile.projectNewsMagazine" xml:space="preserve">
<value>News Magazine</value>
</data>
<data name="users.profile.projectPersonalBlog" xml:space="preserve">
<value>Personal Blog</value>
</data>
<data name="users.profile.projectSmallBusiness" xml:space="preserve">
<value>Website for Small Business</value>
</data>
<data name="users.profile.propertiesHint" xml:space="preserve"> <data name="users.profile.propertiesHint" xml:space="preserve">
<value>Use propriedades personalizadas para regras e scripts.</value> <value>Use propriedades personalizadas para regras e scripts.</value>
</data> </data>
@ -1186,12 +1222,45 @@
<data name="users.profile.removeLoginDone" xml:space="preserve"> <data name="users.profile.removeLoginDone" xml:space="preserve">
<value>Provedor de login removido com sucesso.</value> <value>Provedor de login removido com sucesso.</value>
</data> </data>
<data name="users.profile.roleBusinessAnalyst" xml:space="preserve">
<value>Business Analyst</value>
</data>
<data name="users.profile.roleBusinessOwner" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.roleContentCreator" xml:space="preserve">
<value>Content Creator</value>
</data>
<data name="users.profile.roleEmployee" xml:space="preserve">
<value>Work at a company</value>
</data>
<data name="users.profile.roleProductManager" xml:space="preserve">
<value>Product Manager</value>
</data>
<data name="users.profile.roleSoftwareDeveloper" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.setPassword" xml:space="preserve"> <data name="users.profile.setPassword" xml:space="preserve">
<value>Set Password</value> <value>Set Password</value>
</data> </data>
<data name="users.profile.setPasswordDone" xml:space="preserve"> <data name="users.profile.setPasswordDone" xml:space="preserve">
<value>Password configurada com sucesso.</value> <value>Password configurada com sucesso.</value>
</data> </data>
<data name="users.profile.sizeLarge" xml:space="preserve">
<value>101-1000</value>
</data>
<data name="users.profile.sizeMedium" xml:space="preserve">
<value>51-100</value>
</data>
<data name="users.profile.sizeSingle" xml:space="preserve">
<value>1</value>
</data>
<data name="users.profile.sizeSmall" xml:space="preserve">
<value>2-10</value>
</data>
<data name="users.profile.sizeVeryLarge" xml:space="preserve">
<value>1000+</value>
</data>
<data name="users.profile.title" xml:space="preserve"> <data name="users.profile.title" xml:space="preserve">
<value>Perfil</value> <value>Perfil</value>
</data> </data>

71
backend/src/Squidex.Shared/Texts.resx

@ -1135,6 +1135,12 @@
<data name="users.noEmailAddress" xml:space="preserve"> <data name="users.noEmailAddress" xml:space="preserve">
<value>We cannot get the email address from authentication provider.</value> <value>We cannot get the email address from authentication provider.</value>
</data> </data>
<data name="users.profile.aboutHint" xml:space="preserve">
<value>Please share some information about your. It helps us to get an understanding about our users and to improve the product.</value>
</data>
<data name="users.profile.aboutTitle" xml:space="preserve">
<value>About You</value>
</data>
<data name="users.profile.addLoginDone" xml:space="preserve"> <data name="users.profile.addLoginDone" xml:space="preserve">
<value>Login added successfully.</value> <value>Login added successfully.</value>
</data> </data>
@ -1145,11 +1151,17 @@
<value>Password changed successfully.</value> <value>Password changed successfully.</value>
</data> </data>
<data name="users.profile.clientHint" xml:space="preserve"> <data name="users.profile.clientHint" xml:space="preserve">
<value>Use the client credentials to access the API with your profile information and permissions</value> <value>Use the client credentials to access the API with your profile information and personal permissions, for example to create apps.</value>
</data> </data>
<data name="users.profile.clientTitle" xml:space="preserve"> <data name="users.profile.clientTitle" xml:space="preserve">
<value>Client</value> <value>Client</value>
</data> </data>
<data name="users.profile.companyRole" xml:space="preserve">
<value>What is your role?</value>
</data>
<data name="users.profile.companySize" xml:space="preserve">
<value>How many people work in a company?</value>
</data>
<data name="users.profile.confirmPassword" xml:space="preserve"> <data name="users.profile.confirmPassword" xml:space="preserve">
<value>Confirm</value> <value>Confirm</value>
</data> </data>
@ -1174,6 +1186,30 @@
<data name="users.profile.pii" xml:space="preserve"> <data name="users.profile.pii" xml:space="preserve">
<value>Personal Information</value> <value>Personal Information</value>
</data> </data>
<data name="users.profile.project" xml:space="preserve">
<value>What kind of project do you realize?</value>
</data>
<data name="users.profile.projectBackend" xml:space="preserve">
<value>Backend Data Management</value>
</data>
<data name="users.profile.projectCommerce" xml:space="preserve">
<value>E-Commerce Solution</value>
</data>
<data name="users.profile.projectLearning" xml:space="preserve">
<value>None, I am just here for learning</value>
</data>
<data name="users.profile.projectMobileApp" xml:space="preserve">
<value>Mobile App</value>
</data>
<data name="users.profile.projectNewsMagazine" xml:space="preserve">
<value>News Magazine</value>
</data>
<data name="users.profile.projectPersonalBlog" xml:space="preserve">
<value>Personal Blog</value>
</data>
<data name="users.profile.projectSmallBusiness" xml:space="preserve">
<value>Website for Small Business</value>
</data>
<data name="users.profile.propertiesHint" xml:space="preserve"> <data name="users.profile.propertiesHint" xml:space="preserve">
<value>Use custom properties for rules and scripts.</value> <value>Use custom properties for rules and scripts.</value>
</data> </data>
@ -1186,12 +1222,45 @@
<data name="users.profile.removeLoginDone" xml:space="preserve"> <data name="users.profile.removeLoginDone" xml:space="preserve">
<value>Login provider removed successfully.</value> <value>Login provider removed successfully.</value>
</data> </data>
<data name="users.profile.roleBusinessAnalyst" xml:space="preserve">
<value>Business Analyst</value>
</data>
<data name="users.profile.roleBusinessOwner" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.roleContentCreator" xml:space="preserve">
<value>Content Creator</value>
</data>
<data name="users.profile.roleEmployee" xml:space="preserve">
<value>Work at a company</value>
</data>
<data name="users.profile.roleProductManager" xml:space="preserve">
<value>Product Manager</value>
</data>
<data name="users.profile.roleSoftwareDeveloper" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.setPassword" xml:space="preserve"> <data name="users.profile.setPassword" xml:space="preserve">
<value>Set Password</value> <value>Set Password</value>
</data> </data>
<data name="users.profile.setPasswordDone" xml:space="preserve"> <data name="users.profile.setPasswordDone" xml:space="preserve">
<value>Password set successfully.</value> <value>Password set successfully.</value>
</data> </data>
<data name="users.profile.sizeLarge" xml:space="preserve">
<value>101-1000</value>
</data>
<data name="users.profile.sizeMedium" xml:space="preserve">
<value>51-100</value>
</data>
<data name="users.profile.sizeSingle" xml:space="preserve">
<value>1</value>
</data>
<data name="users.profile.sizeSmall" xml:space="preserve">
<value>2-10</value>
</data>
<data name="users.profile.sizeVeryLarge" xml:space="preserve">
<value>1000+</value>
</data>
<data name="users.profile.title" xml:space="preserve"> <data name="users.profile.title" xml:space="preserve">
<value>Profile</value> <value>Profile</value>
</data> </data>

69
backend/src/Squidex.Shared/Texts.zh.resx

@ -1135,6 +1135,12 @@
<data name="users.noEmailAddress" xml:space="preserve"> <data name="users.noEmailAddress" xml:space="preserve">
<value>We cannot get the email address from authentication provider.</value> <value>We cannot get the email address from authentication provider.</value>
</data> </data>
<data name="users.profile.aboutHint" xml:space="preserve">
<value>Please share some information about your. It helps us to get an understanding about our users and to improve the product.</value>
</data>
<data name="users.profile.aboutTitle" xml:space="preserve">
<value>About You</value>
</data>
<data name="users.profile.addLoginDone" xml:space="preserve"> <data name="users.profile.addLoginDone" xml:space="preserve">
<value>登录添加成功。</value> <value>登录添加成功。</value>
</data> </data>
@ -1150,6 +1156,12 @@
<data name="users.profile.clientTitle" xml:space="preserve"> <data name="users.profile.clientTitle" xml:space="preserve">
<value>客户端</value> <value>客户端</value>
</data> </data>
<data name="users.profile.companyRole" xml:space="preserve">
<value>What is your role?</value>
</data>
<data name="users.profile.companySize" xml:space="preserve">
<value>How many people work in a company?</value>
</data>
<data name="users.profile.confirmPassword" xml:space="preserve"> <data name="users.profile.confirmPassword" xml:space="preserve">
<value>确认</value> <value>确认</value>
</data> </data>
@ -1174,6 +1186,30 @@
<data name="users.profile.pii" xml:space="preserve"> <data name="users.profile.pii" xml:space="preserve">
<value>个人信息</value> <value>个人信息</value>
</data> </data>
<data name="users.profile.project" xml:space="preserve">
<value>What kind of project do you realize?</value>
</data>
<data name="users.profile.projectBackend" xml:space="preserve">
<value>Backend Data Management</value>
</data>
<data name="users.profile.projectCommerce" xml:space="preserve">
<value>E-Commerce Solution</value>
</data>
<data name="users.profile.projectLearning" xml:space="preserve">
<value>None, I am just here for learning</value>
</data>
<data name="users.profile.projectMobileApp" xml:space="preserve">
<value>Mobile App</value>
</data>
<data name="users.profile.projectNewsMagazine" xml:space="preserve">
<value>News Magazine</value>
</data>
<data name="users.profile.projectPersonalBlog" xml:space="preserve">
<value>Personal Blog</value>
</data>
<data name="users.profile.projectSmallBusiness" xml:space="preserve">
<value>Website for Small Business</value>
</data>
<data name="users.profile.propertiesHint" xml:space="preserve"> <data name="users.profile.propertiesHint" xml:space="preserve">
<value>为规则和脚本使用自定义属性。</value> <value>为规则和脚本使用自定义属性。</value>
</data> </data>
@ -1186,12 +1222,45 @@
<data name="users.profile.removeLoginDone" xml:space="preserve"> <data name="users.profile.removeLoginDone" xml:space="preserve">
<value>登录提供程序删除成功。</value> <value>登录提供程序删除成功。</value>
</data> </data>
<data name="users.profile.roleBusinessAnalyst" xml:space="preserve">
<value>Business Analyst</value>
</data>
<data name="users.profile.roleBusinessOwner" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.roleContentCreator" xml:space="preserve">
<value>Content Creator</value>
</data>
<data name="users.profile.roleEmployee" xml:space="preserve">
<value>Work at a company</value>
</data>
<data name="users.profile.roleProductManager" xml:space="preserve">
<value>Product Manager</value>
</data>
<data name="users.profile.roleSoftwareDeveloper" xml:space="preserve">
<value>Business Owner</value>
</data>
<data name="users.profile.setPassword" xml:space="preserve"> <data name="users.profile.setPassword" xml:space="preserve">
<value>设置密码</value> <value>设置密码</value>
</data> </data>
<data name="users.profile.setPasswordDone" xml:space="preserve"> <data name="users.profile.setPasswordDone" xml:space="preserve">
<value>密码设置成功。</value> <value>密码设置成功。</value>
</data> </data>
<data name="users.profile.sizeLarge" xml:space="preserve">
<value>101-1000</value>
</data>
<data name="users.profile.sizeMedium" xml:space="preserve">
<value>51-100</value>
</data>
<data name="users.profile.sizeSingle" xml:space="preserve">
<value>1</value>
</data>
<data name="users.profile.sizeSmall" xml:space="preserve">
<value>2-10</value>
</data>
<data name="users.profile.sizeVeryLarge" xml:space="preserve">
<value>1000+</value>
</data>
<data name="users.profile.title" xml:space="preserve"> <data name="users.profile.title" xml:space="preserve">
<value>个人资料</value> <value>个人资料</value>
</data> </data>

2
backend/src/Squidex/Areas/Api/Controllers/Users/Models/UpdateProfileDto.cs

@ -16,7 +16,7 @@ public sealed class UpdateProfileDto
/// <summary> /// <summary>
/// The answers from a questionaire. /// The answers from a questionaire.
/// </summary> /// </summary>
public Dictionary<string, string>? Answers { get; set; } public Dictionary<string, string?>? Answers { get; set; }
public UserValues ToValues() public UserValues ToValues()
{ {

32
backend/src/Squidex/Areas/IdentityServer/Controllers/Profile/ChangeAboutModel.cs

@ -0,0 +1,32 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Users;
namespace Squidex.Areas.IdentityServer.Controllers.Profile;
public class ChangeAboutModel
{
public string? CompanyRole { get; set; }
public string? CompanySize { get; set; }
public string? Project { get; set; }
public UserValues ToValues()
{
return new UserValues
{
Answers = new Dictionary<string, string?>
{
["companyRole"] = CompanyRole,
["companySize"] = CompanySize,
["project"] = Project,
}
};
}
}

14
backend/src/Squidex/Areas/IdentityServer/Controllers/Profile/ProfileController.cs

@ -92,6 +92,14 @@ public sealed class ProfileController : IdentityServerController
T.Get("users.profile.updatePropertiesDone"), model); T.Get("users.profile.updatePropertiesDone"), model);
} }
[HttpPost]
[Route("account/profile/about/")]
public Task<IActionResult> UpdateAbout(ChangeAboutModel model)
{
return MakeChangeAsync((id, ct) => userService.UpdateAsync(id, model.ToValues(), ct: ct),
T.Get("users.profile.updateProfileDone"), model);
}
[HttpPost] [HttpPost]
[Route("account/profile/login-remove/")] [Route("account/profile/login-remove/")]
public Task<IActionResult> RemoveLogin(RemoveLoginModel model) public Task<IActionResult> RemoveLogin(RemoveLoginModel model)
@ -249,14 +257,18 @@ public sealed class ProfileController : IdentityServerController
{ {
Id = user.Id, Id = user.Id,
ClientSecret = user.Claims.ClientSecret()!, ClientSecret = user.Claims.ClientSecret()!,
CompanyRole = user.Claims.Answer("companyRole"),
CompanySize = user.Claims.Answer("companySize"),
DisplayName = user.Claims.DisplayName()!,
Email = user.Email, Email = user.Email,
ErrorMessage = errorMessage, ErrorMessage = errorMessage,
ExternalLogins = logins, ExternalLogins = logins,
ExternalProviders = providers, ExternalProviders = providers,
DisplayName = user.Claims.DisplayName()!,
HasPassword = hasPassword, HasPassword = hasPassword,
HasPasswordAuth = identityOptions.AllowPasswordAuth, HasPasswordAuth = identityOptions.AllowPasswordAuth,
IsHidden = user.Claims.IsHidden(), IsHidden = user.Claims.IsHidden(),
Project = user.Claims.Answer("project"),
ShowAbout = identityOptions.ShowAbout,
SuccessMessage = successMessage SuccessMessage = successMessage
}; };

8
backend/src/Squidex/Areas/IdentityServer/Controllers/Profile/ProfileVM.cs

@ -17,12 +17,20 @@ public sealed class ProfileVM
public string DisplayName { get; set; } public string DisplayName { get; set; }
public string? CompanyRole { get; set; }
public string? CompanySize { get; set; }
public string? Project { get; set; }
public string? ClientSecret { get; set; } public string? ClientSecret { get; set; }
public string? ErrorMessage { get; set; } public string? ErrorMessage { get; set; }
public string? SuccessMessage { get; set; } public string? SuccessMessage { get; set; }
public bool ShowAbout { get; set; }
public bool IsHidden { get; set; } public bool IsHidden { get; set; }
public bool HasPassword { get; set; } public bool HasPassword { get; set; }

68
backend/src/Squidex/Areas/IdentityServer/Views/Profile/Profile.cshtml

@ -53,7 +53,7 @@
@Html.AntiForgeryToken() @Html.AntiForgeryToken()
<div class="form-group"> <div class="form-group">
<label for="email">@T.Get("common.email")</label> <label asp-for="Email">@T.Get("common.email")</label>
@{ RenderValidation("Email"); } @{ RenderValidation("Email"); }
@ -61,7 +61,7 @@
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="displayName">@T.Get("common.displayName")</label> <label asp-for="DisplayName">@T.Get("common.displayName")</label>
@{ RenderValidation("DisplayName"); } @{ RenderValidation("DisplayName"); }
@ -79,6 +79,66 @@
<button type="submit" class="btn btn-primary">@T.Get("common.save")</button> <button type="submit" class="btn btn-primary">@T.Get("common.save")</button>
</form> </form>
@if (Model.ShowAbout)
{
<hr />
<div class="profile-section">
<h2 id="about">@T.Get("users.profile.aboutTitle")</h2>
<small class="form-text text-muted mt-0 mb-3 d-block">@T.Get("users.profile.aboutHint")</small>
<form class="profile-form" asp-controller="Profile" asp-action="UpdateAbout" method="post">
@Html.AntiForgeryToken()
<div class="form-group">
<label asp-for="CompanyRole">@T.Get("users.profile.companyRole")</label>
<select type="password" class="form-select" asp-for="CompanyRole">
<option></option>
<option value="RoleEmployee">@T.Get("users.profile.roleEmployee")</option>
<option value="RoleProductManager">@T.Get("users.profile.roleProductManager")</option>
<option value="RoleContentCreator">@T.Get("users.profile.roleContentCreator")</option>
<option value="RoleSoftwareDeveloper">@T.Get("users.profile.roleSoftwareDeveloper")</option>
<option value="RoleBusinessAnalyst">@T.Get("users.profile.roleBusinessAnalyst")</option>
</select>
</div>
<div class="form-group">
<label asp-for="CompanySize">@T.Get("users.profile.companySize")</label>
<select type="password" class="form-select" asp-for="CompanySize">
<option></option>
<option value="SizeSingle">@T.Get("users.profile.sizeSingle")</option>
<option value="SizeSmall">@T.Get("users.profile.sizeSmall")</option>
<option value="SizeMedium">@T.Get("users.profile.sizeMedium")</option>
<option value="SizeLarge">@T.Get("users.profile.sizeLarge")</option>
<option value="SizeVeryLarge">@T.Get("users.profile.sizeVeryLarge")</option>
</select>
</div>
<div class="form-group">
<label asp-for="Project">@T.Get("users.profile.project")</label>
<select type="password" class="form-select" asp-for="Project">
<option></option>
<option value="ProjectNewsMagazine">@T.Get("users.profile.projectNewsMagazine")</option>
<option value="ProjectPersonalBlog">@T.Get("users.profile.projectPersonalBlog")</option>
<option value="ProjectSmallBusiness">@T.Get("users.profile.projectSmallBusiness")</option>
<option value="ProjectCommerce">@T.Get("users.profile.projectCommerce")</option>
<option value="ProjectMobileApp">@T.Get("users.profile.projectMobileApp")</option>
<option value="ProjectBackend">@T.Get("users.profile.projectBackend")</option>
<option value="ProjectLearning">@T.Get("users.profile.projectLearning")</option>
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">@T.Get("common.save")</button>
</div>
</form>
</div>
}
@if (Model!.ExternalProviders.Any()) @if (Model!.ExternalProviders.Any())
{ {
<hr /> <hr />
@ -210,7 +270,7 @@
<div class="profile-section"> <div class="profile-section">
<h2>@T.Get("users.profile.clientTitle")</h2> <h2>@T.Get("users.profile.clientTitle")</h2>
<small class="form-text text-muted mt-2 mb-2">@T.Get("users.profile.clientHint")</small> <small class="form-text text-muted mt-0 mb-3 d-block">@T.Get("users.profile.clientHint")</small>
<div class="row g-2 form-group"> <div class="row g-2 form-group">
<div class="col-8"> <div class="col-8">
@ -242,7 +302,7 @@
<div class="profile-section"> <div class="profile-section">
<h2>@T.Get("users.profile.propertiesTitle")</h2> <h2>@T.Get("users.profile.propertiesTitle")</h2>
<small class="form-text text-muted mt-2 mb-2">@T.Get("users.profile.propertiesHint")</small> <small class="form-text text-muted mt-0 mb-3 d-block">@T.Get("users.profile.propertiesHint")</small>
<form class="profile-form" asp-controller="Profile" asp-action="UpdateProperties" method="post"> <form class="profile-form" asp-controller="Profile" asp-action="UpdateProperties" method="post">
@Html.AntiForgeryToken() @Html.AntiForgeryToken()

2
backend/src/Squidex/Config/MyIdentityOptions.cs

@ -73,6 +73,8 @@ public sealed class MyIdentityOptions
public bool ShowPII { get; set; } public bool ShowPII { get; set; }
public bool ShowAbout { get; set; }
public bool SuppressXFrameOptionsHeader { get; set; } public bool SuppressXFrameOptionsHeader { get; set; }
public bool IsAdminConfigured() public bool IsAdminConfigured()

14
backend/src/Squidex/Startup.cs

@ -79,27 +79,28 @@ public sealed class Startup
public void Configure(IApplicationBuilder app) public void Configure(IApplicationBuilder app)
{ {
app.UseWebSockets(); app.UseWebSockets();
app.UseCookiePolicy(); app.UseCookiePolicy();
app.UseDefaultPathBase(); app.UseDefaultPathBase();
app.UseDefaultForwardRules(); app.UseDefaultForwardRules();
app.UseSquidexHealthCheck(); app.UseSquidexHealthCheck();
app.UseSquidexRobotsTxt(); app.UseSquidexRobotsTxt();
app.UseSquidexLogging(); app.UseSquidexLogging();
app.UseSquidexLocalization(); app.UseSquidexLocalization();
app.UseSquidexLocalCache(); app.UseSquidexLocalCache();
app.UseSquidexCors(); app.UseSquidexCors();
app.UseOpenApi(options => app.UseOpenApi(options =>
{ {
options.Path = "/api/swagger/v1/swagger.json"; options.Path = "/api/swagger/v1/swagger.json";
}); });
app.UseWhen(c => c.Request.Path.StartsWithSegments(Constants.PrefixIdentityServer, StringComparison.OrdinalIgnoreCase), builder => if (!app.ApplicationServices.GetRequiredService<IWebHostEnvironment>().IsDevelopment())
{ {
builder.UseExceptionHandler("/identity-server/error"); app.UseWhen(c => c.Request.Path.StartsWithSegments(Constants.PrefixIdentityServer, StringComparison.OrdinalIgnoreCase), builder =>
}); {
builder.UseExceptionHandler("/identity-server/error");
});
}
app.UseWhen(c => c.Request.Path.StartsWithSegments(Constants.PrefixApi, StringComparison.OrdinalIgnoreCase), builder => app.UseWhen(c => c.Request.Path.StartsWithSegments(Constants.PrefixApi, StringComparison.OrdinalIgnoreCase), builder =>
{ {
@ -110,7 +111,6 @@ public sealed class Startup
}); });
app.UseRouting(); app.UseRouting();
app.UseAuthentication(); app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();

4
frontend/src/app/features/apps/pages/onboarding-dialog.component.html

@ -32,7 +32,7 @@
<div [innerHTML]="'tour.stepDataText' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div> <div [innerHTML]="'tour.stepDataText' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div class="form-group mt-4"> <div class="form-group mt-4">
<label for="role">{{ 'tour.stepDataRole' | sqxTranslate }}</label> <label for="role">{{ 'tour.stepDataCompanyRole' | sqxTranslate }}</label>
<select class="form-select" id="companyRole" formControlName="companyRole"> <select class="form-select" id="companyRole" formControlName="companyRole">
<option [ngValue]="'RoleEmployee'">{{ 'tour.roleEmployee' | sqxTranslate }}</option> <option [ngValue]="'RoleEmployee'">{{ 'tour.roleEmployee' | sqxTranslate }}</option>
@ -60,7 +60,7 @@
<select class="form-select" id="project" formControlName="project"> <select class="form-select" id="project" formControlName="project">
<option [ngValue]="'ProjectNewsMagazine'">{{ 'tour.projectNewsMagazine' | sqxTranslate }}</option> <option [ngValue]="'ProjectNewsMagazine'">{{ 'tour.projectNewsMagazine' | sqxTranslate }}</option>
<option [ngValue]="'ProjectSmallBusiness'">{{ 'tour.projectPersonalBlog' | sqxTranslate }}</option> <option [ngValue]="'ProjectPersonalBlog'">{{ 'tour.projectPersonalBlog' | sqxTranslate }}</option>
<option [ngValue]="'ProjectSmallBusiness'">{{ 'tour.projectSmallBusiness' | sqxTranslate }}</option> <option [ngValue]="'ProjectSmallBusiness'">{{ 'tour.projectSmallBusiness' | sqxTranslate }}</option>
<option [ngValue]="'ProjectCommerce'">{{ 'tour.projectCommerce' | sqxTranslate }}</option> <option [ngValue]="'ProjectCommerce'">{{ 'tour.projectCommerce' | sqxTranslate }}</option>
<option [ngValue]="'ProjectMobileApp'">{{ 'tour.projectMobileApp' | sqxTranslate }}</option> <option [ngValue]="'ProjectMobileApp'">{{ 'tour.projectMobileApp' | sqxTranslate }}</option>

Loading…
Cancel
Save