|
| 1 | +/* eslint-disable react-refresh/only-export-components */ |
1 | 2 | import $ from 'jquery'; |
2 | 3 | import React from 'react'; |
3 | 4 | import { i18n, tpl } from 'vj/utils'; |
| 5 | +import DomainSelectAutoComplete from '../autocomplete/components/DomainSelectAutoComplete'; |
| 6 | +import UserSelectAutoComplete from '../autocomplete/components/UserSelectAutoComplete'; |
4 | 7 | import DomDialog, { DialogOptions } from './DomDialog'; |
5 | 8 |
|
6 | 9 | export class Dialog { |
@@ -108,7 +111,96 @@ export class ConfirmDialog extends Dialog { |
108 | 111 | } |
109 | 112 | } |
110 | 113 |
|
| 114 | +export interface Field { |
| 115 | + type: 'text' | 'checkbox' | 'user' | 'domain'; |
| 116 | + placeholder?: string; |
| 117 | + label?: string; |
| 118 | + autofocus?: boolean; |
| 119 | + required?: boolean; |
| 120 | + default?: string; |
| 121 | +} |
| 122 | + |
| 123 | +export async function prompt<T extends string>(title: string, fields: Record<T, Field>) { |
| 124 | + let valueCache: Record<T, string | number | boolean> = {} as any; |
| 125 | + const defaultValues = Object.fromEntries(Object.entries(fields) |
| 126 | + .map(([name, field]: [T, Field]) => [name, field.default || ''])) as Record<T, string | number | boolean>; |
| 127 | + |
| 128 | + const Component = () => { |
| 129 | + const [values, setValues] = React.useState(defaultValues); |
| 130 | + |
| 131 | + React.useEffect(() => { |
| 132 | + valueCache = values; |
| 133 | + }, [values]); |
| 134 | + |
| 135 | + return <div style={{ display: 'none' }}> |
| 136 | + <div className="row"><div className="columns"> |
| 137 | + <h1>{title}</h1> |
| 138 | + </div></div> |
| 139 | + {Object.entries(fields).map(([name, field]: [string, Field]) => <div className="row" key={name}> |
| 140 | + <div className="columns"> |
| 141 | + {['text', 'user', 'domain'].includes(field.type) && <label> |
| 142 | + {field.label} |
| 143 | + <div className="textbox-container"> |
| 144 | + {field.type === 'text' |
| 145 | + ? <input |
| 146 | + type="text" className="textbox" data-autofocus={field.autofocus} |
| 147 | + defaultValue={field.default} |
| 148 | + onChange={(e) => setValues({ ...values, [name]: e.target.value })} |
| 149 | + /> |
| 150 | + : field.type === 'user' |
| 151 | + ? <UserSelectAutoComplete |
| 152 | + data-autofocus={field.autofocus} selectedKeys={values[name] ? [values[name]] : []} |
| 153 | + onChange={(e) => setValues({ ...values, [name]: e })} |
| 154 | + /> |
| 155 | + : <DomainSelectAutoComplete |
| 156 | + data-autofocus={field.autofocus} selectedKeys={values[name] ? [values[name]] : []} |
| 157 | + onChange={(e) => setValues({ ...values, [name]: e })} |
| 158 | + />} |
| 159 | + </div> |
| 160 | + </label>} |
| 161 | + {field.type === 'checkbox' && <label className="checkbox"> |
| 162 | + <input type="checkbox" |
| 163 | + defaultChecked={field.default === 'true'} |
| 164 | + onChange={(e) => setValues({ ...values, [name]: !!e.target.checked })} |
| 165 | + /> |
| 166 | + {field.label} |
| 167 | + </label>} |
| 168 | + </div> |
| 169 | + </div>)} |
| 170 | + </div>; |
| 171 | + }; |
| 172 | + const res = await new Dialog({ |
| 173 | + $body: $(tpl(<Component />, true)), |
| 174 | + onDispatch(action) { |
| 175 | + if (action === 'ok') { |
| 176 | + for (const [name, field] of Object.entries(fields)) { |
| 177 | + if ((field as any).required && !valueCache[name]) return false; |
| 178 | + } |
| 179 | + } |
| 180 | + return true; |
| 181 | + }, |
| 182 | + }).open(); |
| 183 | + if (res !== 'ok') return null; |
| 184 | + return valueCache; |
| 185 | +} |
| 186 | + |
| 187 | +export async function confirm(text: string) { |
| 188 | + const res = await new ConfirmDialog({ |
| 189 | + $body: tpl.typoMsg(text), |
| 190 | + }).open(); |
| 191 | + return res === 'yes'; |
| 192 | +} |
| 193 | + |
| 194 | +export async function alert(text: string) { |
| 195 | + return await new InfoDialog({ |
| 196 | + $body: tpl.typoMsg(text), |
| 197 | + }).open(); |
| 198 | +} |
| 199 | + |
111 | 200 | window.Hydro.components.Dialog = Dialog; |
112 | 201 | window.Hydro.components.InfoDialog = InfoDialog; |
113 | 202 | window.Hydro.components.ActionDialog = ActionDialog; |
114 | 203 | window.Hydro.components.ConfirmDialog = ConfirmDialog; |
| 204 | +window.Hydro.components.prompt = prompt; |
| 205 | +window.Hydro.components.confirm = confirm; |
| 206 | +window.Hydro.components.alert = alert; |
0 commit comments