mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-11-19 12:20:53 +00:00
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:
parent
8244cfb8eb
commit
49b2cb998b
|
@ -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.
|
||||||
|
|
|
@ -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',
|
||||||
|
|
Loading…
Reference in a new issue