Fix project board bug and improve documents (#17753)

* the project board was broken, this PR fixes it, and refactor the code, and we prevent the uncategorized column from being dragged.
* improve the frontend guideline (as discussed in https://github.com/go-gitea/gitea/pull/17699)
This commit is contained in:
wxiaoguang 2021-11-22 19:40:17 +08:00 committed by GitHub
parent 8244cfb8eb
commit 49b2cb998b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 9 deletions

View file

@ -40,6 +40,19 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h
7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue2 (or Vue3 in future). 7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue2 (or Vue3 in future).
### Framework Usage
Mixing different frameworks together is highly discouraged. A JavaScript module should follow one major framework and follow the framework's best practice.
Recommended implementations:
* Vue + Native
* Fomantic-UI (jQuery)
* Native only
Discouraged implementations:
* Vue + jQuery
* jQuery + Native
### `async` Functions ### `async` Functions
Only mark a function as `async` if and only if there are `await` calls Only mark a function as `async` if and only if there are `await` calls
@ -98,6 +111,19 @@ $('#el').on('click', async (e) => { // not recommended but acceptable
}); });
``` ```
### HTML Attributes and `dataset`
We forbid `dataset` usage, its camel-casing behaviour makes it hard to grep for attributes. However there are still some special cases, so the current guideline is:
* For legacy code:
* `$.data()` should be refactored to `$.attr()`.
* `$.data()` can be used to bind some non-string data to elements in rare cases, but it is highly discouraged.
* For new code:
* `node.dataset` should not be used, use `node.getAttribute` instead.
* never bind any user data to a DOM node, use a suitable design pattern to describe the relation between node and data.
### Vue2/Vue3 and JSX ### Vue2/Vue3 and JSX
Gitea is using Vue2 now, we plan to upgrade to Vue3. We decided not to introduce JSX to keep the HTML and the JavaScript code separated. Gitea is using Vue2 now, we plan to upgrade to Vue3. We decided not to introduce JSX to keep the HTML and the JavaScript code separated.

View file

@ -1,22 +1,24 @@
const {csrfToken} = window.config; const {csrfToken} = window.config;
async function initRepoProjectSortable() { async function initRepoProjectSortable() {
const els = document.getElementsByClassName('board'); const els = document.querySelectorAll('#project-board > .board');
if (!els.length) return; if (!els.length) return;
const {Sortable} = await import(/* webpackChunkName: "sortable" */'sortablejs'); const {Sortable} = await import(/* webpackChunkName: "sortable" */'sortablejs');
const boardColumns = document.getElementsByClassName('board-column');
new Sortable(els[0], { // the HTML layout is: #project-board > .board > .board-column .board.cards > .board-card.card .content
const mainBoard = els[0];
let boardColumns = mainBoard.getElementsByClassName('board-column');
new Sortable(mainBoard, {
group: 'board-column', group: 'board-column',
draggable: '.board-column', draggable: '.board-column',
filter: '[data-id="0"]',
animation: 150, animation: 150,
ghostClass: 'card-ghost', ghostClass: 'card-ghost',
onSort: () => { onSort: () => {
const board = document.getElementsByClassName('board')[0]; boardColumns = mainBoard.getElementsByClassName('board-column');
const boardColumns = board.getElementsByClassName('board-column'); for (let i = 0; i < boardColumns.length; i++) {
const column = boardColumns[i];
for (const [i, column] of boardColumns.entries()) {
if (parseInt($(column).data('sorting')) !== i) { if (parseInt($(column).data('sorting')) !== i) {
$.ajax({ $.ajax({
url: $(column).data('url'), url: $(column).data('url'),
@ -33,8 +35,9 @@ async function initRepoProjectSortable() {
}, },
}); });
for (const column of boardColumns) { for (const boardColumn of boardColumns) {
new Sortable(column.getElementsByClassName('board')[0], { const boardCardList = boardColumn.getElementsByClassName('board')[0];
new Sortable(boardCardList, {
group: 'shared', group: 'shared',
animation: 150, animation: 150,
ghostClass: 'card-ghost', ghostClass: 'card-ghost',