Refactor: move displayname logic from backend to frontend (#62845)

* remove fallback from backend

* add: displayname logic to frontend

* Update public/app/core/components/RolePicker/utils.ts

Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>

* add: fetchTeamRoles and return earlier

* refactor: change to const

---------

Co-authored-by: Alexander Zobnin <alexanderzobnin@gmail.com>
This commit is contained in:
Eric Leijonmarck 2023-02-03 10:39:44 +00:00 committed by GitHub
parent 8b017f5aa4
commit ed18a249b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 36 deletions

View File

@ -27,7 +27,7 @@ type Role struct {
Version int64 `json:"version"`
UID string `xorm:"uid" json:"uid"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
DisplayName string `json:"displayName,omitempty"`
Group string `xorm:"group_name" json:"group"`
Description string `json:"description"`
Hidden bool `json:"hidden"`
@ -48,17 +48,9 @@ func (r *Role) IsBasic() bool {
return strings.HasPrefix(r.Name, BasicRolePrefix) || strings.HasPrefix(r.UID, BasicRoleUIDPrefix)
}
func (r *Role) GetDisplayName() string {
if r.IsFixed() && r.DisplayName == "" {
r.DisplayName = fallbackDisplayName(r.Name)
}
return r.DisplayName
}
func (r Role) MarshalJSON() ([]byte, error) {
type Alias Role
r.DisplayName = r.GetDisplayName()
return json.Marshal(&struct {
Alias
Global bool `json:"global" xorm:"-"`
@ -72,7 +64,7 @@ type RoleDTO struct {
Version int64 `json:"version"`
UID string `xorm:"uid" json:"uid"`
Name string `json:"name"`
DisplayName string `json:"displayName"`
DisplayName string `json:"displayName,omitempty"`
Description string `json:"description"`
Group string `xorm:"group_name" json:"group"`
Permissions []Permission `json:"permissions,omitempty"`
@ -137,20 +129,9 @@ func (r *RoleDTO) IsBasic() bool {
return strings.HasPrefix(r.Name, BasicRolePrefix) || strings.HasPrefix(r.UID, BasicRoleUIDPrefix)
}
func (r *RoleDTO) GetDisplayName() string {
if r.IsFixed() && r.DisplayName == "" {
r.DisplayName = fallbackDisplayName(r.Name)
}
if r.DisplayName == "" {
return r.Name
}
return r.DisplayName
}
func (r RoleDTO) MarshalJSON() ([]byte, error) {
type Alias RoleDTO
r.DisplayName = r.GetDisplayName()
return json.Marshal(&struct {
Alias
Global bool `json:"global" xorm:"-"`
@ -160,17 +141,6 @@ func (r RoleDTO) MarshalJSON() ([]byte, error) {
})
}
// fallbackDisplayName provides a fallback name for role
// that can be displayed in the ui for better readability
// example: currently this would give:
// fixed:datasources:name -> datasources name
// datasources:admin -> datasources admin
func fallbackDisplayName(rName string) string {
// removing prefix for fixed roles
rNameWithoutPrefix := strings.Replace(rName, FixedRolePrefix, "", 1)
return strings.TrimSpace(strings.ReplaceAll(rNameWithoutPrefix, ":", " "))
}
type TeamRole struct {
ID int64 `json:"id" xorm:"pk autoincr 'id'"`
OrgID int64 `json:"orgId" xorm:"org_id"`

View File

@ -60,7 +60,7 @@ export const RolePickerInput = ({
<div className={styles.wrapper}>
{showBasicRole && <ValueContainer>{basicRole}</ValueContainer>}
{appliedRoles.map((role) => (
<ValueContainer key={role.uid}>{role.displayName}</ValueContainer>
<ValueContainer key={role.uid}>{role.displayName || role.name}</ValueContainer>
))}
{!disabled && (

View File

@ -1,6 +1,8 @@
import { getBackendSrv, isFetchError } from '@grafana/runtime';
import { Role } from 'app/types';
import { addDisplayNameForFixedRole } from './utils';
export const fetchRoleOptions = async (orgId?: number, query?: string): Promise<Role[]> => {
let rolesUrl = '/api/access-control/roles?delegatable=true';
if (orgId) {
@ -10,7 +12,7 @@ export const fetchRoleOptions = async (orgId?: number, query?: string): Promise<
if (!roles || !roles.length) {
return [];
}
return roles;
return roles.map(addDisplayNameForFixedRole);
};
export const fetchUserRoles = async (userId: number, orgId?: number): Promise<Role[]> => {
@ -23,7 +25,7 @@ export const fetchUserRoles = async (userId: number, orgId?: number): Promise<Ro
if (!roles || !roles.length) {
return [];
}
return roles;
return roles.map(addDisplayNameForFixedRole);
} catch (error) {
if (isFetchError(error)) {
error.isHandled = true;
@ -54,7 +56,7 @@ export const fetchTeamRoles = async (teamId: number, orgId?: number): Promise<Ro
if (!roles || !roles.length) {
return [];
}
return roles;
return roles.map(addDisplayNameForFixedRole);
} catch (error) {
if (isFetchError(error)) {
error.isHandled = true;

View File

@ -3,3 +3,19 @@ import { Role } from 'app/types';
export const isNotDelegatable = (role: Role) => {
return role.delegatable !== undefined && !role.delegatable;
};
// addDisplayNameForFixedRole provides a fallback name for fixed roles
// this is "incase" a fixed role is introduced but without a displayname set
// example: currently this would give:
// fixed:datasources:name -> datasources name
// fixed:datasources:admin -> datasources admin
export const addDisplayNameForFixedRole = (role: Role) => {
const fixedRolePrefix = 'fixed:';
if (!role.displayName && role.name.startsWith(fixedRolePrefix)) {
let newRoleName = '';
let rNameWithoutFixedPrefix = role.name.replace(fixedRolePrefix, '');
newRoleName = rNameWithoutFixedPrefix.replace(/:/g, ' ');
role.displayName = newRoleName;
}
return role;
};