Browse Source

New onboarding.

pull/1016/head
Sebastian 3 years ago
parent
commit
509eab945d
  1. 48
      backend/i18n/frontend_en.json
  2. 48
      backend/i18n/frontend_fr.json
  3. 48
      backend/i18n/frontend_it.json
  4. 48
      backend/i18n/frontend_nl.json
  5. 48
      backend/i18n/frontend_pt.json
  6. 48
      backend/i18n/frontend_zh.json
  7. 48
      backend/i18n/source/frontend_en.json
  8. 24
      backend/i18n/source/frontend_fr.json
  9. 24
      backend/i18n/source/frontend_it.json
  10. 24
      backend/i18n/source/frontend_nl.json
  11. 24
      backend/i18n/source/frontend_pt.json
  12. 24
      backend/i18n/source/frontend_zh.json
  13. 8
      backend/src/Squidex.Domain.Users/UserManagerExtensions.cs
  14. 2
      backend/src/Squidex.Domain.Users/UserValues.cs
  15. 2
      backend/src/Squidex.Shared/Identity/SquidexClaimTypes.cs
  16. 28
      backend/src/Squidex/Areas/Api/Controllers/Users/Models/UpdateProfileDto.cs
  17. 20
      backend/src/Squidex/Areas/Api/Controllers/Users/UsersController.cs
  18. BIN
      backend/src/Squidex/wwwroot/images/client.png
  19. 95
      backend/src/Squidex/wwwroot/images/client.svg
  20. BIN
      backend/src/Squidex/wwwroot/images/onboarding-step1.png
  21. BIN
      backend/src/Squidex/wwwroot/images/onboarding-step2.png
  22. BIN
      backend/src/Squidex/wwwroot/images/onboarding-step3.png
  23. BIN
      backend/src/Squidex/wwwroot/images/onboarding-step4.png
  24. 17
      backend/src/Squidex/wwwroot/images/squid.svg
  25. BIN
      backend/src/Squidex/wwwroot/images/tour-apps.png
  26. BIN
      backend/src/Squidex/wwwroot/images/tour-assets.png
  27. BIN
      backend/src/Squidex/wwwroot/images/tour-content.png
  28. BIN
      backend/src/Squidex/wwwroot/images/tour-graphql.png
  29. BIN
      backend/src/Squidex/wwwroot/images/tour-languages.png
  30. BIN
      backend/src/Squidex/wwwroot/images/tour-rules.png
  31. BIN
      backend/src/Squidex/wwwroot/images/tour-schema.png
  32. BIN
      backend/src/Squidex/wwwroot/images/tour-workflow.png
  33. BIN
      frontend/src/app/assets/onboarding-background.png
  34. 90
      frontend/src/app/assets/squid.svg
  35. 15
      frontend/src/app/features/apps/pages/apps-page.component.html
  36. 13
      frontend/src/app/features/apps/pages/apps-page.component.scss
  37. 168
      frontend/src/app/features/apps/pages/onboarding-dialog.component.html
  38. 87
      frontend/src/app/features/apps/pages/onboarding-dialog.component.scss
  39. 23
      frontend/src/app/features/apps/pages/onboarding-dialog.component.ts
  40. 15
      frontend/src/app/features/dashboard/pages/dashboard-page.component.html
  41. 13
      frontend/src/app/features/dashboard/pages/dashboard-page.component.scss
  42. 15
      frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.html
  43. 13
      frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.scss
  44. 2
      frontend/src/app/shared/components/pipes.ts
  45. 10
      frontend/src/app/shared/services/users.service.spec.ts
  46. 11
      frontend/src/app/shared/services/users.service.ts

48
backend/i18n/frontend_en.json

@ -1065,19 +1065,43 @@
"templates.reloaded": "Templates reloaded.",
"tour.joinForum": "Join our Forum",
"tour.joinGithub": "Join us on Github",
"tour.projectBackend": "Backend Data Management",
"tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "",
"tour.projectPersonalBlog": "News Magazine",
"tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner",
"tour.roleContentCreator": "Content Creator",
"tour.roleEmployee": "Work at a company",
"tour.roleProductManager": "Product Manager",
"tour.roleSoftwareDeveloper": "Business Owner",
"tour.sizeLarge": "101-1000",
"tour.sizeMedium": "51-100",
"tour.sizeSingle": "1",
"tour.sizeSmall": "2-10",
"tour.sizeVeryLarge": "1000+",
"tour.skip": "Skip Tour",
"tour.step0Next": "Let's take a look around",
"tour.step0Text": "You can start managing and distributing your content right away, but we we'd like to walk you through some basics first...\n\nHow'that",
"tour.step1Next": "Continue",
"tour.step1Text": "An App is the repository for your project, e.g. (blog, web shop or mobile app). You can assign contributors to your app to work together.\n\nYou can create an unlimited number of Apps in Squidex to manage multiple projects at the same time.",
"tour.step2Next": "Keep going!",
"tour.step2Text": "Schemas define the structure of your content, the fields and the data types of a content item.\n\nBefore you can add content to your schema, make sure to hit the 'Publish' button at the top to make the schema available to your content appSettings.editors.",
"tour.step3Next": "Almost there!",
"tour.step3Text": "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.step4Next": "Got It!",
"tour.step4Text": "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.step5Text": "But that's not all of the support we can provide.\n\nYou can go to https://docs.squidex.io to read more.\n\nDo you want to join our community?",
"tour.step5Title": "Awesome, now you know the basics!",
"tour.stepAppNext": "Continue",
"tour.stepAppText": "An app is the repository for your project (for example a blog, web shop or mobile app). You can assign contributors to your app to work together.\n\nCreate an unlimited number of apps in Squidex to manage multiple projects at the same time.",
"tour.stepAssetsNext": "Got It!",
"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.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.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue",
"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.stepDataTitle": "About You",
"tour.stepIntroNext": "Let's take a look around",
"tour.stepIntroText": "You can start managing and distributing your content right away, but we we'd like to walk you through some basics first...\n\n",
"tour.stepOutroText": "But that's not all of the support we can provide.\n\nYou can go to https://docs.squidex.io to read more.\n\nDo you want to join our community?",
"tour.stepOutroTitle": "Awesome, now you know the basics!",
"tour.stepSchemasNext": "Keep going!",
"tour.stepSchemasText": "Schemas define the structure of your content, the fields and the data types of a content item.\n\nBefore you can add content to your schema, make sure to hit the publish button at the top to make the schema available to your content editors.",
"tour.tooltipConfirm": "Got It",
"tour.tooltipStop": "Stop Tour",
"tour.welcome": "Welcome to",

48
backend/i18n/frontend_fr.json

@ -1065,19 +1065,43 @@
"templates.reloaded": "Modèles rechargés.",
"tour.joinForum": "Rejoignez notre forum",
"tour.joinGithub": "Rejoignez-nous sur Github",
"tour.projectBackend": "Backend Data Management",
"tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "",
"tour.projectPersonalBlog": "News Magazine",
"tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner",
"tour.roleContentCreator": "Content Creator",
"tour.roleEmployee": "Work at a company",
"tour.roleProductManager": "Product Manager",
"tour.roleSoftwareDeveloper": "Business Owner",
"tour.sizeLarge": "101-1000",
"tour.sizeMedium": "51-100",
"tour.sizeSingle": "1",
"tour.sizeSmall": "2-10",
"tour.sizeVeryLarge": "1000+",
"tour.skip": "Passer le tour",
"tour.step0Next": "Jetons un coup d'œil autour",
"tour.step0Text": "Vous pouvez commencer à gérer et à distribuer votre contenu tout de suite, mais nous aimerions d'abord vous expliquer quelques notions de base...",
"tour.step1Next": "Continuer",
"tour.step1Text": "Une application est le référentiel de votre projet, par exemple (blog, boutique en ligne ou application mobile). Vous pouvez affecter des contributeurs à votre application pour travailler ensemble. Vous pouvez créer un nombre illimité d'applications dans Squidex pour gérer plusieurs projets en même temps.",
"tour.step2Next": "Continuer!",
"tour.step2Text": "Les schémas définissent la structure de votre contenu, les champs et les types de données d'un élément de contenu. Avant de pouvoir ajouter du contenu à votre schéma, assurez-vous d'appuyer sur le bouton \"Publier\" en haut pour rendre le schéma disponible pour vos appSettings.editors de contenu.",
"tour.step3Next": "Presque là!",
"tour.step3Text": "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.step4Next": "J'ai compris!",
"tour.step4Text": "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.step5Text": "Mais ce n'est pas tout le soutien que nous pouvons fournir. Vous pouvez aller sur https://docs.squidex.io pour en savoir plus. Vous souhaitez rejoindre notre communauté ?",
"tour.step5Title": "Génial, maintenant vous connaissez les bases !",
"tour.stepAppNext": "Continuer",
"tour.stepAppText": "Une application est le référentiel de votre projet, par exemple (blog, boutique en ligne ou application mobile). Vous pouvez affecter des contributeurs à votre application pour travailler ensemble. Vous pouvez créer un nombre illimité d'applications dans Squidex pour gérer plusieurs projets en même temps.",
"tour.stepAssetsNext": "J'ai compris!",
"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.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.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue",
"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.stepDataTitle": "About You",
"tour.stepIntroNext": "Jetons un coup d'œil autour",
"tour.stepIntroText": "Vous pouvez commencer à gérer et à distribuer votre contenu tout de suite, mais nous aimerions d'abord vous expliquer quelques notions de base...",
"tour.stepOutroText": "Mais ce n'est pas tout le soutien que nous pouvons fournir. Vous pouvez aller sur https://docs.squidex.io pour en savoir plus. Vous souhaitez rejoindre notre communauté ?",
"tour.stepOutroTitle": "Génial, maintenant vous connaissez les bases !",
"tour.stepSchemasNext": "Continuer!",
"tour.stepSchemasText": "Les schémas définissent la structure de votre contenu, les champs et les types de données d'un élément de contenu. Avant de pouvoir ajouter du contenu à votre schéma, assurez-vous d'appuyer sur le bouton \"Publier\" en haut pour rendre le schéma disponible pour vos appSettings.editors de contenu.",
"tour.tooltipConfirm": "J'ai compris",
"tour.tooltipStop": "Visite d'arrêt",
"tour.welcome": "Bienvenue à",

48
backend/i18n/frontend_it.json

@ -1065,19 +1065,43 @@
"templates.reloaded": "Templates reloaded.",
"tour.joinForum": "Unisciti al nostro Forum",
"tour.joinGithub": "Unisciti a Github",
"tour.projectBackend": "Backend Data Management",
"tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "",
"tour.projectPersonalBlog": "News Magazine",
"tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner",
"tour.roleContentCreator": "Content Creator",
"tour.roleEmployee": "Work at a company",
"tour.roleProductManager": "Product Manager",
"tour.roleSoftwareDeveloper": "Business Owner",
"tour.sizeLarge": "101-1000",
"tour.sizeMedium": "51-100",
"tour.sizeSingle": "1",
"tour.sizeSmall": "2-10",
"tour.sizeVeryLarge": "1000+",
"tour.skip": "Salta il Tour",
"tour.step0Next": "Guardiamoci intorno",
"tour.step0Text": "Puoi iniziare subito a gestire e distribuire i tuoi contenuti, ma prima vorremmo illustrarti alcune nozioni di base...\n\nIn questo modo",
"tour.step1Next": "Continua",
"tour.step1Text": "Un'App è il repository per il tuo progetto, ad es. (un blog, un negozio sul web o una app per dispositivi mobili). Puoi assegnare collaboratori alla tua App per lavorare insieme.\n\nPuoi creare un numero illimitato di app in Squidex per gestire più progetti contemporaneamente.",
"tour.step2Next": "Vai avanti!",
"tour.step2Text": "Gli Schemi definiscono la struttura per i tuoi contenuti, i campi e i tipi di dato per ogni tipo di contenuto.\n\nPrima di creare un contenuto riferito al tuo schema, assicurati di aver pubblicato lo schema premendo il pulsante 'Pubblica' visualizzato nell'editor dei contenuti.",
"tour.step3Next": "Ci siamo quasi!",
"tour.step3Text": "I contenuti della tua app sono raggruppati tramite gli schemi.\n\nSeleziona uno schema pubblicato e poi crea il relativo contenuto.",
"tour.step4Next": "Fatto!",
"tour.step4Text": "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.step5Text": "Ma non è tutto il supporto che possiamo fornire.\n\nPer maggiori informazioni visita il sito https://docs.squidex.io.\n\nVuoi far parte della nostra community?",
"tour.step5Title": "Fantastico, ora conosci le basi!",
"tour.stepAppNext": "Continua",
"tour.stepAppText": "Un'App è il repository per il tuo progetto, ad es. (un blog, un negozio sul web o una app per dispositivi mobili). Puoi assegnare collaboratori alla tua App per lavorare insieme.\n\nPuoi creare un numero illimitato di app in Squidex per gestire più progetti contemporaneamente.",
"tour.stepAssetsNext": "Fatto!",
"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.stepContentText": "I contenuti della tua app sono raggruppati tramite gli schemi.\n\nSeleziona uno schema pubblicato e poi crea il relativo contenuto.",
"tour.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue",
"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.stepDataTitle": "About You",
"tour.stepIntroNext": "Guardiamoci intorno",
"tour.stepIntroText": "Puoi iniziare subito a gestire e distribuire i tuoi contenuti, ma prima vorremmo illustrarti alcune nozioni di base...\n\nIn questo modo",
"tour.stepOutroText": "Ma non è tutto il supporto che possiamo fornire.\n\nPer maggiori informazioni visita il sito https://docs.squidex.io.\n\nVuoi far parte della nostra community?",
"tour.stepOutroTitle": "Fantastico, ora conosci le basi!",
"tour.stepSchemasNext": "Vai avanti!",
"tour.stepSchemasText": "Gli Schemi definiscono la struttura per i tuoi contenuti, i campi e i tipi di dato per ogni tipo di contenuto.\n\nPrima di creare un contenuto riferito al tuo schema, assicurati di aver pubblicato lo schema premendo il pulsante 'Pubblica' visualizzato nell'editor dei contenuti.",
"tour.tooltipConfirm": "Capito",
"tour.tooltipStop": "Ferma il Tour",
"tour.welcome": "Benvenuto su",

48
backend/i18n/frontend_nl.json

@ -1065,19 +1065,43 @@
"templates.reloaded": "Templates reloaded.",
"tour.joinForum": "Word lid van ons forum",
"tour.joinGithub": "Bezoek ons ​​op Github",
"tour.projectBackend": "Backend Data Management",
"tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "",
"tour.projectPersonalBlog": "News Magazine",
"tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner",
"tour.roleContentCreator": "Content Creator",
"tour.roleEmployee": "Work at a company",
"tour.roleProductManager": "Product Manager",
"tour.roleSoftwareDeveloper": "Business Owner",
"tour.sizeLarge": "101-1000",
"tour.sizeMedium": "51-100",
"tour.sizeSingle": "1",
"tour.sizeSmall": "2-10",
"tour.sizeVeryLarge": "1000+",
"tour.skip": "Tour overslaan",
"tour.step0Next": "Laten we eens rondkijken",
"tour.step0Text": "Je kunt direct beginnen met het beheren en distribueren van uw inhoud, maar we willen je graag eerst wat basisbeginselen laten zien ... \n \n Hoe dat",
"tour.step1Next": "Doorgaan",
"tour.step1Text": "Een app is de opslagplaats voor uw project, bijvoorbeeld (blog, webshop of mobiele app). Je kunt bijdragers aan uw app toewijzen om samen te werken. \n \n Je kunt een onbeperkt aantal apps maken in Squidex om meerdere projecten tegelijkertijd te beheren. ",
"tour.step2Next": "Ga door!",
"tour.step2Text": "Schema's bepalen de structuur van uw inhoud, de velden en de gegevenstypen van een inhoudsitem. \n \n Voordat je inhoud aan uw schema kunt toevoegen, moet je op de knop 'Publiceren' bovenaan klikken om het schema beschikbaar te maken voor uw inhoudappSettings.editors. ",
"tour.step3Next": "Bijna klaar!",
"tour.step3Text": "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.step4Next": "Begrepen!",
"tour.step4Text": "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.step5Text": "Maar dat is niet alle ondersteuning die we kunnen bieden. \n \n Je kunt naar https://docs.squidex.io gaan om meer te lezen. \n \n Wil je lid worden van onze community ? ",
"tour.step5Title": "Geweldig, nu ken je de basis!",
"tour.stepAppNext": "Doorgaan",
"tour.stepAppText": "Een app is de opslagplaats voor uw project, bijvoorbeeld (blog, webshop of mobiele app). Je kunt bijdragers aan uw app toewijzen om samen te werken. \n \n Je kunt een onbeperkt aantal apps maken in Squidex om meerdere projecten tegelijkertijd te beheren. ",
"tour.stepAssetsNext": "Begrepen!",
"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.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.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue",
"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.stepDataTitle": "About You",
"tour.stepIntroNext": "Laten we eens rondkijken",
"tour.stepIntroText": "Je kunt direct beginnen met het beheren en distribueren van uw inhoud, maar we willen je graag eerst wat basisbeginselen laten zien ... \n \n Hoe dat",
"tour.stepOutroText": "Maar dat is niet alle ondersteuning die we kunnen bieden. \n \n Je kunt naar https://docs.squidex.io gaan om meer te lezen. \n \n Wil je lid worden van onze community ? ",
"tour.stepOutroTitle": "Geweldig, nu ken je de basis!",
"tour.stepSchemasNext": "Ga door!",
"tour.stepSchemasText": "Schema's bepalen de structuur van uw inhoud, de velden en de gegevenstypen van een inhoudsitem. \n \n Voordat je inhoud aan uw schema kunt toevoegen, moet je op de knop 'Publiceren' bovenaan klikken om het schema beschikbaar te maken voor uw inhoudappSettings.editors. ",
"tour.tooltipConfirm": "Begrepen",
"tour.tooltipStop": "Tour stoppen",
"tour.welcome": "Welkom bij",

48
backend/i18n/frontend_pt.json

@ -1065,19 +1065,43 @@
"templates.reloaded": "Modelos recarregados.",
"tour.joinForum": "Junte-se ao nosso Fórum",
"tour.joinGithub": "Junte-se a nós em Github",
"tour.projectBackend": "Backend Data Management",
"tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "",
"tour.projectPersonalBlog": "News Magazine",
"tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner",
"tour.roleContentCreator": "Content Creator",
"tour.roleEmployee": "Work at a company",
"tour.roleProductManager": "Product Manager",
"tour.roleSoftwareDeveloper": "Business Owner",
"tour.sizeLarge": "101-1000",
"tour.sizeMedium": "51-100",
"tour.sizeSingle": "1",
"tour.sizeSmall": "2-10",
"tour.sizeVeryLarge": "1000+",
"tour.skip": "Tour de salto",
"tour.step0Next": "Vamos dar uma vista de olhos.",
"tour.step0Text": "Pode começar a gerir e distribuir o seu conteúdo imediatamente, mas gostaríamos de o acompanhar primeiro...\n\nComo é que",
"tour.step1Next": "Continuar",
"tour.step1Text": "Uma App é o repositório do seu projeto, por exemplo (blog, web shop ou aplicativo móvel). Pode atribuir colaboradores à sua aplicação para trabalharem em conjunto.\n\nPode criar um número ilimitado de Apps em Squidex para gerir vários projetos ao mesmo tempo.",
"tour.step2Next": "Continua!",
"tour.step2Text": "Os esquemas definem a estrutura do seu conteúdo, os campos e os tipos de dados de um item de conteúdo.\n\nAntes de poder adicionar conteúdo ao seu esquema, certifique-se de carregar no botão 'Publicar' no topo para disponibilizar o esquema para as suas aplicações de conteúdoSettings.editores.",
"tour.step3Next": "Está quase!",
"tour.step3Text": "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.step4Next": "Apanhei!",
"tour.step4Text": "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.step5Text": "Mas não é todo o apoio que podemos dar.\n\nPode ir a https://docs.squidex.io ler mais.\n\nQuer se juntar à nossa comunidade?",
"tour.step5Title": "Incrível, agora já sabes o básico!",
"tour.stepAppNext": "Continuar",
"tour.stepAppText": "Uma App é o repositório do seu projeto, por exemplo (blog, web shop ou aplicativo móvel). Pode atribuir colaboradores à sua aplicação para trabalharem em conjunto.\n\nPode criar um número ilimitado de Apps em Squidex para gerir vários projetos ao mesmo tempo.",
"tour.stepAssetsNext": "Apanhei!",
"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.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.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue",
"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.stepDataTitle": "About You",
"tour.stepIntroNext": "Vamos dar uma vista de olhos.",
"tour.stepIntroText": "Pode começar a gerir e distribuir o seu conteúdo imediatamente, mas gostaríamos de o acompanhar primeiro...\n\nComo é que",
"tour.stepOutroText": "Mas não é todo o apoio que podemos dar.\n\nPode ir a https://docs.squidex.io ler mais.\n\nQuer se juntar à nossa comunidade?",
"tour.stepOutroTitle": "Incrível, agora já sabes o básico!",
"tour.stepSchemasNext": "Continua!",
"tour.stepSchemasText": "Os esquemas definem a estrutura do seu conteúdo, os campos e os tipos de dados de um item de conteúdo.\n\nAntes de poder adicionar conteúdo ao seu esquema, certifique-se de carregar no botão 'Publicar' no topo para disponibilizar o esquema para as suas aplicações de conteúdoSettings.editores.",
"tour.tooltipConfirm": "Entendi",
"tour.tooltipStop": "Terminar Tour",
"tour.welcome": "Bem vindo a",

48
backend/i18n/frontend_zh.json

@ -1065,19 +1065,43 @@
"templates.reloaded": "Templates reloaded.",
"tour.joinForum": "加入我们的论坛",
"tour.joinGithub": "加入我们的 Github",
"tour.projectBackend": "Backend Data Management",
"tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "",
"tour.projectPersonalBlog": "News Magazine",
"tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner",
"tour.roleContentCreator": "Content Creator",
"tour.roleEmployee": "Work at a company",
"tour.roleProductManager": "Product Manager",
"tour.roleSoftwareDeveloper": "Business Owner",
"tour.sizeLarge": "101-1000",
"tour.sizeMedium": "51-100",
"tour.sizeSingle": "1",
"tour.sizeSmall": "2-10",
"tour.sizeVeryLarge": "1000+",
"tour.skip": "跳过游览",
"tour.step0Next": "我们看看周围",
"tour.step0Text": "您可以立即开始管理和分发您的内容,但我们想先向您介绍一些基础知识...\n\n如何",
"tour.step1Next": "继续",
"tour.step1Text": "应用程序是您项目的存储库,例如(博客、网上商店或移动应用程序)。您可以为您的应用程序分配贡献者以协同工作。\n\n您可以在其中创建无限数量的应用程序Squidex 同时管理多个项目。",
"tour.step2Next": "继续!",
"tour.step2Text": "Schemas定义内容的结构、内容项的字段和数据类型。\n\n在向Schemas添加内容之前,请确保点击顶部的“发布”按钮使Schemas可用于您的内容 appSettings.editors。",
"tour.step3Next": "快到了!",
"tour.step3Text": "内容是您的应用程序中按Schemas分组的实际数据。\n\n首先选择一个已发布的Schemas,然后为此Schemas添加内容。",
"tour.step4Next": "知道了!",
"tour.step4Text": "资源包含所有也可以链接到您的内容的文件。例如图像、视频或文档。\n\n您可以在此处上传资源供以后使用,也可以在创建时直接上传带有资源字段的新内容项。",
"tour.step5Text": "但这还不是我们可以提供的全部支持。\n\n您可以访问 https://docs.squidex.io 阅读更多信息。\n\n您想加入我们的社区吗? ?",
"tour.step5Title": "太棒了,现在你知道基础了!",
"tour.stepAppNext": "继续",
"tour.stepAppText": "应用程序是您项目的存储库,例如(博客、网上商店或移动应用程序)。您可以为您的应用程序分配贡献者以协同工作。\n\n您可以在其中创建无限数量的应用程序Squidex 同时管理多个项目。",
"tour.stepAssetsNext": "知道了!",
"tour.stepAssetsText": "资源包含所有也可以链接到您的内容的文件。例如图像、视频或文档。\n\n您可以在此处上传资源供以后使用,也可以在创建时直接上传带有资源字段的新内容项。",
"tour.stepContentNext": "快到了!",
"tour.stepContentText": "内容是您的应用程序中按Schemas分组的实际数据。\n\n首先选择一个已发布的Schemas,然后为此Schemas添加内容。",
"tour.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue",
"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.stepDataTitle": "About You",
"tour.stepIntroNext": "我们看看周围",
"tour.stepIntroText": "您可以立即开始管理和分发您的内容,但我们想先向您介绍一些基础知识...\n\n如何",
"tour.stepOutroText": "但这还不是我们可以提供的全部支持。\n\n您可以访问 https://docs.squidex.io 阅读更多信息。\n\n您想加入我们的社区吗? ?",
"tour.stepOutroTitle": "太棒了,现在你知道基础了!",
"tour.stepSchemasNext": "继续!",
"tour.stepSchemasText": "Schemas定义内容的结构、内容项的字段和数据类型。\n\n在向Schemas添加内容之前,请确保点击顶部的“发布”按钮使Schemas可用于您的内容 appSettings.editors。",
"tour.tooltipConfirm": "知道了",
"tour.tooltipStop": "停止游览",
"tour.welcome": "欢迎来到",

48
backend/i18n/source/frontend_en.json

@ -1065,19 +1065,43 @@
"templates.reloaded": "Templates reloaded.",
"tour.joinForum": "Join our Forum",
"tour.joinGithub": "Join us on Github",
"tour.projectBackend": "Backend Data Management",
"tour.projectCommerce": "E-Commerce Solution",
"tour.projectLearning": "None, I am just here for learning",
"tour.projectMobileApp": "Mobile App",
"tour.projectNewsMagazine": "",
"tour.projectPersonalBlog": "News Magazine",
"tour.projectSmallBusiness": "Website for Small Business",
"tour.roleBusinessAnalyst": "Business Analyst",
"tour.roleBusinessOwner": "Business Owner",
"tour.roleContentCreator": "Content Creator",
"tour.roleEmployee": "Work at a company",
"tour.roleProductManager": "Product Manager",
"tour.roleSoftwareDeveloper": "Business Owner",
"tour.sizeLarge": "101-1000",
"tour.sizeMedium": "51-100",
"tour.sizeSingle": "1",
"tour.sizeSmall": "2-10",
"tour.sizeVeryLarge": "1000+",
"tour.skip": "Skip Tour",
"tour.step0Next": "Let's take a look around",
"tour.step0Text": "You can start managing and distributing your content right away, but we we'd like to walk you through some basics first...\n\nHow'that",
"tour.step1Next": "Continue",
"tour.step1Text": "An App is the repository for your project, e.g. (blog, web shop or mobile app). You can assign contributors to your app to work together.\n\nYou can create an unlimited number of Apps in Squidex to manage multiple projects at the same time.",
"tour.step2Next": "Keep going!",
"tour.step2Text": "Schemas define the structure of your content, the fields and the data types of a content item.\n\nBefore you can add content to your schema, make sure to hit the 'Publish' button at the top to make the schema available to your content appSettings.editors.",
"tour.step3Next": "Almost there!",
"tour.step3Text": "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.step4Next": "Got It!",
"tour.step4Text": "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.step5Text": "But that's not all of the support we can provide.\n\nYou can go to https://docs.squidex.io to read more.\n\nDo you want to join our community?",
"tour.step5Title": "Awesome, now you know the basics!",
"tour.stepAppNext": "Continue",
"tour.stepAppText": "An app is the repository for your project (for example a blog, web shop or mobile app). You can assign contributors to your app to work together.\n\nCreate an unlimited number of apps in Squidex to manage multiple projects at the same time.",
"tour.stepAssetsNext": "Got It!",
"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.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.stepDataCompanySize": "How many people work in a company?",
"tour.stepDataNext": "Continue",
"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.stepDataTitle": "About You",
"tour.stepIntroNext": "Let's take a look around",
"tour.stepIntroText": "You can start managing and distributing your content right away, but we we'd like to walk you through some basics first...\n\n",
"tour.stepOutroText": "But that's not all of the support we can provide.\n\nYou can go to https://docs.squidex.io to read more.\n\nDo you want to join our community?",
"tour.stepOutroTitle": "Awesome, now you know the basics!",
"tour.stepSchemasNext": "Keep going!",
"tour.stepSchemasText": "Schemas define the structure of your content, the fields and the data types of a content item.\n\nBefore you can add content to your schema, make sure to hit the publish button at the top to make the schema available to your content editors.",
"tour.tooltipConfirm": "Got It",
"tour.tooltipStop": "Stop Tour",
"tour.welcome": "Welcome to",

24
backend/i18n/source/frontend_fr.json

@ -1042,18 +1042,18 @@
"tour.joinForum": "Rejoignez notre forum",
"tour.joinGithub": "Rejoignez-nous sur Github",
"tour.skip": "Passer le tour",
"tour.step0Next": "Jetons un coup d'œil autour",
"tour.step0Text": "Vous pouvez commencer à gérer et à distribuer votre contenu tout de suite, mais nous aimerions d'abord vous expliquer quelques notions de base...",
"tour.step1Next": "Continuer",
"tour.step1Text": "Une application est le référentiel de votre projet, par exemple (blog, boutique en ligne ou application mobile). Vous pouvez affecter des contributeurs à votre application pour travailler ensemble. Vous pouvez créer un nombre illimité d'applications dans Squidex pour gérer plusieurs projets en même temps.",
"tour.step2Next": "Continuer!",
"tour.step2Text": "Les schémas définissent la structure de votre contenu, les champs et les types de données d'un élément de contenu. Avant de pouvoir ajouter du contenu à votre schéma, assurez-vous d'appuyer sur le bouton \"Publier\" en haut pour rendre le schéma disponible pour vos appSettings.editors de contenu.",
"tour.step3Next": "Presque là!",
"tour.step3Text": "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.step4Next": "J'ai compris!",
"tour.step4Text": "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.step5Text": "Mais ce n'est pas tout le soutien que nous pouvons fournir. Vous pouvez aller sur https://docs.squidex.io pour en savoir plus. Vous souhaitez rejoindre notre communauté ?",
"tour.step5Title": "Génial, maintenant vous connaissez les bases !",
"tour.stepAppNext": "Continuer",
"tour.stepAppText": "Une application est le référentiel de votre projet, par exemple (blog, boutique en ligne ou application mobile). Vous pouvez affecter des contributeurs à votre application pour travailler ensemble. Vous pouvez créer un nombre illimité d'applications dans Squidex pour gérer plusieurs projets en même temps.",
"tour.stepAssetsNext": "J'ai compris!",
"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.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.stepIntroNext": "Jetons un coup d'œil autour",
"tour.stepIntroText": "Vous pouvez commencer à gérer et à distribuer votre contenu tout de suite, mais nous aimerions d'abord vous expliquer quelques notions de base...",
"tour.stepOutroText": "Mais ce n'est pas tout le soutien que nous pouvons fournir. Vous pouvez aller sur https://docs.squidex.io pour en savoir plus. Vous souhaitez rejoindre notre communauté ?",
"tour.stepOutroTitle": "Génial, maintenant vous connaissez les bases !",
"tour.stepSchemasNext": "Continuer!",
"tour.stepSchemasText": "Les schémas définissent la structure de votre contenu, les champs et les types de données d'un élément de contenu. Avant de pouvoir ajouter du contenu à votre schéma, assurez-vous d'appuyer sur le bouton \"Publier\" en haut pour rendre le schéma disponible pour vos appSettings.editors de contenu.",
"tour.tooltipConfirm": "J'ai compris",
"tour.tooltipStop": "Visite d'arrêt",
"tour.welcome": "Bienvenue à",

24
backend/i18n/source/frontend_it.json

@ -815,18 +815,18 @@
"tour.joinForum": "Unisciti al nostro Forum",
"tour.joinGithub": "Unisciti a Github",
"tour.skip": "Salta il Tour",
"tour.step0Next": "Guardiamoci intorno",
"tour.step0Text": "Puoi iniziare subito a gestire e distribuire i tuoi contenuti, ma prima vorremmo illustrarti alcune nozioni di base...\n\nIn questo modo",
"tour.step1Next": "Continua",
"tour.step1Text": "Un'App è il repository per il tuo progetto, ad es. (un blog, un negozio sul web o una app per dispositivi mobili). Puoi assegnare collaboratori alla tua App per lavorare insieme.\n\nPuoi creare un numero illimitato di app in Squidex per gestire più progetti contemporaneamente.",
"tour.step2Next": "Vai avanti!",
"tour.step2Text": "Gli Schemi definiscono la struttura per i tuoi contenuti, i campi e i tipi di dato per ogni tipo di contenuto.\n\nPrima di creare un contenuto riferito al tuo schema, assicurati di aver pubblicato lo schema premendo il pulsante 'Pubblica' visualizzato nell'editor dei contenuti.",
"tour.step3Next": "Ci siamo quasi!",
"tour.step3Text": "I contenuti della tua app sono raggruppati tramite gli schemi.\n\nSeleziona uno schema pubblicato e poi crea il relativo contenuto.",
"tour.step4Next": "Fatto!",
"tour.step4Text": "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.step5Text": "Ma non è tutto il supporto che possiamo fornire.\n\nPer maggiori informazioni visita il sito https://docs.squidex.io.\n\nVuoi far parte della nostra community?",
"tour.step5Title": "Fantastico, ora conosci le basi!",
"tour.stepAppNext": "Continua",
"tour.stepAppText": "Un'App è il repository per il tuo progetto, ad es. (un blog, un negozio sul web o una app per dispositivi mobili). Puoi assegnare collaboratori alla tua App per lavorare insieme.\n\nPuoi creare un numero illimitato di app in Squidex per gestire più progetti contemporaneamente.",
"tour.stepAssetsNext": "Fatto!",
"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.stepContentText": "I contenuti della tua app sono raggruppati tramite gli schemi.\n\nSeleziona uno schema pubblicato e poi crea il relativo contenuto.",
"tour.stepIntroNext": "Guardiamoci intorno",
"tour.stepIntroText": "Puoi iniziare subito a gestire e distribuire i tuoi contenuti, ma prima vorremmo illustrarti alcune nozioni di base...\n\nIn questo modo",
"tour.stepOutroText": "Ma non è tutto il supporto che possiamo fornire.\n\nPer maggiori informazioni visita il sito https://docs.squidex.io.\n\nVuoi far parte della nostra community?",
"tour.stepOutroTitle": "Fantastico, ora conosci le basi!",
"tour.stepSchemasNext": "Vai avanti!",
"tour.stepSchemasText": "Gli Schemi definiscono la struttura per i tuoi contenuti, i campi e i tipi di dato per ogni tipo di contenuto.\n\nPrima di creare un contenuto riferito al tuo schema, assicurati di aver pubblicato lo schema premendo il pulsante 'Pubblica' visualizzato nell'editor dei contenuti.",
"tour.tooltipConfirm": "Capito",
"tour.tooltipStop": "Ferma il Tour",
"tour.welcome": "Benvenuto su",

24
backend/i18n/source/frontend_nl.json

@ -937,18 +937,18 @@
"tour.joinForum": "Word lid van ons forum",
"tour.joinGithub": "Bezoek ons ​​op Github",
"tour.skip": "Tour overslaan",
"tour.step0Next": "Laten we eens rondkijken",
"tour.step0Text": "Je kunt direct beginnen met het beheren en distribueren van uw inhoud, maar we willen je graag eerst wat basisbeginselen laten zien ... \n \n Hoe dat",
"tour.step1Next": "Doorgaan",
"tour.step1Text": "Een app is de opslagplaats voor uw project, bijvoorbeeld (blog, webshop of mobiele app). Je kunt bijdragers aan uw app toewijzen om samen te werken. \n \n Je kunt een onbeperkt aantal apps maken in Squidex om meerdere projecten tegelijkertijd te beheren. ",
"tour.step2Next": "Ga door!",
"tour.step2Text": "Schema's bepalen de structuur van uw inhoud, de velden en de gegevenstypen van een inhoudsitem. \n \n Voordat je inhoud aan uw schema kunt toevoegen, moet je op de knop 'Publiceren' bovenaan klikken om het schema beschikbaar te maken voor uw inhoudappSettings.editors. ",
"tour.step3Next": "Bijna klaar!",
"tour.step3Text": "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.step4Next": "Begrepen!",
"tour.step4Text": "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.step5Text": "Maar dat is niet alle ondersteuning die we kunnen bieden. \n \n Je kunt naar https://docs.squidex.io gaan om meer te lezen. \n \n Wil je lid worden van onze community ? ",
"tour.step5Title": "Geweldig, nu ken je de basis!",
"tour.stepAppNext": "Doorgaan",
"tour.stepAppText": "Een app is de opslagplaats voor uw project, bijvoorbeeld (blog, webshop of mobiele app). Je kunt bijdragers aan uw app toewijzen om samen te werken. \n \n Je kunt een onbeperkt aantal apps maken in Squidex om meerdere projecten tegelijkertijd te beheren. ",
"tour.stepAssetsNext": "Begrepen!",
"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.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.stepIntroNext": "Laten we eens rondkijken",
"tour.stepIntroText": "Je kunt direct beginnen met het beheren en distribueren van uw inhoud, maar we willen je graag eerst wat basisbeginselen laten zien ... \n \n Hoe dat",
"tour.stepOutroText": "Maar dat is niet alle ondersteuning die we kunnen bieden. \n \n Je kunt naar https://docs.squidex.io gaan om meer te lezen. \n \n Wil je lid worden van onze community ? ",
"tour.stepOutroTitle": "Geweldig, nu ken je de basis!",
"tour.stepSchemasNext": "Ga door!",
"tour.stepSchemasText": "Schema's bepalen de structuur van uw inhoud, de velden en de gegevenstypen van een inhoudsitem. \n \n Voordat je inhoud aan uw schema kunt toevoegen, moet je op de knop 'Publiceren' bovenaan klikken om het schema beschikbaar te maken voor uw inhoudappSettings.editors. ",
"tour.tooltipConfirm": "Begrepen",
"tour.tooltipStop": "Tour stoppen",
"tour.welcome": "Welkom bij",

24
backend/i18n/source/frontend_pt.json

@ -1013,18 +1013,18 @@
"tour.joinForum": "Junte-se ao nosso Fórum",
"tour.joinGithub": "Junte-se a nós em Github",
"tour.skip": "Tour de salto",
"tour.step0Next": "Vamos dar uma vista de olhos.",
"tour.step0Text": "Pode começar a gerir e distribuir o seu conteúdo imediatamente, mas gostaríamos de o acompanhar primeiro...\n\nComo é que",
"tour.step1Next": "Continuar",
"tour.step1Text": "Uma App é o repositório do seu projeto, por exemplo (blog, web shop ou aplicativo móvel). Pode atribuir colaboradores à sua aplicação para trabalharem em conjunto.\n\nPode criar um número ilimitado de Apps em Squidex para gerir vários projetos ao mesmo tempo.",
"tour.step2Next": "Continua!",
"tour.step2Text": "Os esquemas definem a estrutura do seu conteúdo, os campos e os tipos de dados de um item de conteúdo.\n\nAntes de poder adicionar conteúdo ao seu esquema, certifique-se de carregar no botão 'Publicar' no topo para disponibilizar o esquema para as suas aplicações de conteúdoSettings.editores.",
"tour.step3Next": "Está quase!",
"tour.step3Text": "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.step4Next": "Apanhei!",
"tour.step4Text": "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.step5Text": "Mas não é todo o apoio que podemos dar.\n\nPode ir a https://docs.squidex.io ler mais.\n\nQuer se juntar à nossa comunidade?",
"tour.step5Title": "Incrível, agora já sabes o básico!",
"tour.stepAppNext": "Continuar",
"tour.stepAppText": "Uma App é o repositório do seu projeto, por exemplo (blog, web shop ou aplicativo móvel). Pode atribuir colaboradores à sua aplicação para trabalharem em conjunto.\n\nPode criar um número ilimitado de Apps em Squidex para gerir vários projetos ao mesmo tempo.",
"tour.stepAssetsNext": "Apanhei!",
"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.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.stepIntroNext": "Vamos dar uma vista de olhos.",
"tour.stepIntroText": "Pode começar a gerir e distribuir o seu conteúdo imediatamente, mas gostaríamos de o acompanhar primeiro...\n\nComo é que",
"tour.stepOutroText": "Mas não é todo o apoio que podemos dar.\n\nPode ir a https://docs.squidex.io ler mais.\n\nQuer se juntar à nossa comunidade?",
"tour.stepOutroTitle": "Incrível, agora já sabes o básico!",
"tour.stepSchemasNext": "Continua!",
"tour.stepSchemasText": "Os esquemas definem a estrutura do seu conteúdo, os campos e os tipos de dados de um item de conteúdo.\n\nAntes de poder adicionar conteúdo ao seu esquema, certifique-se de carregar no botão 'Publicar' no topo para disponibilizar o esquema para as suas aplicações de conteúdoSettings.editores.",
"tour.tooltipConfirm": "Entendi",
"tour.tooltipStop": "Terminar Tour",
"tour.welcome": "Bem vindo a",

24
backend/i18n/source/frontend_zh.json

@ -826,18 +826,18 @@
"tour.joinForum": "加入我们的论坛",
"tour.joinGithub": "加入我们的 Github",
"tour.skip": "跳过游览",
"tour.step0Next": "我们看看周围",
"tour.step0Text": "您可以立即开始管理和分发您的内容,但我们想先向您介绍一些基础知识...\n\n如何",
"tour.step1Next": "继续",
"tour.step1Text": "应用程序是您项目的存储库,例如(博客、网上商店或移动应用程序)。您可以为您的应用程序分配贡献者以协同工作。\n\n您可以在其中创建无限数量的应用程序Squidex 同时管理多个项目。",
"tour.step2Next": "继续!",
"tour.step2Text": "Schemas定义内容的结构、内容项的字段和数据类型。\n\n在向Schemas添加内容之前,请确保点击顶部的“发布”按钮使Schemas可用于您的内容 appSettings.editors。",
"tour.step3Next": "快到了!",
"tour.step3Text": "内容是您的应用程序中按Schemas分组的实际数据。\n\n首先选择一个已发布的Schemas,然后为此Schemas添加内容。",
"tour.step4Next": "知道了!",
"tour.step4Text": "资源包含所有也可以链接到您的内容的文件。例如图像、视频或文档。\n\n您可以在此处上传资源供以后使用,也可以在创建时直接上传带有资源字段的新内容项。",
"tour.step5Text": "但这还不是我们可以提供的全部支持。\n\n您可以访问 https://docs.squidex.io 阅读更多信息。\n\n您想加入我们的社区吗? ?",
"tour.step5Title": "太棒了,现在你知道基础了!",
"tour.stepAppNext": "继续",
"tour.stepAppText": "应用程序是您项目的存储库,例如(博客、网上商店或移动应用程序)。您可以为您的应用程序分配贡献者以协同工作。\n\n您可以在其中创建无限数量的应用程序Squidex 同时管理多个项目。",
"tour.stepAssetsNext": "知道了!",
"tour.stepAssetsText": "资源包含所有也可以链接到您的内容的文件。例如图像、视频或文档。\n\n您可以在此处上传资源供以后使用,也可以在创建时直接上传带有资源字段的新内容项。",
"tour.stepContentNext": "快到了!",
"tour.stepContentText": "内容是您的应用程序中按Schemas分组的实际数据。\n\n首先选择一个已发布的Schemas,然后为此Schemas添加内容。",
"tour.stepIntroNext": "我们看看周围",
"tour.stepIntroText": "您可以立即开始管理和分发您的内容,但我们想先向您介绍一些基础知识...\n\n如何",
"tour.stepOutroText": "但这还不是我们可以提供的全部支持。\n\n您可以访问 https://docs.squidex.io 阅读更多信息。\n\n您想加入我们的社区吗? ?",
"tour.stepOutroTitle": "太棒了,现在你知道基础了!",
"tour.stepSchemasNext": "继续!",
"tour.stepSchemasText": "Schemas定义内容的结构、内容项的字段和数据类型。\n\n在向Schemas添加内容之前,请确保点击顶部的“发布”按钮使Schemas可用于您的内容 appSettings.editors。",
"tour.tooltipConfirm": "知道了",
"tour.tooltipStop": "停止游览",
"tour.welcome": "欢迎来到",

8
backend/src/Squidex.Domain.Users/UserManagerExtensions.cs

@ -125,6 +125,14 @@ internal static class UserManagerExtensions
}
}
if (values.Answers != null)
{
foreach (var (name, value) in values.Answers.Where(x => !string.IsNullOrWhiteSpace(x.Value)))
{
AddClaim(SquidexClaimTypes.Answer, $"{name}={value}");
}
}
if (values.CustomClaims != null)
{
foreach (var group in values.CustomClaims.GroupBy(x => x.Type))

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

@ -35,4 +35,6 @@ public sealed class UserValues
public List<Claim>? CustomClaims { get; set; }
public List<(string Name, string Value)>? Properties { get; set; }
public Dictionary<string, string>? Answers { get; set; }
}

2
backend/src/Squidex.Shared/Identity/SquidexClaimTypes.cs

@ -31,6 +31,8 @@ namespace Squidex.Shared.Identity
public const string PictureUrlStore = "store";
public const string Answer = "urn:squidex:answer";
public const string TotalApps = "urn:squidex:internal:totalApps";
public const string UIProperty = "urn:squidex:ui";

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

@ -0,0 +1,28 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Domain.Users;
using Squidex.Web;
namespace Squidex.Areas.Api.Controllers.Users.Models;
[OpenApiRequest]
public sealed class UpdateProfileDto
{
/// <summary>
/// The answers from a questionaire.
/// </summary>
public Dictionary<string, string>? Answers { get; set; }
public UserValues ToValues()
{
return new UserValues
{
Answers = Answers
};
}
}

20
backend/src/Squidex/Areas/Api/Controllers/Users/UsersController.cs

@ -25,6 +25,7 @@ public sealed class UsersController : ApiController
private static readonly byte[] AvatarBytes;
private readonly IHttpClientFactory httpClientFactory;
private readonly IUserPictureStore userPictureStore;
private readonly IUserService userService;
private readonly IUserResolver userResolver;
private readonly ILogger<UsersController> log;
@ -45,13 +46,14 @@ public sealed class UsersController : ApiController
IHttpClientFactory httpClientFactory,
IUserPictureStore userPictureStore,
IUserResolver userResolver,
IUserService userService,
ILogger<UsersController> log)
: base(commandBus)
{
this.httpClientFactory = httpClientFactory;
this.userPictureStore = userPictureStore;
this.userService = userService;
this.userResolver = userResolver;
this.log = log;
}
@ -70,6 +72,22 @@ public sealed class UsersController : ApiController
return Ok(response);
}
/// <summary>
/// Update the user profile.
/// </summary>
/// <param name="request">The values to update.</param>
/// <response code="204">User updated.</response>.
[HttpPost]
[Route("user")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ApiPermission]
public async Task<IActionResult> PostUser([FromBody] UpdateProfileDto request)
{
await userService.UpdateAsync(UserId, request.ToValues(), true, HttpContext.RequestAborted);
return NoContent();
}
/// <summary>
/// Get users by query.
/// </summary>

BIN
backend/src/Squidex/wwwroot/images/client.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 792 B

95
backend/src/Squidex/wwwroot/images/client.svg

@ -1,95 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 32 32"
width="32"
height="32"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="client.svg"
inkscape:export-filename="C:\Users\mail2\Downloads\client.png"
inkscape:export-xdpi="180"
inkscape:export-ydpi="180">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0.12941176"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1017"
id="namedview6"
showgrid="true"
inkscape:zoom="32"
inkscape:cx="20.671165"
inkscape:cy="20.571089"
inkscape:window-x="1912"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
showguides="false" />
<rect
style="fill:#f2f2f2;fill-opacity:1;stroke:none;stroke-opacity:1"
id="rect4138"
width="32"
height="32"
x="0"
y="0" />
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4140"
width="17"
height="15"
x="7.5"
y="8.5" />
<rect
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4142"
width="18"
height="1"
x="7"
y="14" />
<rect
style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4144"
width="6"
height="2"
x="16.5"
y="10.5" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4146"
cx="10.5"
cy="11.5"
r="1" />
<circle
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4146-1"
cx="13.5"
cy="11.5"
r="1" />
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

BIN
backend/src/Squidex/wwwroot/images/onboarding-step1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

BIN
backend/src/Squidex/wwwroot/images/onboarding-step2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

BIN
backend/src/Squidex/wwwroot/images/onboarding-step3.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

BIN
backend/src/Squidex/wwwroot/images/onboarding-step4.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

17
backend/src/Squidex/wwwroot/images/squid.svg

@ -0,0 +1,17 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M36.2237 18.6711C36.3533 17.6484 38.4691 18.5637 38.419 17.5869C38.3519 16.4729 38.1725 15.3767 37.8978 14.315C37.63 13.2737 37.2744 12.2674 36.8501 11.2998C35.2671 7.68489 32.7907 4.498 29.8985 1.84248C29.2973 1.28834 28.7141 0.655763 27.8882 0.452968C27.0548 0.249692 26.2203 0.354404 25.4231 0.606316C19.3279 2.27948 15.3775 5.79748 13.3957 7.99943C13.3524 8.0464 13.312 8.09414 13.2705 8.14006C13.1731 8.25116 13.0802 8.35727 12.9927 8.46022C12.9478 8.51295 12.9005 8.56346 12.8553 8.61762C12.7504 8.74521 12.6466 8.87463 12.5442 9.00442C12.0961 9.57029 11.8754 9.91809 11.8754 9.91809C11.5902 10.3349 11.3227 10.7657 11.0758 11.2113C10.6 12.0581 12.8994 12.1794 12.5786 13.1586C12.1828 14.355 9.5289 14.2497 9.06781 17.8394C8.56112 21.7083 11.3541 26.3796 10.9939 28.5382L13.9008 29.442L13.9794 29.1486C14.1407 28.472 14.8535 28.0649 15.5872 28.2276C16.3199 28.4054 16.8036 29.0884 16.6427 29.7636L16.623 29.8369L19.9438 29.156L19.9625 29.0978C20.1248 28.406 20.8537 27.9847 21.6029 28.1639C22.3522 28.3431 22.8352 29.0398 22.6729 29.7316L22.6543 29.7898L25.3445 31.8748L25.3642 31.8014C25.5255 31.1248 26.2383 30.7177 26.972 30.8804C27.7047 31.0582 28.1718 31.7399 28.0274 32.4164L28.0078 32.4898L31.0209 33.1923C31.9979 30.2741 36.1304 28.129 37.3542 24.4214C38.4825 21.0074 36.0682 19.9165 36.2237 18.6711Z" fill="#4593FF"/>
<path d="M33.1671 43.1588C33.0591 41.1198 32.0433 39.4187 30.7518 37.6915C30.2717 37.0465 30.0536 36.2898 30.2671 35.5732C30.4977 34.8273 31.1702 34.3185 31.7061 33.7515C32.3128 33.1156 32.6319 32.3487 32.8822 31.5294C33.1681 30.6688 33.3179 29.7656 33.4333 28.8593C33.7109 26.6308 33.6638 24.3415 33.4936 22.087C33.3144 19.5912 32.9446 17.1075 32.4375 14.6256C31.974 12.3881 31.4057 10.158 30.5948 7.97847C30.0553 6.50058 29.4331 4.89569 28.3159 3.63603C27.9989 3.27673 27.5978 2.89333 27.0827 2.78614C26.1061 2.56144 24.9323 3.6111 24.3135 4.08035C22.7741 5.26173 21.4176 6.65547 20.1465 8.05671C18.518 9.84618 17.0258 11.723 15.6346 13.6532C14.2243 15.6429 12.9164 17.6863 11.829 19.8412C10.9079 21.6506 10.1041 23.5609 9.79935 25.5756C9.58094 26.9984 9.74636 28.336 10.3051 29.725C10.8344 31.0059 10.4126 32.3049 9.08056 32.9191C7.13502 33.822 5.46149 34.8565 4.42185 36.6095C3.47355 38.2051 3.34175 40.1475 4.46109 41.8578C5.0537 42.7534 5.88597 42.124 5.30989 41.2297C4.15757 39.4705 5.19835 37.6731 6.59949 36.5086C8.53195 34.8977 11.7721 34.5636 13.2356 32.5187C13.6867 31.8843 14.0052 31.1311 14.0819 30.3578C17.7272 31.3839 23.187 32.833 27.3455 33.4401C27.1706 34.0699 27.1317 34.7424 27.2311 35.3979C27.5654 37.8936 30.3041 39.7234 31.2651 42.0649C31.9702 43.7676 32.0587 45.8506 30.232 46.8548C29.3013 47.37 29.7542 48.3283 30.6849 47.8132C32.499 46.8102 33.263 45.0311 33.1671 43.1588Z" fill="#3370FF"/>
<path d="M16.9941 29.0052C16.5978 27.9618 13.5818 28.8354 13.9785 29.8774C15.4343 33.7202 13.91 36.3531 12.0302 39.1033C10.5526 41.2585 10.321 43.7737 11.4993 46.3075C11.9699 47.32 12.8335 46.608 12.3633 45.5941C10.6261 41.884 14.2262 39.4498 15.7055 36.6692C16.8684 34.439 17.963 31.5523 16.9941 29.0052ZM23.908 27.7147C24.5362 26.6144 27.3064 27.9594 26.6628 29.0602C24.3171 33.1191 25.1967 36.2173 26.3863 39.494C26.4603 39.688 28.6311 42.3414 25.1997 47.4998C24.4975 48.5556 23.8188 47.6601 24.5207 46.6057C27.1026 42.7257 24.1612 39.5945 23.3569 36.347C22.7288 33.7263 22.3557 30.4063 23.908 27.7147Z" fill="#3370FF"/>
<path d="M20.636 40.3886C20.6031 38.8198 20.1978 37.512 20.105 35.955C20.0036 34.0688 20.7829 32.3586 21.7613 30.7941C22.3737 29.8329 19.6018 28.7634 18.9908 29.708C17.5648 31.9741 17.948 34.8036 18.373 37.4254C18.6378 39.0686 19.2512 40.6433 18.5895 42.362C17.9654 43.9628 16.7582 45.3781 15.6972 46.609C14.9734 47.4586 15.7986 48.2716 16.5375 47.423C18.2247 45.472 20.688 43.2557 20.636 40.3886Z" fill="#3370FF"/>
<path d="M15.0419 22.1484C16.1696 22.408 17.222 22.0189 17.3924 21.2793C17.5629 20.5397 16.7868 19.7297 15.6591 19.4701C14.5314 19.2105 13.479 19.5996 13.3086 20.3391C13.1381 21.0787 13.9141 21.8887 15.0419 22.1484Z" fill="#63A5FF" fill-opacity="0.5"/>
<path d="M30.1525 25.3194C31.3414 25.5931 32.451 25.1829 32.6307 24.4031C32.8104 23.6234 31.9922 22.7693 30.8032 22.4956C29.6143 22.2219 28.5047 22.6321 28.325 23.4119C28.1453 24.1916 28.9635 25.0457 30.1525 25.3194Z" fill="#63A5FF" fill-opacity="0.5"/>
<path d="M26.461 23.3919C25.7954 26.2787 23.4465 28.1954 21.2057 27.6683C18.9667 27.1418 17.7076 24.3977 18.3472 21.5333C19.0128 18.6465 20.1629 21.9611 22.4032 22.4624C24.644 22.9894 27.1237 20.53 26.461 23.3919Z" fill="#253256"/>
<path d="M22.4013 22.4639C21.4354 22.2345 20.6919 21.5161 20.0808 20.9727C20.5983 21.8451 21.2678 22.9692 22.2341 23.1969C23.2 23.4264 24.277 22.7024 25.1263 22.132C24.371 22.3717 23.3693 22.6921 22.4013 22.4639Z" fill="white"/>
<path d="M42.9895 11.1613C43.6807 11.205 44.2774 10.6785 44.3222 9.98517C44.367 9.29186 43.8431 8.69433 43.1519 8.65055C42.4607 8.60678 41.864 9.13333 41.8192 9.82665C41.7744 10.52 42.2983 11.1175 42.9895 11.1613Z" fill="#414E7C"/>
<path d="M37.7525 7.45387C37.9635 7.46724 38.1457 7.30647 38.1594 7.09478C38.1731 6.88309 38.0131 6.70065 37.802 6.68729C37.591 6.67392 37.4088 6.83469 37.3951 7.04638C37.3814 7.25807 37.5414 7.44051 37.7525 7.45387Z" fill="#3389FF"/>
<path d="M42.4483 16.5572C42.8704 16.5839 43.2347 16.2623 43.2621 15.839C43.2895 15.4156 42.9695 15.0507 42.5474 15.024C42.1254 14.9973 41.761 15.3188 41.7336 15.7422C41.7063 16.1655 42.0262 16.5304 42.4483 16.5572Z" fill="#3389FF"/>
<path d="M27.5826 19.3326C28.8014 19.6592 30.0551 18.9325 30.3828 17.7095C30.7105 16.4866 29.9881 15.2304 28.7693 14.9038C27.5505 14.5772 26.2968 15.3039 25.9691 16.5269C25.6415 17.7499 26.3638 19.0061 27.5826 19.3326Z" fill="white"/>
<path d="M19.7252 16.7272C20.944 17.0537 22.1977 16.3271 22.5254 15.1041C22.8531 13.8811 22.1307 12.6249 20.9119 12.2983C19.6931 11.9718 18.4394 12.6985 18.1117 13.9214C17.784 15.1444 18.5064 16.4006 19.7252 16.7272Z" fill="white"/>
<path d="M20.2665 12.4812C18.4713 12.0861 17.8384 14.8572 19.6318 15.2492C21.3882 15.6795 22.0248 12.8746 20.2665 12.4812Z" fill="#253256"/>
<path d="M28.1728 15.1023C26.3775 14.7072 25.7447 17.4783 27.5381 17.8703C29.2945 18.3006 29.9311 15.4957 28.1728 15.1023Z" fill="#253256"/>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
backend/src/Squidex/wwwroot/images/tour-apps.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
backend/src/Squidex/wwwroot/images/tour-assets.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

BIN
backend/src/Squidex/wwwroot/images/tour-content.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

BIN
backend/src/Squidex/wwwroot/images/tour-graphql.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 147 KiB

BIN
backend/src/Squidex/wwwroot/images/tour-languages.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
backend/src/Squidex/wwwroot/images/tour-rules.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
backend/src/Squidex/wwwroot/images/tour-schema.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

BIN
backend/src/Squidex/wwwroot/images/tour-workflow.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

BIN
frontend/src/app/assets/onboarding-background.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 21 KiB

90
frontend/src/app/assets/squid.svg

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
id="Layer_1"
viewBox="0 0 204.02457 346.98514"
version="1.1"
sodipodi:docname="squid.svg"
width="204.02457"
height="346.98514"
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs13" />
<sodipodi:namedview
id="namedview13"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1.4506252"
inkscape:cx="-161.65444"
inkscape:cy="150.96939"
inkscape:window-width="2560"
inkscape:window-height="1351"
inkscape:window-x="-9"
inkscape:window-y="-2"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<style
id="style1">&#10; .st0{fill:#3389ff}&#10; .st1{fill:#3370ff}&#10; .st2{fill:#fff}&#10; .st3{fill:#253256}&#10; .st6{font-family:-apple-system,BlinkMacSystemFont,&quot;Segoe UI&quot;,Roboto,&quot;Helvetica Neue&quot;,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;,&quot;Segoe UI Symbol&quot;}&#10; .st10{font-size:30px}&#10; .st11{font-size:20px;font-weight:bold;}&#10; .st12{fill:#3e4c7d}&#10; </style>
<path
class="st0"
d="m 190.70501,118.5 c 0.5,-6.9 13.9,-1.9 13.3,-8.4 -6.8,-67.5 -69.9,-110.1 -70,-110.1 -0.1,0 -73.499999,20.2 -101.499999,82 -2.7,5.9 11.6,5.5 9.9,12.2 -2.1,8.2 -18.6,8.9 -20.4,33.1 -2,26.1 16.7,55.8 15.1,70.4 l 18.3,4.5 0.4,-2 c 0.8,-4.6 5.1,-7.7 9.7,-7 4.6,0.8 7.8,5.1 7,9.7 l -0.1,0.5 20.4,-6.3 0.1,-0.4 c 0.8,-4.7 5.2,-7.9 9.899999,-7.1 4.7,0.8 7.9,5.2 7.1,9.9 l -0.1,0.4 17.3,12.5 0.1,-0.5 c 0.8,-4.6 5.1,-7.7 9.7,-7 4.6,0.8 7.7,5.1 7,9.7 l -0.1,0.5 18.9,3.1 c 5.2,-20 30.2,-36.5 36.7,-61.9 6,-23.4 -9.3,-29.4 -8.7,-37.8 z"
id="path1" />
<path
class="st1"
d="m 78.805011,199.5 c -2.7,-7 -23,-1.1 -20.3,5.9 9.9,25.8 -0.3,43.5 -12.9,62 -9.9,14.5 -11.4,31.4 -3.4,48.4 3.2,6.8 9,2 5.8,-4.8 -11.8,-24.9 12.4,-41.3 22.3,-60 7.8,-15 15.1,-34.4 8.5,-51.5 z m 39.899999,11.4 c 4.2,-7.4 22.9,1.6 18.6,9 -15.7,27.3 -9.7,48.1 -1.6,70.1 0.5,1.3 15.2,19.1 -7.8,53.8 -4.7,7.1 -9.3,1.1 -4.6,-6 17.3,-26.1 -2.6,-47.1 -8.1,-68.9 -4.3,-17.6 -6.9,-39.9 3.5,-58 z"
id="path2" />
<path
class="st1"
d="m 105.90501,282.4 c -0.9,-10.5 -4.2,-19.1 -5.5,-29.5 -1.499999,-12.6 3,-24.4 8.9,-35.3 3.7,-6.7 -15.399999,-12.7 -19.099999,-6.1 -8.6,15.8 -4.8,34.6 -0.8,52 2.5,10.9 7.3,21.2 3.6,33 -3.5,11 -11,21 -17.6,29.7 -4.5,6 1.4,11.1 6,5.1 10.5,-13.8 26.099999,-29.7 24.499999,-48.9 z"
id="path3" />
<path
class="st1"
d="m 171.60501,284.2 c -1,-13.5 -7.2,-24.2 -15,-34.9 -2.9,-4 -4.3,-8.9 -3.2,-13.8 1.2,-5.1 5,-8.9 8,-13 3.4,-4.6 5.1,-9.9 6.4,-15.5 1.5,-5.9 2.2,-12 2.7,-18.1 1.2,-15 0.5,-30.2 -0.9,-45.1 -1.5,-16.5 -4.1,-32.8 -7.5,-49 -3.1,-14.6 -6.8,-29.1 -11.9,-43.1 -3.4,-9.5 -7.3,-19.8 -14,-27.5 -1.9,-2.2 -4.3,-4.5 -7.3,-4.9 -5.7,-0.9 -12.3,6.8 -15.8,10.3 -8.7,8.8 -16.299999,18.9 -23.399999,29 -9.1,12.9 -17.4,26.3 -25.1,40 -7.8,14.1 -15,28.5 -20.9,43.5 -5,12.6 -9.3,25.8 -10.7,39.4 -1,9.6 0.2,18.4 3.7,27.3 3.3,8.2 1.1,17.1 -6.5,22 -11.1,7.2 -20.5999998,15.1 -26.2999998,27.4 -5.2,11.2 -5.6,24.2 1.2,34.9 3.6,5.6 8.2999998,0.9 4.8,-4.7 -7,-11 -1.3,-23.6 6.5999998,-32.2 10.9,-11.9 29.6,-16.1 37.7,-30.6 2.5,-4.5 4.2,-9.7 4.5,-14.9 21.3,4.6 53.199999,10.9 77.399999,12.4 -0.9,4.3 -1,8.8 -0.3,13.1 2.4,16.4 18.6,26.9 24.6,41.9 4.4,10.9 5.3,24.7 -5.1,32.5 -5.3,4 -2.5,10.1 2.8,6.1 10.3,-7.8 14.4,-20.1 13.5,-32.5 z"
id="path4" />
<ellipse
transform="rotate(-80.689)"
class="st0"
cx="-131.70465"
cy="86.110695"
rx="8.3000002"
ry="12.7"
id="ellipse4" />
<ellipse
transform="rotate(-80.689)"
class="st0"
cx="-131.66716"
cy="174.7867"
rx="8.3000002"
ry="12.7"
id="ellipse5" />
<circle
transform="rotate(-80.689)"
class="st3"
cx="-110.48609"
cy="163.43916"
id="ellipse6"
r="9.3999996" />
<circle
transform="rotate(-80.689)"
class="st3"
cx="-110.45959"
cy="101.08974"
id="ellipse7"
r="9.3999996" />
<path
class="st3"
d="m 124.80501,165.5 c -2,12.2 -11.3,20.8 -20.8,19.2 -9.499999,-1.6 -15.499999,-12.7 -13.599999,-24.8 2,-12.2 7.7,1.3 17.199999,2.8 9.5,1.6 19.2,-9.3 17.2,2.8 z"
id="path7" />
<path
class="st2"
d="m 81.405011,119 c -5.2,-0.8 -6.5,7.2 -1.3,8 5.1,0.9 6.4,-7.2 1.3,-8 z m 61.499999,10.1 c -5.2,-0.8 -6.5,7.2 -1.3,8 5.1,0.8 6.5,-7.2 1.3,-8 z m -35.3,33.6 c -4.1,-0.7 -7.4,-3.5 -10.099999,-5.6 2.4,3.5 5.499999,8 9.599999,8.7 4.1,0.7 8.4,-2.6 11.8,-5.2 -3.1,1.2 -7.2,2.8 -11.3,2.1 z"
id="path8" />
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

15
frontend/src/app/features/apps/pages/apps-page.component.html

@ -2,10 +2,19 @@
<div class="panel-container page" *ngIf="authState.userChanges | async; let user">
<div class="apps-section">
<h1 class="apps-title">{{ 'apps.welcomeTitle' | sqxTranslate: { user: user.displayName } }}</h1>
<div class="row g-3">
<div class="col-auto">
<div class="squid d-flex align-items-center justify-content-center bordered">
<img src="./images/squid.svg">
</div>
</div>
<div class="col">
<h1 class="apps-title">{{ 'apps.welcomeTitle' | sqxTranslate: { user: user.displayName } }}</h1>
<div class="subtext">
{{ 'apps.welcomeSubtitle' | sqxTranslate }}
<div class="subtext">
{{ 'apps.welcomeSubtitle' | sqxTranslate }}
</div>
</div>
</div>
</div>

13
frontend/src/app/features/apps/pages/apps-page.component.scss

@ -11,6 +11,19 @@
overflow-y: auto;
}
.squid {
@include circle(60px);
background: $color-white;
&.bordered {
border: 1px solid $color-border;
}
img {
max-height: 80%;
}
}
:host ::ng-deep {
.card {
@include hover-visible('.deeplinks', inline);

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

@ -1,102 +1,156 @@
<sqx-modal-dialog [showHeader]="false">
<ng-container tabs>
<div class="squid d-flex align-items-center justify-content-center">
<img src="./images/squid.svg">
</div>
</ng-container>
<ng-container content>
<a class="header-right modal-close" (click)="close.emit()">{{ 'tour.skip' | sqxTranslate }}</a>
<a class="header-right modal-close force" (click)="close.emit()">{{ 'tour.skip' | sqxTranslate }}</a>
<div class="onboarding-step" *ngIf="step === 0">
<div class="onboarding-step " *ngIf="step === 0">
<img @fade class="header-left" src="./images/logo-white-small.png">
<div @slide class="onboarding-enter-leave">
<div @slide class="onboarding-enter-leave text-center">
<h1>{{ 'tour.welcome' | sqxTranslate }} <span class="header-focus">{{ 'tour.welcomeProduct' | sqxTranslate }}</span></h1>
<div [innerHTML]="'tour.step0Text' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div [innerHTML]="'tour.stepIntroText' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<button (click)="next()" class="btn btn-success">{{ 'tour.step0Next' | sqxTranslate }}</button>
<div class="mt-4">
<button (click)="next()" class="btn btn-success">{{ 'tour.stepIntroNext' | sqxTranslate }}</button>
</div>
</div>
</div>
<div class="onboarding-step" *ngIf="step === 1">
<h1 @fade class="header-left header-focus">{{ 'common.apps' | sqxTranslate }}</h1>
<div @slide>
<div class="row">
<div class="col">
<div class="onboarding-text" [innerHTML]="'tour.step1Text' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div *ngIf="step === 1">
<img @fade class="header-left" src="./images/logo-white-small.png">
<div @slide class="onboarding-enter-leave">
<form [formGroup]="answersForm" (ngSubmit)="submitAnswers()">
<h2>{{ 'tour.stepDataTitle' | sqxTranslate }}</h2>
<div [innerHTML]="'tour.stepDataText' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div class="form-group mt-4">
<label for="role">{{ 'tour.stepDataRole' | sqxTranslate }}</label>
<select class="form-select" id="companyRole" formControlName="companyRole">
<option [ngValue]="'RoleEmployee'">{{ 'tour.roleEmployee' | sqxTranslate }}</option>
<option [ngValue]="'RoleProductManager'">{{ 'tour.roleProductManager' | sqxTranslate }}</option>
<option [ngValue]="'RoleContentCreator'">{{ 'tour.roleContentCreator' | sqxTranslate }}</option>
<option [ngValue]="'RoleSoftwareDeveloper'">{{ 'tour.roleSoftwareDeveloper' | sqxTranslate }}</option>
<option [ngValue]="'RoleBusinessAnalyst'">{{ 'tour.roleBusinessAnalyst' | sqxTranslate }}</option>
</select>
</div>
<div class="col col-image">
<img src="./images/onboarding-step1.png">
<div class="form-group">
<label for="companySize">{{ 'tour.stepDataCompanySize' | sqxTranslate }}</label>
<select class="form-select" id="companySize" formControlName="companySize">
<option [ngValue]="'SizeSingle'">{{ 'tour.sizeSingle' | sqxTranslate }}</option>
<option [ngValue]="'SizeSmall'">{{ 'tour.sizeSmall' | sqxTranslate }}</option>
<option [ngValue]="'SizeMedium'">{{ 'tour.sizeMedium' | sqxTranslate }}</option>
<option [ngValue]="'SizeLarge'">{{ 'tour.sizeLarge' | sqxTranslate }}</option>
<option [ngValue]="'SizeVeryLarge'">{{ 'tour.sizeVeryLarge' | sqxTranslate }}</option>
</select>
</div>
</div>
<div class="footer">
<button (click)="next()" class="btn btn-success">{{ 'tour.step1Next' | sqxTranslate }}</button>
</div>
<div class="form-group">
<label for="project">{{ 'tour.stepDataProject' | sqxTranslate }}</label>
<select class="form-select" id="project" formControlName="project">
<option [ngValue]="'ProjectNewsMagazine'">{{ 'tour.projectNewsMagazine' | sqxTranslate }}</option>
<option [ngValue]="'ProjectSmallBusiness'">{{ 'tour.projectPersonalBlog' | sqxTranslate }}</option>
<option [ngValue]="'ProjectSmallBusiness'">{{ 'tour.projectSmallBusiness' | sqxTranslate }}</option>
<option [ngValue]="'ProjectCommerce'">{{ 'tour.projectCommerce' | sqxTranslate }}</option>
<option [ngValue]="'ProjectMobileApp'">{{ 'tour.projectMobileApp' | sqxTranslate }}</option>
<option [ngValue]="'ProjectBackend'">{{ 'tour.projectBackend' | sqxTranslate }}</option>
<option [ngValue]="'ProjectLearning'">{{ 'tour.projectLearning' | sqxTranslate }}</option>
</select>
</div>
<button type="submit" class="btn btn-success">{{ 'tour.stepDataNext' | sqxTranslate }}</button>
</form>
</div>
</div>
<div class="onboarding-step" *ngIf="step === 2">
<h1 @fade class="header-left header-focus">{{ 'common.schemas' | sqxTranslate }}</h1>
<div class="row g-0" @slide>
<div class="col">
<h2>{{ 'common.apps' | sqxTranslate }}</h2>
<div @slide>
<div class="row">
<div class="col">
<div class="onboarding-text" [innerHTML]="'tour.step2Text' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
</div>
<div class="col col-image">
<img src="./images/onboarding-step2.png">
<div [innerHTML]="'tour.stepAppText' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div class="footer">
<button (click)="next()" class="btn btn-success">{{ 'tour.stepAppNext' | sqxTranslate }}</button>
</div>
</div>
<div class="footer">
<button (click)="next()" class="btn btn-success">{{ 'tour.step2Next' | sqxTranslate }}</button>
<div class="col col-image">
<img src="./images/tour-apps.png">
</div>
</div>
</div>
<div class="onboarding-step" *ngIf="step === 3">
<h1 @fade class="header-left header-focus">{{ 'common.contents' | sqxTranslate }}</h1>
<div class="row g-0" @slide>
<div class="col">
<h2>{{ 'common.schemas' | sqxTranslate }}</h2>
<div @slide>
<div class="row">
<div class="col">
<div class="onboarding-text" [innerHTML]="'tour.step3Text' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
</div>
<div class="col col-image">
<img src="./images/onboarding-step3.png">
<div [innerHTML]="'tour.stepSchemasText' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div class="footer">
<button (click)="next()" class="btn btn-success">{{ 'tour.stepSchemasNext' | sqxTranslate }}</button>
</div>
</div>
<div class="footer">
<button (click)="next()" class="btn btn-success">{{ 'tour.step3Next' | sqxTranslate }}</button>
<div class="col col-image">
<img src="./images/tour-schema.png">
</div>
</div>
</div>
<div class="onboarding-step" *ngIf="step === 4">
<h1 @fade class="header-left header-focus">{{ 'common.assets' | sqxTranslate }}</h1>
<div class="row g-0" @slide>
<div class="col">
<h2>{{ 'common.contents' | sqxTranslate }}</h2>
<div @slide>
<div class="row">
<div class="col">
<div class="onboarding-text" [innerHTML]="'tour.step4Text' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
</div>
<div class="col col-image">
<img src="./images/onboarding-step4.png">
<div [innerHTML]="'tour.stepContentText' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div class="footer">
<button (click)="next()" class="btn btn-success">{{ 'tour.stepContentNext' | sqxTranslate }}</button>
</div>
</div>
<div class="col col-image">
<img src="./images/tour-content.png">
</div>t
</div>
</div>
<div class="onboarding-step" *ngIf="step === 5">
<div class="row g-0" @slide>
<div class="col">
<h2>{{ 'common.assets' | sqxTranslate }}</h2>
<div class="footer">
<button (click)="next()" class="btn btn-success">{{ 'tour.step4Next' | sqxTranslate }}</button>
<div [innerHTML]="'tour.stepAssetsText' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div class="footer">
<button (click)="next()" class="btn btn-success">{{ 'tour.stepAssetsNext' | sqxTranslate }}</button>
</div>
</div>
<div class="col col-image">
<img src="./images/tour-assets.png">
</div>
</div>
</div>
<div class="onboarding-step" *ngIf="step === 5">
<div class="onboarding-step" *ngIf="step === 6">
<img @fade class="header-left" src="./images/logo-white-small.png">
<div @slide class="onboarding-enter-leave">
<h1>{{ 'tour.step5Title' | sqxTranslate }}</h1>
<div @slide class="onboarding-enter-leave text-center">
<h2>{{ 'tour.stepOutroTitle' | sqxTranslate }}</h2>
<div [innerHTML]="'tour.step5Text' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div [innerHTML]="'tour.stepOutroText' | sqxTranslate | sqxMarkdown | sqxSafeHtml"></div>
<div>
<a class="btn btn-success" href="https://support.squidex.io" sqxExternalLink>
<div class="mt-4">
<a class="btn btn-success me-2" href="https://support.squidex.io" sqxExternalLink>
{{ 'tour.joinForum' | sqxTranslate }}
</a> &nbsp;
</a>
<a class="btn btn-success" href="https://github.com/squidex/squidex" sqxExternalLink>
{{ 'tour.joinGithub' | sqxTranslate }}

87
frontend/src/app/features/apps/pages/onboarding-dialog.component.scss

@ -4,6 +4,7 @@
$size-width: 825px;
$size-height: 576px;
$size-image: 476px;
$size-squid: 80px;
h1 {
font-size: 1.6rem;
@ -15,6 +16,10 @@ p {
.col-image {
@include force-width(489px);
img {
width: 900px;
}
}
:host ::ng-deep {
@ -25,16 +30,16 @@ p {
@include force-height($size-height);
}
&-dialog {
top: 6rem;
}
&-content {
background-color: $color-dark-onboarding;
background-image: url('../../../assets/onboarding-background.png');
color: $color-white;
position: relative;
}
&-body,
&-content {
overflow: hidden;
position: relative;
}
&-footer {
@ -42,46 +47,76 @@ p {
}
&-close {
color: $color-white;
cursor: pointer;
text-decoration: underline !important;
text-decoration: none !important;
}
}
}
.header-focus {
h2 {
color: $color-theme-brand;
}
.header-left {
@include absolute($t: -70px, $l: 2rem);
.header-focus {
color: $color-theme-brand;
}
.header-right {
@include absolute($t: 2rem, $r: 2rem);
@include absolute(2rem, 2rem);
}
.footer {
@include absolute($t: 18rem, $l: 2rem);
.squid {
@include absolute(0, null, null, 50%);
@include circle($size-squid);
border: 1px solid $color-border;
background: $color-white;
margin-left: -$size-squid * .5;
margin-top: -$size-squid * .5;
img {
max-height: 80%;
}
}
.onboarding {
&-enter-leave {
@include force-width(28rem);
margin: 4rem auto 0;
text-align: center;
text-decoration: none;
p {
margin: 2rem 0;
}
}
&-text {
padding-left: 2rem;
width: 28rem;
margin-left: auto;
margin-right: auto;
}
&-step {
@include absolute($size-height - $size-image, 0, 0, 0);
overflow: hidden;
& > div {
height: 100%;
}
.row {
height: 100%;
}
.col:first-child {
padding-left: 2rem;
padding-right: 2rem;
p {
line-height: 2rem;
}
}
.col-image {
overflow: hidden 100%;
img {
border-left: 1px solid $color-border;
border-top: 1px solid $color-border;
position: absolute;
}
}
.footer {
@include absolute(null, null, 10rem);
}
}
}

23
frontend/src/app/features/apps/pages/onboarding-dialog.component.ts

@ -6,7 +6,9 @@
*/
import { Component, EventEmitter, Output } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { fadeAnimation, slideAnimation } from '@app/framework';
import { UsersService } from '@app/shared';
@Component({
selector: 'sqx-onboarding-dialog',
@ -17,11 +19,30 @@ import { fadeAnimation, slideAnimation } from '@app/framework';
],
})
export class OnboardingDialogComponent {
public step = 0;
@Output()
public close = new EventEmitter();
public answersForm =
this.formBuilder.group({
companySize: '',
companyRole: '',
project: '',
});
public step = 0;
constructor(
private readonly formBuilder: FormBuilder,
private readonly usersService: UsersService,
) {
}
public submitAnswers() {
this.usersService.postUser({ answers: this.answersForm.value as any }).subscribe();
this.next();
}
public next() {
this.step += 1;
}

15
frontend/src/app/features/dashboard/pages/dashboard-page.component.html

@ -3,9 +3,18 @@
<ng-container *ngIf="selectedApp | async; let app">
<div class="dashboard" @fade>
<div class="dashboard-summary" *ngIf="!isScrolled" @fade>
<h1 class="dashboard-title">{{ 'dashboard.welcomeTitle' | sqxTranslate: { user: user } }}</h1>
<div class="subtext" [innerHTML]="'dashboard.welcomeText' | sqxTranslate: { app: app.displayName } | sqxMarkdown | sqxSafeHtml"></div>
<div class="row g-3">
<div class="col-auto">
<div class="squid d-flex align-items-center justify-content-center bordered">
<img src="./images/squid.svg">
</div>
</div>
<div class="col">
<h1 class="dashboard-title">{{ 'dashboard.welcomeTitle' | sqxTranslate: { user: user } }}</h1>
<div class="subtext" [innerHTML]="'dashboard.welcomeText' | sqxTranslate: { app: app.displayName } | sqxMarkdown | sqxSafeHtml"></div>
</div>
</div>
</div>
<gridster [options]="gridOptions" #grid>

13
frontend/src/app/features/dashboard/pages/dashboard-page.component.scss

@ -56,6 +56,19 @@ gridster-item {
z-index: 1000;
}
.squid {
@include circle(60px);
background: $color-white;
&.bordered {
border: 1px solid $color-border;
}
img {
max-height: 80%;
}
}
:host ::ng-deep {
.subtext {
margin-bottom: 2rem;

15
frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.html

@ -3,9 +3,18 @@
<ng-container *ngIf="selectedTeam | async; let team">
<div class="dashboard" @fade>
<div class="dashboard-summary" *ngIf="!isScrolled" @fade>
<h1 class="dashboard-title">{{ 'dashboard.welcomeTitle' | sqxTranslate: { user: user } }}</h1>
<div class="subtext" [innerHTML]="'dashboard.welcomeTextTeam' | sqxTranslate: { team: team.name } | sqxMarkdown | sqxSafeHtml"></div>
<div class="row g-3">
<div class="col-auto">
<div class="squid d-flex align-items-center justify-content-center bordered">
<img src="./images/squid.svg">
</div>
</div>
<div class="col">
<h1 class="dashboard-title">{{ 'dashboard.welcomeTitle' | sqxTranslate: { user: user } }}</h1>
<div class="subtext" [innerHTML]="'dashboard.welcomeTextTeam' | sqxTranslate: { team: team.name } | sqxMarkdown | sqxSafeHtml"></div>
</div>
</div>
</div>
<gridster [options]="gridOptions" #grid>

13
frontend/src/app/features/teams/pages/dashboard/dashboard-page.component.scss

@ -56,6 +56,19 @@ gridster-item {
z-index: 1000;
}
.squid {
@include circle(60px);
background: $color-white;
&.bordered {
border: 1px solid $color-border;
}
img {
max-height: 80%;
}
}
:host ::ng-deep {
.subtext {
margin-bottom: 2rem;

2
frontend/src/app/shared/components/pipes.ts

@ -192,7 +192,7 @@ export class UserPictureRefPipe extends UserAsyncPipe implements OnDestroy, Pipe
if (type === 'subject') {
return users.getUser(id).pipe(map(u => this.apiUrl.buildUrl(`api/users/${u.id}/picture`)));
} else {
return of('./images/client.png');
return of('./images/squid.svg');
}
});
}

10
frontend/src/app/shared/services/users.service.spec.ts

@ -26,6 +26,16 @@ describe('UsersService', () => {
httpMock.verify();
}));
it('should make post request to update profile',
inject([UsersService, HttpTestingController], (usersService: UsersService, httpMock: HttpTestingController) => {
usersService.postUser({ answers: {} }).subscribe();
const req = httpMock.expectOne('http://service/p/api/user');
expect(req.request.method).toEqual('POST');
expect(req.request.headers.get('If-Match')).toBeNull();
}));
it('should make get request to get many users',
inject([UsersService, HttpTestingController], (usersService: UsersService, httpMock: HttpTestingController) => {
let users: ReadonlyArray<UserDto>;

11
frontend/src/app/shared/services/users.service.ts

@ -19,6 +19,11 @@ export class UserDto {
}
}
export type UpdateProfileDto = Readonly<{
// The given answers.
answers: { [question: string]: string };
}>;
@Injectable()
export class UsersService {
constructor(
@ -27,6 +32,12 @@ export class UsersService {
) {
}
public postUser(dto: UpdateProfileDto): Observable<any> {
const url = this.apiUrl.buildUrl('api/user');
return this.http.post<any[]>(url, dto);
}
public getUsers(query?: string): Observable<ReadonlyArray<UserDto>> {
const url = this.apiUrl.buildUrl(`api/users?query=${query || ''}`);

Loading…
Cancel
Save