From f660ace679afc8e67b47d2205d923d62f097a03e Mon Sep 17 00:00:00 2001
From: Jonathan Weth <git@jonathanweth.de>
Date: Wed, 9 Apr 2025 15:02:16 +0200
Subject: [PATCH] Allow changing icons of oauth applications in frontend

---
 CHANGELOG.rst                                 |  1 +
 .../components/oauth/OAuthApplications.vue    | 39 ++++++++++++++++---
 .../oauth/oauthApplications.graphql           |  5 ++-
 3 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index d6581d2ec..bacf97396 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -18,6 +18,7 @@ Fixed
 * [Dev] AddressInputType missed country field.
 * Detail pages, e.g. for groups, did not work anymore.
 * The configured theme colors were not used by the frontend.
+* It wasn't possible to change icons of OAuth applications in the frontend.
 
 `4.0`_ - 2025-03-29
 -------------------
diff --git a/aleksis/core/frontend/components/oauth/OAuthApplications.vue b/aleksis/core/frontend/components/oauth/OAuthApplications.vue
index 7ff6fadb1..fc89dd155 100644
--- a/aleksis/core/frontend/components/oauth/OAuthApplications.vue
+++ b/aleksis/core/frontend/components/oauth/OAuthApplications.vue
@@ -1,5 +1,6 @@
 <script setup>
 import CRUDList from "../generic/CRUDList.vue";
+import FileField from "../generic/forms/FileField.vue";
 </script>
 
 <template>
@@ -128,6 +129,32 @@ import CRUDList from "../generic/CRUDList.vue";
         :true-value="true"
       />
     </template>
+
+    <template #icon="{ item }">
+      <v-img
+        v-if="item.icon.url"
+        :src="item.icon.url"
+        :alt="$t('oauth.application.icon')"
+        max-width="6em"
+      />
+      <span v-else>–</span>
+    </template>
+
+    <!-- eslint-disable-next-line vue/valid-v-slot -->
+    <template #icon.field="{ attrs, on }">
+      <div aria-required="false">
+        <file-field v-bind="attrs" v-on="on" accept="image/jpeg, image/png">
+          <template #append-outer="{ fileUrl }">
+            <v-img
+              v-if="fileUrl"
+              :src="fileUrl"
+              :alt="$t('oauth.application.icon')"
+              max-width="4em"
+            />
+          </template>
+        </file-field>
+      </div>
+    </template>
   </c-r-u-d-list>
 </template>
 
@@ -154,11 +181,11 @@ export default {
           value: "name",
           cols: 12,
         },
-        // {
-        //   text: this.$t("oauth.application.icon"),
-        //   value: "icon",
-        //   cols: 12,
-        // },
+        {
+          text: this.$t("oauth.application.icon"),
+          value: "icon",
+          cols: 12,
+        },
         {
           text: this.$t("oauth.application.client_id"),
           value: "clientId",
@@ -233,7 +260,7 @@ export default {
     defaultItem() {
       return {
         name: "",
-        // icon: "",
+        icon: null,
         clientId: this.initOauthApplication?.clientId,
         clientSecret: this.initOauthApplication?.clientSecret,
         clientType: "",
diff --git a/aleksis/core/frontend/components/oauth/oauthApplications.graphql b/aleksis/core/frontend/components/oauth/oauthApplications.graphql
index 6523f3ad2..82df97073 100644
--- a/aleksis/core/frontend/components/oauth/oauthApplications.graphql
+++ b/aleksis/core/frontend/components/oauth/oauthApplications.graphql
@@ -1,7 +1,10 @@
 fragment oauthApplicationFields on OAuthApplicationType {
   id
   name
-  # icon
+  icon {
+    url
+    name
+  }
   clientId
   clientSecret
   clientType
-- 
GitLab