Skip to content

Commit

Permalink
Remove key results from the global store
Browse files Browse the repository at this point in the history
Remove key results from the global store to make them easier to work
with (and start uncluttering the cursed `set_active_period_and_data`
action).

They are now loaded on-demand instead according to the objectives they
belong to. This also makes it easier to load key results belonging to
others, since they're no longer loaded based on `parent`, but on
`objective`.
  • Loading branch information
simenheg committed Aug 16, 2023
1 parent dc00baf commit c3cb7fd
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 127 deletions.
40 changes: 35 additions & 5 deletions src/components/KeyResultsList.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,60 @@
<template>
<ul class="key-results-list">
<ul v-if="keyResults.length" class="key-results-list">
<li v-for="keyResult in keyResults" :key="keyResult.id" class="key-results-list__row">
<key-result-row :key-result="keyResult" :compact="compact" />
</li>
</ul>
<empty-state
v-else-if="showEmptyState && !loading"
:heading="$t('empty.noKeyResults.heading')"
:body="$t('empty.noKeyResults.body')"
/>
</template>

<script>
import { db } from '@/config/firebaseConfig';
export default {
name: 'KeyResultsList',
components: {
EmptyState: () => import('@/components/EmptyState.vue'),
KeyResultRow: () => import('@/components/KeyResultRow.vue'),
},
props: {
keyResults: {
type: Array,
required: false,
default: () => [],
objective: {
type: Object,
required: true,
},
compact: {
type: Boolean,
required: false,
default: false,
},
showEmptyState: {
type: Boolean,
required: false,
default: true,
},
},
data: () => ({
loading: true,
keyResults: [],
}),
async created() {
const objectiveRef = await db.doc(`objectives/${this.objective.id}`);
const keyResults = await db
.collection('keyResults')
.where('archived', '==', false)
.where('objective', '==', objectiveRef)
.orderBy('name');
await this.$bind('keyResults', keyResults);
this.loading = false;
},
};
</script>
Expand Down
61 changes: 26 additions & 35 deletions src/components/ObjectiveWorkbench.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,35 @@
/>
</header>

<div v-if="selectedObjectives.length > 1" class="objective-workbench__list">
<div
:class="singular ? 'objective-workbench__objective' : 'objective-workbench__list'"
>
<p v-if="singular && selectedObjectives[0].description" class="mb-size-16">
{{ selectedObjectives[0].description }}
</p>

<div
v-for="objective in selectedObjectives"
:key="objective.id"
class="objective-workbench__list-item"
:class="{
'objective-workbench__list-item': !singular,
}"
>
<objective-row :objective="objective" />
<div
v-if="singular"
class="objective-workbench__objective-progression mb-size-16"
>
<progress-bar :is-compact="false" :progression="objective.progression * 100" />
<span class="pkt-txt-20-medium">
{{ percent(objective.progression) }}
</span>
</div>
<objective-row v-else :objective="objective" />

<key-results-list
v-if="objective.keyResults.length"
:key-results="objective.keyResults"
/>
<key-results-list :objective="objective" :show-empty-state="singular" />

<pkt-button
v-if="!singular"
v-tooltip.bottom="$t('btn.remove')"
class="objective-workbench__remove-button"
size="small"
Expand All @@ -52,33 +67,6 @@
/>
</div>
</div>

<div v-else class="objective-workbench__objective">
<p v-if="selectedObjectives[0].description" class="mb-size-16">
{{ selectedObjectives[0].description }}
</p>

<div class="objective-workbench__objective-progression mb-size-16">
<progress-bar
:is-compact="false"
:progression="selectedObjectives[0].progression * 100"
/>
<span class="pkt-txt-20-medium">
{{ percent(selectedObjectives[0].progression) }}
</span>
</div>

<key-results-list
v-if="selectedObjectives[0].keyResults.length"
:key-results="selectedObjectives[0].keyResults"
/>

<empty-state
v-else
:heading="$t('empty.noKeyResults.heading')"
:body="$t('empty.noKeyResults.body')"
/>
</div>
</div>
</template>

Expand All @@ -91,7 +79,6 @@ export default {
name: 'ObjectiveWorkbench',
components: {
EmptyState: () => import('@/components/EmptyState.vue'),
KeyResultsList: () => import('@/components/KeyResultsList.vue'),
ObjectiveRow: () => import('@/components/ObjectiveRow.vue'),
ProgressBar: () => import('@/components/ProgressBar.vue'),
Expand All @@ -100,6 +87,10 @@ export default {
computed: {
...mapGetters(['selectedObjectives']),
singular() {
return this.selectedObjectives.length === 1;
},
},
methods: {
Expand Down
1 change: 0 additions & 1 deletion src/components/drawers/EditKeyResult.vue
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ export default {
...mapState([
'activeItem',
'activeItemRef',
'keyResults',
'organizations',
'departments',
'products',
Expand Down
60 changes: 18 additions & 42 deletions src/components/widgets/WidgetWeights.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<widget :title="$t('weight.heading')" size="small">
<div class="scales">
<router-link
v-for="{ id, weight, name } in weights"
v-for="{ id, weight, name } in keyResults"
:key="id"
v-tooltip.bottom="name"
:to="getToLink(id)"
Expand All @@ -18,6 +18,7 @@
<script>
import { scaleLinear } from 'd3-scale';
import { max } from 'd3-array';
import { db } from '@/config/firebaseConfig';
export default {
name: 'WidgetWeights',
Expand All @@ -27,60 +28,39 @@ export default {
},
props: {
items: {
type: Array,
required: true,
},
activeItem: {
objective: {
type: Object,
required: false,
default: () => ({}),
},
type: {
type: String,
required: true,
},
},
data: () => ({
chart: null,
scale: scaleLinear(),
keyResults: [],
}),
computed: {
weights() {
if (!this.activeItem) {
return [];
}
let siblings = this.items;
if (this.type !== 'objective') {
siblings = siblings.filter(
({ objective }) => objective.split('/')[1] === this.activeItem.id
);
}
const processWeights = ({ weight, id, name }) => ({
weight,
id,
name,
});
return siblings.map(processWeights);
},
},
watch: {
weights: {
keyResults: {
immediate: true,
handler(weights) {
const maxValue = max([0, max(weights, ({ weight }) => weight)]);
handler(keyResults) {
const maxValue = max([0, max(keyResults, ({ weight }) => weight)]);
this.scale.domain([0, maxValue]);
},
},
},
async created() {
const objectiveRef = await db.doc(`objectives/${this.objective.id}`);
const keyResults = await db
.collection('keyResults')
.where('archived', '==', false)
.where('objective', '==', objectiveRef)
.orderBy('name');
this.$bind('keyResults', keyResults);
},
mounted() {
if (this.$refs.svg) {
this.init();
Expand All @@ -93,10 +73,6 @@ export default {
},
getToLink(id) {
if (this.type === 'objective') {
return { name: 'ObjectiveHome', params: { objectiveId: id } };
}
return { name: 'KeyResultHome', params: { keyResultId: id } };
},
},
Expand Down
9 changes: 0 additions & 9 deletions src/store/actions/set_active_period_and_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export default firestoreAction(
if (!periodId && !item) {
unbindFirestoreRef('periods');
unbindFirestoreRef('objectives');
unbindFirestoreRef('keyResults');
unbindFirestoreRef('activePeriod');
return false;
}
Expand All @@ -34,17 +33,9 @@ export default firestoreAction(
.then((snapshot) => snapshot.docs.map((doc) => doc.ref));

if (activeObjectivesList.length) {
const keyResultsRef = db
.collection('keyResults')
.where('archived', '==', false)
.where('parent', '==', parentRef)
.orderBy('name');

await bindFirestoreRef('objectives', objectivesRef, { maxRefDepth: 1 });
await bindFirestoreRef('keyResults', keyResultsRef, { maxRefDepth: 0 });
} else {
unbindFirestoreRef('objectives');
unbindFirestoreRef('keyResults');
}

return true;
Expand Down
8 changes: 3 additions & 5 deletions src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,12 @@ export const storeGetters = {
},

/**
* Return `state.objectives` enriched with ID and key results.
* Return `state.objectives` enriched with ID.
*/
objectivesWithKeyResults: (state) => {
objectivesWithID: (state) => {
return state.objectives.map((o) => ({
...o,
id: o.id,
keyResults: state.keyResults.filter((kr) => kr.objective === `objectives/${o.id}`),
}));
},

Expand All @@ -165,7 +164,7 @@ export const storeGetters = {
if (!objectiveIds.length) {
return [];
}
return getters.objectivesWithKeyResults.filter((o) => objectiveIds.includes(o.id));
return getters.objectivesWithID.filter((o) => objectiveIds.includes(o.id));
},
};

Expand Down Expand Up @@ -295,7 +294,6 @@ export default new Vuex.Store({
activeObjective: null,
periods: [],
objectives: [],
keyResults: [],
kpis: [],
subKpis: [],
loginError: null,
Expand Down
12 changes: 6 additions & 6 deletions src/views/Item/ItemOKRs.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<page-layout
v-if="objectivesWithKeyResults.length || dataLoading"
v-if="objectivesWithID.length || dataLoading"
breakpoint="full"
:sidebar-grid="false"
:sidebar-cols="5"
Expand All @@ -24,8 +24,8 @@

<div class="okrs-timeline__body">
<gantt-chart
v-if="dataLoading || objectivesWithKeyResults.length"
:objectives="objectivesWithKeyResults"
v-if="dataLoading || objectivesWithID.length"
:objectives="objectivesWithID"
:period="selectedPeriod"
:loading="dataLoading"
/>
Expand Down Expand Up @@ -96,7 +96,7 @@ export default {
computed: {
...mapState(['activeItem', 'dataLoading', 'selectedPeriod', 'user']),
...mapGetters(['objectivesWithKeyResults', 'selectedObjectives', 'hasEditRights']),
...mapGetters(['objectivesWithID', 'selectedObjectives', 'hasEditRights']),
view() {
return this.user.preferences.view;
Expand All @@ -106,11 +106,11 @@ export default {
* Return the most recently created objective for the current item.
*/
newestObjective() {
if (!this.objectivesWithKeyResults.length) {
if (!this.objectivesWithID.length) {
return null;
}
return this.objectivesWithKeyResults.slice().sort((a, b) => {
return this.objectivesWithID.slice().sort((a, b) => {
if (a.created && b.created) {
return a.created.seconds > b.created.seconds ? -1 : 1;
}
Expand Down
Loading

0 comments on commit c3cb7fd

Please sign in to comment.