diff --git a/frontend/src/components/misc/User.vue b/frontend/src/components/misc/User.vue
index 6e3820c18..5570f11d6 100644
--- a/frontend/src/components/misc/User.vue
+++ b/frontend/src/components/misc/User.vue
@@ -15,6 +15,10 @@
v-if="showUsername"
class="username"
>{{ displayName }}
+ {{ $t('user.bot.badge') }}
@@ -36,6 +40,7 @@ const props = withDefaults(defineProps<{
})
const displayName = computed(() => getDisplayName(props.user))
+const isBot = computed(() => ((props.user as IUser & {botOwnerId?: number}).botOwnerId ?? 0) > 0)
const avatarSrc = ref('')
async function loadAvatar() {
@@ -60,4 +65,17 @@ watch(() => [props.user, props.avatarSize], loadAvatar, { immediate: true })
vertical-align: middle;
margin-inline-end: .5rem;
}
+
+.bot-badge {
+ display: inline-block;
+ align-self: center;
+ margin-inline-start: .5rem;
+ padding: 0 .4rem;
+ font-size: .75rem;
+ line-height: 1.2;
+ color: var(--grey-700);
+ background: var(--grey-200);
+ border-radius: 4px;
+ text-transform: uppercase;
+}
diff --git a/frontend/src/i18n/lang/en.json b/frontend/src/i18n/lang/en.json
index 3b8eab1a6..07f5d376a 100644
--- a/frontend/src/i18n/lang/en.json
+++ b/frontend/src/i18n/lang/en.json
@@ -59,6 +59,9 @@
"text": "Please check your network connection and try again."
},
"user": {
+ "bot": {
+ "badge": "Bot"
+ },
"auth": {
"username": "Username",
"usernameEmail": "Username Or Email Address",
diff --git a/frontend/src/modelTypes/IUser.ts b/frontend/src/modelTypes/IUser.ts
index 470ceb7ae..ae2f6ee45 100644
--- a/frontend/src/modelTypes/IUser.ts
+++ b/frontend/src/modelTypes/IUser.ts
@@ -24,4 +24,5 @@ export interface IUser extends IAbstract {
isLocalUser: boolean
deletionScheduledAt: string | Date | null
isAdmin?: boolean
+ botOwnerId?: number
}
diff --git a/frontend/src/models/user.ts b/frontend/src/models/user.ts
index d3cba06dd..e3fe2b128 100644
--- a/frontend/src/models/user.ts
+++ b/frontend/src/models/user.ts
@@ -82,6 +82,7 @@ export default class UserModel extends AbstractModel implements IUser {
isLocalUser: boolean
deletionScheduledAt: null
isAdmin?: boolean
+ botOwnerId = 0
constructor(data: Partial = {}) {
super()
@@ -92,4 +93,8 @@ export default class UserModel extends AbstractModel implements IUser {
this.settings = new UserSettingsModel(this.settings || {})
}
+
+ get isBot(): boolean {
+ return (this.botOwnerId ?? 0) > 0
+ }
}
diff --git a/frontend/src/stores/config.ts b/frontend/src/stores/config.ts
index 6ca087ff4..7784e0507 100644
--- a/frontend/src/stores/config.ts
+++ b/frontend/src/stores/config.ts
@@ -44,6 +44,7 @@ export interface ConfigState {
},
},
publicTeamsEnabled: boolean,
+ botUsersEnabled: boolean,
enabledProFeatures: string[],
}
@@ -84,6 +85,7 @@ export const useConfigStore = defineStore('config', () => {
},
},
publicTeamsEnabled: false,
+ botUsersEnabled: false,
enabledProFeatures: [],
})