11import React , { DetailedHTMLProps , FC , HTMLAttributes , useMemo , useState } from 'react'
22import {
3- AuthorMutation ,
4- AvalibleArrowBlock ,
5- AvalibleArrowLable ,
6- AvalibleLable ,
7- AvalibleLableBlock ,
8- AvalibleMutations ,
9- ButtonBack ,
10- ButtonListBlock ,
11- ButtonMutation ,
12- ImageBlock ,
13- InputBlock ,
14- InputIconWrapper ,
15- InputInfoWrapper ,
16- InputMutation ,
17- ListMutations ,
18- MutationsList ,
19- MutationsListWrapper ,
203 OpenList ,
214 OpenListDefault ,
225 SelectedMutationBlock ,
@@ -27,66 +10,30 @@ import {
2710 WrapperDropdown ,
2811 SpanStyled ,
2912} from '../assets/styles-dropdown'
30- import {
31- AvailableIcon ,
32- Back ,
33- IconDropdown ,
34- Mutate ,
35- StarMutationList ,
36- StarMutationListDefault ,
37- StarSelectMutation ,
38- StarSelectMutationDefault ,
39- } from '../assets/vectors'
40-
41- import { useDeleteLocalMutation , useMutableWeb } from '@mweb/engine'
42- import { EntitySourceType , MutationWithSettings } from '@mweb/backend'
43- import defaultIcon from '../assets/images/default.svg'
44- import { Image } from './image'
13+ import { IconDropdown , StarSelectMutation , StarSelectMutationDefault } from '../assets/vectors'
14+ import { useMutableWeb } from '@mweb/engine'
15+ import { EntitySourceType } from '@mweb/backend'
4516import { Badge } from './badge'
46- import { ArrowDownOutlined , DeleteOutlined , EyeFilled , EyeInvisibleFilled } from '@ant-design/icons'
47- import styled from 'styled-components'
48- import { ModalDelete } from './modal-delete'
17+ import { EyeFilled , EyeInvisibleFilled } from '@ant-design/icons'
4918import { MutationVersionDropdown } from './mutation-version-dropdown'
5019
51- const ModalConfirmBackground = styled . div `
52- position: absolute;
53- display: flex;
54- justify-content: center;
55- align-items: center;
56- width: 100%;
57- height: 100%;
58- min-height: 190px;
59- top: 0;
60- left: 0;
61- background-color: rgba(255, 255, 255, 0.7);
62- border-radius: inherit;
63- z-index: 1;
64- `
65-
6620export type DropdownProps = DetailedHTMLProps < HTMLAttributes < HTMLDivElement > , HTMLDivElement > & {
6721 isVisible : boolean
6822 onVisibilityChange : ( visible : boolean ) => void
6923 onMutateButtonClick : ( ) => void
7024}
7125
72- export const Dropdown : FC < DropdownProps > = ( {
73- isVisible,
74- onVisibilityChange,
75- onMutateButtonClick,
76- } : DropdownProps ) => {
26+ export const Dropdown : FC < DropdownProps > = ( { isVisible, onVisibilityChange } : DropdownProps ) => {
7727 const {
7828 mutations,
7929 selectedMutation,
8030 favoriteMutationId,
8131 setFavoriteMutation,
82- switchMutation,
8332 switchPreferredSource,
84- getPreferredSource,
85- removeMutationFromRecents,
8633 } = useMutableWeb ( )
8734
88- const { deleteLocalMutation } = useDeleteLocalMutation ( )
89-
35+ // ToDo: think about this
36+ // The state is here to prevent closing dropdown when mutation changed
9037 const [ expandedVersion , setExpandedVersion ] = useState ( false )
9138 const toggleDropdown = ( ) => setExpandedVersion ( ! expandedVersion )
9239
@@ -109,26 +56,6 @@ export const Dropdown: FC<DropdownProps> = ({
10956 [ mutations ]
11057 )
11158
112- const [ isAccordeonExpanded , setIsAccordeonExpanded ] = useState (
113- Object . keys ( recentlyUsedMutations ) . length === 0
114- )
115- const [ mutationIdToDelete , setMutationIdToDelete ] = useState < string | null > ( null )
116-
117- const unusedMutations = useMemo (
118- ( ) =>
119- Object . groupBy (
120- mutations . filter ( ( mut ) => ! mut . settings . lastUsage ) ,
121- ( mut ) => mut . id
122- ) ,
123- [ mutations ]
124- )
125-
126- const handleMutationClick = ( mutationId : string ) => {
127- onVisibilityChange ( false )
128- setExpandedVersion ( false )
129- switchMutation ( mutationId )
130- }
131-
13259 const handleSwitchSourceClick : React . MouseEventHandler < HTMLSpanElement > = ( e ) => {
13360 e . stopPropagation ( ) // do not open dropdown
13461
@@ -142,31 +69,10 @@ export const Dropdown: FC<DropdownProps> = ({
14269 switchPreferredSource ( selectedMutation . id , source )
14370 }
14471
145- // todo: mock
146- const handleAccordeonClick = ( ) => {
147- setIsAccordeonExpanded ( ( val ) => ! val )
148- }
149-
150- const handleMutateButtonClick = ( ) => {
151- setExpandedVersion ( false )
152- onVisibilityChange ( false )
153- onMutateButtonClick ( )
154- }
155-
15672 const handleFavoriteButtonClick = ( mutationId : string ) => {
15773 setFavoriteMutation ( mutationId === favoriteMutationId ? null : mutationId )
15874 }
15975
160- const handleOriginalButtonClick = async ( ) => {
161- setExpandedVersion ( false )
162- onVisibilityChange ( false )
163- switchMutation ( null )
164- }
165-
166- const handleRemoveFromRecentlyUsedClick = async ( mut : MutationWithSettings ) => {
167- removeMutationFromRecents ( mut . id )
168- }
169-
17076 return (
17177 < WrapperDropdown >
17278 { selectedMutation && selectedMutation . metadata ? (
@@ -240,169 +146,6 @@ export const Dropdown: FC<DropdownProps> = ({
240146 </ OpenListDefault >
241147 ) }
242148 </ SelectedMutationBlock >
243-
244- { isVisible && (
245- < MutationsList >
246- < ButtonListBlock >
247- < ButtonBack onClick = { handleOriginalButtonClick } > { < Back /> } to Original</ ButtonBack >
248- < ButtonMutation
249- onClick = { handleMutateButtonClick }
250- data-testid = "mutate-button"
251- data-mweb-context-type = "notch"
252- data-mweb-context-parsed = { JSON . stringify ( { id : 'mutate-button' } ) }
253- data-mweb-context-level = "system"
254- >
255- Mutate { < Mutate /> }
256- < div data-mweb-insertion-point = "hidden" style = { { display : 'none' } } > </ div >
257- </ ButtonMutation >
258- </ ButtonListBlock >
259- < MutationsListWrapper >
260- { Object . keys ( recentlyUsedMutations ) . length > 0 ? (
261- < ListMutations
262- data-testid = "recently-used-mutations"
263- data-mweb-context-type = "notch"
264- data-mweb-context-parsed = { JSON . stringify ( { id : 'recently-used-mutations' } ) }
265- data-mweb-context-level = "system"
266- >
267- { Object . values ( recentlyUsedMutations ) . map ( ( muts ) => {
268- if ( ! muts || ! muts . length ) return null
269- const recentlyUsedSource = getPreferredSource ( muts [ 0 ] . id )
270- const mut =
271- muts . find (
272- ( mut ) => mut . source === ( recentlyUsedSource ?? EntitySourceType . Local )
273- ) ?? muts [ 0 ]
274- return (
275- < InputBlock key = { mut . id } isActive = { mut . id === selectedMutation ?. id } >
276- < ImageBlock >
277- < Image image = { mut . metadata . image } fallbackUrl = { defaultIcon } />
278- </ ImageBlock >
279- < InputInfoWrapper onClick = { ( ) => handleMutationClick ( mut . id ) } >
280- { /* todo: mocked classname */ }
281- < InputMutation
282- className = { mut . id === selectedMutation ?. id ? 'inputMutationSelected' : '' }
283- >
284- { mut . metadata ? mut . metadata . name : '' } { ' ' }
285- { recentlyUsedMutations [ mut . id ] ?. length === 2 ? (
286- mut . source === EntitySourceType . Local ? (
287- < Badge margin = "0 0 0 4px" text = "local on" theme = "blue" />
288- ) : (
289- < Badge margin = "0 0 0 4px" text = "local off" theme = "yellow" />
290- )
291- ) : mut . source === EntitySourceType . Local ? (
292- < Badge margin = "0 0 0 4px" text = "local" theme = "blue" />
293- ) : null }
294- </ InputMutation >
295- { /* todo: mocked classname */ }
296- { mut . authorId ? (
297- < AuthorMutation
298- className = {
299- mut . id === selectedMutation ?. id && mut . id === favoriteMutationId
300- ? 'authorMutationSelected'
301- : ''
302- }
303- >
304- by { mut . authorId }
305- </ AuthorMutation >
306- ) : null }
307- </ InputInfoWrapper >
308- { /* todo: mocked */ }
309-
310- { mut . id === favoriteMutationId ? (
311- < InputIconWrapper onClick = { ( ) => handleFavoriteButtonClick ( mut . id ) } >
312- < StarMutationList />
313- </ InputIconWrapper >
314- ) : mut . id === selectedMutation ?. id ? (
315- < InputIconWrapper onClick = { ( ) => handleFavoriteButtonClick ( mut . id ) } >
316- < StarMutationListDefault />
317- </ InputIconWrapper >
318- ) : null }
319-
320- { mut . source === EntitySourceType . Local ? (
321- < InputIconWrapper onClick = { ( ) => setMutationIdToDelete ( mut . id ) } >
322- < DeleteOutlined />
323- </ InputIconWrapper >
324- ) : mut . id !== selectedMutation ?. id &&
325- mut . id !== favoriteMutationId &&
326- ! getPreferredSource ( mut . id ) ? (
327- < InputIconWrapper onClick = { ( ) => handleRemoveFromRecentlyUsedClick ( mut ) } >
328- < ArrowDownOutlined />
329- </ InputIconWrapper >
330- ) : null }
331- </ InputBlock >
332- )
333- } ) }
334- < div
335- data-mweb-insertion-point = "recently-used-mutations"
336- style = { { display : 'none' } }
337- > </ div >
338- </ ListMutations >
339- ) : null }
340-
341- { Object . keys ( unusedMutations ) . length > 0 ? (
342- < AvalibleMutations >
343- < AvalibleLableBlock
344- onClick = { handleAccordeonClick }
345- data-mweb-context-type = "notch"
346- data-mweb-context-parsed = { JSON . stringify ( { id : 'unused-mutations-title' } ) }
347- data-mweb-context-level = "system"
348- >
349- < AvalibleLable > available</ AvalibleLable >
350- { /* todo: mock */ }
351- < AvalibleArrowBlock className = { isAccordeonExpanded ? 'iconRotate' : '' } >
352- < AvalibleArrowLable >
353- { Object . keys ( unusedMutations ) . length } mutations
354- </ AvalibleArrowLable >
355- < AvailableIcon />
356- </ AvalibleArrowBlock >
357- < div data-mweb-insertion-point = "hidden" style = { { display : 'none' } } > </ div >
358- </ AvalibleLableBlock >
359-
360- { isAccordeonExpanded ? (
361- < div data-testid = "unused-mutations" >
362- { Object . values ( unusedMutations ) . map ( ( muts ) => {
363- if ( ! muts ) return null
364- const [ mut ] = muts
365-
366- return (
367- < InputBlock
368- key = { mut . id }
369- isActive = { mut . id === selectedMutation ?. id }
370- onClick = { ( ) => handleMutationClick ( mut . id ) }
371- className = "avalibleMutationsInput"
372- >
373- < ImageBlock >
374- < Image image = { mut . metadata . image } fallbackUrl = { defaultIcon } />
375- </ ImageBlock >
376- < InputInfoWrapper >
377- < InputMutation > { mut . metadata ? mut . metadata . name : '' } </ InputMutation >
378- { mut . authorId ? (
379- < AuthorMutation > by { mut . authorId } </ AuthorMutation >
380- ) : null }
381- </ InputInfoWrapper >
382- </ InputBlock >
383- )
384- } ) }
385- </ div >
386- ) : null }
387- </ AvalibleMutations >
388- ) : null }
389- </ MutationsListWrapper >
390-
391- { mutationIdToDelete && (
392- < ModalConfirmBackground >
393- < ModalDelete
394- onAction = { async ( ) => {
395- await deleteLocalMutation ( mutationIdToDelete )
396- if ( mutationIdToDelete === favoriteMutationId )
397- handleFavoriteButtonClick ( mutationIdToDelete )
398- setMutationIdToDelete ( null )
399- } }
400- onCloseCurrent = { ( ) => setMutationIdToDelete ( null ) }
401- />
402- </ ModalConfirmBackground >
403- ) }
404- </ MutationsList >
405- ) }
406149 </ WrapperDropdown >
407150 )
408151}
0 commit comments