Skip to content

Commit

Permalink
Merge pull request #875 from oslokommune/drag-n-drop-key-results
Browse files Browse the repository at this point in the history
Support drag & drop for key results
  • Loading branch information
simenheg authored Sep 28, 2023
2 parents ddcf659 + e3da8b1 commit 6689102
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ All notable changes to this project will be documented in this file. The format
now toggles the detail pane rather than adding objectives to a list. To group
objectives in a list (and see combined progression), the meta key must now be
pressed while selecting one or more objectives.
- Key results can now be rearranged by drag and drop.

### Removed

Expand Down
2 changes: 1 addition & 1 deletion src/components/drawers/EditObjective.vue
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
import { mapActions, mapState } from 'vuex';
import { isEqual } from 'date-fns';
import { db } from '@/config/firebaseConfig';
import formattedPeriod from '@/util/okr';
import { formattedPeriod } from '@/util/okr';
import Objective from '@/db/Objective';
import firebase from 'firebase/compat/app';
import locale from 'flatpickr/dist/l10n/no';
Expand Down
45 changes: 42 additions & 3 deletions src/components/panes/ObjectivePane.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,31 @@
{{ $t('general.loading') }}
</div>

<draggable
v-else-if="hasEditRights && keyResults.length"
v-model="orderedKeyResults"
class="objective-pane__key-results-list"
animation="200"
>
<transition-group>
<okr-link-card
v-for="keyResult in orderedKeyResults"
:key="keyResult.id"
:route="{
name: 'KeyResultHome',
params: { objectiveId: activeObjective.id, keyResultId: keyResult.id },
}"
:title="keyResult.name"
:progression="keyResult.progression"
:active="activeKeyResult && activeKeyResult.id === keyResult.id"
compact
/>
</transition-group>
</draggable>

<div v-else-if="keyResults.length" class="objective-pane__key-results-list">
<okr-link-card
v-for="keyResult in keyResults"
v-for="keyResult in orderedKeyResults"
:key="keyResult.id"
:route="{
name: 'KeyResultHome',
Expand Down Expand Up @@ -96,9 +118,12 @@
<script>
import { format } from 'd3-format';
import { mapGetters, mapState } from 'vuex';
import { PktBreadcrumbs, PktButton, PktTag } from '@oslokommune/punkt-vue2';
import draggable from 'vuedraggable';
import { compareKeyResults } from '@/util/okr';
import { dateLong, periodDates } from '@/util';
import { db } from '@/config/firebaseConfig';
import { PktBreadcrumbs, PktButton, PktTag } from '@oslokommune/punkt-vue2';
import KeyResult from '@/db/KeyResult';
import ProgressBar from '@/components/ProgressBar.vue';
import PaneWrapper from '@/components/panes/PaneWrapper.vue';
import LoadingSmall from '@/components/LoadingSmall.vue';
Expand All @@ -112,6 +137,7 @@ export default {
name: 'ObjectivePane',
components: {
draggable,
PaneWrapper,
EmptyState,
OkrLinkCard,
Expand Down Expand Up @@ -159,6 +185,19 @@ export default {
{ text: this.activeObjective.name },
];
},
orderedKeyResults: {
get() {
return this.keyResults.map((kr) => kr).sort(compareKeyResults);
},
set(keyResults) {
keyResults.forEach((kr, i) => {
if (kr.order !== i) {
KeyResult.update(kr.id, { order: i });
}
});
},
},
},
watch: {
Expand Down Expand Up @@ -234,7 +273,7 @@ export default {
margin-left: 3rem;
}
> .okr-link-card {
& .okr-link-card {
position: relative;
margin-top: 1rem;
Expand Down
2 changes: 1 addition & 1 deletion src/components/period/PeriodShortcut.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</template>

<script>
import formattedPeriod from '@/util/okr';
import { formattedPeriod } from '@/util/okr';
import { PktButton } from '@oslokommune/punkt-vue2';
export default {
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/WidgetKeyResultDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
import { mapState } from 'vuex';
import { db } from '@/config/firebaseConfig';
import { dateLong } from '@/util';
import formattedPeriod from '@/util/okr';
import { formattedPeriod } from '@/util/okr';
import ProfileModal from '@/components/modals/ProfileModal.vue';
import Widget from './WidgetWrapper.vue';
Expand Down
2 changes: 1 addition & 1 deletion src/components/widgets/WidgetObjectiveDetails.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
<script>
import { mapState } from 'vuex';
import { dateLong } from '@/util';
import formattedPeriod from '@/util/okr';
import { formattedPeriod } from '@/util/okr';
import ProfileModal from '@/components/modals/ProfileModal.vue';
import Widget from './WidgetWrapper.vue';
Expand Down
27 changes: 25 additions & 2 deletions src/util/okr.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { dateShort, periodDates } from '@/util';
/**
* Return a nicely formatted period range for `objective`'s period.
*/
function formattedPeriod(objective) {
export function formattedPeriod(objective) {
const { period, startDate, endDate } = objective;

if (startDate && endDate) {
Expand All @@ -16,4 +16,27 @@ function formattedPeriod(objective) {
return null;
}

export default formattedPeriod;
/**
* Compare two key results for sorting.
*
* The returned function returns a negative number if `a` should come before
* `b`, otherwise it returns a positive number.
*
* Key results that haven't gotten any order set yet are ordered by their names
* instead to retain backwards compatibility.
*/
export function compareKeyResults(a, b) {
// Sort by order only if both have one.
if ('order' in a && 'order' in b) {
return a.order - b.order;
}
// When only one of them has an order, sort that one first.
if ('order' in a) {
return -1;
}
if ('order' in b) {
return 1;
}
// Otherwise fall back to ordering by name.
return a.name.localeCompare(b.name);
}

0 comments on commit 6689102

Please sign in to comment.