fix checkbox alignment in admin panel

This commit is contained in:
Phillip Thelen
2024-07-29 18:18:31 +02:00
parent 26d5a4503c
commit e2f25e34e6
15 changed files with 603 additions and 453 deletions

View File

@@ -175,16 +175,16 @@
} }
.btn-warning { .btn-warning {
background: $yellow-10; background: $orange-10;
border: 1px solid transparent; border: 1px solid transparent;
&:hover:not(:disabled):not(.disabled) { &:hover:not(:disabled):not(.disabled) {
background: $yellow-100; background: $orange-100;
border: 1px solid transparent; border: 1px solid transparent;
} }
&:focus { &:focus {
background: $yellow-10; background: $orange-10;
border-color: $purple-400; border-color: $purple-400;
} }
@@ -194,7 +194,7 @@
} }
&:not(:disabled):not(.disabled):active, &:not(:disabled):not(.disabled).active { &:not(:disabled):not(.disabled):active, &:not(:disabled):not(.disabled).active {
background: $yellow-10; background: $orange-10;
border: 1px solid transparent; border: 1px solid transparent;
} }
} }

View File

@@ -17,16 +17,25 @@
<button <button
class="btn btn-primary" class="btn btn-primary"
type="button" type="button"
@click="loadUser(userIdentifier)">Load User</button> @click="loadUser(userIdentifier)"
>
Load User
</button>
<button <button
class="btn btn-secondary" class="btn btn-secondary"
type="button" type="button"
@click="searchUsers(userIdentifier)">Search</button> @click="searchUsers(userIdentifier)"
>
Search
</button>
</div> </div>
</div> </div>
</form> </form>
<router-view @changeUserIdentifier="changeUserIdentifier" class="mt-3" /> <router-view
class="mt-3"
@changeUserIdentifier="changeUserIdentifier"
/>
</div> </div>
</div> </div>
</template> </template>
@@ -75,7 +84,7 @@ export default {
}, },
async searchUsers (userIdentifier) { async searchUsers (userIdentifier) {
if (!userIdentifier || userIdentifier === '') { if (!userIdentifier || userIdentifier === '') {
loadUser(); this.loadUser();
return; return;
} }
this.$router.push({ this.$router.push({

View File

@@ -1,29 +1,38 @@
<template> <template>
<div> <div>
<div class="alert alert-warning" role="alert" <div
v-if="noUsersFound" v-if="noUsersFound"
class="alert alert-warning"
role="alert"
> >
Could not find any matching users. Could not find any matching users.
</div> </div>
<div class="list-group" <div
v-if="users.length > 0"> v-if="users.length > 0"
<a href="#" class="list-group-item list-group-item-action" class="list-group"
>
<a
v-for="user in users" v-for="user in users"
:key="user._id" :key="user._id"
href="#"
class="list-group-item list-group-item-action"
@click="loadUser(user._id)" @click="loadUser(user._id)"
> >
<div class="d-flex w-100 justify-content-between"> <div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{ user.profile.name }}</h5> <h5 class="mb-1">{{ user.profile.name }}</h5>
<small>{{ user._id }}</small> <small>{{ user._id }}</small>
</div> </div>
<p class="mb-1" <p
:class="{'font-weight-bold': matchValueToIdentifier(user.auth.local.username)}"> class="mb-1"
:class="{'font-weight-bold': matchValueToIdentifier(user.auth.local.username)}"
>
@{{ user.auth.local.username }}</p> @{{ user.auth.local.username }}</p>
<p class="mb-0"> <p class="mb-0">
<span <span
v-for="email in userEmails(user)" v-for="email in userEmails(user)"
:key="email"
:class="{'font-weigh-bold': matchValueToIdentifier(email)}" :class="{'font-weigh-bold': matchValueToIdentifier(email)}"
:key="email"> >
{{ email }} {{ email }}
</span> </span>
</p> </p>

View File

@@ -9,7 +9,10 @@
Achievements Achievements
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<ul> <ul>
<li <li
v-for="item in achievements" v-for="item in achievements"

View File

@@ -9,7 +9,10 @@
Current Avatar Appearance, Drop Count Today Current Avatar Appearance, Drop Count Today
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<div>Drops Today: {{ items.lastDrop.count }}</div> <div>Drops Today: {{ items.lastDrop.count }}</div>
<div>Most Recent Drop: {{ items.lastDrop.date | formatDate }}</div> <div>Most Recent Drop: {{ items.lastDrop.date | formatDate }}</div>
<div>Use Costume: {{ preferences.costume ? 'on' : 'off' }}</div> <div>Use Costume: {{ preferences.costume ? 'on' : 'off' }}</div>

View File

@@ -10,68 +10,31 @@
Contributor Details Contributor Details
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<div class="mb-4"> <div class="mb-4">
<h3 class="mt-0">Permissions</h3> <h3 class="mt-0">
<div class="checkbox"> Permissions
<label> </h3>
<div
v-for="permission in permissionList"
:key="permission.key"
class="col-sm-9 offset-sm-3"
>
<div class="custom-control custom-checkbox">
<input <input
v-model="hero.permissions.fullAccess" v-model="hero.permissions[permission.key]"
:disabled="!hasPermission(user, 'fullAccess')" :disabled="!hasPermission(user, permission.key)"
class="custom-control-input"
type="checkbox" type="checkbox"
> >
Full Admin Access (Allows access to everything. EVERYTHING) <label class="custom-control-label">
{{ permission.name }}<br>
<small class="text-secondary">{{ permission.description }}</small>
</label> </label>
</div> </div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.userSupport"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
User Support (Access this form, access purchase history)
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.news"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
News poster (Bailey CMS)
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.moderator"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
Community Moderator (ban and mute users, access chat flags, manage social spaces)
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.challengeAdmin"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
Challenge Admin (can create official habitica challenges and admin all challenges)
</label>
</div>
<div class="checkbox">
<label>
<input
v-model="hero.permissions.coupons"
:disabled="!hasPermission(user, 'fullAccess')"
type="checkbox"
>
Coupon Creator (can manage coupon codes)
</label>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
@@ -104,7 +67,6 @@
<small> <small>
1-7 for normal contributors, 8 for moderators, 9 for staff. 1-7 for normal contributors, 8 for moderators, 9 for staff.
This determines which items, pets, mounts are available, and name-tag coloring. This determines which items, pets, mounts are available, and name-tag coloring.
Tiers 8 and 9 are automatically given admin status.
</small> </small>
</div> </div>
</div> </div>
@@ -116,7 +78,8 @@
class="form-control" class="form-control"
cols="5" cols="5"
rows="5" rows="5"
></textarea> >
</textarea>
<div <div
v-markdown="hero.contributor.contributions" v-markdown="hero.contributor.contributions"
class="markdownPreview" class="markdownPreview"
@@ -139,12 +102,16 @@
</div> </div>
</div> </div>
</div> </div>
<div class="card-footer" v-if="expand"> <div
v-if="expand"
class="card-footer"
>
<input <input
type="submit" type="submit"
value="Save" value="Save"
class="btn btn-primary mt-1" class="btn btn-primary mt-1"
></div> >
</div>
</div> </div>
</form> </form>
</template> </template>
@@ -153,6 +120,7 @@
.levelField { .levelField {
min-width: 10ch; min-width: 10ch;
} }
.textField { .textField {
min-width: 50ch; min-width: 50ch;
} }
@@ -165,6 +133,39 @@ import saveHero from '../mixins/saveHero';
import { mapState } from '@/libs/store'; import { mapState } from '@/libs/store';
import { userStateMixin } from '../../../mixins/userState'; import { userStateMixin } from '../../../mixins/userState';
const permissionList = [
{
key: 'fullAccess',
name: 'Full Admin Access',
description: 'Allows access to everything. EVERYTHING',
},
{
key: 'userSupport',
name: 'User Support',
description: 'Access this form, access purchase history',
},
{
key: 'news',
name: 'News Poster',
description: 'Bailey CMS',
},
{
key: 'moderator',
name: 'Community Moderator',
description: 'Ban and mute users, access chat flags, manage social spaces',
},
{
key: 'challengeAdmin',
name: 'Challenge Admin',
description: 'Can create official habitica challenges and admin all challenges',
},
{
key: 'coupons',
name: 'Coupon Creator',
description: 'Can manage coupon codes',
},
];
function resetData (self) { function resetData (self) {
self.expand = self.hero.contributor.level; self.expand = self.hero.contributor.level;
} }
@@ -193,6 +194,7 @@ export default {
data () { data () {
return { return {
expand: false, expand: false,
permissionList,
}; };
}, },
watch: { watch: {

View File

@@ -13,7 +13,10 @@
>- ERRORS / WARNINGS EXIST</span> >- ERRORS / WARNINGS EXIST</span>
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<p <p
v-if="errorsOrWarningsExist" v-if="errorsOrWarningsExist"
class="errorMessage" class="errorMessage"
@@ -26,7 +29,10 @@
<strong class="col-sm-9 col-form-label"> <strong class="col-sm-9 col-form-label">
{{ hero.auth.timestamps.created | formatDate }}</strong> {{ hero.auth.timestamps.created | formatDate }}</strong>
</div> </div>
<div class="form-group row" v-if="hero.flags.thirdPartyTools"> <div
v-if="hero.flags.thirdPartyTools"
class="form-group row"
>
User has employed <strong>third party tools</strong>. Last known usage: User has employed <strong>third party tools</strong>. Last known usage:
<strong class="col-sm-9 col-form-label"> <strong class="col-sm-9 col-form-label">
{{ hero.flags.thirdPartyTools | formatDate }}</strong> {{ hero.flags.thirdPartyTools | formatDate }}</strong>
@@ -104,9 +110,10 @@
<label class="col-sm-3 col-form-label">API Token</label> <label class="col-sm-3 col-form-label">API Token</label>
<div class="col-sm-9"> <div class="col-sm-9">
<button <button
@click="changeApiToken()"
value="Change API Token" value="Change API Token"
class="btn btn-danger"> class="btn btn-danger"
@click="changeApiToken()"
>
Change API Token Change API Token
</button> </button>
<div <div
@@ -162,12 +169,16 @@
<pre>{{ hero.auth }}</pre> <pre>{{ hero.auth }}</pre>
</div> </div>
</div> </div>
<div class="card-footer" v-if="expand"> <div
v-if="expand"
class="card-footer"
>
<input <input
type="submit" type="submit"
value="Save" value="Save"
class="btn btn-primary mt-1" class="btn btn-primary mt-1"
></div> >
</div>
</div> </div>
</form> </form>
</template> </template>

View File

@@ -9,7 +9,10 @@
Customizations Customizations
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<div <div
v-for="itemType in itemTypes" v-for="itemType in itemTypes"
:key="itemType" :key="itemType"

View File

@@ -9,7 +9,10 @@
Items Items
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<div> <div>
The sections below display each item's key (bolded if the player has ever owned it), The sections below display each item's key (bolded if the player has ever owned it),
followed by the item's English name. followed by the item's English name.

View File

@@ -12,7 +12,10 @@
>- ERRORS / WARNINGS EXIST</span> >- ERRORS / WARNINGS EXIST</span>
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<div <div
v-if="errorsOrWarningsExist" v-if="errorsOrWarningsExist"
class="errorMessage" class="errorMessage"

View File

@@ -10,38 +10,53 @@
Priviliges, Gem Balance Priviliges, Gem Balance
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<p <p
v-if="errorsOrWarningsExist" v-if="errorsOrWarningsExist"
class="errorMessage" class="errorMessage"
> >
Player has had privileges removed or has moderation notes. Player has had privileges removed or has moderation notes.
</p> </p>
<div class="form-group row"> <div
<div class="col-sm-9 offset-sm-3">
<div class="form-check">
<input
v-if="hero.flags" v-if="hero.flags"
class="form-group row"
>
<div class="col-sm-9 offset-sm-3">
<div class="custom-control custom-checkbox">
<input
id="chatShadowMuted"
v-model="hero.flags.chatShadowMuted" v-model="hero.flags.chatShadowMuted"
class="form-check-input" class="custom-control-input"
type="checkbox" type="checkbox"
> >
<label class="form-check-label"> <label
class="custom-control-label"
for="chatShadowMuted"
>
Shadow Mute Shadow Mute
</label> </label>
</div> </div>
</div> </div>
</div> </div>
<div class="form-group row"> <div
<div class="col-sm-9 offset-sm-3">
<div class="form-check">
<input
v-if="hero.flags" v-if="hero.flags"
class="form-group row"
>
<div class="col-sm-9 offset-sm-3">
<div class="custom-control custom-checkbox">
<input
id="chatRevoked"
v-model="hero.flags.chatRevoked" v-model="hero.flags.chatRevoked"
class="form-check-input" class="custom-control-input"
type="checkbox" type="checkbox"
> >
<label class="form-check-label"> <label
class="custom-control-label"
for="chatRevoked"
>
Mute (Revoke Chat Privileges) Mute (Revoke Chat Privileges)
</label> </label>
</div> </div>
@@ -49,13 +64,17 @@
</div> </div>
<div class="form-group row"> <div class="form-group row">
<div class="col-sm-9 offset-sm-3"> <div class="col-sm-9 offset-sm-3">
<div class="form-check"> <div class="custom-control custom-checkbox">
<input <input
id="blocked"
v-model="hero.auth.blocked" v-model="hero.auth.blocked"
class="form-check-input" class="custom-control-input"
type="checkbox" type="checkbox"
> >
<label class="form-check-label"> <label
class="custom-control-label"
for="blocked"
>
Ban / Block Ban / Block
</label> </label>
</div> </div>
@@ -96,12 +115,16 @@
</div> </div>
</div> </div>
</div> </div>
<div class="card-footer" v-if="expand"> <div
v-if="expand"
class="card-footer"
>
<input <input
type="submit" type="submit"
value="Save" value="Save"
class="btn btn-primary mt-1" class="btn btn-primary mt-1"
></div> >
</div>
</div> </div>
</form> </form>
</template> </template>

View File

@@ -2,11 +2,18 @@
<form @submit.prevent="saveHero({ hero, msg: 'Subscription Perks' })"> <form @submit.prevent="saveHero({ hero, msg: 'Subscription Perks' })">
<div class="card mt-2"> <div class="card mt-2">
<div class="card-header"> <div class="card-header">
<h3 class="mb-0 mt-0" :class="{ 'open': expand }" @click="expand = !expand"> <h3
class="mb-0 mt-0"
:class="{ 'open': expand }"
@click="expand = !expand"
>
Subscription, Monthly Perks Subscription, Monthly Perks
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<div v-if="hero.purchased.plan.paymentMethod"> <div v-if="hero.purchased.plan.paymentMethod">
Payment method: Payment method:
<strong>{{ hero.purchased.plan.paymentMethod }}</strong> <strong>{{ hero.purchased.plan.paymentMethod }}</strong>
@@ -19,13 +26,20 @@
Group plan ID: Group plan ID:
<strong>{{ hero.purchased.plan.owner }}</strong> <strong>{{ hero.purchased.plan.owner }}</strong>
</div> </div>
<div v-if="hero.purchased.plan.dateCreated" class="form-group row"> <div
v-if="hero.purchased.plan.dateCreated"
class="form-group row"
>
<label class="col-sm-3 col-form-label"> <label class="col-sm-3 col-form-label">
Creation date: Creation date:
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group"> <div class="input-group">
<input v-model="hero.purchased.plan.dateCreated" class="form-control" type="text"> <input
v-model="hero.purchased.plan.dateCreated"
class="form-control"
type="text"
>
<div class="input-group-append"> <div class="input-group-append">
<strong> <strong>
{{ dateFormat(hero.purchased.plan.dateCreated) }} {{ dateFormat(hero.purchased.plan.dateCreated) }}
@@ -34,13 +48,20 @@
</div> </div>
</div> </div>
</div> </div>
<div v-if="hero.purchased.plan.dateCurrentTypeCreated" class="form-group row"> <div
v-if="hero.purchased.plan.dateCurrentTypeCreated"
class="form-group row"
>
<label class="col-sm-3 col-form-label"> <label class="col-sm-3 col-form-label">
Current sub start date: Current sub start date:
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group"> <div class="input-group">
<input v-model="hero.purchased.plan.dateCurrentTypeCreated" class="form-control" type="text"> <input
v-model="hero.purchased.plan.dateCurrentTypeCreated"
class="form-control"
type="text"
>
<div class="input-group-append"> <div class="input-group-append">
<strong> <strong>
{{ dateFormat(hero.purchased.plan.dateCurrentTypeCreated) }} {{ dateFormat(hero.purchased.plan.dateCurrentTypeCreated) }}
@@ -55,7 +76,11 @@
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group"> <div class="input-group">
<input v-model="hero.purchased.plan.dateTerminated" class="form-control" type="text"> <input
v-model="hero.purchased.plan.dateTerminated"
class="form-control"
type="text"
>
<div class="input-group-append"> <div class="input-group-append">
<strong class="input-group-text"> <strong class="input-group-text">
{{ dateFormat(hero.purchased.plan.dateTerminated) }} {{ dateFormat(hero.purchased.plan.dateTerminated) }}
@@ -69,7 +94,13 @@
Consecutive months: Consecutive months:
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<input v-model="hero.purchased.plan.consecutive.count" class="form-control" type="number" min="0" step="1"> <input
v-model="hero.purchased.plan.consecutive.count"
class="form-control"
type="number"
min="0"
step="1"
>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
@@ -77,7 +108,13 @@
Perk offset months: Perk offset months:
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<input v-model="hero.purchased.plan.consecutive.offset" class="form-control" type="number" min="0" step="1"> <input
v-model="hero.purchased.plan.consecutive.offset"
class="form-control"
type="number"
min="0"
step="1"
>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
@@ -85,8 +122,14 @@
Perk month count: Perk month count:
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<input v-model="hero.purchased.plan.perkMonthCount" class="form-control" type="number" min="0" max="2" <input
step="1"> v-model="hero.purchased.plan.perkMonthCount"
class="form-control"
type="number"
min="0"
max="2"
step="1"
>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
@@ -100,8 +143,13 @@
Mystic Hourglasses: Mystic Hourglasses:
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<input v-model="hero.purchased.plan.consecutive.trinkets" class="form-control" type="number" min="0" <input
step="1"> v-model="hero.purchased.plan.consecutive.trinkets"
class="form-control"
type="number"
min="0"
step="1"
>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
@@ -109,8 +157,14 @@
Gem cap increase: Gem cap increase:
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<input v-model="hero.purchased.plan.consecutive.gemCapExtra" class="form-control" type="number" min="0" <input
max="25" step="5"> v-model="hero.purchased.plan.consecutive.gemCapExtra"
class="form-control"
type="number"
min="0"
max="25"
step="5"
>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
@@ -126,8 +180,14 @@
Gems bought this month: Gems bought this month:
</label> </label>
<div class="col-sm-9"> <div class="col-sm-9">
<input v-model="hero.purchased.plan.gemsBought" class="form-control" type="number" min="0" <input
:max="hero.purchased.plan.consecutive.gemCapExtra + 25" step="1"> v-model="hero.purchased.plan.gemsBought"
class="form-control"
type="number"
min="0"
:max="hero.purchased.plan.consecutive.gemCapExtra + 25"
step="1"
>
</div> </div>
</div> </div>
<div v-if="hero.purchased.plan.extraMonths > 0"> <div v-if="hero.purchased.plan.extraMonths > 0">
@@ -140,7 +200,10 @@
</label> </label>
<div class="col-sm-9 col-form-label"> <div class="col-sm-9 col-form-label">
<span v-if="hero.purchased.plan.mysteryItems.length > 0"> <span v-if="hero.purchased.plan.mysteryItems.length > 0">
<span v-for="(item, index) in hero.purchased.plan.mysteryItems" :key="index"> <span
v-for="(item, index) in hero.purchased.plan.mysteryItems"
:key="index"
>
<strong v-if="index < hero.purchased.plan.mysteryItems.length - 1"> <strong v-if="index < hero.purchased.plan.mysteryItems.length - 1">
{{ item }}, {{ item }},
</strong> </strong>
@@ -153,8 +216,15 @@
</div> </div>
</div> </div>
</div> </div>
<div class="card-footer" v-if="expand"> <div
<input type="submit" value="Save" class="btn btn-primary mt-1"> v-if="expand"
class="card-footer"
>
<input
type="submit"
value="Save"
class="btn btn-primary mt-1"
>
</div> </div>
</div> </div>
</form> </form>

View File

@@ -9,7 +9,10 @@
Transactions Transactions
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<purchase-history-table <purchase-history-table
:gem-transactions="gemTransactions" :gem-transactions="gemTransactions"
:hourglass-transactions="hourglassTransactions" :hourglass-transactions="hourglassTransactions"

View File

@@ -10,7 +10,10 @@
User Profile User Profile
</h3> </h3>
</div> </div>
<div v-if="expand" class="card-body"> <div
v-if="expand"
class="card-body"
>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-3 col-form-label">Display name</label> <label class="col-sm-3 col-form-label">Display name</label>
<div class="col-sm-9"> <div class="col-sm-9">
@@ -28,7 +31,8 @@
v-model="hero.profile.imageUrl" v-model="hero.profile.imageUrl"
class="form-control" class="form-control"
type="text" type="text"
></div> >
</div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-3 col-form-label">About</label> <label class="col-sm-3 col-form-label">About</label>
@@ -45,12 +49,16 @@
</div> </div>
</div> </div>
</div> </div>
<div class="card-footer" v-if="expand"> <div
v-if="expand"
class="card-footer"
>
<input <input
type="submit" type="submit"
value="Save" value="Save"
class="btn btn-primary mt-1" class="btn btn-primary mt-1"
></div> >
</div>
</div> </div>
</form> </form>
</template> </template>