-
Notifications
You must be signed in to change notification settings - Fork 235
fix: Disable logo update button when no file is selected #10587
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev/7.4.x
Are you sure you want to change the base?
Changes from all commits
e95b38b
7957f36
5178bed
27f2c8c
a64101e
2959b16
a0e936d
746887d
38419dc
6494810
1e65d48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,15 +28,22 @@ const CustomizeLogoSetting = (): JSX.Element => { | |
| const [isImageCropModalShow, setIsImageCropModalShow] = useState<boolean>(false); | ||
| const [isDefaultLogoSelected, setIsDefaultLogoSelected] = useState<boolean>(isDefaultLogo ?? true); | ||
| const [retrieveError, setRetrieveError] = useState<any>(); | ||
| const [isImageCropped, setIsImageCropped] = useState<boolean>(false); | ||
| const [fileInputKey, setFileInputKey] = useState<string>(Date.now().toString()); | ||
|
|
||
| const onSelectFile = useCallback((e: React.ChangeEvent<HTMLInputElement>) => { | ||
| if (e.target.files != null && e.target.files.length > 0) { | ||
| const files = e.target.files; | ||
| const hasFile = files != null && files.length > 0; | ||
|
|
||
| setIsImageCropped(false); | ||
|
|
||
| if (hasFile) { | ||
| const reader = new FileReader(); | ||
| reader.addEventListener('load', () => setUploadLogoSrc(reader.result)); | ||
| reader.readAsDataURL(e.target.files[0]); | ||
| reader.readAsDataURL(files[0]); | ||
| setIsImageCropModalShow(true); | ||
| } | ||
| }, []); | ||
| }, [setUploadLogoSrc, setIsImageCropModalShow, setIsImageCropped]); | ||
|
|
||
| const onClickSubmit = useCallback(async () => { | ||
| try { | ||
|
|
@@ -48,25 +55,34 @@ const CustomizeLogoSetting = (): JSX.Element => { | |
| } | ||
| }, [t, isDefaultLogoSelected]); | ||
|
|
||
| const resetFileInput = useCallback(() => { | ||
| setFileInputKey(Date.now().toString()); | ||
| }, []); | ||
|
|
||
| const onClickDeleteBtn = useCallback(async () => { | ||
| try { | ||
| await apiv3Delete('/customize-setting/delete-brand-logo'); | ||
| setIsCustomizedLogoUploaded(false); | ||
| toastSuccess(t('toaster.update_successed', { target: t('admin:customize_settings.current_logo'), ns: 'commons' })); | ||
| setUploadLogoSrc(null); | ||
| setIsImageCropped(false); | ||
| setIsImageCropModalShow(false); | ||
| resetFileInput(); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| } | ||
| catch (err) { | ||
| toastError(err); | ||
| setRetrieveError(err); | ||
| throw new Error('Failed to delete logo'); | ||
| } | ||
| }, [setIsCustomizedLogoUploaded, t]); | ||
|
|
||
| }, [setIsCustomizedLogoUploaded, t, setUploadLogoSrc, setIsImageCropped, setIsImageCropModalShow, resetFileInput, setRetrieveError]); | ||
|
|
||
| const processImageCompletedHandler = useCallback(async (croppedImage) => { | ||
| try { | ||
| const formData = new FormData(); | ||
| formData.append('file', croppedImage); | ||
| await apiv3PostForm('/customize-setting/upload-brand-logo', formData); | ||
| setIsImageCropModalShow(false); | ||
| setIsImageCropped(true); | ||
| setIsCustomizedLogoUploaded(true); | ||
| toastSuccess(t('toaster.update_successed', { target: t('admin:customize_settings.current_logo'), ns: 'commons' })); | ||
| } | ||
|
|
@@ -75,7 +91,8 @@ const CustomizeLogoSetting = (): JSX.Element => { | |
| setRetrieveError(err); | ||
| throw new Error('Failed to upload brand logo'); | ||
| } | ||
| }, [setIsCustomizedLogoUploaded, t]); | ||
| }, [setIsCustomizedLogoUploaded, t, setIsImageCropped, setIsImageCropModalShow, setRetrieveError]); | ||
|
|
||
|
|
||
| return ( | ||
| <React.Fragment> | ||
|
|
@@ -142,20 +159,36 @@ const CustomizeLogoSetting = (): JSX.Element => { | |
| {t('admin:customize_settings.upload_new_logo')} | ||
| </label> | ||
| <div className="col-sm-8 col-12"> | ||
| <input type="file" onChange={onSelectFile} name="brandLogo" accept="image/*" /> | ||
| <input | ||
| type="file" | ||
| key={fileInputKey} | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. この部分でinputタグのkeyに呼び出した現在のミリ秒の文字列を代入しています。この処理により毎回 |
||
| onChange={onSelectFile} | ||
| name="brandLogo" | ||
| accept="image/*" | ||
| /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <AdminUpdateButtonRow onClick={onClickSubmit} disabled={retrieveError != null} /> | ||
| <AdminUpdateButtonRow | ||
| onClick={onClickSubmit} | ||
| disabled={retrieveError != null | ||
| || (!isDefaultLogoSelected && uploadLogoSrc == null && !isCustomizedLogoUploaded)} | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| /> | ||
| </div> | ||
| </div> | ||
| </div> | ||
|
|
||
| <ImageCropModal | ||
| isShow={isImageCropModalShow} | ||
| src={uploadLogoSrc} | ||
| onModalClose={() => setIsImageCropModalShow(false)} | ||
| onModalClose={() => { | ||
| if (!isImageCropped) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. onImageProcessCompleted というメソッドが ImageCropModal 側に提供されているみたいですが、ためしてみました? state が増えると実装が複雑になるので増やすのは慎重にしたいです |
||
| resetFileInput(); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. jsx の部分にロジックがあると見にくいので closeImageCropModalHandler みたいなメソッドを作ってそれを渡すようにしてください |
||
| setUploadLogoSrc(null); | ||
| } | ||
| setIsImageCropModalShow(false); | ||
| }} | ||
| onImageProcessCompleted={processImageCompletedHandler} | ||
| isCircular={false} | ||
| showCropOption={false} | ||
|
|
||


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ここで呼び出した瞬間のミリ秒時間を引数として入力することによって呼び出したら必ず異なるkeyがinput タグに入力されることになります。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
key をリセットするやり方がちょっとトリッキーなので useRef 使って実装してみてください。
例