2017-06-26 21:55:14 +00:00
|
|
|
<template lang="pug">
|
2017-08-03 02:15:00 +00:00
|
|
|
.tasks-column(:class='type')
|
2017-08-01 12:30:17 +00:00
|
|
|
b-modal(ref="editTaskModal")
|
2017-10-23 21:05:35 +00:00
|
|
|
buy-quest-modal(:item="selectedItemToBuy || {}",
|
|
|
|
|
:priceType="selectedItemToBuy ? selectedItemToBuy.currency : ''",
|
|
|
|
|
:withPin="true",
|
|
|
|
|
@change="resetItemToBuy($event)"
|
|
|
|
|
v-if='type === "reward"')
|
2018-05-04 21:10:02 +00:00
|
|
|
.d-flex.align-items-center
|
|
|
|
|
h2.column-title {{ $t(typeLabel) }}
|
|
|
|
|
.badge.badge-pill.badge-purple.column-badge.mx-1(v-if="badgeCount > 0") {{ badgeCount }}
|
2017-06-26 21:55:14 +00:00
|
|
|
.filters.d-flex.justify-content-end
|
|
|
|
|
.filter.small-text(
|
2018-03-18 15:23:58 +00:00
|
|
|
v-for="filter in typeFilters",
|
|
|
|
|
:class="{active: activeFilter.label === filter}",
|
2017-08-01 12:30:17 +00:00
|
|
|
@click="activateFilter(type, filter)",
|
2018-03-18 15:23:58 +00:00
|
|
|
) {{ $t(filter) }}
|
2017-10-17 21:38:42 +00:00
|
|
|
.tasks-list(ref="tasksWrapper")
|
2017-11-02 20:07:38 +00:00
|
|
|
textarea.quick-add(
|
|
|
|
|
:rows="quickAddRows",
|
2017-10-20 13:22:13 +00:00
|
|
|
v-if="isUser", :placeholder="quickAddPlaceholder",
|
2017-11-02 20:07:38 +00:00
|
|
|
v-model="quickAddText", @keypress.enter="quickAdd",
|
2017-10-17 21:38:42 +00:00
|
|
|
ref="quickAdd",
|
2017-11-02 20:07:38 +00:00
|
|
|
@focus="quickAddFocused = true", @blur="quickAddFocused = false",
|
|
|
|
|
)
|
|
|
|
|
transition(name="quick-add-tip-slide")
|
2018-05-18 15:11:04 +00:00
|
|
|
.quick-add-tip.small-text(v-show="quickAddFocused", v-html="$t('addMultipleTip', {taskType: $t(typeLabel)})")
|
2018-03-18 15:23:58 +00:00
|
|
|
clear-completed-todos(v-if="activeFilter.label === 'complete2' && isUser === true")
|
2017-11-02 20:07:38 +00:00
|
|
|
.column-background(
|
|
|
|
|
v-if="isUser === true",
|
|
|
|
|
:class="{'initial-description': initialColumnDescription}",
|
|
|
|
|
ref="columnBackground",
|
|
|
|
|
)
|
|
|
|
|
.svg-icon(v-html="icons[type]", :class="`icon-${type}`", v-once)
|
2018-03-18 15:23:58 +00:00
|
|
|
h3(v-once) {{$t('theseAreYourTasks', {taskType: $t(typeLabel)})}}
|
2017-11-02 20:07:38 +00:00
|
|
|
.small-text {{$t(`${type}sDesc`)}}
|
2018-01-08 17:43:57 +00:00
|
|
|
draggable.sortable-tasks(
|
2017-11-14 23:54:11 +00:00
|
|
|
ref="tasksList",
|
Feature/sortable reward area (#9930)
* Client POC
We need to wrap each draggable region it its own div or else the
"draggable" element will conflict with each other. This screws up the
styling but that is totally fixable
* Ah that ref was being used after all, changing back
* Scaffold out a new callback for when we drag these things
Next is going to be the hard part: I need to save the sort order for
these to the database. I don't even know if there is a schema but hey
this is the best place to start
* Firefox caching is the problem: don't actually need the wrapper div
So I guess I should try this in chrome and see how it works then come
back to firefox and figure out what the heck is going on
* Scaffolding out our API call to save the sort order
The endpoint doesn't exist yet so we will need to add that
* Ok we are now calling our API endpoint to reorder these things
Of course it doesn't exist yet so you get a 404 when you try, but that
is ok
* Defining api endpoint, a work in progress
In particular I really had ought to use _id for these too, it appears
that the primary way we detect order doesn't even use "key" at all.
* Switching to using the pinned item UUID
This has much better results, but of course the server and client logic
don't match now. Will have to keep working on my splice to make sure
that they are the same
* I thought this would fix our server/client mismatch but it is not it
Something is really wrong with my logic somewhere, maybe I need to
update the db step?
* Moving this logic to the "user" rather than "tasks" and key off path
Path is unique and is less finiky than dealing with string comparisons
with ids. Unfortunately everything is still not working... I suppose
user.update() doesn't care about the position?
* This client code caused quite a lot of problems if you dragged fast
We don't really need it it seems, so off it goes
* Updating markup and CSS so it actually looks good.
Everything is working horray!!
I did just notice the following bug: the popover text sometimes makes it
very annoying to drag because you can't drop over it@
* Cleaning up my comments in the API section user.js
I had a lot of TODOS that are mostly done now
* Fixing a spacing code standards thing
* Turns out we never use type, so we should remove this from the API call
* Adding pinnedItemsOrder into the user schema
And disabling my call in the frontend before I do any more damage
* Halfway to using pinnedItemsOrder
This isn't working yet but it is not going to break it horribly like it
was before.
* Hooking up inAppRewards to always produce sorted information
It is suspicially working right now even though I have not added the
seasonal stuff logic yet...
* Updating the comments in user.js in movedPinnedItem
It turns out that my bandaid fix to just get the ball rolling perfectly
does what I need it to do when we have a length discrepancy. So we are
getting much closer to the final product, just need lots of testing
* Cleaning up code standards kinds of things
* Yay, this fixes the popover issue
I hope this is the right "vue" way to do things, because I tried a bunch
of other things that definately were not the right way to do it. And
this appears to work too
* ** Partial Work ** Starting tests on api call for draggable items
Doesn't work, doesn't compile so don't include in PR!
* Test failing still...
This is worth a save. The api call grabs the seasonal items too, so we
can't get away from using the common functions and calls here to get the
actual list of items
* Okay have the first test passing
Need to clean up my linter problems though
* Planning out the next two tests and fixing my format problems
* 2nd Test case written, this time with the "more" odd case
* Making sure that we didn't mess with pinned items
* Huh... this test doesn't give me the expected result
Drat, I guess I found a bug
* Throw an error when we put garbage in our api call.
Well, before we got user.pinnedItemsOrder filled with a bunch of "null"
entries which is not ideal. it still worked, but isn't this confusing
enough already?
* Cleaning up the multitude of linting problems thanks gulp :)
* Writing tests for inAppRewards.js, but something is wrong
* Fixing my linting errors in inAppRewards tests
These tests still do not run though, so they may fail and I would not
know
* Applying Negue's fixes to inAppRewards.js test
It never occured to me that we shouldn't try to reach the database while
in the common tests. Well, we shouldn't do that, we should use the
common.helpers instead. Thanks!
2018-04-13 13:22:06 +00:00
|
|
|
@update='taskSorted',
|
2018-03-18 15:23:58 +00:00
|
|
|
:options='{disabled: activeFilter.label === "scheduled"}',
|
Feature/sortable reward area (#9930)
* Client POC
We need to wrap each draggable region it its own div or else the
"draggable" element will conflict with each other. This screws up the
styling but that is totally fixable
* Ah that ref was being used after all, changing back
* Scaffold out a new callback for when we drag these things
Next is going to be the hard part: I need to save the sort order for
these to the database. I don't even know if there is a schema but hey
this is the best place to start
* Firefox caching is the problem: don't actually need the wrapper div
So I guess I should try this in chrome and see how it works then come
back to firefox and figure out what the heck is going on
* Scaffolding out our API call to save the sort order
The endpoint doesn't exist yet so we will need to add that
* Ok we are now calling our API endpoint to reorder these things
Of course it doesn't exist yet so you get a 404 when you try, but that
is ok
* Defining api endpoint, a work in progress
In particular I really had ought to use _id for these too, it appears
that the primary way we detect order doesn't even use "key" at all.
* Switching to using the pinned item UUID
This has much better results, but of course the server and client logic
don't match now. Will have to keep working on my splice to make sure
that they are the same
* I thought this would fix our server/client mismatch but it is not it
Something is really wrong with my logic somewhere, maybe I need to
update the db step?
* Moving this logic to the "user" rather than "tasks" and key off path
Path is unique and is less finiky than dealing with string comparisons
with ids. Unfortunately everything is still not working... I suppose
user.update() doesn't care about the position?
* This client code caused quite a lot of problems if you dragged fast
We don't really need it it seems, so off it goes
* Updating markup and CSS so it actually looks good.
Everything is working horray!!
I did just notice the following bug: the popover text sometimes makes it
very annoying to drag because you can't drop over it@
* Cleaning up my comments in the API section user.js
I had a lot of TODOS that are mostly done now
* Fixing a spacing code standards thing
* Turns out we never use type, so we should remove this from the API call
* Adding pinnedItemsOrder into the user schema
And disabling my call in the frontend before I do any more damage
* Halfway to using pinnedItemsOrder
This isn't working yet but it is not going to break it horribly like it
was before.
* Hooking up inAppRewards to always produce sorted information
It is suspicially working right now even though I have not added the
seasonal stuff logic yet...
* Updating the comments in user.js in movedPinnedItem
It turns out that my bandaid fix to just get the ball rolling perfectly
does what I need it to do when we have a length discrepancy. So we are
getting much closer to the final product, just need lots of testing
* Cleaning up code standards kinds of things
* Yay, this fixes the popover issue
I hope this is the right "vue" way to do things, because I tried a bunch
of other things that definately were not the right way to do it. And
this appears to work too
* ** Partial Work ** Starting tests on api call for draggable items
Doesn't work, doesn't compile so don't include in PR!
* Test failing still...
This is worth a save. The api call grabs the seasonal items too, so we
can't get away from using the common functions and calls here to get the
actual list of items
* Okay have the first test passing
Need to clean up my linter problems though
* Planning out the next two tests and fixing my format problems
* 2nd Test case written, this time with the "more" odd case
* Making sure that we didn't mess with pinned items
* Huh... this test doesn't give me the expected result
Drat, I guess I found a bug
* Throw an error when we put garbage in our api call.
Well, before we got user.pinnedItemsOrder filled with a bunch of "null"
entries which is not ideal. it still worked, but isn't this confusing
enough already?
* Cleaning up the multitude of linting problems thanks gulp :)
* Writing tests for inAppRewards.js, but something is wrong
* Fixing my linting errors in inAppRewards tests
These tests still do not run though, so they may fail and I would not
know
* Applying Negue's fixes to inAppRewards.js test
It never occured to me that we shouldn't try to reach the database while
in the common tests. Well, we shouldn't do that, we should use the
common.helpers instead. Thanks!
2018-04-13 13:22:06 +00:00
|
|
|
class="sortable-tasks"
|
2017-07-22 18:30:08 +00:00
|
|
|
)
|
2017-10-16 20:04:16 +00:00
|
|
|
task(
|
|
|
|
|
v-for="task in taskList",
|
|
|
|
|
:key="task.id", :task="task",
|
|
|
|
|
:isUser="isUser",
|
|
|
|
|
@editTask="editTask",
|
2017-11-02 20:07:38 +00:00
|
|
|
@moveTo="moveTo",
|
2017-10-16 20:04:16 +00:00
|
|
|
:group='group',
|
|
|
|
|
)
|
2017-09-02 16:08:32 +00:00
|
|
|
template(v-if="hasRewardsList")
|
Feature/sortable reward area (#9930)
* Client POC
We need to wrap each draggable region it its own div or else the
"draggable" element will conflict with each other. This screws up the
styling but that is totally fixable
* Ah that ref was being used after all, changing back
* Scaffold out a new callback for when we drag these things
Next is going to be the hard part: I need to save the sort order for
these to the database. I don't even know if there is a schema but hey
this is the best place to start
* Firefox caching is the problem: don't actually need the wrapper div
So I guess I should try this in chrome and see how it works then come
back to firefox and figure out what the heck is going on
* Scaffolding out our API call to save the sort order
The endpoint doesn't exist yet so we will need to add that
* Ok we are now calling our API endpoint to reorder these things
Of course it doesn't exist yet so you get a 404 when you try, but that
is ok
* Defining api endpoint, a work in progress
In particular I really had ought to use _id for these too, it appears
that the primary way we detect order doesn't even use "key" at all.
* Switching to using the pinned item UUID
This has much better results, but of course the server and client logic
don't match now. Will have to keep working on my splice to make sure
that they are the same
* I thought this would fix our server/client mismatch but it is not it
Something is really wrong with my logic somewhere, maybe I need to
update the db step?
* Moving this logic to the "user" rather than "tasks" and key off path
Path is unique and is less finiky than dealing with string comparisons
with ids. Unfortunately everything is still not working... I suppose
user.update() doesn't care about the position?
* This client code caused quite a lot of problems if you dragged fast
We don't really need it it seems, so off it goes
* Updating markup and CSS so it actually looks good.
Everything is working horray!!
I did just notice the following bug: the popover text sometimes makes it
very annoying to drag because you can't drop over it@
* Cleaning up my comments in the API section user.js
I had a lot of TODOS that are mostly done now
* Fixing a spacing code standards thing
* Turns out we never use type, so we should remove this from the API call
* Adding pinnedItemsOrder into the user schema
And disabling my call in the frontend before I do any more damage
* Halfway to using pinnedItemsOrder
This isn't working yet but it is not going to break it horribly like it
was before.
* Hooking up inAppRewards to always produce sorted information
It is suspicially working right now even though I have not added the
seasonal stuff logic yet...
* Updating the comments in user.js in movedPinnedItem
It turns out that my bandaid fix to just get the ball rolling perfectly
does what I need it to do when we have a length discrepancy. So we are
getting much closer to the final product, just need lots of testing
* Cleaning up code standards kinds of things
* Yay, this fixes the popover issue
I hope this is the right "vue" way to do things, because I tried a bunch
of other things that definately were not the right way to do it. And
this appears to work too
* ** Partial Work ** Starting tests on api call for draggable items
Doesn't work, doesn't compile so don't include in PR!
* Test failing still...
This is worth a save. The api call grabs the seasonal items too, so we
can't get away from using the common functions and calls here to get the
actual list of items
* Okay have the first test passing
Need to clean up my linter problems though
* Planning out the next two tests and fixing my format problems
* 2nd Test case written, this time with the "more" odd case
* Making sure that we didn't mess with pinned items
* Huh... this test doesn't give me the expected result
Drat, I guess I found a bug
* Throw an error when we put garbage in our api call.
Well, before we got user.pinnedItemsOrder filled with a bunch of "null"
entries which is not ideal. it still worked, but isn't this confusing
enough already?
* Cleaning up the multitude of linting problems thanks gulp :)
* Writing tests for inAppRewards.js, but something is wrong
* Fixing my linting errors in inAppRewards tests
These tests still do not run though, so they may fail and I would not
know
* Applying Negue's fixes to inAppRewards.js test
It never occured to me that we shouldn't try to reach the database while
in the common tests. Well, we shouldn't do that, we should use the
common.helpers instead. Thanks!
2018-04-13 13:22:06 +00:00
|
|
|
draggable(
|
|
|
|
|
ref="rewardsList",
|
|
|
|
|
@update="rewardSorted",
|
|
|
|
|
@start="rewardDragStart",
|
|
|
|
|
@end="rewardDragEnd",
|
|
|
|
|
class="reward-items",
|
|
|
|
|
)
|
2017-08-14 17:15:32 +00:00
|
|
|
shopItem(
|
|
|
|
|
v-for="reward in inAppRewards",
|
|
|
|
|
:item="reward",
|
|
|
|
|
:key="reward.key",
|
|
|
|
|
:highlightBorder="reward.isSuggested",
|
Feature/sortable reward area (#9930)
* Client POC
We need to wrap each draggable region it its own div or else the
"draggable" element will conflict with each other. This screws up the
styling but that is totally fixable
* Ah that ref was being used after all, changing back
* Scaffold out a new callback for when we drag these things
Next is going to be the hard part: I need to save the sort order for
these to the database. I don't even know if there is a schema but hey
this is the best place to start
* Firefox caching is the problem: don't actually need the wrapper div
So I guess I should try this in chrome and see how it works then come
back to firefox and figure out what the heck is going on
* Scaffolding out our API call to save the sort order
The endpoint doesn't exist yet so we will need to add that
* Ok we are now calling our API endpoint to reorder these things
Of course it doesn't exist yet so you get a 404 when you try, but that
is ok
* Defining api endpoint, a work in progress
In particular I really had ought to use _id for these too, it appears
that the primary way we detect order doesn't even use "key" at all.
* Switching to using the pinned item UUID
This has much better results, but of course the server and client logic
don't match now. Will have to keep working on my splice to make sure
that they are the same
* I thought this would fix our server/client mismatch but it is not it
Something is really wrong with my logic somewhere, maybe I need to
update the db step?
* Moving this logic to the "user" rather than "tasks" and key off path
Path is unique and is less finiky than dealing with string comparisons
with ids. Unfortunately everything is still not working... I suppose
user.update() doesn't care about the position?
* This client code caused quite a lot of problems if you dragged fast
We don't really need it it seems, so off it goes
* Updating markup and CSS so it actually looks good.
Everything is working horray!!
I did just notice the following bug: the popover text sometimes makes it
very annoying to drag because you can't drop over it@
* Cleaning up my comments in the API section user.js
I had a lot of TODOS that are mostly done now
* Fixing a spacing code standards thing
* Turns out we never use type, so we should remove this from the API call
* Adding pinnedItemsOrder into the user schema
And disabling my call in the frontend before I do any more damage
* Halfway to using pinnedItemsOrder
This isn't working yet but it is not going to break it horribly like it
was before.
* Hooking up inAppRewards to always produce sorted information
It is suspicially working right now even though I have not added the
seasonal stuff logic yet...
* Updating the comments in user.js in movedPinnedItem
It turns out that my bandaid fix to just get the ball rolling perfectly
does what I need it to do when we have a length discrepancy. So we are
getting much closer to the final product, just need lots of testing
* Cleaning up code standards kinds of things
* Yay, this fixes the popover issue
I hope this is the right "vue" way to do things, because I tried a bunch
of other things that definately were not the right way to do it. And
this appears to work too
* ** Partial Work ** Starting tests on api call for draggable items
Doesn't work, doesn't compile so don't include in PR!
* Test failing still...
This is worth a save. The api call grabs the seasonal items too, so we
can't get away from using the common functions and calls here to get the
actual list of items
* Okay have the first test passing
Need to clean up my linter problems though
* Planning out the next two tests and fixing my format problems
* 2nd Test case written, this time with the "more" odd case
* Making sure that we didn't mess with pinned items
* Huh... this test doesn't give me the expected result
Drat, I guess I found a bug
* Throw an error when we put garbage in our api call.
Well, before we got user.pinnedItemsOrder filled with a bunch of "null"
entries which is not ideal. it still worked, but isn't this confusing
enough already?
* Cleaning up the multitude of linting problems thanks gulp :)
* Writing tests for inAppRewards.js, but something is wrong
* Fixing my linting errors in inAppRewards tests
These tests still do not run though, so they may fail and I would not
know
* Applying Negue's fixes to inAppRewards.js test
It never occured to me that we shouldn't try to reach the database while
in the common tests. Well, we shouldn't do that, we should use the
common.helpers instead. Thanks!
2018-04-13 13:22:06 +00:00
|
|
|
:showPopover="showPopovers"
|
2017-08-16 22:34:25 +00:00
|
|
|
@click="openBuyDialog(reward)",
|
|
|
|
|
:popoverPosition="'left'"
|
2017-08-14 17:15:32 +00:00
|
|
|
)
|
2017-11-14 17:24:11 +00:00
|
|
|
template(slot="itemBadge", slot-scope="ctx")
|
|
|
|
|
span.badge.badge-pill.badge-item.badge-svg(
|
|
|
|
|
:class="{'item-selected-badge': ctx.item.pinned, 'hide': !ctx.highlightBorder}",
|
|
|
|
|
@click.prevent.stop="togglePinned(ctx.item)"
|
|
|
|
|
)
|
|
|
|
|
span.svg-icon.inline.icon-12.color(v-html="icons.pin")
|
2017-06-26 21:55:14 +00:00
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2017-08-02 16:57:57 +00:00
|
|
|
@import '~client/assets/scss/colors.scss';
|
|
|
|
|
|
2017-11-14 17:24:11 +00:00
|
|
|
|
2017-08-02 16:57:57 +00:00
|
|
|
.tasks-column {
|
2017-09-29 16:17:58 +00:00
|
|
|
min-height: 556px;
|
2017-08-02 16:57:57 +00:00
|
|
|
}
|
|
|
|
|
|
2018-07-12 20:10:23 +00:00
|
|
|
.sortable-tasks {
|
|
|
|
|
word-break: break-word;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-16 20:04:16 +00:00
|
|
|
.sortable-tasks + .reward-items {
|
2017-08-28 18:00:06 +00:00
|
|
|
margin-top: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-14 23:10:33 +00:00
|
|
|
|
2017-08-14 17:15:32 +00:00
|
|
|
.reward-items {
|
2017-11-28 02:54:03 +00:00
|
|
|
@supports (display: grid) {
|
|
|
|
|
display: grid;
|
2018-01-08 17:43:57 +00:00
|
|
|
justify-content: center;
|
2017-11-28 02:54:03 +00:00
|
|
|
grid-column-gap: 16px;
|
|
|
|
|
grid-row-gap: 4px;
|
|
|
|
|
grid-template-columns: repeat(auto-fill, 94px);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@supports not (display: grid) {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-wrap: wrap;
|
|
|
|
|
& > div {
|
2018-01-08 17:43:57 +00:00
|
|
|
margin: 0 16px 4px 0;
|
2017-11-28 02:54:03 +00:00
|
|
|
}
|
|
|
|
|
}
|
2017-08-14 17:15:32 +00:00
|
|
|
}
|
|
|
|
|
|
2017-08-02 16:57:57 +00:00
|
|
|
.tasks-list {
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
background: $gray-600;
|
|
|
|
|
padding: 8px;
|
2017-09-29 16:17:58 +00:00
|
|
|
position: relative; // needed for the .bottom-gradient to be position: absolute
|
|
|
|
|
height: calc(100% - 56px);
|
|
|
|
|
padding-bottom: 30px;
|
2017-06-26 21:55:14 +00:00
|
|
|
}
|
|
|
|
|
|
2017-10-16 20:04:16 +00:00
|
|
|
.quick-add {
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
background-color: rgba($black, 0.06);
|
|
|
|
|
width: 100%;
|
2018-01-08 17:43:57 +00:00
|
|
|
margin-bottom: 3px;
|
2017-10-16 20:04:16 +00:00
|
|
|
padding: 12px 16px;
|
|
|
|
|
border-color: transparent;
|
|
|
|
|
transition: background 0.15s ease-in;
|
2017-11-02 20:07:38 +00:00
|
|
|
resize: none;
|
2017-10-16 20:04:16 +00:00
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
background-color: rgba($black, 0.1);
|
|
|
|
|
border-color: transparent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:active, &:focus {
|
|
|
|
|
background: $white;
|
|
|
|
|
border-color: $purple-500;
|
|
|
|
|
color: $gray-50;
|
2018-01-08 17:43:57 +00:00
|
|
|
margin-bottom: 0px;
|
2017-10-16 20:04:16 +00:00
|
|
|
}
|
2017-11-02 20:07:38 +00:00
|
|
|
|
|
|
|
|
&::placeholder {
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
2017-10-16 20:04:16 +00:00
|
|
|
}
|
|
|
|
|
|
2017-11-02 20:07:38 +00:00
|
|
|
.quick-add-tip {
|
|
|
|
|
font-style: normal;
|
|
|
|
|
padding: 16px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
|
|
|
|
overflow-y: hidden;
|
|
|
|
|
max-height: 65px; // approximate max height
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.quick-add-tip-slide-enter-active {
|
|
|
|
|
transition: all 0.5s cubic-bezier(0, 1, 0.5, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.quick-add-tip-slide-leave-active {
|
|
|
|
|
transition: all 0.5s cubic-bezier(0, 1, 0.5, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.quick-add-tip-slide-enter, .quick-add-tip-slide-leave-to {
|
|
|
|
|
max-height: 0;
|
2018-05-04 21:10:02 +00:00
|
|
|
padding: 0 16px;
|
2017-06-26 21:55:14 +00:00
|
|
|
}
|
|
|
|
|
|
2018-05-04 21:10:02 +00:00
|
|
|
.column-title {
|
|
|
|
|
margin-bottom: 0;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
2017-11-02 20:07:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.column-badge {
|
2018-05-04 21:10:02 +00:00
|
|
|
position: static;
|
2017-08-02 16:57:57 +00:00
|
|
|
}
|
2017-06-26 21:55:14 +00:00
|
|
|
|
2017-08-02 16:57:57 +00:00
|
|
|
.filters {
|
2018-05-04 21:10:02 +00:00
|
|
|
margin-left: auto;
|
2017-06-26 21:55:14 +00:00
|
|
|
}
|
|
|
|
|
|
2017-08-02 16:57:57 +00:00
|
|
|
.filter {
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
color: $gray-100;
|
|
|
|
|
font-style: normal;
|
|
|
|
|
padding: 8px;
|
|
|
|
|
cursor: pointer;
|
2018-05-04 21:10:02 +00:00
|
|
|
white-space: nowrap;
|
2017-08-02 16:57:57 +00:00
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
color: $purple-200;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.active {
|
|
|
|
|
color: $purple-200;
|
|
|
|
|
border-bottom: 2px solid $purple-200;
|
|
|
|
|
padding-bottom: 6px;
|
|
|
|
|
}
|
2017-06-26 21:55:14 +00:00
|
|
|
}
|
|
|
|
|
|
2017-08-02 16:57:57 +00:00
|
|
|
.column-background {
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: 32px;
|
|
|
|
|
|
|
|
|
|
&.initial-description {
|
|
|
|
|
top: 30%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.svg-icon {
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h3, .small-text {
|
|
|
|
|
color: $gray-300;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
h3 {
|
|
|
|
|
font-weight: normal;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.small-text {
|
|
|
|
|
font-style: normal;
|
|
|
|
|
padding-left: 24px;
|
|
|
|
|
padding-right: 24px;
|
|
|
|
|
}
|
2017-06-26 21:55:14 +00:00
|
|
|
}
|
|
|
|
|
|
2017-08-02 16:57:57 +00:00
|
|
|
.icon-habit {
|
|
|
|
|
width: 30px;
|
|
|
|
|
height: 20px;
|
2017-10-16 20:04:16 +00:00
|
|
|
color: $gray-300;
|
2017-06-26 21:55:14 +00:00
|
|
|
}
|
|
|
|
|
|
2017-08-02 16:57:57 +00:00
|
|
|
.icon-daily {
|
|
|
|
|
width: 30px;
|
|
|
|
|
height: 20px;
|
2017-10-16 20:04:16 +00:00
|
|
|
color: $gray-300;
|
2017-08-02 16:57:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-todo {
|
|
|
|
|
width: 20px;
|
|
|
|
|
height: 20px;
|
2017-10-16 20:04:16 +00:00
|
|
|
color: $gray-300;
|
2017-08-02 16:57:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.icon-reward {
|
|
|
|
|
width: 26px;
|
|
|
|
|
height: 20px;
|
2017-10-16 20:04:16 +00:00
|
|
|
color: $gray-300;
|
2017-06-26 21:55:14 +00:00
|
|
|
}
|
|
|
|
|
</style>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import Task from './task';
|
2018-01-22 15:28:42 +00:00
|
|
|
import ClearCompletedTodos from './clearCompletedTodos';
|
2017-10-04 02:15:00 +00:00
|
|
|
import throttle from 'lodash/throttle';
|
2018-03-18 15:23:58 +00:00
|
|
|
import isEmpty from 'lodash/isEmpty';
|
2017-10-04 02:15:00 +00:00
|
|
|
import buyMixin from 'client/mixins/buy';
|
2018-03-18 15:23:58 +00:00
|
|
|
import { mapState, mapActions, mapGetters } from 'client/libs/store';
|
2017-10-04 02:15:00 +00:00
|
|
|
import shopItem from '../shops/shopItem';
|
2017-10-23 21:05:35 +00:00
|
|
|
import BuyQuestModal from 'client/components/shops/quests/buyQuestModal.vue';
|
2017-10-04 02:15:00 +00:00
|
|
|
|
2017-11-14 23:10:33 +00:00
|
|
|
import notifications from 'client/mixins/notifications';
|
2017-06-26 21:55:14 +00:00
|
|
|
import { shouldDo } from 'common/script/cron';
|
2017-08-14 17:15:32 +00:00
|
|
|
import inAppRewards from 'common/script/libs/inAppRewards';
|
2017-10-04 02:15:00 +00:00
|
|
|
import spells from 'common/script/content/spells';
|
2017-10-16 20:04:16 +00:00
|
|
|
import taskDefaults from 'common/script/libs/taskDefaults';
|
2017-10-04 02:15:00 +00:00
|
|
|
|
2018-03-18 15:23:58 +00:00
|
|
|
import {
|
|
|
|
|
getTypeLabel,
|
|
|
|
|
getFilterLabels,
|
|
|
|
|
getActiveFilter,
|
|
|
|
|
} from 'client/libs/store/helpers/filterTasks.js';
|
|
|
|
|
|
2017-11-14 17:24:11 +00:00
|
|
|
import svgPin from 'assets/svg/pin.svg';
|
2017-06-26 21:55:14 +00:00
|
|
|
import habitIcon from 'assets/svg/habit.svg';
|
|
|
|
|
import dailyIcon from 'assets/svg/daily.svg';
|
|
|
|
|
import todoIcon from 'assets/svg/todo.svg';
|
|
|
|
|
import rewardIcon from 'assets/svg/reward.svg';
|
2017-11-28 01:43:24 +00:00
|
|
|
import draggable from 'vuedraggable';
|
2017-06-26 21:55:14 +00:00
|
|
|
|
|
|
|
|
export default {
|
2017-11-14 23:10:33 +00:00
|
|
|
mixins: [buyMixin, notifications],
|
2017-06-26 21:55:14 +00:00
|
|
|
components: {
|
|
|
|
|
Task,
|
2018-01-22 15:28:42 +00:00
|
|
|
ClearCompletedTodos,
|
2017-10-23 21:05:35 +00:00
|
|
|
BuyQuestModal,
|
2017-08-14 17:15:32 +00:00
|
|
|
shopItem,
|
2017-11-28 01:43:24 +00:00
|
|
|
draggable,
|
2017-09-14 19:53:27 +00:00
|
|
|
},
|
2018-03-18 15:23:58 +00:00
|
|
|
// Set default values for props
|
|
|
|
|
// allows for better control of props values
|
|
|
|
|
// allows for better control of where this component is called
|
|
|
|
|
props: {
|
|
|
|
|
type: {},
|
|
|
|
|
isUser: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false,
|
|
|
|
|
},
|
|
|
|
|
searchText: {},
|
|
|
|
|
selectedTags: {},
|
|
|
|
|
taskListOverride: {},
|
|
|
|
|
group: {},
|
|
|
|
|
}, // @TODO: maybe we should store the group on state?
|
2017-06-26 21:55:14 +00:00
|
|
|
data () {
|
|
|
|
|
const icons = Object.freeze({
|
|
|
|
|
habit: habitIcon,
|
|
|
|
|
daily: dailyIcon,
|
|
|
|
|
todo: todoIcon,
|
|
|
|
|
reward: rewardIcon,
|
2017-11-14 17:24:11 +00:00
|
|
|
pin: svgPin,
|
2017-06-26 21:55:14 +00:00
|
|
|
});
|
|
|
|
|
|
2018-03-18 15:23:58 +00:00
|
|
|
let typeLabel = '';
|
|
|
|
|
let typeFilters = [];
|
|
|
|
|
let activeFilter = {};
|
2017-09-25 18:02:12 +00:00
|
|
|
|
2017-06-26 21:55:14 +00:00
|
|
|
return {
|
2018-03-18 15:23:58 +00:00
|
|
|
typeLabel,
|
|
|
|
|
typeFilters,
|
|
|
|
|
activeFilter,
|
|
|
|
|
|
2017-06-26 21:55:14 +00:00
|
|
|
icons,
|
2017-08-01 12:30:17 +00:00
|
|
|
openedCompletedTodos: false,
|
2017-09-21 00:28:11 +00:00
|
|
|
|
|
|
|
|
forceRefresh: new Date(),
|
2017-10-16 20:04:16 +00:00
|
|
|
quickAddText: '',
|
2017-11-02 20:07:38 +00:00
|
|
|
quickAddFocused: false,
|
|
|
|
|
quickAddRows: 1,
|
Feature/sortable reward area (#9930)
* Client POC
We need to wrap each draggable region it its own div or else the
"draggable" element will conflict with each other. This screws up the
styling but that is totally fixable
* Ah that ref was being used after all, changing back
* Scaffold out a new callback for when we drag these things
Next is going to be the hard part: I need to save the sort order for
these to the database. I don't even know if there is a schema but hey
this is the best place to start
* Firefox caching is the problem: don't actually need the wrapper div
So I guess I should try this in chrome and see how it works then come
back to firefox and figure out what the heck is going on
* Scaffolding out our API call to save the sort order
The endpoint doesn't exist yet so we will need to add that
* Ok we are now calling our API endpoint to reorder these things
Of course it doesn't exist yet so you get a 404 when you try, but that
is ok
* Defining api endpoint, a work in progress
In particular I really had ought to use _id for these too, it appears
that the primary way we detect order doesn't even use "key" at all.
* Switching to using the pinned item UUID
This has much better results, but of course the server and client logic
don't match now. Will have to keep working on my splice to make sure
that they are the same
* I thought this would fix our server/client mismatch but it is not it
Something is really wrong with my logic somewhere, maybe I need to
update the db step?
* Moving this logic to the "user" rather than "tasks" and key off path
Path is unique and is less finiky than dealing with string comparisons
with ids. Unfortunately everything is still not working... I suppose
user.update() doesn't care about the position?
* This client code caused quite a lot of problems if you dragged fast
We don't really need it it seems, so off it goes
* Updating markup and CSS so it actually looks good.
Everything is working horray!!
I did just notice the following bug: the popover text sometimes makes it
very annoying to drag because you can't drop over it@
* Cleaning up my comments in the API section user.js
I had a lot of TODOS that are mostly done now
* Fixing a spacing code standards thing
* Turns out we never use type, so we should remove this from the API call
* Adding pinnedItemsOrder into the user schema
And disabling my call in the frontend before I do any more damage
* Halfway to using pinnedItemsOrder
This isn't working yet but it is not going to break it horribly like it
was before.
* Hooking up inAppRewards to always produce sorted information
It is suspicially working right now even though I have not added the
seasonal stuff logic yet...
* Updating the comments in user.js in movedPinnedItem
It turns out that my bandaid fix to just get the ball rolling perfectly
does what I need it to do when we have a length discrepancy. So we are
getting much closer to the final product, just need lots of testing
* Cleaning up code standards kinds of things
* Yay, this fixes the popover issue
I hope this is the right "vue" way to do things, because I tried a bunch
of other things that definately were not the right way to do it. And
this appears to work too
* ** Partial Work ** Starting tests on api call for draggable items
Doesn't work, doesn't compile so don't include in PR!
* Test failing still...
This is worth a save. The api call grabs the seasonal items too, so we
can't get away from using the common functions and calls here to get the
actual list of items
* Okay have the first test passing
Need to clean up my linter problems though
* Planning out the next two tests and fixing my format problems
* 2nd Test case written, this time with the "more" odd case
* Making sure that we didn't mess with pinned items
* Huh... this test doesn't give me the expected result
Drat, I guess I found a bug
* Throw an error when we put garbage in our api call.
Well, before we got user.pinnedItemsOrder filled with a bunch of "null"
entries which is not ideal. it still worked, but isn't this confusing
enough already?
* Cleaning up the multitude of linting problems thanks gulp :)
* Writing tests for inAppRewards.js, but something is wrong
* Fixing my linting errors in inAppRewards tests
These tests still do not run though, so they may fail and I would not
know
* Applying Negue's fixes to inAppRewards.js test
It never occured to me that we shouldn't try to reach the database while
in the common tests. Well, we shouldn't do that, we should use the
common.helpers instead. Thanks!
2018-04-13 13:22:06 +00:00
|
|
|
showPopovers: true,
|
2017-10-23 21:05:35 +00:00
|
|
|
|
|
|
|
|
selectedItemToBuy: {},
|
2017-06-26 21:55:14 +00:00
|
|
|
};
|
|
|
|
|
},
|
2018-03-18 15:23:58 +00:00
|
|
|
created () {
|
|
|
|
|
// Set Task Column Label
|
|
|
|
|
this.typeLabel = getTypeLabel(this.type);
|
|
|
|
|
// Get Category Filter Labels
|
|
|
|
|
this.typeFilters = getFilterLabels(this.type);
|
|
|
|
|
// Set default filter for task column
|
|
|
|
|
this.activateFilter(this.type);
|
|
|
|
|
},
|
2017-06-26 21:55:14 +00:00
|
|
|
computed: {
|
|
|
|
|
...mapState({
|
2017-08-14 17:15:32 +00:00
|
|
|
user: 'user.data',
|
2017-06-26 21:55:14 +00:00
|
|
|
}),
|
2018-03-18 15:23:58 +00:00
|
|
|
...mapGetters({
|
|
|
|
|
getFilteredTaskList: 'tasks:getFilteredTaskList',
|
|
|
|
|
getUnfilteredTaskList: 'tasks:getUnfilteredTaskList',
|
|
|
|
|
getUserPreferences: 'user:preferences',
|
|
|
|
|
getUserBuffs: 'user:buffs',
|
|
|
|
|
}),
|
2017-08-02 16:57:57 +00:00
|
|
|
taskList () {
|
2017-08-14 19:19:41 +00:00
|
|
|
// @TODO: This should not default to user's tasks. It should require that you pass options in
|
2018-03-18 15:23:58 +00:00
|
|
|
let filteredTaskList = this.isUser ?
|
|
|
|
|
this.getFilteredTaskList({
|
|
|
|
|
type: this.type,
|
|
|
|
|
filterType: this.activeFilter.label,
|
|
|
|
|
}) :
|
|
|
|
|
this.taskListOverride;
|
2018-02-22 11:28:24 +00:00
|
|
|
|
2018-03-18 15:23:58 +00:00
|
|
|
let taggedList = this.filterByTagList(filteredTaskList, this.selectedTags);
|
|
|
|
|
let searchedList = this.filterBySearchText(taggedList, this.searchText);
|
2017-10-23 22:27:26 +00:00
|
|
|
|
2018-03-18 15:23:58 +00:00
|
|
|
return searchedList;
|
2017-08-02 16:57:57 +00:00
|
|
|
},
|
2017-08-14 17:15:32 +00:00
|
|
|
inAppRewards () {
|
2017-09-21 00:28:11 +00:00
|
|
|
let watchRefresh = this.forceRefresh; // eslint-disable-line
|
2017-10-04 02:15:00 +00:00
|
|
|
let rewards = inAppRewards(this.user);
|
|
|
|
|
|
|
|
|
|
// Add season rewards if user is affected
|
2018-05-18 15:11:04 +00:00
|
|
|
// @TODO: Add buff conditional
|
2017-10-04 02:15:00 +00:00
|
|
|
const seasonalSkills = {
|
|
|
|
|
snowball: 'salt',
|
|
|
|
|
spookySparkles: 'opaquePotion',
|
|
|
|
|
shinySeed: 'petalFreePotion',
|
|
|
|
|
seafoam: 'sand',
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (let key in seasonalSkills) {
|
2018-03-18 15:23:58 +00:00
|
|
|
if (this.getUserBuffs(key)) {
|
2017-10-04 02:15:00 +00:00
|
|
|
let debuff = seasonalSkills[key];
|
|
|
|
|
let item = Object.assign({}, spells.special[debuff]);
|
|
|
|
|
item.text = item.text();
|
|
|
|
|
item.notes = item.notes();
|
|
|
|
|
item.class = `shop_${key}`;
|
|
|
|
|
rewards.push(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-09-21 00:28:11 +00:00
|
|
|
|
2017-10-04 02:15:00 +00:00
|
|
|
return rewards;
|
2017-08-14 17:15:32 +00:00
|
|
|
},
|
2017-09-02 16:08:32 +00:00
|
|
|
hasRewardsList () {
|
2018-03-18 15:23:58 +00:00
|
|
|
return this.isUser === true && this.type === 'reward' && this.activeFilter.label !== 'custom';
|
2017-09-02 16:08:32 +00:00
|
|
|
},
|
|
|
|
|
initialColumnDescription () {
|
|
|
|
|
// Show the column description in the middle only if there are no elements (tasks or in app items)
|
|
|
|
|
if (this.hasRewardsList) {
|
|
|
|
|
if (this.inAppRewards && this.inAppRewards.length >= 0) return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-18 15:23:58 +00:00
|
|
|
return this.taskList.length === 0;
|
2017-09-25 18:02:12 +00:00
|
|
|
},
|
2017-10-16 20:04:16 +00:00
|
|
|
quickAddPlaceholder () {
|
|
|
|
|
const type = this.$t(this.type);
|
|
|
|
|
return this.$t('addATask', {type});
|
|
|
|
|
},
|
2017-11-02 20:07:38 +00:00
|
|
|
badgeCount () {
|
|
|
|
|
// 0 means the badge will not be shown
|
|
|
|
|
// It is shown for the all and due views of dailies
|
|
|
|
|
// and for the active and scheduled views of todos.
|
2018-03-18 15:23:58 +00:00
|
|
|
if (this.type === 'todo' && this.activeFilter.label !== 'complete2') {
|
|
|
|
|
return this.taskList.length;
|
2017-11-02 20:07:38 +00:00
|
|
|
} else if (this.type === 'daily') {
|
2018-03-18 15:23:58 +00:00
|
|
|
if (this.activeFilter.label === 'due') {
|
2017-11-02 20:07:38 +00:00
|
|
|
return this.taskList.length;
|
2018-03-18 15:23:58 +00:00
|
|
|
} else if (this.activeFilter.label === 'all') {
|
2017-11-02 20:07:38 +00:00
|
|
|
return this.taskList.reduce((count, t) => {
|
2018-03-18 15:23:58 +00:00
|
|
|
return !t.completed && shouldDo(new Date(), t, this.getUserPreferences) ? count + 1 : count;
|
2017-11-02 20:07:38 +00:00
|
|
|
}, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
},
|
2017-06-26 21:55:14 +00:00
|
|
|
},
|
2017-08-09 15:13:40 +00:00
|
|
|
watch: {
|
|
|
|
|
taskList: {
|
|
|
|
|
handler: throttle(function setColumnBackgroundVisibility () {
|
|
|
|
|
this.setColumnBackgroundVisibility();
|
|
|
|
|
}, 250),
|
|
|
|
|
deep: true,
|
|
|
|
|
},
|
2017-12-01 14:37:37 +00:00
|
|
|
quickAddFocused (newValue) {
|
|
|
|
|
if (newValue) this.quickAddRows = this.quickAddText.split('\n').length;
|
|
|
|
|
if (!newValue) this.quickAddRows = 1;
|
|
|
|
|
},
|
2017-08-09 15:13:40 +00:00
|
|
|
},
|
|
|
|
|
mounted () {
|
|
|
|
|
this.setColumnBackgroundVisibility();
|
2017-09-21 00:28:11 +00:00
|
|
|
|
|
|
|
|
this.$root.$on('buyModal::boughtItem', () => {
|
|
|
|
|
this.forceRefresh = new Date();
|
|
|
|
|
});
|
2018-01-22 15:19:47 +00:00
|
|
|
|
|
|
|
|
if (this.type !== 'todo') return;
|
|
|
|
|
this.$root.$on('habitica::resync-requested', () => {
|
2018-07-16 10:02:37 +00:00
|
|
|
if (this.activeFilter.label !== 'complete2') return;
|
2018-01-22 15:19:47 +00:00
|
|
|
this.loadCompletedTodos(true);
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
destroyed () {
|
|
|
|
|
this.$root.$off('buyModal::boughtItem');
|
|
|
|
|
if (this.type !== 'todo') return;
|
|
|
|
|
this.$root.$off('habitica::resync-requested');
|
2017-08-09 15:13:40 +00:00
|
|
|
},
|
2017-07-22 18:30:08 +00:00
|
|
|
methods: {
|
2017-10-16 20:04:16 +00:00
|
|
|
...mapActions({
|
|
|
|
|
loadCompletedTodos: 'tasks:fetchCompletedTodos',
|
|
|
|
|
createTask: 'tasks:create',
|
|
|
|
|
}),
|
Feature/sortable reward area (#9930)
* Client POC
We need to wrap each draggable region it its own div or else the
"draggable" element will conflict with each other. This screws up the
styling but that is totally fixable
* Ah that ref was being used after all, changing back
* Scaffold out a new callback for when we drag these things
Next is going to be the hard part: I need to save the sort order for
these to the database. I don't even know if there is a schema but hey
this is the best place to start
* Firefox caching is the problem: don't actually need the wrapper div
So I guess I should try this in chrome and see how it works then come
back to firefox and figure out what the heck is going on
* Scaffolding out our API call to save the sort order
The endpoint doesn't exist yet so we will need to add that
* Ok we are now calling our API endpoint to reorder these things
Of course it doesn't exist yet so you get a 404 when you try, but that
is ok
* Defining api endpoint, a work in progress
In particular I really had ought to use _id for these too, it appears
that the primary way we detect order doesn't even use "key" at all.
* Switching to using the pinned item UUID
This has much better results, but of course the server and client logic
don't match now. Will have to keep working on my splice to make sure
that they are the same
* I thought this would fix our server/client mismatch but it is not it
Something is really wrong with my logic somewhere, maybe I need to
update the db step?
* Moving this logic to the "user" rather than "tasks" and key off path
Path is unique and is less finiky than dealing with string comparisons
with ids. Unfortunately everything is still not working... I suppose
user.update() doesn't care about the position?
* This client code caused quite a lot of problems if you dragged fast
We don't really need it it seems, so off it goes
* Updating markup and CSS so it actually looks good.
Everything is working horray!!
I did just notice the following bug: the popover text sometimes makes it
very annoying to drag because you can't drop over it@
* Cleaning up my comments in the API section user.js
I had a lot of TODOS that are mostly done now
* Fixing a spacing code standards thing
* Turns out we never use type, so we should remove this from the API call
* Adding pinnedItemsOrder into the user schema
And disabling my call in the frontend before I do any more damage
* Halfway to using pinnedItemsOrder
This isn't working yet but it is not going to break it horribly like it
was before.
* Hooking up inAppRewards to always produce sorted information
It is suspicially working right now even though I have not added the
seasonal stuff logic yet...
* Updating the comments in user.js in movedPinnedItem
It turns out that my bandaid fix to just get the ball rolling perfectly
does what I need it to do when we have a length discrepancy. So we are
getting much closer to the final product, just need lots of testing
* Cleaning up code standards kinds of things
* Yay, this fixes the popover issue
I hope this is the right "vue" way to do things, because I tried a bunch
of other things that definately were not the right way to do it. And
this appears to work too
* ** Partial Work ** Starting tests on api call for draggable items
Doesn't work, doesn't compile so don't include in PR!
* Test failing still...
This is worth a save. The api call grabs the seasonal items too, so we
can't get away from using the common functions and calls here to get the
actual list of items
* Okay have the first test passing
Need to clean up my linter problems though
* Planning out the next two tests and fixing my format problems
* 2nd Test case written, this time with the "more" odd case
* Making sure that we didn't mess with pinned items
* Huh... this test doesn't give me the expected result
Drat, I guess I found a bug
* Throw an error when we put garbage in our api call.
Well, before we got user.pinnedItemsOrder filled with a bunch of "null"
entries which is not ideal. it still worked, but isn't this confusing
enough already?
* Cleaning up the multitude of linting problems thanks gulp :)
* Writing tests for inAppRewards.js, but something is wrong
* Fixing my linting errors in inAppRewards tests
These tests still do not run though, so they may fail and I would not
know
* Applying Negue's fixes to inAppRewards.js test
It never occured to me that we shouldn't try to reach the database while
in the common tests. Well, we shouldn't do that, we should use the
common.helpers instead. Thanks!
2018-04-13 13:22:06 +00:00
|
|
|
async taskSorted (data) {
|
2017-11-02 20:07:38 +00:00
|
|
|
const filteredList = this.taskList;
|
2017-11-14 23:54:11 +00:00
|
|
|
const taskToMove = filteredList[data.oldIndex];
|
|
|
|
|
const taskIdToMove = taskToMove._id;
|
2018-03-18 15:23:58 +00:00
|
|
|
let originTasks = this.getUnfilteredTaskList(this.type);
|
2017-11-14 23:54:11 +00:00
|
|
|
if (this.taskListOverride) originTasks = this.taskListOverride;
|
2017-09-14 19:53:27 +00:00
|
|
|
|
2017-10-23 17:59:52 +00:00
|
|
|
// Server
|
|
|
|
|
const taskIdToReplace = filteredList[data.newIndex];
|
2017-11-14 23:54:11 +00:00
|
|
|
const newIndexOnServer = originTasks.findIndex(taskId => taskId === taskIdToReplace);
|
|
|
|
|
|
|
|
|
|
let newOrder;
|
|
|
|
|
if (taskToMove.group.id) {
|
|
|
|
|
newOrder = await this.$store.dispatch('tasks:moveGroupTask', {
|
|
|
|
|
taskId: taskIdToMove,
|
|
|
|
|
position: newIndexOnServer,
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
newOrder = await this.$store.dispatch('tasks:move', {
|
|
|
|
|
taskId: taskIdToMove,
|
|
|
|
|
position: newIndexOnServer,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (!this.taskListOverride) this.user.tasksOrder[`${this.type}s`] = newOrder;
|
2017-10-23 17:59:52 +00:00
|
|
|
|
|
|
|
|
// Client
|
2017-11-14 23:54:11 +00:00
|
|
|
const deleted = originTasks.splice(data.oldIndex, 1);
|
|
|
|
|
originTasks.splice(data.newIndex, 0, deleted[0]);
|
2017-09-14 19:53:27 +00:00
|
|
|
},
|
2017-11-02 20:07:38 +00:00
|
|
|
async moveTo (task, where) { // where is 'top' or 'bottom'
|
|
|
|
|
const taskIdToMove = task._id;
|
2018-03-18 15:23:58 +00:00
|
|
|
const list = this.getUnfilteredTaskList(this.type);
|
2017-11-02 20:07:38 +00:00
|
|
|
|
|
|
|
|
const oldPosition = list.findIndex(t => t._id === taskIdToMove);
|
|
|
|
|
const moved = list.splice(oldPosition, 1);
|
|
|
|
|
const newPosition = where === 'top' ? 0 : list.length;
|
|
|
|
|
list.splice(newPosition, 0, moved[0]);
|
|
|
|
|
|
|
|
|
|
let newOrder = await this.$store.dispatch('tasks:move', {
|
|
|
|
|
taskId: taskIdToMove,
|
|
|
|
|
position: newPosition,
|
|
|
|
|
});
|
|
|
|
|
this.user.tasksOrder[`${this.type}s`] = newOrder;
|
|
|
|
|
},
|
Feature/sortable reward area (#9930)
* Client POC
We need to wrap each draggable region it its own div or else the
"draggable" element will conflict with each other. This screws up the
styling but that is totally fixable
* Ah that ref was being used after all, changing back
* Scaffold out a new callback for when we drag these things
Next is going to be the hard part: I need to save the sort order for
these to the database. I don't even know if there is a schema but hey
this is the best place to start
* Firefox caching is the problem: don't actually need the wrapper div
So I guess I should try this in chrome and see how it works then come
back to firefox and figure out what the heck is going on
* Scaffolding out our API call to save the sort order
The endpoint doesn't exist yet so we will need to add that
* Ok we are now calling our API endpoint to reorder these things
Of course it doesn't exist yet so you get a 404 when you try, but that
is ok
* Defining api endpoint, a work in progress
In particular I really had ought to use _id for these too, it appears
that the primary way we detect order doesn't even use "key" at all.
* Switching to using the pinned item UUID
This has much better results, but of course the server and client logic
don't match now. Will have to keep working on my splice to make sure
that they are the same
* I thought this would fix our server/client mismatch but it is not it
Something is really wrong with my logic somewhere, maybe I need to
update the db step?
* Moving this logic to the "user" rather than "tasks" and key off path
Path is unique and is less finiky than dealing with string comparisons
with ids. Unfortunately everything is still not working... I suppose
user.update() doesn't care about the position?
* This client code caused quite a lot of problems if you dragged fast
We don't really need it it seems, so off it goes
* Updating markup and CSS so it actually looks good.
Everything is working horray!!
I did just notice the following bug: the popover text sometimes makes it
very annoying to drag because you can't drop over it@
* Cleaning up my comments in the API section user.js
I had a lot of TODOS that are mostly done now
* Fixing a spacing code standards thing
* Turns out we never use type, so we should remove this from the API call
* Adding pinnedItemsOrder into the user schema
And disabling my call in the frontend before I do any more damage
* Halfway to using pinnedItemsOrder
This isn't working yet but it is not going to break it horribly like it
was before.
* Hooking up inAppRewards to always produce sorted information
It is suspicially working right now even though I have not added the
seasonal stuff logic yet...
* Updating the comments in user.js in movedPinnedItem
It turns out that my bandaid fix to just get the ball rolling perfectly
does what I need it to do when we have a length discrepancy. So we are
getting much closer to the final product, just need lots of testing
* Cleaning up code standards kinds of things
* Yay, this fixes the popover issue
I hope this is the right "vue" way to do things, because I tried a bunch
of other things that definately were not the right way to do it. And
this appears to work too
* ** Partial Work ** Starting tests on api call for draggable items
Doesn't work, doesn't compile so don't include in PR!
* Test failing still...
This is worth a save. The api call grabs the seasonal items too, so we
can't get away from using the common functions and calls here to get the
actual list of items
* Okay have the first test passing
Need to clean up my linter problems though
* Planning out the next two tests and fixing my format problems
* 2nd Test case written, this time with the "more" odd case
* Making sure that we didn't mess with pinned items
* Huh... this test doesn't give me the expected result
Drat, I guess I found a bug
* Throw an error when we put garbage in our api call.
Well, before we got user.pinnedItemsOrder filled with a bunch of "null"
entries which is not ideal. it still worked, but isn't this confusing
enough already?
* Cleaning up the multitude of linting problems thanks gulp :)
* Writing tests for inAppRewards.js, but something is wrong
* Fixing my linting errors in inAppRewards tests
These tests still do not run though, so they may fail and I would not
know
* Applying Negue's fixes to inAppRewards.js test
It never occured to me that we shouldn't try to reach the database while
in the common tests. Well, we shouldn't do that, we should use the
common.helpers instead. Thanks!
2018-04-13 13:22:06 +00:00
|
|
|
async rewardSorted (data) {
|
|
|
|
|
const rewardsList = this.inAppRewards;
|
|
|
|
|
const rewardToMove = rewardsList[data.oldIndex];
|
|
|
|
|
|
|
|
|
|
let newOrder = await this.$store.dispatch('user:movePinnedItem', {
|
|
|
|
|
path: rewardToMove.path,
|
|
|
|
|
position: data.newIndex,
|
|
|
|
|
});
|
|
|
|
|
this.user.pinnedItemsOrder = newOrder;
|
|
|
|
|
},
|
|
|
|
|
rewardDragStart () {
|
|
|
|
|
// We need to stop popovers from interfering with our dragging
|
|
|
|
|
this.showPopovers = false;
|
|
|
|
|
},
|
|
|
|
|
rewardDragEnd () {
|
|
|
|
|
this.showPopovers = true;
|
|
|
|
|
},
|
2017-11-02 20:07:38 +00:00
|
|
|
quickAdd (ev) {
|
|
|
|
|
// Add a new line if Shift+Enter Pressed
|
|
|
|
|
if (ev.shiftKey) {
|
|
|
|
|
this.quickAddRows++;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Do not add new line is added if only Enter is pressed
|
|
|
|
|
ev.preventDefault();
|
|
|
|
|
const text = this.quickAddText;
|
|
|
|
|
if (!text) return false;
|
|
|
|
|
|
|
|
|
|
const tasks = text.split('\n').reverse().filter(taskText => {
|
|
|
|
|
return taskText ? true : false;
|
|
|
|
|
}).map(taskText => {
|
|
|
|
|
const task = taskDefaults({type: this.type, text: taskText});
|
|
|
|
|
task.tags = this.selectedTags;
|
|
|
|
|
return task;
|
|
|
|
|
});
|
|
|
|
|
|
2018-03-17 20:13:12 +00:00
|
|
|
this.quickAddText = '';
|
2017-11-02 20:07:38 +00:00
|
|
|
this.quickAddRows = 1;
|
|
|
|
|
this.createTask(tasks);
|
2018-06-27 17:08:45 +00:00
|
|
|
this.$refs.quickAdd.blur();
|
2017-10-16 20:04:16 +00:00
|
|
|
},
|
2017-08-01 12:30:17 +00:00
|
|
|
editTask (task) {
|
|
|
|
|
this.$emit('editTask', task);
|
|
|
|
|
},
|
2018-03-18 15:23:58 +00:00
|
|
|
activateFilter (type, filter = '') {
|
|
|
|
|
// Needs a separate API call as this data may not reside in store
|
|
|
|
|
if (type === 'todo' && filter === 'complete2') {
|
2017-08-01 12:30:17 +00:00
|
|
|
this.loadCompletedTodos();
|
|
|
|
|
}
|
2017-11-17 23:13:07 +00:00
|
|
|
|
2018-03-18 15:23:58 +00:00
|
|
|
// the only time activateFilter is called with filter==='' is when the component is first created
|
|
|
|
|
// this can be used to check If the user has set 'due' as default filter for daily
|
|
|
|
|
// and set the filter as 'due' only when the component first loads and not on subsequent reloads.
|
|
|
|
|
if (type === 'daily' && filter === '' && this.user.preferences.dailyDueDefaultView) {
|
|
|
|
|
filter = 'due';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.activeFilter = getActiveFilter(type, filter);
|
2017-08-01 12:30:17 +00:00
|
|
|
},
|
2017-08-09 15:13:40 +00:00
|
|
|
setColumnBackgroundVisibility () {
|
|
|
|
|
this.$nextTick(() => {
|
2017-08-14 19:19:41 +00:00
|
|
|
if (!this.$refs.columnBackground) return;
|
|
|
|
|
|
2017-10-17 21:38:42 +00:00
|
|
|
const tasksWrapperEl = this.$refs.tasksWrapper;
|
|
|
|
|
|
|
|
|
|
const tasksWrapperHeight = tasksWrapperEl.offsetHeight;
|
|
|
|
|
const quickAddHeight = this.$refs.quickAdd ? this.$refs.quickAdd.offsetHeight : 0;
|
2018-01-08 17:43:57 +00:00
|
|
|
const tasksListHeight = this.$refs.tasksList.$el.offsetHeight;
|
2017-10-17 21:38:42 +00:00
|
|
|
|
|
|
|
|
let combinedTasksHeights = tasksListHeight + quickAddHeight;
|
|
|
|
|
|
|
|
|
|
const rewardsList = tasksWrapperEl.getElementsByClassName('reward-items')[0];
|
2017-08-14 17:15:32 +00:00
|
|
|
if (rewardsList) {
|
|
|
|
|
combinedTasksHeights += rewardsList.offsetHeight;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-09 15:13:40 +00:00
|
|
|
const columnBackgroundStyle = this.$refs.columnBackground.style;
|
|
|
|
|
|
2017-10-17 21:38:42 +00:00
|
|
|
if (tasksWrapperHeight - combinedTasksHeights < 150) {
|
2017-08-09 15:13:40 +00:00
|
|
|
columnBackgroundStyle.display = 'none';
|
|
|
|
|
} else {
|
|
|
|
|
columnBackgroundStyle.display = 'block';
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
2018-03-18 15:23:58 +00:00
|
|
|
filterByTagList (taskList, tagList = []) {
|
|
|
|
|
let filteredTaskList = taskList;
|
2018-04-28 15:38:38 +00:00
|
|
|
// filter requested tasks by tags
|
2018-03-18 15:23:58 +00:00
|
|
|
if (!isEmpty(tagList)) {
|
|
|
|
|
filteredTaskList = taskList.filter(
|
|
|
|
|
task => tagList.every(tag => task.tags.indexOf(tag) !== -1)
|
|
|
|
|
);
|
2017-07-22 18:30:08 +00:00
|
|
|
}
|
2018-03-18 15:23:58 +00:00
|
|
|
return filteredTaskList;
|
|
|
|
|
},
|
|
|
|
|
filterBySearchText (taskList, searchText = '') {
|
|
|
|
|
let filteredTaskList = taskList;
|
|
|
|
|
// filter requested tasks by search text
|
|
|
|
|
if (searchText) {
|
|
|
|
|
// to ensure broadest case insensitive search matching
|
|
|
|
|
let searchTextLowerCase = searchText.toLowerCase();
|
|
|
|
|
filteredTaskList = taskList.filter(
|
|
|
|
|
task => {
|
|
|
|
|
// eslint rule disabled for block to allow nested binary expression
|
|
|
|
|
/* eslint-disable no-extra-parens */
|
|
|
|
|
return (
|
|
|
|
|
task.text.toLowerCase().indexOf(searchTextLowerCase) > -1 ||
|
2018-03-30 20:30:15 +00:00
|
|
|
(task.notes && task.notes.toLowerCase().indexOf(searchTextLowerCase) > -1) ||
|
2018-03-18 15:23:58 +00:00
|
|
|
(task.checklist && task.checklist.length > 0 &&
|
|
|
|
|
task.checklist.some(checkItem => checkItem.text.toLowerCase().indexOf(searchTextLowerCase) > -1))
|
|
|
|
|
);
|
|
|
|
|
/* eslint-enable no-extra-parens */
|
|
|
|
|
});
|
2017-07-22 18:30:08 +00:00
|
|
|
}
|
2018-03-18 15:23:58 +00:00
|
|
|
return filteredTaskList;
|
2017-07-22 18:30:08 +00:00
|
|
|
},
|
2017-08-14 17:15:32 +00:00
|
|
|
openBuyDialog (rewardItem) {
|
2017-10-20 13:22:13 +00:00
|
|
|
if (rewardItem.locked) return;
|
|
|
|
|
|
2017-10-04 02:15:00 +00:00
|
|
|
// Buy armoire and health potions immediately
|
|
|
|
|
let itemsToPurchaseImmediately = ['potion', 'armoire'];
|
|
|
|
|
if (itemsToPurchaseImmediately.indexOf(rewardItem.key) !== -1) {
|
|
|
|
|
this.makeGenericPurchase(rewardItem);
|
|
|
|
|
this.$emit('buyPressed', rewardItem);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-23 21:05:35 +00:00
|
|
|
if (rewardItem.purchaseType === 'quests') {
|
|
|
|
|
this.selectedItemToBuy = rewardItem;
|
2017-11-09 18:37:47 +00:00
|
|
|
this.$root.$emit('bv::show::modal', 'buy-quest-modal');
|
2017-10-23 21:05:35 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-29 00:17:45 +00:00
|
|
|
if (rewardItem.purchaseType !== 'gear' || !rewardItem.locked) {
|
|
|
|
|
this.$emit('openBuyDialog', rewardItem);
|
|
|
|
|
}
|
2017-08-14 17:15:32 +00:00
|
|
|
},
|
2017-10-23 21:05:35 +00:00
|
|
|
resetItemToBuy ($event) {
|
|
|
|
|
if (!$event) {
|
|
|
|
|
this.selectedItemToBuy = null;
|
|
|
|
|
}
|
|
|
|
|
},
|
2017-11-14 17:24:11 +00:00
|
|
|
togglePinned (item) {
|
2018-03-31 11:39:26 +00:00
|
|
|
if (!item.pinType) {
|
|
|
|
|
this.error(this.$t('errorTemporaryItem'));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-14 17:24:11 +00:00
|
|
|
try {
|
|
|
|
|
if (!this.$store.dispatch('user:togglePinnedItem', {type: item.pinType, path: item.path})) {
|
2017-11-14 23:10:33 +00:00
|
|
|
this.text(this.$t('unpinnedItem', {item: item.text}));
|
2017-11-14 17:24:11 +00:00
|
|
|
}
|
|
|
|
|
} catch (e) {
|
2017-11-14 23:10:33 +00:00
|
|
|
this.error(e.message);
|
2017-11-14 17:24:11 +00:00
|
|
|
}
|
|
|
|
|
},
|
2017-07-22 18:30:08 +00:00
|
|
|
},
|
2017-06-26 21:55:14 +00:00
|
|
|
};
|
|
|
|
|
</script>
|