mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Rework delete org and rename org UI (#34762)
# What's the problem of the original implementation Renaming organization will mix with organization's information change make the operation difficult to keep consistent. This PR created a danger zone like what's repository setting. It also moved organization's `rename` and `delete` operations to this zone. The original updating repository will not change the name any more. This is also a step to extract the `updaterepository` function completely. Before:   After:     --------- Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
		| @@ -9,9 +9,9 @@ const fomanticDropdownFn = $.fn.dropdown; | ||||
| // use our own `$().dropdown` function to patch Fomantic's dropdown module | ||||
| export function initAriaDropdownPatch() { | ||||
|   if ($.fn.dropdown === ariaDropdownFn) throw new Error('initAriaDropdownPatch could only be called once'); | ||||
|   $.fn.dropdown.settings.onAfterFiltered = onAfterFiltered; | ||||
|   $.fn.dropdown = ariaDropdownFn; | ||||
|   $.fn.fomanticExt.onResponseKeepSelectedItem = onResponseKeepSelectedItem; | ||||
|   $.fn.fomanticExt.onDropdownAfterFiltered = onDropdownAfterFiltered; | ||||
|   (ariaDropdownFn as FomanticInitFunction).settings = fomanticDropdownFn.settings; | ||||
| } | ||||
|  | ||||
| @@ -71,7 +71,7 @@ function updateSelectionLabel(label: HTMLElement) { | ||||
|   } | ||||
| } | ||||
|  | ||||
| function onAfterFiltered(this: any) { | ||||
| function onDropdownAfterFiltered(this: any) { | ||||
|   const $dropdown = $(this).closest('.ui.dropdown'); // "this" can be the "ui dropdown" or "<select>" | ||||
|   const hideEmptyDividers = $dropdown.dropdown('setting', 'hideDividers') === 'empty'; | ||||
|   const itemsMenu = $dropdown[0].querySelector('.scrolling.menu') || $dropdown[0].querySelector('.menu'); | ||||
|   | ||||
| @@ -1,5 +1,7 @@ | ||||
| import $ from 'jquery'; | ||||
| import type {FomanticInitFunction} from '../../types.ts'; | ||||
| import {queryElems} from '../../utils/dom.ts'; | ||||
| import {hideToastsFrom} from '../toast.ts'; | ||||
|  | ||||
| const fomanticModalFn = $.fn.modal; | ||||
|  | ||||
| @@ -7,6 +9,7 @@ const fomanticModalFn = $.fn.modal; | ||||
| export function initAriaModalPatch() { | ||||
|   if ($.fn.modal === ariaModalFn) throw new Error('initAriaModalPatch could only be called once'); | ||||
|   $.fn.modal = ariaModalFn; | ||||
|   $.fn.fomanticExt.onModalBeforeHidden = onModalBeforeHidden; | ||||
|   (ariaModalFn as FomanticInitFunction).settings = fomanticModalFn.settings; | ||||
| } | ||||
|  | ||||
| @@ -27,3 +30,10 @@ function ariaModalFn(this: any, ...args: Parameters<FomanticInitFunction>) { | ||||
|   } | ||||
|   return ret; | ||||
| } | ||||
|  | ||||
| function onModalBeforeHidden(this: any) { | ||||
|   const $modal = $(this); | ||||
|   const elModal = $modal[0]; | ||||
|   queryElems(elModal, 'form', (form: HTMLFormElement) => form.reset()); | ||||
|   hideToastsFrom(elModal.closest('.ui.dimmer') ?? document.body); | ||||
| } | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import {htmlEscape} from 'escape-goat'; | ||||
| import {svg} from '../svg.ts'; | ||||
| import {animateOnce, showElem} from '../utils/dom.ts'; | ||||
| import {animateOnce, queryElems, showElem} from '../utils/dom.ts'; | ||||
| import Toastify from 'toastify-js'; // don't use "async import", because when network error occurs, the "async import" also fails and nothing is shown | ||||
| import type {Intent} from '../types.ts'; | ||||
| import type {SvgName} from '../svg.ts'; | ||||
| @@ -37,17 +37,20 @@ const levels: ToastLevels = { | ||||
|  | ||||
| type ToastOpts = { | ||||
|   useHtmlBody?: boolean, | ||||
|   preventDuplicates?: boolean, | ||||
|   preventDuplicates?: boolean | string, | ||||
| } & Options; | ||||
|  | ||||
| type ToastifyElement = HTMLElement & {_giteaToastifyInstance?: Toast }; | ||||
|  | ||||
| // See https://github.com/apvarun/toastify-js#api for options | ||||
| function showToast(message: string, level: Intent, {gravity, position, duration, useHtmlBody, preventDuplicates = true, ...other}: ToastOpts = {}): Toast { | ||||
|   const body = useHtmlBody ? String(message) : htmlEscape(message); | ||||
|   const key = `${level}-${body}`; | ||||
|   const parent = document.querySelector('.ui.dimmer.active') ?? document.body; | ||||
|   const duplicateKey = preventDuplicates ? (preventDuplicates === true ? `${level}-${body}` : preventDuplicates) : ''; | ||||
|  | ||||
|   // prevent showing duplicate toasts with same level and message, and give a visual feedback for end users | ||||
|   // prevent showing duplicate toasts with the same level and message, and give visual feedback for end users | ||||
|   if (preventDuplicates) { | ||||
|     const toastEl = document.querySelector(`.toastify[data-toast-unique-key="${CSS.escape(key)}"]`); | ||||
|     const toastEl = parent.querySelector(`:scope > .toastify.on[data-toast-unique-key="${CSS.escape(duplicateKey)}"]`); | ||||
|     if (toastEl) { | ||||
|       const toastDupNumEl = toastEl.querySelector('.toast-duplicate-number'); | ||||
|       showElem(toastDupNumEl); | ||||
| @@ -59,6 +62,7 @@ function showToast(message: string, level: Intent, {gravity, position, duration, | ||||
|  | ||||
|   const {icon, background, duration: levelDuration} = levels[level ?? 'info']; | ||||
|   const toast = Toastify({ | ||||
|     selector: parent, | ||||
|     text: ` | ||||
|       <div class='toast-icon'>${svg(icon)}</div> | ||||
|       <div class='toast-body'><span class="toast-duplicate-number tw-hidden">1</span>${body}</div> | ||||
| @@ -74,7 +78,8 @@ function showToast(message: string, level: Intent, {gravity, position, duration, | ||||
|  | ||||
|   toast.showToast(); | ||||
|   toast.toastElement.querySelector('.toast-close').addEventListener('click', () => toast.hideToast()); | ||||
|   toast.toastElement.setAttribute('data-toast-unique-key', key); | ||||
|   toast.toastElement.setAttribute('data-toast-unique-key', duplicateKey); | ||||
|   (toast.toastElement as ToastifyElement)._giteaToastifyInstance = toast; | ||||
|   return toast; | ||||
| } | ||||
|  | ||||
| @@ -89,3 +94,15 @@ export function showWarningToast(message: string, opts?: ToastOpts): Toast { | ||||
| export function showErrorToast(message: string, opts?: ToastOpts): Toast { | ||||
|   return showToast(message, 'error', opts); | ||||
| } | ||||
|  | ||||
| function hideToastByElement(el: Element): void { | ||||
|   (el as ToastifyElement)?._giteaToastifyInstance?.hideToast(); | ||||
| } | ||||
|  | ||||
| export function hideToastsFrom(parent: Element): void { | ||||
|   queryElems(parent, ':scope > .toastify.on', hideToastByElement); | ||||
| } | ||||
|  | ||||
| export function hideToastsAll(): void { | ||||
|   queryElems(document, '.toastify.on', hideToastByElement); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user