aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwxiaoguang2023-03-01 10:22:14 +0800
committerGitHub2023-03-01 10:22:14 +0800
commit7a5af25592003ddc3017fcd7b822a3e02fc40ef6 (patch)
tree49fd2f094bdbbe7b4a6d79eaafeac3de72e312ed
parent3e426bba78dbdd3e1369dd929de4ef7186f3d630 (diff)
Fix incorrect checkbox behaviors in the dashboard repolist's filter (#23147)
Co-author: yp05327 , this PR is based on yp05327's #22813. The problems of the old DashboardRepoList / repolist.tmpl: * It mixes many different frameworks together * It "just works", bug on bug * It uses many anti-pattern of Vue This PR: * Fix bugs and close #22800 * Decouple the "checkbox" elements from Fomantic UI (only use CSS styles) * Simplify the HTML layout * Simplify JS logic * Make it easier to refactor the DashboardRepoList into a pure Vue component in the future. ### Screenshots #### Default ![image](https://user-images.githubusercontent.com/2114189/221355768-a3eb5b23-85b4-4e3d-b906-844d8b15539d.png) #### Click "Archived" to make it checked ![image](https://user-images.githubusercontent.com/2114189/221355777-9a104ddf-52a7-4504-869a-43a73827d802.png) #### Click "Archived" to make it intermediate ![image](https://user-images.githubusercontent.com/2114189/221355802-0f67a073-67ad-4e92-84a6-558c432103a5.png) #### Click "Archived" to make it unchecked ![image](https://user-images.githubusercontent.com/2114189/221355810-acf1d9d8-ccce-47fe-a02e-70cf4e666331.png) --------- Co-authored-by: yp05327 <576951401@qq.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
-rw-r--r--templates/user/dashboard/repolist.tmpl82
-rw-r--r--web_src/js/components/DashboardRepoList.js91
2 files changed, 60 insertions, 113 deletions
diff --git a/templates/user/dashboard/repolist.tmpl b/templates/user/dashboard/repolist.tmpl
index 22af578fc..97234176b 100644
--- a/templates/user/dashboard/repolist.tmpl
+++ b/templates/user/dashboard/repolist.tmpl
@@ -46,56 +46,38 @@
<div class="ui dropdown icon button" title="{{.locale.Tr "home.filter"}}">
<i class="icon gt-df gt-ac gt-jc gt-m-0">{{svg "octicon-filter" 16}}</i>
<div class="menu">
- <div class="item">
- <a @click="toggleArchivedFilter()">
- <div class="ui checkbox" id="archivedFilterCheckbox" title="{{.locale.Tr "home.show_both_archived_unarchived"}}" v-if="archivedFilter === 'both'">
- <input type="checkbox">
- <label>
- {{svg "octicon-archive" 16 "gt-mr-2"}}
- {{.locale.Tr "home.show_archived"}}
- </label>
- </div>
- <div class="ui checkbox" id="archivedFilterCheckbox" title="{{.locale.Tr "home.show_only_unarchived"}}" v-if="archivedFilter === 'unarchived'">
- <input type="checkbox">
- <label>
- {{svg "octicon-archive" 16 "gt-mr-2"}}
- {{.locale.Tr "home.show_archived"}}
- </label>
- </div>
- <div class="ui checkbox" id="archivedFilterCheckbox" title="{{.locale.Tr "home.show_only_archived"}}" v-if="archivedFilter === 'archived'">
- <input type="checkbox">
- <label>
- {{svg "octicon-archive" 16 "gt-mr-2"}}
- {{.locale.Tr "home.show_archived"}}
- </label>
- </div>
- </a>
- </div>
- <div class="item">
- <a @click="togglePrivateFilter()">
- <div class="ui checkbox" id="privateFilterCheckbox" title="{{.locale.Tr "home.show_both_private_public"}}" v-if="privateFilter === 'both'">
- <input type="checkbox">
- <label>
- {{svg "octicon-lock" 16 "gt-mr-2"}}
- {{.locale.Tr "home.show_private"}}
- </label>
- </div>
- <div class="ui checkbox" id="privateFilterCheckbox" title="{{.locale.Tr "home.show_only_public"}}" v-if="privateFilter === 'public'">
- <input type="checkbox">
- <label>
- {{svg "octicon-lock" 16 "gt-mr-2"}}
- {{.locale.Tr "home.show_private"}}
- </label>
- </div>
- <div class="ui checkbox" id="privateFilterCheckbox" title="{{.locale.Tr "home.show_only_private"}}" v-if="privateFilter === 'private'">
- <input type="checkbox">
- <label>
- {{svg "octicon-lock" 16 "gt-mr-2"}}
- {{.locale.Tr "home.show_private"}}
- </label>
- </div>
- </a>
- </div>
+ <a class="item" @click="toggleArchivedFilter()">
+ <div class="ui checkbox"
+ ref="checkboxArchivedFilter"
+ data-title-both="{{.locale.Tr "home.show_both_archived_unarchived"}}"
+ data-title-unarchived="{{.locale.Tr "home.show_only_unarchived"}}"
+ data-title-archived="{{.locale.Tr "home.show_only_archived"}}"
+ :title="checkboxArchivedFilterTitle"
+ >
+ <!--the "hidden" is necessary to make the checkbox work without Fomantic UI js,
+ otherwise if the "input" handles click event for intermediate status, it breaks the internal state-->
+ <input type="checkbox" class="hidden" v-bind.prop="checkboxArchivedFilterProps">
+ <label>
+ {{svg "octicon-archive" 16 "gt-mr-2"}}
+ {{.locale.Tr "home.show_archived"}}
+ </label>
+ </div>
+ </a>
+ <a class="item" @click="togglePrivateFilter()">
+ <div class="ui checkbox"
+ ref="checkboxPrivateFilter"
+ data-title-both="{{.locale.Tr "home.show_both_private_public"}}"
+ data-title-public="{{.locale.Tr "home.show_only_public"}}"
+ data-title-private="{{.locale.Tr "home.show_only_private"}}"
+ :title="checkboxPrivateFilterTitle"
+ >
+ <input type="checkbox" class="hidden" v-bind.prop="checkboxPrivateFilterProps">
+ <label>
+ {{svg "octicon-lock" 16 "gt-mr-2"}}
+ {{.locale.Tr "home.show_private"}}
+ </label>
+ </div>
+ </a>
</div>
</div>
</div>
diff --git a/web_src/js/components/DashboardRepoList.js b/web_src/js/components/DashboardRepoList.js
index 0a009e78d..2328cc83a 100644
--- a/web_src/js/components/DashboardRepoList.js
+++ b/web_src/js/components/DashboardRepoList.js
@@ -87,6 +87,7 @@ function initVueComponents(app) {
}
return {
+ hasMounted: false, // accessing $refs in computed() need to wait for mounted
tab,
repos: [],
reposTotalCount: 0,
@@ -134,7 +135,19 @@ function initVueComponents(app) {
},
repoTypeCount() {
return this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`];
- }
+ },
+ checkboxArchivedFilterTitle() {
+ return this.hasMounted && this.$refs.checkboxArchivedFilter?.getAttribute(`data-title-${this.archivedFilter}`);
+ },
+ checkboxArchivedFilterProps() {
+ return {checked: this.archivedFilter === 'archived', indeterminate: this.archivedFilter === 'both'};
+ },
+ checkboxPrivateFilterTitle() {
+ return this.hasMounted && this.$refs.checkboxPrivateFilter?.getAttribute(`data-title-${this.privateFilter}`);
+ },
+ checkboxPrivateFilterProps() {
+ return {checked: this.privateFilter === 'private', indeterminate: this.privateFilter === 'both'};
+ },
},
mounted() {
@@ -144,10 +157,11 @@ function initVueComponents(app) {
initTooltip(elTooltip);
}
$(el).find('.dropdown').dropdown();
- this.setCheckboxes();
nextTick(() => {
this.$refs.search.focus();
});
+
+ this.hasMounted = true;
},
methods: {
@@ -156,39 +170,6 @@ function initVueComponents(app) {
this.updateHistory();
},
- setCheckboxes() {
- switch (this.archivedFilter) {
- case 'unarchived':
- $('#archivedFilterCheckbox').checkbox('set unchecked');
- break;
- case 'archived':
- $('#archivedFilterCheckbox').checkbox('set checked');
- break;
- case 'both':
- $('#archivedFilterCheckbox').checkbox('set indeterminate');
- break;
- default:
- this.archivedFilter = 'unarchived';
- $('#archivedFilterCheckbox').checkbox('set unchecked');
- break;
- }
- switch (this.privateFilter) {
- case 'public':
- $('#privateFilterCheckbox').checkbox('set unchecked');
- break;
- case 'private':
- $('#privateFilterCheckbox').checkbox('set checked');
- break;
- case 'both':
- $('#privateFilterCheckbox').checkbox('set indeterminate');
- break;
- default:
- this.privateFilter = 'both';
- $('#privateFilterCheckbox').checkbox('set indeterminate');
- break;
- }
- },
-
changeReposFilter(filter) {
this.reposFilter = filter;
this.repos = [];
@@ -245,45 +226,29 @@ function initVueComponents(app) {
},
toggleArchivedFilter() {
- switch (this.archivedFilter) {
- case 'both':
- this.archivedFilter = 'unarchived';
- break;
- case 'unarchived':
- this.archivedFilter = 'archived';
- break;
- case 'archived':
- this.archivedFilter = 'both';
- break;
- default:
- this.archivedFilter = 'unarchived';
- break;
+ if (this.archivedFilter === 'unarchived') {
+ this.archivedFilter = 'archived';
+ } else if (this.archivedFilter === 'archived') {
+ this.archivedFilter = 'both';
+ } else { // including both
+ this.archivedFilter = 'unarchived';
}
this.page = 1;
this.repos = [];
- this.setCheckboxes();
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
this.searchRepos();
},
togglePrivateFilter() {
- switch (this.privateFilter) {
- case 'both':
- this.privateFilter = 'public';
- break;
- case 'public':
- this.privateFilter = 'private';
- break;
- case 'private':
- this.privateFilter = 'both';
- break;
- default:
- this.privateFilter = 'both';
- break;
+ if (this.privateFilter === 'both') {
+ this.privateFilter = 'public';
+ } else if (this.privateFilter === 'public') {
+ this.privateFilter = 'private';
+ } else { // including private
+ this.privateFilter = 'both';
}
this.page = 1;
this.repos = [];
- this.setCheckboxes();
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
this.searchRepos();
},