Skip to content

Commit

Permalink
Merge pull request #877 from oslokommune/checkbox-workbench
Browse files Browse the repository at this point in the history
Add checkboxes for toggling workbench objectives
  • Loading branch information
petterhj authored Oct 3, 2023
2 parents 6689102 + 285a14c commit 73d55e0
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 60 deletions.
127 changes: 91 additions & 36 deletions src/components/GanttChart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@
:tabindex="o.tabindex"
:progression="o.objective.progression"
:style="objectiveStyle(o)"
:active="
(activeObjective && activeObjective.id === o.objective.id) ||
workbenchObjectives.map((o) => o.id).includes(o.objective.id)
"
:checkable="workbenchObjectives.length > 0"
:checked="workbenchObjectives.map((o) => o.id).includes(o.objective.id)"
:active="activeObjective && activeObjective.id === o.objective.id"
:data-id="o.objective.id"
:before-navigate="beforeSelectObjective(o.objective)"
:before-navigate="beforeObjectiveNavigate(o.objective)"
@toggle="toggleObjective($event, o.objective)"
@hook:mounted="onObjectiveMounted(o.objective)"
/>
</div>
Expand Down Expand Up @@ -430,41 +430,86 @@ export default {
window.removeEventListener('mouseup', this.stopDrag);
},
beforeSelectObjective(objective) {
async selectObjective(objective) {
if (
!this.workbenchObjectives.length &&
this.activeObjective &&
objective.id !== this.activeObjective.id
) {
// Close currently active objective if next objective is selected for
// the workbench
const activeObjectiveId = this.activeObjective.id;
this.$router.push({ name: 'ItemHome' });
// Add both objectives to the workbench using `setTimeout` to give the
// browser a chance to "catch up" while toggling panes
setTimeout(async () => {
await Promise.all(
[activeObjectiveId, objective.id].map(this.addWorkbenchObjective)
);
this.scrollToObjective(objective);
});
return;
}
// Add selected objective to workbench
await this.addWorkbenchObjective(objective.id);
this.scrollToObjective(objective);
},
async unselectObjective(objective) {
// Remove objective from workbench
await this.removeWorkbenchObjective(objective.id);
// Set next workbench objective as active if available
if (this.activeObjective && this.activeObjective.id === objective.id) {
if (this.workbenchObjectives.length) {
this.$router.replace({
name: 'ObjectiveHome',
params: { objectiveId: this.workbenchObjectives[0].id },
});
} else {
this.$router.push({ name: 'ItemHome' });
}
}
},
beforeObjectiveNavigate(objective) {
return async (event) => {
if (event.metaKey) {
event.preventDefault();
const modifierKey = event.metaKey || event.altKey;
if (this.activeObjective && objective.id !== this.activeObjective.id) {
// Add currently active objective to workbench if the next objective
// is selected with the modifier key.
await this.addWorkbenchObjective(this.activeObjective.id);
}
if (!modifierKey && !this.workbenchObjectives.length) {
return;
}
if (!this.workbenchObjectives.find((o) => o.id === objective.id)) {
await this.addWorkbenchObjective(objective.id);
this.scrollToObjective(objective);
if (this.activeObjective && objective.id !== this.activeObjective.id) {
await this.$router.replace({
name: 'ObjectiveHome',
params: { objectiveId: objective.id },
});
}
} else {
await this.removeWorkbenchObjective(objective.id);
// Prevent default link navigation when selecting/unselecting
// objectives for the workbench
event.preventDefault();
if (!this.workbenchObjectives.find((o) => o.id === objective.id)) {
await this.selectObjective(objective);
// Replace any active objective with the one newly selected
if (this.activeObjective && objective.id !== this.activeObjective.id) {
await this.$router.replace({
name: 'ObjectiveHome',
params: { objectiveId: objective.id },
});
}
} else if (
this.workbenchObjectives.length &&
!this.workbenchObjectives.find((o) => objective.id === o.id)
) {
// Clear the workbench if an object is selected with the modifier key
// and it is not currently listed.
this.clearWorkbenchObjectives();
} else {
await this.unselectObjective(objective);
}
};
},
async toggleObjective(checked, objective) {
if (checked) {
await this.selectObjective(objective);
} else {
await this.unselectObjective(objective);
}
},
onObjectiveMounted(objective) {
// Scroll to active objective when first mounted in the timeline.
if (objective.id === this.activeObjective?.id) {
Expand All @@ -489,10 +534,20 @@ export default {
},
async periodObjectivesToWorkbench() {
this.periodObjectives
.filter((po) => !this.workbenchObjectives.map((o) => o.id).includes(po.id))
.map((o) => o.id)
.forEach(this.addWorkbenchObjective);
// Reset and add all objectives within current period to the workbench
await this.clearWorkbenchObjectives();
if (!this.periodObjectives.length) {
return;
}
this.periodObjectives.map((o) => o.id).forEach(this.addWorkbenchObjective);
// Set first workbench objective as active
await this.$router.replace({
name: 'ObjectiveHome',
params: { objectiveId: this.periodObjectives[0].id },
});
this.$nextTick(() => {
if (this.$refs.period) {
Expand Down
42 changes: 30 additions & 12 deletions src/components/OkrLinkCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,26 @@
'okr-link-card',
{
'okr-link-card--active': isExactActive || active,
'okr-link-card--checked': checked,
'okr-link-card--compact': compact,
},
]"
:href="href"
@click="activate($event, navigate)"
>
<div class="okr-link-card__inner">
<pkt-tag
v-if="!compact"
text-style="normal-text"
skin="yellow"
size="small"
class="okr-link-card__owner"
>
{{ activeItem.name }}
</pkt-tag>
<div v-if="!compact" class="okr-link-card__header">
<input
v-if="checkable"
type="checkbox"
class="pkt-form-check-input"
:checked="checked"
@click.stop="$emit('toggle', $event.target.checked)"
/>
<pkt-tag text-style="normal-text" skin="yellow" size="small">
{{ activeItem.name }}
</pkt-tag>
</div>

<span class="okr-link-card__title pkt-txt-14">
{{ title }}
Expand Down Expand Up @@ -62,6 +66,14 @@ export default {
type: Boolean,
default: false,
},
checked: {
type: Boolean,
default: false,
},
checkable: {
type: Boolean,
default: false,
},
compact: {
type: Boolean,
default: false,
Expand Down Expand Up @@ -117,18 +129,24 @@ export default {
padding: 1rem;
}
&__owner {
&__header {
display: flex;
gap: 0.5rem;
align-items: center;
white-space: nowrap;
}
&__title {
text-wrap: balance;
}
&--active {
&--active,
&--checked {
color: var(--color-hover);
background-color: var(--color-blue-5);
border: 2px solid var(--color-hover);
}
&--active {
background-color: var(--color-blue-5);
}
}
</style>
3 changes: 1 addition & 2 deletions src/components/drawers/EditObjective.vue
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
</template>

<script>
import { mapActions, mapState } from 'vuex';
import { mapState } from 'vuex';
import { isEqual } from 'date-fns';
import { db } from '@/config/firebaseConfig';
import { formattedPeriod } from '@/util/okr';
Expand Down Expand Up @@ -220,7 +220,6 @@ export default {
methods: {
formattedPeriod,
...mapActions('okrs', ['setActiveObjective', 'addWorkbenchObjective']),
getCurrentDateRange() {
if (this.thisObjective.startDate && this.thisObjective.endDate) {
Expand Down
4 changes: 2 additions & 2 deletions src/components/layout/PaneLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ export default {
}
.slide-fade-enter-active {
transition: all 0.3s ease;
transition: all 0.4s ease;
}
.slide-fade-leave-active {
transition: all 0.1s cubic-bezier(1, 0.5, 0.8, 1);
transition: none;
}
.slide-fade-enter,
.slide-fade-leave-to {
Expand Down
9 changes: 3 additions & 6 deletions src/components/panes/WorkbenchPane.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
variant="icon-only"
icon-name="minus-circle"
skin="tertiary"
@onClick="removeObject(objective)"
@onClick="removeObjective(objective)"
/>
</div>
</div>
Expand Down Expand Up @@ -66,7 +66,7 @@ export default {
methods: {
...mapActions('okrs', ['removeWorkbenchObjective', 'clearWorkbenchObjectives']),
async removeObject(objective) {
async removeObjective(objective) {
await this.removeWorkbenchObjective(objective.id);
// Set next objective as active or unset current if removed.
Expand All @@ -84,9 +84,6 @@ export default {
async close() {
await this.clearWorkbenchObjectives();
if (this.$route.name !== 'ItemHome') {
this.$router.push({ name: 'ItemHome' });
}
},
},
};
Expand All @@ -108,7 +105,7 @@ export default {
top: -1rem;
right: -1rem;
height: 2rem;
padding: 0 0.25rem;
padding: 0 0.25rem !important;
color: var(--color-grayscale-40);
background-color: var(--color-white);
border-radius: 50%;
Expand Down
4 changes: 2 additions & 2 deletions src/views/Item/ItemOKRs.vue
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export default {
...mapActions('okrs', [
'setActiveObjective',
'setActiveKeyResult',
'clearWorkbenchObjectives',
'addWorkbenchObjective',
]),
async setData() {
Expand Down Expand Up @@ -247,7 +247,7 @@ export default {
this.$router.push({ name: 'ObjectiveHome', params: { objectiveId: objective.id } });
if (this.workbenchObjectives.length) {
await this.addWorkbenchObjective(objective);
await this.addWorkbenchObjective(objective.id);
}
},
},
Expand Down

0 comments on commit 73d55e0

Please sign in to comment.