mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-27 01:53:08 +02:00
enhance: ロールの並び順を設定可能に
This commit is contained in:
parent
57cac0aa23
commit
7c2d8d73ce
11 changed files with 42 additions and 7 deletions
|
@ -15,6 +15,7 @@ You should also include the user name that made the change.
|
||||||
### Improvements
|
### Improvements
|
||||||
- ユーザーごとにRenoteをミュートできるように
|
- ユーザーごとにRenoteをミュートできるように
|
||||||
- ノートごとに絵文字リアクションを受け取るか設定できるように
|
- ノートごとに絵文字リアクションを受け取るか設定できるように
|
||||||
|
- ロールの並び順を設定可能に
|
||||||
- enhance(client): DM作成時にメンションも含むように
|
- enhance(client): DM作成時にメンションも含むように
|
||||||
- enhance(client): フォロー申請のボタンのデザインを改善
|
- enhance(client): フォロー申請のボタンのデザインを改善
|
||||||
- enhance(backend): OpenAPIエンドポイントを復旧
|
- enhance(backend): OpenAPIエンドポイントを復旧
|
||||||
|
|
|
@ -969,6 +969,7 @@ cannotBeChangedLater: "後から変更できません。"
|
||||||
reactionAcceptance: "リアクションの受け入れ"
|
reactionAcceptance: "リアクションの受け入れ"
|
||||||
likeOnly: "いいねのみ"
|
likeOnly: "いいねのみ"
|
||||||
likeOnlyForRemote: "リモートからはいいねのみ"
|
likeOnlyForRemote: "リモートからはいいねのみ"
|
||||||
|
rolesAssignedToMe: "自分に割り当てられたロール"
|
||||||
|
|
||||||
_achievements:
|
_achievements:
|
||||||
earnedAt: "獲得日時"
|
earnedAt: "獲得日時"
|
||||||
|
@ -1230,6 +1231,8 @@ _role:
|
||||||
iconUrl: "アイコン画像のURL"
|
iconUrl: "アイコン画像のURL"
|
||||||
asBadge: "バッジとして表示"
|
asBadge: "バッジとして表示"
|
||||||
descriptionOfAsBadge: "オンにすると、ユーザー名の横にロールのアイコンが表示されます。"
|
descriptionOfAsBadge: "オンにすると、ユーザー名の横にロールのアイコンが表示されます。"
|
||||||
|
displayOrder: "表示順"
|
||||||
|
descriptionOfDisplayOrder: "数値が大きいほどUI上で先頭に表示されます。"
|
||||||
canEditMembersByModerator: "モデレーターのメンバー編集を許可"
|
canEditMembersByModerator: "モデレーターのメンバー編集を許可"
|
||||||
descriptionOfCanEditMembersByModerator: "オンにすると、管理者に加えてモデレーターもこのロールへユーザーをアサイン/アサイン解除できるようになります。オフにすると管理者のみが行えます。"
|
descriptionOfCanEditMembersByModerator: "オンにすると、管理者に加えてモデレーターもこのロールへユーザーをアサイン/アサイン解除できるようになります。オフにすると管理者のみが行えます。"
|
||||||
priority: "優先度"
|
priority: "優先度"
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
export class roleDisplayOrder1678602320354 {
|
||||||
|
name = 'roleDisplayOrder1678602320354'
|
||||||
|
|
||||||
|
async up(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "role" ADD "displayOrder" integer NOT NULL DEFAULT '0'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(queryRunner) {
|
||||||
|
await queryRunner.query(`ALTER TABLE "role" DROP COLUMN "displayOrder"`);
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,6 +61,7 @@ export class RoleEntityService {
|
||||||
isModerator: role.isModerator,
|
isModerator: role.isModerator,
|
||||||
asBadge: role.asBadge,
|
asBadge: role.asBadge,
|
||||||
canEditMembersByModerator: role.canEditMembersByModerator,
|
canEditMembersByModerator: role.canEditMembersByModerator,
|
||||||
|
displayOrder: role.displayOrder,
|
||||||
policies: policies,
|
policies: policies,
|
||||||
usersCount: assignedCount,
|
usersCount: assignedCount,
|
||||||
});
|
});
|
||||||
|
|
|
@ -390,9 +390,10 @@ export class UserEntityService implements OnModuleInit {
|
||||||
emojis: this.customEmojiService.populateEmojis(user.emojis, user.host),
|
emojis: this.customEmojiService.populateEmojis(user.emojis, user.host),
|
||||||
onlineStatus: this.getOnlineStatus(user),
|
onlineStatus: this.getOnlineStatus(user),
|
||||||
// パフォーマンス上の理由でローカルユーザーのみ
|
// パフォーマンス上の理由でローカルユーザーのみ
|
||||||
badgeRoles: user.host == null ? this.roleService.getUserBadgeRoles(user.id).then(rs => rs.map(r => ({
|
badgeRoles: user.host == null ? this.roleService.getUserBadgeRoles(user.id).then(rs => rs.sort((a, b) => b.displayOrder - a.displayOrder).map(r => ({
|
||||||
name: r.name,
|
name: r.name,
|
||||||
iconUrl: r.iconUrl,
|
iconUrl: r.iconUrl,
|
||||||
|
displayOrder: r.displayOrder,
|
||||||
}))) : undefined,
|
}))) : undefined,
|
||||||
|
|
||||||
...(opts.detail ? {
|
...(opts.detail ? {
|
||||||
|
@ -429,7 +430,7 @@ export class UserEntityService implements OnModuleInit {
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
}).then(result => result >= 1)
|
}).then(result => result >= 1)
|
||||||
: false,
|
: false,
|
||||||
roles: this.roleService.getUserRoles(user.id).then(roles => roles.filter(role => role.isPublic).map(role => ({
|
roles: this.roleService.getUserRoles(user.id).then(roles => roles.filter(role => role.isPublic).sort((a, b) => b.displayOrder - a.displayOrder).map(role => ({
|
||||||
id: role.id,
|
id: role.id,
|
||||||
name: role.name,
|
name: role.name,
|
||||||
color: role.color,
|
color: role.color,
|
||||||
|
@ -437,6 +438,7 @@ export class UserEntityService implements OnModuleInit {
|
||||||
description: role.description,
|
description: role.description,
|
||||||
isModerator: role.isModerator,
|
isModerator: role.isModerator,
|
||||||
isAdministrator: role.isAdministrator,
|
isAdministrator: role.isAdministrator,
|
||||||
|
displayOrder: role.displayOrder,
|
||||||
}))),
|
}))),
|
||||||
} : {}),
|
} : {}),
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,12 @@ export class Role {
|
||||||
})
|
})
|
||||||
public canEditMembersByModerator: boolean;
|
public canEditMembersByModerator: boolean;
|
||||||
|
|
||||||
|
// UIに表示する際の並び順用(大きいほど先頭)
|
||||||
|
@Column('integer', {
|
||||||
|
default: 0,
|
||||||
|
})
|
||||||
|
public displayOrder: number;
|
||||||
|
|
||||||
@Column('jsonb', {
|
@Column('jsonb', {
|
||||||
default: { },
|
default: { },
|
||||||
})
|
})
|
||||||
|
|
|
@ -27,6 +27,7 @@ export const paramDef = {
|
||||||
isAdministrator: { type: 'boolean' },
|
isAdministrator: { type: 'boolean' },
|
||||||
asBadge: { type: 'boolean' },
|
asBadge: { type: 'boolean' },
|
||||||
canEditMembersByModerator: { type: 'boolean' },
|
canEditMembersByModerator: { type: 'boolean' },
|
||||||
|
displayOrder: { type: 'number' },
|
||||||
policies: {
|
policies: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
},
|
},
|
||||||
|
@ -43,6 +44,7 @@ export const paramDef = {
|
||||||
'isAdministrator',
|
'isAdministrator',
|
||||||
'asBadge',
|
'asBadge',
|
||||||
'canEditMembersByModerator',
|
'canEditMembersByModerator',
|
||||||
|
'displayOrder',
|
||||||
'policies',
|
'policies',
|
||||||
],
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -76,6 +78,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
isModerator: ps.isModerator,
|
isModerator: ps.isModerator,
|
||||||
asBadge: ps.asBadge,
|
asBadge: ps.asBadge,
|
||||||
canEditMembersByModerator: ps.canEditMembersByModerator,
|
canEditMembersByModerator: ps.canEditMembersByModerator,
|
||||||
|
displayOrder: ps.displayOrder,
|
||||||
policies: ps.policies,
|
policies: ps.policies,
|
||||||
}).then(x => this.rolesRepository.findOneByOrFail(x.identifiers[0]));
|
}).then(x => this.rolesRepository.findOneByOrFail(x.identifiers[0]));
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ export const paramDef = {
|
||||||
isAdministrator: { type: 'boolean' },
|
isAdministrator: { type: 'boolean' },
|
||||||
asBadge: { type: 'boolean' },
|
asBadge: { type: 'boolean' },
|
||||||
canEditMembersByModerator: { type: 'boolean' },
|
canEditMembersByModerator: { type: 'boolean' },
|
||||||
|
displayOrder: { type: 'number' },
|
||||||
policies: {
|
policies: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
},
|
},
|
||||||
|
@ -52,6 +53,7 @@ export const paramDef = {
|
||||||
'isAdministrator',
|
'isAdministrator',
|
||||||
'asBadge',
|
'asBadge',
|
||||||
'canEditMembersByModerator',
|
'canEditMembersByModerator',
|
||||||
|
'displayOrder',
|
||||||
'policies',
|
'policies',
|
||||||
],
|
],
|
||||||
} as const;
|
} as const;
|
||||||
|
@ -85,6 +87,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> {
|
||||||
isAdministrator: ps.isAdministrator,
|
isAdministrator: ps.isAdministrator,
|
||||||
asBadge: ps.asBadge,
|
asBadge: ps.asBadge,
|
||||||
canEditMembersByModerator: ps.canEditMembersByModerator,
|
canEditMembersByModerator: ps.canEditMembersByModerator,
|
||||||
|
displayOrder: ps.displayOrder,
|
||||||
policies: ps.policies,
|
policies: ps.policies,
|
||||||
});
|
});
|
||||||
const updated = await this.rolesRepository.findOneByOrFail({ id: ps.roleId });
|
const updated = await this.rolesRepository.findOneByOrFail({ id: ps.roleId });
|
||||||
|
|
|
@ -55,6 +55,7 @@ if (props.id) {
|
||||||
isPublic: false,
|
isPublic: false,
|
||||||
asBadge: false,
|
asBadge: false,
|
||||||
canEditMembersByModerator: false,
|
canEditMembersByModerator: false,
|
||||||
|
displayOrder: 0,
|
||||||
policies: {},
|
policies: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,11 @@
|
||||||
<template #label>{{ i18n.ts._role.iconUrl }}</template>
|
<template #label>{{ i18n.ts._role.iconUrl }}</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
|
|
||||||
|
<MkInput v-model="role.displayOrder" type="number">
|
||||||
|
<template #label>{{ i18n.ts._role.displayOrder }}</template>
|
||||||
|
<template #caption>{{ i18n.ts._role.descriptionOfDisplayOrder }}</template>
|
||||||
|
</MkInput>
|
||||||
|
|
||||||
<MkSelect v-model="rolePermission" :readonly="readonly">
|
<MkSelect v-model="rolePermission" :readonly="readonly">
|
||||||
<template #label><i class="ti ti-shield-lock"></i> {{ i18n.ts._role.permission }}</template>
|
<template #label><i class="ti ti-shield-lock"></i> {{ i18n.ts._role.permission }}</template>
|
||||||
<template #caption><div v-html="i18n.ts._role.descriptionOfPermission.replaceAll('\n', '<br>')"></div></template>
|
<template #caption><div v-html="i18n.ts._role.descriptionOfPermission.replaceAll('\n', '<br>')"></div></template>
|
||||||
|
@ -444,6 +449,7 @@ const save = throttle(100, () => {
|
||||||
description: role.description,
|
description: role.description,
|
||||||
color: role.color === '' ? null : role.color,
|
color: role.color === '' ? null : role.color,
|
||||||
iconUrl: role.iconUrl === '' ? null : role.iconUrl,
|
iconUrl: role.iconUrl === '' ? null : role.iconUrl,
|
||||||
|
displayOrder: role.displayOrder,
|
||||||
target: role.target,
|
target: role.target,
|
||||||
condFormula: role.condFormula,
|
condFormula: role.condFormula,
|
||||||
isAdministrator: role.isAdministrator,
|
isAdministrator: role.isAdministrator,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<MkSpacer :content-max="1200">
|
<MkSpacer :content-max="700">
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
<MkRolePreview v-for="role in roles" :key="role.id" :role="role" :for-moderation="false"/>
|
<MkRolePreview v-for="role in roles" :key="role.id" :role="role" :for-moderation="false"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -13,10 +13,8 @@ import * as os from '@/os';
|
||||||
|
|
||||||
let roles = $ref();
|
let roles = $ref();
|
||||||
|
|
||||||
os.api('roles/list', {
|
os.api('roles/list').then(res => {
|
||||||
limit: 30,
|
roles = res.filter(x => x.target === 'manual').sort((a, b) => b.displayOrder - a.displayOrder);
|
||||||
}).then(res => {
|
|
||||||
roles = res.filter(x => x.target === 'manual');
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue