admin/plugins: animation on stop button
Massimo Melina committed
Nov 29, 2024 at 20:27 UTC
5717e6fc0a2de5a66332e3cccb6b55130647bd41
3 files changed
+10
-10
admin/src/InstalledPlugins.ts
+2
-4
@@ -76,10 +76,8 @@ export default function InstalledPlugins({ updates }: { updates?: true }) {
76
'aria-label': `Stop ${id}`,
77
size,
78
color: 'success',
79
- async onClick() {
80
- await apiCall('stop_plugin', { id })
81
- toast("Plugin stopped", h(StopCircle, { color: 'warning' }))
82
- }
79
+ doneAnimation: true,
80
+ onClick: () => apiCall('stop_plugin', { id }),
81
} : {
82
icon: PlayCircle,
83
title: `Start ${id}`,
admin/src/index.scss
+1
-1
@@ -68,7 +68,7 @@ h2.MuiDialogTitle-root { /* less padding */
68
@keyframes animate-dash { to { background-position: 20px 0; } }
69
70
@keyframes success {
71
- 50% { transform: scale(1.5); color: var(--success); }
71
+ 50% { transform: scale(1.3); color: var(--success); }
72
100% { transform: inherit; color: inherit; }
73
}
74
admin/src/mui.ts
+7
-5
@@ -107,6 +107,7 @@ export function propsForModifiedValues(modified: boolean | undefined) {
107
return modified ? { sx: { outline: '2px solid' } } : undefined
108
}
109
110
+// use ref.pass as prop
111
function useRefPass<T=unknown>(forwarded: ForwardedRef<any>) {
112
const ref = useRef<T | null>(null)
113
return Object.assign(ref, {
@@ -117,7 +118,6 @@ function useRefPass<T=unknown>(forwarded: ForwardedRef<any>) {
118
else if (forwarded)
119
forwarded.current = el
120
},
120
-
121
})
122
}
123
@@ -134,13 +134,15 @@ export interface BtnProps extends Omit<ButtonProps & IconButtonProps,'disabled'|
134
confirm?: boolean | ReactNode
135
labelIf?: Breakpoint | boolean
136
doneMessage?: boolean | string // displayed only if the result of onClick !== false
137
+ doneAnimation?: boolean
138
tooltipProps?: Partial<TooltipProps>
139
modified?: boolean
140
loading?: boolean
141
onClick?: (...args: Parameters<NonNullable<ButtonProps['onClick']>>) => Promisable<any>
142
}
143
143
-export const Btn = forwardRef(({ icon, title, onClick, disabled, progress, link, tooltipProps, confirm, doneMessage, labelIf, children, modified, loading, ...rest }: BtnProps, forwarded: ForwardedRef<HTMLButtonElement>) => {
144
+export const Btn = forwardRef(({ icon, title, onClick, disabled, progress, link, tooltipProps, confirm, doneMessage,
145
+ doneAnimation, labelIf, children, modified, loading, ...rest }: BtnProps, forwarded: ForwardedRef<HTMLButtonElement>) => {
146
const [loadingState, setLoadingState] = useStateMounted(false)
147
if (typeof disabled === 'string')
148
title = disabled
@@ -152,7 +154,7 @@ export const Btn = forwardRef(({ icon, title, onClick, disabled, progress, link,
154
title = children
155
const ref = useRefPass<HTMLButtonElement>(forwarded)
156
const common = _.merge(propsForModifiedValues(modified), {
155
- ref,
157
+ ref: ref.pass,
158
disabled,
159
'aria-hidden': disabled,
160
async onClick(...args: any[]) {
@@ -161,7 +163,7 @@ export const Btn = forwardRef(({ icon, title, onClick, disabled, progress, link,
163
const ret = onClick?.apply(this, args as any)
164
if (ret && ret instanceof Promise) {
165
setLoadingState(true)
164
- ret.then(x => x !== false && execDoneMessage(doneMessage), alertDialog)
166
+ ret.then(x => x !== false && execDoneMessage(doneMessage, doneAnimation && ref.current), alertDialog)
167
.finally(()=> setLoadingState(false))
168
}
169
},
@@ -194,7 +196,7 @@ export const Btn = forwardRef(({ icon, title, onClick, disabled, progress, link,
196
return ret
197
})
198
197
-function execDoneMessage(msg: boolean | string | undefined, el?: HTMLElement | null) {
199
+function execDoneMessage(msg: boolean | string | undefined, el?: HTMLElement | null | false) {
200
if (el)
201
restartAnimation(el, 'success .5s')
202
if (msg)