More team stuff

This commit is contained in:
Troplo 2020-11-21 01:36:35 +11:00
parent 76d03786f2
commit 8d9ce2ed14
10 changed files with 519 additions and 28 deletions

View File

@ -28,7 +28,7 @@
slot='footer'
class='button is-danger'
style='z-index: 100; width: 50%;'
@click='teamBan(selectedTeam)'
@click=' teamBan(selectedTeam)'
ref='ajaxErrorsModalButton'
>
Delete
@ -93,7 +93,7 @@
<p name='fade' mode='out-in'>
<center><loading-message key='loading' v-if='loading'></loading-message></center>
<center><div class='overlay_message' v-if='!loading && !users.length'>
Something went wrong while loading the users, check your internet connection, or check the <a href="https://status.troplo.com">Service Status</a>
Nothing to display
</div></center></p>
</main>
</template>

View File

@ -94,7 +94,7 @@
<p name='fade' mode='out-in'>
<center><loading-message key='loading' v-if='loading'></loading-message></center>
<center><div class='overlay_message' v-if='!loading && !users.length'>
Something went wrong while loading the users, check your internet connection, or check the <a href="https://status.troplo.com">Service Status</a>
Nothing to display
</div></center></p>
</main>
</template>

View File

@ -111,6 +111,7 @@
<script>
import MenuButton from '../MenuButton'
import AjaxErrorHandler from "@/assets/js/errorHandler";
export default {
name: 'Team',
@ -167,6 +168,17 @@ export default {
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/view/${this.$route.params.username}`)
.then(res => this.user = res.data)
.catch(e => {
let invalidId = e.response.data.errors.find(error => {
return error.name === 'accountDoesNotExist'
})
if(invalidId) {
this.$store.commit('set404Page', true)
} else {
AjaxErrorHandler(this.$store)(e)
}
})
},
leaveTeam () {
this.axios

View File

@ -23,11 +23,11 @@
<scroll-load
key='user-row'
class='columns is-multiline'
v-if='users.length'
v-if='userRoles.length'
:loading='loading'
@loadNext='fetchData'
>
<div class="column is-4" v-for='user in users' :key='"user-row" + user.username' v-show="user"><div class="card">
<div class="column is-4" v-for='user in userRoles' :key='"user-row" + user.User.username' v-show="user"><div class="card">
<div class="card-content">
<router-link :to="'/u/' + user.username"><b-button style="float:right;">View</b-button></router-link>
<div class="media">
@ -37,8 +37,8 @@
</figure>
</div>
<div class="media-content">
<p class="title is-4">{{user.User.username}}</p>
</div>
<p class="title is-4">{{user.User.username}}&nbsp;<b-tag class="is-info" v-if="team.OwnerId === user.User.id">OWNER</b-tag>&nbsp;</p>
<b-tag v-if="user.Role">{{user.Role.name}}</b-tag>&nbsp;<b-tag v-if="user.Role2">{{user.Role2.name}}</b-tag>&nbsp;<b-tag v-if="user.Role3">{{user.Role3.name}}</b-tag>&nbsp;<b-tag v-if="user.Role4">{{user.Role4.name}}</b-tag>&nbsp;<b-tag v-if="user.Role5">{{user.Role5.name}}</b-tag>&nbsp;<b-tag v-if="user.Role6">{{user.Role6.name}}</b-tag>&nbsp;<b-tag v-if="user.Role7">{{user.Role7.name}}</b-tag>&nbsp;<b-tag v-if="user.Role8">{{user.Role8.name}}</b-tag>&nbsp;<b-tag v-if="user.Role9">{{user.Role9.name}}</b-tag>&nbsp;<b-tag v-if="user.Role10">{{user.Role10.name}}</b-tag>&nbsp;</div>
</div>
<div class="content limit">
@ -48,13 +48,7 @@
</div>
</div>
</scroll-load>
<h1>Roles:</h1>
<div v-for='role in userRoles' :key='"user-row" + role.User.username' v-show="userRoles">
<br>
<b-tag class="is-large">{{role.Role.name}}</b-tag><br>
<b-tag>{{role.User.username}}</b-tag>
</div>
</div>
</div>
<p name='fade' mode='out-in'>
<center><loading-message key='loading' v-if='loading'></loading-message></center>
@ -82,6 +76,8 @@ export default {
search: '',
users: [],
userRoles: [],
roles: [],
team: [],
loading: true,
offset: 0,
@ -189,6 +185,38 @@ export default {
AjaxErrorHandler(this.$store)(e);
this.loading = /*loading =*/ false;
});
this.axios
.get( process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/view/' + this.$route.params.username + "/roles")
.then(res => {
this.roles.push(...res.data);
this.loading = /*loading =*/ false;
//If returned data is less than the limit
//then there must be no more pages to paginate
if(res.data.length < this.limit) {
this.offset = null;
} else {
this.offset+= this.limit;
}
})
.catch(e => {
AjaxErrorHandler(this.$store)(e);
this.loading = /*loading =*/ false;
});
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/view/${this.$route.params.username}`)
.then(res => this.team = res.data)
.catch(e => {
let invalidId = e.response.data.errors.find(error => {
return error.name === 'accountDoesNotExist'
})
if(invalidId) {
this.$store.commit('set404Page', true)
} else {
AjaxErrorHandler(this.$store)(e)
}
})
},
resetFetchData () {
this.offset = 0;

View File

@ -1,5 +1,241 @@
<style>
.team-img {
border-radius: 50%;
}
.vertical-alt {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.limit{
margin-top: 0.5rem;
word-break: break-all;
}
</style>
<template>
<main>
<modal-window v-model='showRoleModal' :loading='loading' style='z-index: 99; '>
<div slot="header">
Creating a role&nbsp;<b-tooltip class="is-info" label="From here you can create a Team Role">
<b-tag class="is-info" rounded><i class="fas fa-info-circle"></i></b-tag>
</b-tooltip>
</div>
<div slot='main' class="card-content">
<div>
Name of your new role:
<b-input v-model="tRole.name"></b-input>
<p>Permissions:</p>
<b-switch type="is-info" v-model="tRole.administrator">
Administrator
</b-switch>
<b-switch type="is-info" v-model="tRole.changeTeamMeta">
Modify general Team settings
</b-switch>
<b-switch type="is-info" v-model="tRole.forumAdministrator">
Modify Team Forum <b-tooltip class="is-info" label="Team forums are coming soon, you can set this for the future when they do release."><b-tag class="is-info" rounded><i class="fas fa-info-circle"></i></b-tag></b-tooltip>
</b-switch>
<b-switch type="is-info" v-model="tRole.moderateForumThreads">
Forum moderator <b-tooltip class="is-info" label="Team forums are coming soon, you can set this for the future when they do release. This role only allows people with the permission to delete threads and posts, not have access to forum settings"><b-tag class="is-info" rounded><i class="fas fa-info-circle"></i></b-tag></b-tooltip>
</b-switch>
<b-switch type="is-info" v-model="tRole.submitTeamItems">
Submit Marketplace items <b-tooltip class="is-info" label="Team Marketplace items are coming soon, you can set this for the future when they do release."><b-tag class="is-info" rounded><i class="fas fa-info-circle"></i></b-tag></b-tooltip>
</b-switch>
<br>
Please set a priority value <b-tooltip class="is-info" label="Priority values are how high the role is considered when taking actions and displaying users in some places. For example, the Admin role can be a priority of 1 (most important), and the Moderator role can be a priority of 2, etc"><b-tag class="is-info" rounded><i class="fas fa-info-circle"></i></b-tag></b-tooltip>
<br>
<b-numberinput v-model="tRole.priority"></b-numberinput>
</div>
</div>
<div slot='footer'>
<button class='button is-info' :loading="tRole.loading" @click='addRole()'>Add Role</button>
</div>
</modal-window>
<div class="section">
<div class="">
<h1>Roles:</h1>
<scroll-load
key='user-row'
v-if='roles.length'
:loading='loading'
@loadNext='fetchData'
>
<div class="column is-10" v-for='role in roles' :key='"user-row" + role.name' v-show="role">
<b-tag class="is-large">{{role.name}}</b-tag>
</div>
<br>
<b-button @click="toggleRoleCreate"><i class="fas fa-plus"></i> Add Role</b-button>
</scroll-load>
</div>
</div>
<p name='fade' mode='out-in'>
<center><loading-message key='loading' v-if='loading'></loading-message></center>
<center><div class='overlay_message' v-if='!loading && !roles.length'>
Something went wrong while loading the team roles, check your internet connection, or check the <a href="https://status.troplo.com">Service Status</a>
</div></center></p>
</main>
</template>
<script>
import LoadingMessage from '../LoadingMessage';
import ScrollLoad from '../ScrollLoad';
import ModalWindow from "@/components/ModalWindow";
import throttle from 'lodash.throttle';
import AjaxErrorHandler from '../../assets/js/errorHandler';
export default {
name: 'TeamMembers',
components: {
LoadingMessage,
ScrollLoad,
ModalWindow
},
data () {
return {
search: '',
users: [],
userRoles: [],
roles: [],
team: [],
loading: true,
offset: 0,
limit: 15,
showTeamTab: 0,
showRoleModal: false,
createTeamModal: false,
tRole: {
name: '',
loading: false,
administrator: false,
inviteUsers: true,
changeTeamMeta: false,
forumAdministrator: false,
moderateForumThreads: false,
changeTeamPrivacy: false,
submitTeamItems: false,
priority: null
},
roleOptions: [
{ name: 'Admins', value: 'admin' },
{ name: 'Users', value: 'user' }
],
roleSelected: ['admin', 'user'],
tableSort: {
column: 'username',
sort: 'desc'
}
}
},
methods: {
clearTeamErrors() {
this.tcreateProd.errors.username = ''
this.tcreateProd.errors.name = ''
},
closeAccountModal() {
this.showRoleModal = false
},
addRole() {
let postParams = {
name: this.tRole.name,
administrator: this.tRole.administrator,
inviteUsers: this.tRole.inviteUsers,
changeTeamMeta: this.tRole.changeTeamMeta,
forumAdministrator: this.tRole.forumAdministrator,
moderateForumThreads: this.tRole.moderateForumThreads,
changeTeamPrivacy: this.tRole.changeTeamPrivacy,
submitTeamItems: this.tRole.submitTeamItems,
priority: this.tRole.priority
}
this.tRole.loading = true
this.axios.post(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/admin/roles/create/` + this.$route.params.username, postParams).then(res => {
res()
this.tRole.loading = false
this.closeAccountModal()
}).catch(e => {
this.tRole.loading = false
AjaxErrorHandler(this.$store)(e);
})
},
toggleRoleCreate() {
this.tRole.name = null
this.showRoleModal = true
},
fetchData () {
if(this.offset === null) return;
this.loading = true;
this.axios
.get( process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/view/' + this.$route.params.username + "/roles")
.then(res => {
this.roles.push(...res.data);
this.loading = /*loading =*/ false;
//If returned data is less than the limit
//then there must be no more pages to paginate
if(res.data.length < this.limit) {
this.offset = null;
} else {
this.offset+= this.limit;
}
})
.catch(e => {
AjaxErrorHandler(this.$store)(e);
this.loading = /*loading =*/ false;
});
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + `/` + `teams/view/${this.$route.params.username}`)
.then(res => this.team = res.data)
.catch(e => {
let invalidId = e.response.data.errors.find(error => {
return error.name === 'accountDoesNotExist'
})
if(invalidId) {
this.$store.commit('set404Page', true)
} else {
AjaxErrorHandler(this.$store)(e)
}
})
},
resetFetchData () {
this.offset = 0;
this.users = [];
this.fetchData();
}
},
getNewerUsers () {
this.loadingNewer = true
this.axios
.get(process.env.VUE_APP_APIENDPOINT + process.env.VUE_APP_APIVERSION + '/' + 'teams/view/' + this.$route.params.username + "/members" + '?limit=' + this.newUsers)
.then(res => {
this.loadingNewer = false
this.newUsers = 0
this.threads.unshift(...res.data.Threads)
})
.catch((e) => {
this.loadingNewer = false
AjaxErrorHandler(this.$store)(e)
})
},
mounted () {
this.fetchData();
},
watch: {
tableSort: 'resetFetchData',
roleSelected: 'resetFetchData',
search: throttle(function () {
this.resetFetchData();
}, 200)
}
}
</script>

View File

@ -0,0 +1,55 @@
module.exports = {
up(queryInterface, Sequelize) {
return Promise.all([
queryInterface.addColumn(
'TeamMemberRoles',
'Role4Id',
{
type: Sequelize.BIGINT
},
),
queryInterface.addColumn(
'TeamMemberRoles',
'Role5Id',
{
type: Sequelize.BIGINT
},
),
queryInterface.addColumn(
'TeamMemberRoles',
'Role6Id',
{
type: Sequelize.BIGINT
},
),
queryInterface.addColumn(
'TeamMemberRoles',
'Role7Id',
{
type: Sequelize.BIGINT
},
),
queryInterface.addColumn(
'TeamMemberRoles',
'Role8Id',
{
type: Sequelize.BIGINT
},
),
queryInterface.addColumn(
'TeamMemberRoles',
'Role9Id',
{
type: Sequelize.BIGINT
},
),
queryInterface.addColumn(
'TeamMemberRoles',
'Role10Id',
{
type: Sequelize.BIGINT
},
),
]);
},
}

View File

@ -17,6 +17,33 @@ module.exports = (sequelize, DataTypes) => {
RoleId: {
type: DataTypes.BIGINT
},
Role2Id: {
type: DataTypes.BIGINT
},
Role3Id: {
type: DataTypes.BIGINT
},
Role4Id: {
type: DataTypes.BIGINT
},
Role5Id: {
type: DataTypes.BIGINT
},
Role6Id: {
type: DataTypes.BIGINT
},
Role7Id: {
type: DataTypes.BIGINT
},
Role8Id: {
type: DataTypes.BIGINT
},
Role9Id: {
type: DataTypes.BIGINT
},
Role10Id: {
type: DataTypes.BIGINT
},
UserId: {
type: DataTypes.BIGINT,
allowNull: false
@ -33,8 +60,18 @@ module.exports = (sequelize, DataTypes) => {
classMethods: {
associate(models) {
TeamMemberRole.belongsTo(models.User)
TeamMemberRole.belongsTo(models.TeamRoles, {as: 'Role'})
TeamMemberRole.belongsTo(models.Team)
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role2'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role3'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role4'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role5'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role6'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role7'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role8'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role9'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Role10'})
TeamMemberRole.belongsTo(models.TeamRoles, { as: 'Team' })
},
includeOptions() {
let models = sequelize.models

View File

@ -110,8 +110,9 @@ module.exports = (sequelize, DataTypes) => {
classMethods: {
associate (models) {
// TeamRoles.hasMany(models.User)
// TeamRoles.hasMany(models.TeamMemberRole, { as: 'team'})
TeamRoles.hasMany(models.Team)
TeamRoles.hasMany(models.User, {as: 'User'})
//TeamRoles.hasMany(models.Team, {as: 'team'})
},
includeOptions (from, limit) {
let models = sequelize.models
@ -164,4 +165,4 @@ module.exports = (sequelize, DataTypes) => {
})
return TeamRoles
}
}

View File

@ -111,16 +111,11 @@ router.post('/create', emailLimiter, auth, async(req, res, next) => {
let teamRoleOwner = {
UserId: req.userData.UserId,
TeamId: teamInfo.id,
RoleId: adminRoleInfo.id
}
let teamRoleOwnerUser = {
UserId: req.userData.UserId,
TeamId: teamInfo.id,
RoleId: memberRoleInfo.id
RoleId: adminRoleInfo.id,
Role2Id: memberRoleInfo.id
}
await TeamMembers.create(teamAddOwner)
await TeamMemberRole.create(teamRoleOwner)
await TeamMemberRole.create(teamRoleOwnerUser)
await Transaction.create({UserId: user.id, priceOfPurchase: 300, text: user.username + ' purchased a Kaverti Team for 300 koins', limited: false, ipId: Ip.createIfNotExists(req.ip, user)})
res.json(team.toJSON())
} else {
@ -249,13 +244,25 @@ router.get('/view/:username/userRoles', async(req, res, next) => {
res.status(200)
res.json([])
}
let team = await TeamRoles.findAll({
let team = await TeamMemberRole.findAll({
order: [['id', 'DESC']],
where: {
TeamId: user.id
},
include: [
{ model: TeamMembers, attributes: ['username', 'createdAt', 'id', 'color', 'picture'] }
{ model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture'] },
{ model: TeamRoles, as: 'Role' },
{ model: TeamRoles, as: 'Role2' },
{ model: TeamRoles, as: 'Role3' },
{ model: TeamRoles, as: 'Role4' },
{ model: TeamRoles, as: 'Role5' },
{ model: TeamRoles, as: 'Role6' },
{ model: TeamRoles, as: 'Role7' },
{ model: TeamRoles, as: 'Role8' },
{ model: TeamRoles, as: 'Role9' },
{ model: TeamRoles, as: 'Role10' },
]
})
res.json(team)
@ -281,7 +288,66 @@ router.get('/view/:username/roles', async(req, res, next) => {
order: [['id', 'DESC']],
where: {
TeamId: user.id
}
},
})
res.json(team)
} else {
throw Errors.accountDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/view/:username/roles/id/:id', async(req, res, next) => {
try {
let user = await Team.findOne({
where: {
username: req.params.username
}
})
if(user) {
if(user.banned) {
res.status(200)
res.json([])
}
let team = await TeamMemberRole.findAll({
order: [['id', 'DESC']],
where: {
TeamId: user.id,
RoleId: req.params.id
},
include: { model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture'] },
})
res.json(team)
} else {
throw Errors.accountDoesNotExist
}
} catch (e) { next(e) }
})
router.get('/view/:username/roles/name/:id', async(req, res, next) => {
try {
let user = await Team.findOne({
where: {
username: req.params.username
}
})
let userParam = await User.findOne({
where: {
username: req.params.id
}
})
if(user && userParam) {
if(user.banned) {
res.status(200)
res.json([])
}
let team = await TeamMemberRole.findAll({
order: [['id', 'DESC']],
where: {
TeamId: user.id,
UserID: userParam.id
},
include: [ { model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture'] }, { model: TeamRoles, as: 'Role' } ]
})
res.json(team)
} else {

View File

@ -142,6 +142,19 @@ router.post('/roles/create/:username', auth, async(req, res, next) => {
}
let teamJoinTest = await TeamMembers.findOne(queryObj3)
if (teamJoinTest) {
let makeRole = {
name: req.body.name,
administrator: req.body.administrator,
inviteUsers: req.body.inviteUsers,
changeTeamMeta: req.body.changeTeamMeta,
forumAdministrator: req.body.forumAdministrator,
moderateForumThreads: req.body.moderateForumThreads,
changeTeamPrivacy: req.body.changeTeamPrivacy,
submitTeamItems: req.body.submitTeamItems,
priority: req.body.priority,
teamId: team.id
}
await TeamRoles.create(makeRole)
res.status(200)
res.json({success: true})
} else if (!teamJoinTest) {
@ -154,4 +167,47 @@ router.post('/roles/create/:username', auth, async(req, res, next) => {
} catch (e) { next(e) }
})
router.post('/admin/', auth, async(req, res, next) => {
try {
await Ban.ReadOnlyMode(req.userData.username)
let team = await Team.findOne({
where: { username: req.params.username }
})
if(team) {
if(team.banned) {
throw Errors.teamBanned
}
let queryObj3 = {
where: {userId: req.userData.UserId, teamId: team.id},
}
let teamJoinTest = await TeamMembers.findOne(queryObj3)
if(teamJoinTest) {
throw Errors.joinedTeam
}
let role = await TeamRoles.findOne({
where: {teamId: team.id, name: "Members"}
})
let join = {
userId: req.userData.UserId,
teamId: team.id,
roles: {"deprecated": "deprecated"}
}
console.log(role)
let roleUser = {
UserId: req.userData.UserId,
TeamId: team.id,
RoleId: role.id
}
await TeamMembers.create(join)
await TeamMemberRole.create(roleUser)
res.status(200)
res.json({success: true})
} else {
throw Errors.teamDoesNotExist
}
} catch (e) { next(e) }
})
module.exports = router;