From 633296503d79d70f0f46c1b59800fe613efb6013 Mon Sep 17 00:00:00 2001 From: Jens L Date: Sat, 2 Apr 2022 23:08:58 +0200 Subject: [PATCH] core: add grouping to applications (#2648) * core: add grouping to applications Signed-off-by: Jens Langhammer * core: add new field to tests Signed-off-by: Jens Langhammer --- authentik/core/api/applications.py | 2 + .../core/migrations/0019_application_group.py | 18 ++++++ authentik/core/models.py | 2 + authentik/core/tests/test_applications_api.py | 3 + schema.yml | 6 ++ web/src/locales/de.po | 8 ++- web/src/locales/en.po | 8 ++- web/src/locales/es.po | 8 ++- web/src/locales/fr_FR.po | 8 ++- web/src/locales/pl.po | 8 ++- web/src/locales/pseudo-LOCALE.po | 8 ++- web/src/locales/tr.po | 8 ++- web/src/locales/zh-Hans.po | 8 ++- web/src/locales/zh-Hant.po | 8 ++- web/src/locales/zh_TW.po | 8 ++- web/src/pages/applications/ApplicationForm.ts | 10 +++ .../pages/applications/ApplicationListPage.ts | 4 +- web/src/user/LibraryPage.ts | 64 ++++++++++++------- website/docs/releases/v2022.4.md | 4 ++ 19 files changed, 159 insertions(+), 34 deletions(-) create mode 100644 authentik/core/migrations/0019_application_group.py diff --git a/authentik/core/api/applications.py b/authentik/core/api/applications.py index e14e4127b..c4ad3ac57 100644 --- a/authentik/core/api/applications.py +++ b/authentik/core/api/applications.py @@ -68,6 +68,7 @@ class ApplicationSerializer(ModelSerializer): "meta_description", "meta_publisher", "policy_engine_mode", + "group", ] extra_kwargs = { "meta_icon": {"read_only": True}, @@ -85,6 +86,7 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet): "meta_launch_url", "meta_description", "meta_publisher", + "group", ] lookup_field = "slug" ordering = ["name"] diff --git a/authentik/core/migrations/0019_application_group.py b/authentik/core/migrations/0019_application_group.py new file mode 100644 index 000000000..552d0358a --- /dev/null +++ b/authentik/core/migrations/0019_application_group.py @@ -0,0 +1,18 @@ +# Generated by Django 4.0.3 on 2022-04-02 19:48 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentik_core", "0018_auto_20210330_1345_squashed_0028_alter_token_intent"), + ] + + operations = [ + migrations.AddField( + model_name="application", + name="group", + field=models.TextField(blank=True, default=""), + ), + ] diff --git a/authentik/core/models.py b/authentik/core/models.py index d3bda4bf2..4ebe1b6a1 100644 --- a/authentik/core/models.py +++ b/authentik/core/models.py @@ -267,6 +267,8 @@ class Application(PolicyBindingModel): name = models.TextField(help_text=_("Application's display Name.")) slug = models.SlugField(help_text=_("Internal application name, used in URLs."), unique=True) + group = models.TextField(blank=True, default="") + provider = models.OneToOneField( "Provider", null=True, blank=True, default=None, on_delete=models.SET_DEFAULT ) diff --git a/authentik/core/tests/test_applications_api.py b/authentik/core/tests/test_applications_api.py index dffe7333d..01aca45e0 100644 --- a/authentik/core/tests/test_applications_api.py +++ b/authentik/core/tests/test_applications_api.py @@ -84,6 +84,7 @@ class TestApplicationsAPI(APITestCase): "pk": str(self.allowed.pk), "name": "allowed", "slug": "allowed", + "group": "", "provider": self.provider.pk, "provider_obj": { "assigned_application_name": "allowed", @@ -131,6 +132,7 @@ class TestApplicationsAPI(APITestCase): "pk": str(self.allowed.pk), "name": "allowed", "slug": "allowed", + "group": "", "provider": self.provider.pk, "provider_obj": { "assigned_application_name": "allowed", @@ -157,6 +159,7 @@ class TestApplicationsAPI(APITestCase): "meta_icon": None, "meta_launch_url": "", "meta_publisher": "", + "group": "", "name": "denied", "pk": str(self.denied.pk), "policy_engine_mode": "any", diff --git a/schema.yml b/schema.yml index 89d0f0efd..f2944eef3 100644 --- a/schema.yml +++ b/schema.yml @@ -19108,6 +19108,8 @@ components: type: string policy_engine_mode: $ref: '#/components/schemas/PolicyEngineMode' + group: + type: string required: - launch_url - meta_icon @@ -19142,6 +19144,8 @@ components: type: string policy_engine_mode: $ref: '#/components/schemas/PolicyEngineMode' + group: + type: string required: - name - slug @@ -26598,6 +26602,8 @@ components: type: string policy_engine_mode: $ref: '#/components/schemas/PolicyEngineMode' + group: + type: string PatchedAuthenticateWebAuthnStageRequest: type: object description: AuthenticateWebAuthnStage Serializer diff --git a/web/src/locales/de.po b/web/src/locales/de.po index 5e014d653..b7d40634d 100644 --- a/web/src/locales/de.po +++ b/web/src/locales/de.po @@ -48,6 +48,7 @@ msgstr "(Format: hours=-1;minutes=-2;seconds=-3)." #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2305,6 +2306,8 @@ msgstr "Zurück zur vorherigen Seite" #~ msgid "Go to user interface" #~ msgstr "Zur Benutzeroberfläche" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3538,6 +3541,10 @@ msgstr "Optionaler Wiederherstellungsablauf, der unten auf der Seite verlinkt is msgid "Optional, comma-separated SubjectAlt Names." msgstr "Optionale, durch Kommas getrennte SubjectAlt-Namen" +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "" + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "Geben Sie optional den Eingabewert vor" @@ -4605,7 +4612,6 @@ msgstr "Einmalbenutzung" #~ msgstr "Pfad-Regex überspringen" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/locales/en.po b/web/src/locales/en.po index caf87122b..0d542d7bb 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -32,6 +32,7 @@ msgstr "(Format: hours=1;minutes=2;seconds=3)." #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2343,6 +2344,8 @@ msgstr "Go to previous page" #~ msgid "Go to user interface" #~ msgstr "Go to user interface" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3597,6 +3600,10 @@ msgstr "Optional recovery flow, which is linked at the bottom of the page." msgid "Optional, comma-separated SubjectAlt Names." msgstr "Optional, comma-separated SubjectAlt Names." +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "Optionally enter a group name. Applications with identical groups are shown grouped together." + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "Optionally pre-fill the input value" @@ -4694,7 +4701,6 @@ msgstr "Single use" #~ msgstr "Skip path regex" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/locales/es.po b/web/src/locales/es.po index 3f907ca31..a6de7cb2a 100644 --- a/web/src/locales/es.po +++ b/web/src/locales/es.po @@ -35,6 +35,7 @@ msgstr "(Formato: horas = 1; minutos = 2; segundos = 3)." #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2296,6 +2297,8 @@ msgstr "Ir a la página anterior" #~ msgid "Go to user interface" #~ msgstr "Ir a la interfaz de usuario" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3531,6 +3534,10 @@ msgstr "Flujo de recuperación opcional, que se enlaza en la parte inferior de l msgid "Optional, comma-separated SubjectAlt Names." msgstr "Nombres Alt de asunto separados por comas opcionales." +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "" + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "Rellenar previamente el valor de entrada opcionalmente" @@ -4598,7 +4605,6 @@ msgstr "De un solo uso" #~ msgstr "Omitir expresión regular de ruta" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/locales/fr_FR.po b/web/src/locales/fr_FR.po index 6d2605224..e3794d1f4 100644 --- a/web/src/locales/fr_FR.po +++ b/web/src/locales/fr_FR.po @@ -38,6 +38,7 @@ msgstr "" #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2321,6 +2322,8 @@ msgstr "Aller à la page précédente" #~ msgid "Go to user interface" #~ msgstr "Aller à l'interface utilisateu" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3565,6 +3568,10 @@ msgstr "Flux de récupération facultatif, qui sera accessible en bas de page." msgid "Optional, comma-separated SubjectAlt Names." msgstr "Liste optionnelle de noms alternatifs (SubjetAlt Names), séparés par des virgules." +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "" + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "Pré-remplir la valeur du champ (optionnel)" @@ -4648,7 +4655,6 @@ msgstr "Usage unique" #~ msgstr "Regex chemins exclus" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/locales/pl.po b/web/src/locales/pl.po index 24275d448..e19364bb8 100644 --- a/web/src/locales/pl.po +++ b/web/src/locales/pl.po @@ -35,6 +35,7 @@ msgstr "(Format: hours=1;minutes=2;seconds=3)." #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2293,6 +2294,8 @@ msgstr "Wróć do poprzedniej strony" #~ msgid "Go to user interface" #~ msgstr "Przejdź do interfejsu użytkownika" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3528,6 +3531,10 @@ msgstr "Opcjonalny przepływ odzyskiwania, do którego link znajduje się na dol msgid "Optional, comma-separated SubjectAlt Names." msgstr "Opcjonalne, rozdzielone przecinkami nazwy SubjectAlt." +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "" + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "Opcjonalnie wstępnie wypełnij wartość wejściową" @@ -4595,7 +4602,6 @@ msgstr "Jednorazowego użytku" #~ msgstr "Pomiń path regex" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index a6ea3dc02..d9e4c9954 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -32,6 +32,7 @@ msgstr "" #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2329,6 +2330,8 @@ msgstr "" #~ msgid "Go to user interface" #~ msgstr "" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3579,6 +3582,10 @@ msgstr "" msgid "Optional, comma-separated SubjectAlt Names." msgstr "" +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "" + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "" @@ -4674,7 +4681,6 @@ msgstr "" #~ msgstr "" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/locales/tr.po b/web/src/locales/tr.po index 1e3c8c960..8828b30f0 100644 --- a/web/src/locales/tr.po +++ b/web/src/locales/tr.po @@ -35,6 +35,7 @@ msgstr "(Biçim: saat=1; dakika=2; saniye= 3)." #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2296,6 +2297,8 @@ msgstr "Önceki sayfaya git" #~ msgid "Go to user interface" #~ msgstr "Kullanıcı arayüzüne git" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3533,6 +3536,10 @@ msgstr "Sayfanın alt kısmında bağlı olan isteğe bağlı kurtarma akışı. msgid "Optional, comma-separated SubjectAlt Names." msgstr "İsteğe bağlı, virgülle ayrılmış SubjectAlt Adları." +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "" + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "İsteğe bağlı olarak giriş değerini önceden doldurun" @@ -4600,7 +4607,6 @@ msgstr "Tek kullanımlık" #~ msgstr "Yol regex atla" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/locales/zh-Hans.po b/web/src/locales/zh-Hans.po index d4718ed92..4c91d1b23 100644 --- a/web/src/locales/zh-Hans.po +++ b/web/src/locales/zh-Hans.po @@ -37,6 +37,7 @@ msgstr "(格式:hours=1;minutes=2;seconds=3)。" #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2269,6 +2270,8 @@ msgstr "前往上一页" #~ msgid "Go to user interface" #~ msgstr "前往用户界面" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3490,6 +3493,10 @@ msgstr "可选的恢复流程,链接在页面底部。" msgid "Optional, comma-separated SubjectAlt Names." msgstr "可选,逗号分隔的替代名称。" +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "" + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "可选,预先填充输入值" @@ -4537,7 +4544,6 @@ msgstr "一次性使用" #~ msgstr "跳过路径正则表达式" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/locales/zh-Hant.po b/web/src/locales/zh-Hant.po index 0df67b8e1..cd7c7fbab 100644 --- a/web/src/locales/zh-Hant.po +++ b/web/src/locales/zh-Hant.po @@ -37,6 +37,7 @@ msgstr "(格式: hours=1;minutes=2;seconds=3)." #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2269,6 +2270,8 @@ msgstr "转到上一页" #~ msgid "Go to user interface" #~ msgstr "转到用户界面" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3490,6 +3493,10 @@ msgstr "可选的恢复流程,链接在页面底部。" msgid "Optional, comma-separated SubjectAlt Names." msgstr "可选,逗号分隔的 subjectAlt 名称。" +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "" + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "(可选)预先填充输入值" @@ -4537,7 +4544,6 @@ msgstr "一次性使用" #~ msgstr "跳过路径正则表达式" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/locales/zh_TW.po b/web/src/locales/zh_TW.po index 0d58650f6..4524c7d3f 100644 --- a/web/src/locales/zh_TW.po +++ b/web/src/locales/zh_TW.po @@ -37,6 +37,7 @@ msgstr "(格式: hours=1;minutes=2;seconds=3)." #: src/elements/events/UserEvents.ts #: src/elements/user/SessionList.ts #: src/pages/applications/ApplicationListPage.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/events/EventListPage.ts #: src/pages/groups/GroupListPage.ts @@ -2269,6 +2270,8 @@ msgstr "转到上一页" #~ msgid "Go to user interface" #~ msgstr "转到用户界面" +#: src/pages/applications/ApplicationForm.ts +#: src/pages/applications/ApplicationListPage.ts #: src/pages/events/RuleForm.ts #: src/pages/policies/PolicyBindingForm.ts #: src/pages/policies/PolicyBindingForm.ts @@ -3490,6 +3493,10 @@ msgstr "可选的恢复流程,链接在页面底部。" msgid "Optional, comma-separated SubjectAlt Names." msgstr "可选,逗号分隔的 subjectAlt 名称。" +#: src/pages/applications/ApplicationForm.ts +msgid "Optionally enter a group name. Applications with identical groups are shown grouped together." +msgstr "" + #: src/pages/stages/prompt/PromptForm.ts msgid "Optionally pre-fill the input value" msgstr "(可选)预先填充输入值" @@ -4537,7 +4544,6 @@ msgstr "一次性使用" #~ msgstr "跳过路径正则表达式" #: src/pages/applications/ApplicationForm.ts -#: src/pages/applications/ApplicationListPage.ts #: src/pages/flows/FlowForm.ts #: src/pages/sources/ldap/LDAPSourceForm.ts #: src/pages/sources/oauth/OAuthSourceForm.ts diff --git a/web/src/pages/applications/ApplicationForm.ts b/web/src/pages/applications/ApplicationForm.ts index 49aad66d1..014602d1a 100644 --- a/web/src/pages/applications/ApplicationForm.ts +++ b/web/src/pages/applications/ApplicationForm.ts @@ -121,6 +121,16 @@ export class ApplicationForm extends ModelForm { />

${t`Internal application name, used in URLs.`}

+ + +

+ ${t`Optionally enter a group name. Applications with identical groups are shown grouped together.`} +

+