Skip to content

Commit 98e03a3

Browse files
authored
chore: filter functionality for PR and Issue tab (#1953)
* chore: issues pr * chore: fix test * chore: fix lint * chore: fix lint * chore: fix styles * chore: fix build * chore: fix build * chore: fixing storybook * chore: fix loading state * chore: fix loading state for PR * chore: remove something
1 parent eec3622 commit 98e03a3

38 files changed

Lines changed: 1515 additions & 355 deletions

.github/workflows/ci-vue3-apollo-quasar.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ jobs:
7878
strategy:
7979
fail-fast: false
8080
matrix:
81-
node-version: [16.x, 18.x]
81+
node-version: [16.x]
8282

8383
steps:
8484
- uses: actions/checkout@v2
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
VUE_APP_API_URL = 'https://api.starter.dev/.netlify/functions/server'
22
VUE_APP_GRAPHQL_URL = 'https://api.github.com/graphql'
3+
VUE_APP_URL = 'https://api.github.com'
34
VUE_APP_REDIRECT_URL = 'http://localhost:8080/redirect'

vue3-apollo-quasar/.env.production

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
VUE_APP_API_URL = 'https://api.starter.dev/.netlify/functions/server'
22
VUE_APP_GRAPHQL_URL = 'https://api.github.com/graphql'
3+
VUE_APP_URL = 'https://api.github.com'
34
VUE_APP_REDIRECT_URL = 'https://vue3-apollo-quasar.starter.dev/redirect'
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<template>
2+
<a
3+
:href="$route.path"
4+
v-if="isFiltered"
5+
class="row items-center text-caption q-my-sm q-ml-2 cursor-pointer clear_wrapper"
6+
@click="resetFilter"
7+
>
8+
<span class="q-mr-sm close_icon row just0fy-center items-center">
9+
<q-icon name="close" size="xs" />
10+
</span>
11+
Clear filter
12+
</a>
13+
</template>
14+
15+
<script lang="ts" setup>
16+
import { useRepoStore } from '@/store/respoStore';
17+
import { computed } from 'vue';
18+
const repoStore = useRepoStore();
19+
20+
const resetFilter = () => repoStore.resetFilter();
21+
const isFiltered = computed(
22+
() =>
23+
repoStore.selectedLabel || repoStore.selectedMilestone || repoStore.sortBy,
24+
);
25+
</script>
26+
27+
<style lang="scss" scoped>
28+
.clear_wrapper {
29+
&:hover {
30+
.close_icon {
31+
background-color: rgb(46, 94, 190);
32+
}
33+
}
34+
}
35+
.close_icon {
36+
background-color: rgb(107 114 128);
37+
color: white;
38+
border-radius: 0.375rem;
39+
}
40+
</style>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import ClearIssuePRFilter from './ClearIssuePRFilter.vue';
2+
export default ClearIssuePRFilter;

vue3-apollo-quasar/src/components/IssuePullRequestTab/IssuePullRequestTab.vue

Lines changed: 123 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
name="svguse:app-icons/issue.svg#issue"
1818
v-else
1919
/>
20-
<span class="q-mr-xs" v-if="openCounts">{{ openCounts }}</span>
20+
<span class="q-mr-xs" v-if="!isNaN(openCounts)">{{
21+
openCounts
22+
}}</span>
2123
Open
2224
</button>
2325
<button
@@ -29,7 +31,9 @@
2931
class="text-h6 custom-icon"
3032
name="svguse:app-icons/correct.svg#correct"
3133
/>
32-
<span class="q-mr-xs" v-if="closedCounts">{{ closedCounts }}</span>
34+
<span class="q-mr-xs" v-if="!isNaN(closedCounts)">{{
35+
closedCounts
36+
}}</span>
3337
Closed
3438
</button>
3539
</div>
@@ -38,49 +42,105 @@
3842
label="Label"
3943
flat
4044
class="text-capitalize q-px-xs dropdown-label dropdown-label--label text-caption row justify-center items-center bg-transparent no-border cursor-pointer"
41-
@click="toggleLabelMenu()"
4245
>
43-
<q-list class="dropdown-menu q-menu" v-if="labelRef">
44-
<slot name="label-list">
45-
<q-item
46-
class="text-center text-caption text-primary text-bold q-py-xs block"
47-
>
48-
Label options
49-
</q-item>
50-
</slot>
46+
<q-list separator class="dropdown-menu">
47+
<div
48+
class="q-py-sm q-px-md row justify-between items-center text-caption text-weight-bold"
49+
>
50+
Select Label
51+
<q-icon name="close" size="xs" v-close-popup />
52+
</div>
53+
<q-separator />
54+
<q-item
55+
v-for="label in labelsOpt"
56+
class="text-caption"
57+
:key="label.name"
58+
clickable
59+
v-close-popup
60+
@click="setlabel(label.name)"
61+
>
62+
<q-item-section>
63+
<span class="row items-center q-gutter-x-xs">
64+
<span v-if="repoStore.selectedLabel === label.name">
65+
<q-icon name="check" size="xs" />
66+
</span>
67+
<span class="q-mr-md" v-else />
68+
<span>
69+
{{ label.name }}
70+
</span>
71+
</span>
72+
</q-item-section>
73+
</q-item>
5174
</q-list>
5275
</q-btn-dropdown>
5376
<q-btn-dropdown
54-
v-if="tabType === TAB_TYPE.ISSUE"
5577
label="Milestones"
5678
flat
5779
class="text-capitalize q-px-xs dropdown-label dropdown-label--milestones text-caption row justify-center items-center bg-transparent no-border cursor-pointer"
58-
@click="toggleMilestonesMenu()"
5980
>
60-
<q-list separator class="dropdown-menu q-menu" v-if="milestonesRef">
61-
<slot name="sort-list">
62-
<q-item
63-
class="text-center text-caption text-primary text-bold q-py-xs block"
64-
>
65-
Milestones options
66-
</q-item>
67-
</slot>
81+
<q-list separator class="dropdown-menu">
82+
<div
83+
class="q-py-sm q-px-md row justify-between items-center text-caption text-weight-bold"
84+
>
85+
Select Milestone
86+
<q-icon name="close" size="xs" v-close-popup />
87+
</div>
88+
<q-separator />
89+
<q-item
90+
v-for="milestone in milestoneOpt"
91+
class="text-caption"
92+
:key="milestone.id"
93+
clickable
94+
v-close-popup
95+
@click="setMilestone(milestone.title)"
96+
>
97+
<q-item-section>
98+
<span class="row items-center q-gutter-x-xs">
99+
<span v-if="repoStore.selectedMilestone === milestone.title">
100+
<q-icon name="check" size="xs" />
101+
</span>
102+
<span class="q-mr-md" v-else />
103+
<span>
104+
{{ milestone.title }}
105+
</span>
106+
</span>
107+
</q-item-section>
108+
</q-item>
68109
</q-list>
69110
</q-btn-dropdown>
70111
<q-btn-dropdown
71112
label="Sort"
72113
flat
73114
class="text-capitalize q-px-xs dropdown-label dropdown-label--sort text-caption row justify-center items-center bg-transparent no-border cursor-pointer posi"
74-
@click="toggleSortMenu()"
75115
>
76-
<q-list separator class="dropdown-menu q-menu" v-if="sortRef">
77-
<slot name="sort-list">
78-
<q-item
79-
class="text-center text-caption text-primary text-bold q-py-xs block"
80-
>
81-
Sort options
82-
</q-item>
83-
</slot>
116+
<q-list separator class="dropdown-menu">
117+
<div
118+
class="q-py-sm q-px-md row justify-between items-center text-caption text-weight-bold"
119+
>
120+
Sort By
121+
<q-icon name="close" size="xs" v-close-popup />
122+
</div>
123+
<q-separator />
124+
<q-item
125+
v-for="option in sortOptions"
126+
class="text-caption"
127+
:key="option"
128+
clickable
129+
v-close-popup
130+
@click="setSortBy(option)"
131+
>
132+
<q-item-section>
133+
<span class="row items-center q-gutter-x-xs">
134+
<span v-if="repoStore.sortBy === option">
135+
<q-icon name="check" size="xs" />
136+
</span>
137+
<span class="q-mr-md" v-else />
138+
<span>
139+
{{ option }}
140+
</span>
141+
</span>
142+
</q-item-section>
143+
</q-item>
84144
</q-list>
85145
</q-btn-dropdown>
86146
</div>
@@ -90,8 +150,10 @@
90150
</template>
91151

92152
<script lang="ts">
93-
import { defineComponent, ref } from 'vue';
153+
import { computed, defineComponent, ref } from 'vue';
94154
import { TAB_TYPE, TABS } from './data';
155+
import { useRepoStore } from '@/store/respoStore';
156+
import { getSelectedMilestoneNumber, SORT_OPTIONS } from '@/helpers';
95157
96158
export default defineComponent({
97159
name: 'IssuePullRequestTab',
@@ -116,6 +178,22 @@ export default defineComponent({
116178
const labelRef = ref(false);
117179
const sortRef = ref(false);
118180
const milestonesRef = ref(false);
181+
const sortOptions = Object.values(SORT_OPTIONS);
182+
const repoStore = useRepoStore();
183+
184+
const labelsOpt = computed(() => repoStore.labels);
185+
const milestoneOpt = computed(() => repoStore.milestones);
186+
187+
const setMilestone = (value: string) => {
188+
repoStore.setSelectedMilestone(value);
189+
const milestoneNum = getSelectedMilestoneNumber(
190+
repoStore.milestones || [],
191+
value,
192+
);
193+
repoStore.setSelectedMilestoneNumber(milestoneNum);
194+
};
195+
const setlabel = (value: string) => repoStore.setSelectedLabel(value);
196+
const setSortBy = (value: string) => repoStore.setSortBy(value);
119197
120198
const isTab = (value) => value === activeTab.value;
121199
@@ -158,11 +236,18 @@ export default defineComponent({
158236
milestonesRef,
159237
sortRef,
160238
TAB_TYPE,
239+
milestoneOpt,
240+
labelsOpt,
241+
repoStore,
242+
sortOptions,
161243
isTab,
162244
toggleLabelMenu,
163245
toggleSortMenu,
164246
updateActiveTab,
165247
toggleMilestonesMenu,
248+
setMilestone,
249+
setlabel,
250+
setSortBy,
166251
};
167252
},
168253
});
@@ -200,4 +285,11 @@ export default defineComponent({
200285
transform: translateY(0.1rem);
201286
}
202287
}
288+
289+
.dropdown-menu {
290+
width: 100%;
291+
height: 100%;
292+
min-width: 200px;
293+
max-height: unset;
294+
}
203295
</style>

vue3-apollo-quasar/src/components/IssueTabView/IssueTabView.stories.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ const Template = (args) => ({
1818
export const Default = Template.bind({});
1919
Default.args = {
2020
openIssues: {
21-
edges: ISSUES.openIssue,
21+
pullRequests: ISSUES.openIssue,
22+
totalCount: 20,
23+
pageInfo: { hasNextPage: false, hasPreviousPage: false },
2224
},
2325
closedIssues: {
24-
edges: ISSUES.closedIssue,
26+
pullRequests: ISSUES.closedIssue,
27+
totalCount: 20,
28+
pageInfo: { hasNextPage: false, hasPreviousPage: false },
2529
},
2630
};

0 commit comments

Comments
 (0)