Files
habitica/website/client/src/components/tasks/approvalFooter.vue
T
negue aaf32cc09b Teams UI Redesign and A11y Updates (#12142)
* WIP(a11y): task modal updates

* fix(tasks): borders in modal

* fix(tasks): circley locks

* fix(task-modal): placeholders

* WIP(task-modal): disabled states, hide empty options, +/- restyle

* fix(task-modal): box shadows instead of borders, habit control pointer

* fix(task-modal): button states?

* fix(modal): tighten up layout, new spacing utils

* fix(tasks): more stylin

* fix(tasks): habit hovers

* fix(css): checklist labels, a11y colors

* fix(css): one more missed hover issue

* fix(css): lock Challenges, label fixes

* fix(css): scope input/textarea changes

* fix(style): task tweakies

* fix(style): more button fixage

* WIP(component): start select list story

* working example of a templated selectList

* fix(style): more button corrections

* fix(lint): EOL

* fix(buttons): factor btn-secondary to better override Bootstrap

* fix(styles): standardize more buttons

* wip: difficulty select - style fixes

* selectDifficulty works! 🎉 - fix styles

* change the dropdown-item sizes only for the selectList ones

* selectTranslatedArray

* changed many label margins

* more correct dropdown style

* fix(modals): button corrections

* input-group styling + datetime picker without today button

* Style/margins for "repeat every" - extract selectTag.vue

* working tag-selection / update - cleanup

* fix stories

* fix svg color on create modal (purple)

* fix task modal bottom padding

* correct dropdown shadow

* update dropdown-toggle caret size / color

* fixed checklist style

* sync checked state

* selectTag padding

* fix spacing between positive/negative streak inputs

* toggle-checkbox + fix some spacings

* disable repeat-on when its a groupTask

* fix new checklist-item

* fix toggle-checkbox style - fix difficulty style

* fix checklist ui

* add tags label , when there arent any tags selected

* WORKING select-tag component 🎉

* fix taglist story

* show max 5 items in tag dropdown + "X more" label

* fix datetime clear button

* replace m-b-xs to mb-1 (bootstrap) - fix input-group-text style

* fix styles of advanced settings

* fix delete task styles

* always show grippy on hover of the item

* extract modal-text-input mixin + fix the borders/dropshadow

* fix(spacing): revert most to Bootstrap

* feat(checklists): make local copy of master checklist non-editable
also aggressively update checklists because they weren't syncing??

* fix(checklists): handle add/remove options better

* feat(teams): manager notes field

* fix select/dropdown styles

* input border + icon colors

* delete task underline color

* fix checklist "delete icon" vertical position

* selectTag fixes - normal open/close toggle working again - remove icon color

* fixing icons:

Trash can - Delete
Little X - Remove
Big X - Close
Block - Block

* fix taglist margins / icon sizes

* wip margin overview (in storybook)

* fix routerlink

* remove unused method

* new selectTag style + add markdown inside tagList + scrollable tag selection

* fix selectTag / selectList active border

* fix difficulty select (svg default color)

* fix input padding-left + fix reset habit streak fullwidth / padding + "repeat every" gray text (no border)

* feat(teams): improved approval request > approve > reward flow

* fix(tests): address failures

* fix(lint): oops only

* fix(tasks): short-circuit group related logic

* fix(tasks): more short circuiting

* fix(tasks): more lines, less lint

* fix(tasks): how do i keep missing these

* feat(teams): provide assigning user summary

* fix(teams): don't attempt to record assiging user if not supplied

* fix advanced-settings styling / margin

* fix merge + hide advanced streak settings when none enabled

* fix styles

* set Roboto font for advanced settings

* Add Challenge flag to the tag list

* add tag with enter, when no other tag is found

* fix styles + tag cancel button

* refactor footer / margin

* split repeat fields into option mt-3 groups

* button all the things

* fix(tasks): style updates
* no hover state for non-editable tasks on team board
* keep assign/claim footer on task after requesting approval
* disable more fields on user copy of team task, and remove hover states 
for them

* fix(tasks): functional revisions
* "Claim Rewards" instead of "x" in task approved notif
* Remove default transition supplied by Bootstrap, apply individually to 
some elements
* Delete individual tasks and related notifications when master task 
deleted from team board
* Manager notes now save when supplied at task initial creation
* Can no longer dismiss rewards from approved task by hitting Dismiss 
All

* fix(tasks): clean tasksOrder
also adjust related test expectation

* fix(tests): adjust integration expectations

* fix(test): ratzen fratzen only

* fix(teams): checklist, notes

* fix(teams): improve disabled states

* fix(teams): more style fixage

* BREAKING(teams): return 202 instead of 401 for approval request

* fix(teams): better taskboard sync
also re-re-fix checklist borders

* fix(tests): update expectations for breaking change

* refactor(task-modal): lockable label component

* refactor(teams): move task scoring to mixin

* fix(teams): style corrections

* fix(tasks): spacing and wording corrections

* fix(teams): don't bork manager notes

* fix(teams): assignment fix and more approval flow revisions

* WIP(teams): use tag dropdown control for assignment

* refactor(tasks): better spacing, generic multi select

* fix(tasks): various visual and behavior updates

* fix(tasks): incidental style tweaks

* fix(teams): standardize approval request response

* refactor(teams): correct test, use res.respond message param

* fix(storybook): renamed component

* fix(teams): age approval-required To Do's
Fixes #8730

* fix(teams): sync personal data as well as team on mixin sync

* fix(teams): hide unclaim button, not whole footer; fix switch focus

* fix(achievements): unrevert width fix

Co-authored-by: Sabe Jones <sabrecat@gmail.com>
2020-07-25 07:37:10 -05:00

208 lines
5.8 KiB
Vue

<template>
<div>
<approval-modal :task="task" />
<div
class="claim-bottom-message d-flex align-items-center"
>
<div
class="mr-auto ml-2"
v-html="message"
></div>
<div
v-if="!userIsAssigned && !task.completed"
class="ml-auto mr-2"
>
<a
class="claim-color"
@click="claim()"
>{{ $t('claim') }}</a>
</div>
<div
v-if="userIsAssigned && !approvalRequested && !task.completed"
class="ml-auto mr-2"
>
<a
class="unclaim-color"
@click="unassign()"
>{{ $t('removeClaim') }}</a>
</div>
</div>
<div
v-if="approvalRequested && userIsManager"
class="claim-bottom-message d-flex align-items-center justify-content-around"
>
<a
class="approve-color"
@click="approve()"
>{{ $t('approveTask') }}</a>
<a @click="needsWork()">{{ $t('needsWork') }}</a>
</div>
<div
v-if="multipleApprovalsRequested && userIsManager"
class="claim-bottom-message d-flex align-items-center"
>
<a @click="showRequests()">{{ $t('viewRequests') }}</a>
</div>
<div
v-if="userIsAssigned && task.group.approval.approved
&& !task.completed && task.type !== 'habit'"
class="claim-bottom-message d-flex align-items-center justify-content-around"
>
<a
class="approve-color"
@click="$emit('claimRewards')"
>{{ $t('claimRewards') }}</a>
</div>
</div>
</template>
<style lang="scss" scoped>
@import '~@/assets/scss/colors.scss';
.claim-bottom-message {
background-color: $gray-700;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
color: $gray-200;
font-size: 12px;
padding-bottom: 0.25rem;
padding-top: 0.25rem;
z-index: 9;
}
.approve-color {
color: $green-10 !important;
}
.claim-color {
color: $blue-10 !important;
}
.unclaim-color {
color: $red-50 !important;
}
</style>
<script>
import findIndex from 'lodash/findIndex';
import { mapState } from '@/libs/store';
import approvalModal from './approvalModal';
import sync from '@/mixins/sync';
export default {
components: {
approvalModal,
},
mixins: [sync],
props: ['task', 'group'],
computed: {
...mapState({ user: 'user.data' }),
userIsAssigned () {
return this.task.group.assignedUsers
&& this.task.group.assignedUsers.indexOf(this.user._id) !== -1;
},
message () {
const { assignedUsers } = this.task.group;
const assignedUsersNames = [];
const assignedUsersLength = assignedUsers.length;
// @TODO: Eh, I think we only ever display one user name
if (this.group && this.group.members) {
assignedUsers.forEach(userId => {
const index = findIndex(this.group.members, member => member._id === userId);
const assignedMember = this.group.members[index];
assignedUsersNames.push(assignedMember.profile.name);
});
}
if (assignedUsersLength === 1 && !this.userIsAssigned) {
return this.$t('assignedToUser', { userName: assignedUsersNames[0] });
} if (assignedUsersLength > 1 && !this.userIsAssigned) {
return this.$t('assignedToMembers', { userCount: assignedUsersLength });
} if (assignedUsersLength > 1 && this.userIsAssigned) {
return this.$t('assignedToYouAndMembers', { userCount: assignedUsersLength - 1 });
} if (this.userIsAssigned) {
return this.$t('youAreAssigned');
} // if (assignedUsersLength === 0) {
return this.$t('taskIsUnassigned');
},
userIsManager () {
if (
this.group
&& (this.group.leader.id === this.user._id || this.group.managers[this.user._id])
) return true;
return false;
},
approvalRequested () {
if (
(this.task.approvals && this.task.approvals.length === 1)
|| (this.task.group && this.task.group.approval && this.task.group.approval.requested)
) {
return true;
}
return false;
},
multipleApprovalsRequested () {
if (this.task.approvals && this.task.approvals.length > 1) return true;
return false;
},
},
methods: {
async claim () {
let taskId = this.task._id;
// If we are on the user task
if (this.task.userId) {
taskId = this.task.group.taskId;
}
await this.$store.dispatch('tasks:assignTask', {
taskId,
userId: this.user._id,
});
this.task.group.assignedUsers.push(this.user._id);
this.sync();
},
async unassign () {
if (!window.confirm(this.$t('confirmUnClaim'))) return;
let taskId = this.task._id;
// If we are on the user task
if (this.task.userId) {
taskId = this.task.group.taskId;
}
await this.$store.dispatch('tasks:unassignTask', {
taskId,
userId: this.user._id,
});
const index = this.task.group.assignedUsers.indexOf(this.user._id);
this.task.group.assignedUsers.splice(index, 1);
this.sync();
},
approve () {
const userIdToApprove = this.task.group.assignedUsers[0];
this.$store.dispatch('tasks:approve', {
taskId: this.task._id,
userId: userIdToApprove,
});
this.task.group.assignedUsers.splice(0, 1);
this.task.approvals.splice(0, 1);
this.sync();
},
needsWork () {
if (!window.confirm(this.$t('confirmNeedsWork'))) return;
const userIdNeedsMoreWork = this.task.group.assignedUsers[0];
this.$store.dispatch('tasks:needsWork', {
taskId: this.task._id,
userId: userIdNeedsMoreWork,
});
this.task.approvals.splice(0, 1);
this.sync();
},
showRequests () {
this.$root.$emit('bv::show::modal', 'approval-modal');
},
},
};
</script>