/ packages / ui / src / services / DialogService.tsx
DialogService.tsx
  1  import { Button, Card, CardActions, CardContent, CardHeader } from '@mui/material';
  2  import { computed, Signal } from '@preact/signals-react';
  3  import { inject, injectable } from 'inversify';
  4  import { IDialogOptions, IDialogService, IFileDialogOptions, type IPopupService, IPopupServiceSymbol, type ITranslationService, ITranslationServiceSymbol } from 'ipmc-interfaces';
  5  import React from 'react';
  6  import { FileInput, TextInput } from '../components/atoms';
  7  
  8  @injectable()
  9  export class DialogService implements IDialogService {
 10  	constructor(
 11  		@inject(IPopupServiceSymbol) private popupService: IPopupService,
 12  		@inject(ITranslationServiceSymbol) private translationService: ITranslationService,
 13  	) { }
 14  
 15  	boolDialog(options: IDialogOptions): Promise<boolean> {
 16  		let ok = false;
 17  		return this.popupService.show({
 18  			closeOnOutsideClick: false,
 19  			content: (close) => (
 20  				<Card>
 21  					<CardHeader title={options.title} />
 22  					<CardContent>
 23  					</CardContent>
 24  					<CardActions>
 25  						<Button
 26  							onClick={close}
 27  						>{options.cancelButtonText ?? this.translationService.translate('Cancel')}</Button>
 28  						<Button
 29  							onClick={() => {
 30  								ok = true;
 31  								close();
 32  							}}
 33  						>{options.okButtonText ?? this.translationService.translate('Ok')}</Button>
 34  					</CardActions>
 35  				</Card>
 36  			)
 37  		})
 38  			.then(() => {
 39  				return ok;
 40  			});
 41  	}
 42  
 43  	stringDialog(options: IDialogOptions): Promise<string> {
 44  		const signal = new Signal<string>(); let closeDialog = () => { };
 45  		return new Promise<string>((resolve, reject) => {
 46  			void this.popupService.show({
 47  				closeOnOutsideClick: false,
 48  				content: (close) => {
 49  					closeDialog = close;
 50  					return (
 51  						<Card>
 52  							<CardHeader title={options.title} />
 53  							<CardContent>
 54  								<TextInput
 55  									value={signal}
 56  								/>
 57  							</CardContent>
 58  							<CardActions>
 59  								<Button
 60  									onClick={() => reject()}
 61  								>
 62  									{options.cancelButtonText ?? this.translationService.translate('Cancel')}
 63  								</Button>
 64  								{computed(() => (
 65  									<Button
 66  										onClick={() => resolve(signal.value)}
 67  										disabled={signal.value.length <= 0}
 68  									>
 69  										{options.okButtonText ?? this.translationService.translate('Ok')}
 70  									</Button>
 71  								))}
 72  							</CardActions>
 73  						</Card>
 74  					);
 75  				}
 76  			});
 77  		})
 78  			.finally(() => {
 79  				closeDialog();
 80  			});
 81  	}
 82  
 83  	fileDialog(options: IFileDialogOptions): Promise<any> {
 84  		const signal = new Signal<File[]>([]);
 85  		let closeDialog = () => { };
 86  		return new Promise((resolve, reject) => {
 87  			void this.popupService.show({
 88  				closeOnOutsideClick: false,
 89  				content: (close) => {
 90  					closeDialog = close;
 91  					return (
 92  						<Card>
 93  							<CardHeader title={options.title} />
 94  							<CardContent>
 95  								<FileInput
 96  									accept={options.accept}
 97  									value={signal}
 98  								/>
 99  							</CardContent>
100  							<CardActions>
101  								<Button
102  									onClick={() => reject()}
103  								>
104  									{options.cancelButtonText ?? this.translationService.translate('Cancel')}
105  								</Button>
106  								{computed(() => (
107  									<Button
108  										onClick={() => resolve(signal.value)}
109  										disabled={signal.value.length <= 0}
110  									>
111  										{options.okButtonText ?? this.translationService.translate('Ok')}
112  									</Button>
113  								))}
114  							</CardActions>
115  						</Card>
116  					);
117  				}
118  			});
119  		})
120  			.finally(() => {
121  				closeDialog();
122  			});
123  	}
124  }