mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 02:46:04 +01: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:
		| @@ -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', | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user