Skip to content

Commit 11565ee

Browse files
Lisofffaalsakhaev
andauthored
feat: copy mutation selector to overlay (DAP-4798) (#38)
* feat: replace multitable panel to shared companents * fix: update styles multitable panel * fix: update styles profile * fix: update styles overlay * Revert "fix: update styles overlay" This reverts commit 962b893. * fix: update multitable panel to overlay * fix: update after review * fix: update build * fix: update logo path * fix: after rev * fix: update styles * fix: changed styles * fix: update styles --------- Co-authored-by: Alexander Sakhaev <alsakhaev@gmail.com>
1 parent 56530bc commit 11565ee

34 files changed

+3693
-346
lines changed
Lines changed: 7 additions & 264 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,5 @@
11
import React, { DetailedHTMLProps, FC, HTMLAttributes, useMemo, useState } from 'react'
22
import {
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'
4516
import { 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'
4918
import { 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-
6620
export 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
}

apps/extension/src/contentscript/multitable-panel/multitable-panel.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,13 @@ export const MultitablePanel: FC<MultitablePanelProps> = ({ eventEmitter }) => {
172172

173173
return (
174174
<>
175-
<MutableOverlayContainer notchRef={notchRef} networkId={config.networkId as NearNetworkId} />
175+
<MutableOverlayContainer
176+
notchRef={notchRef}
177+
networkId={config.networkId as NearNetworkId}
178+
setOpen={setIsDropdownVisible}
179+
open={isDropdownVisible}
180+
handleMutateButtonClick={handleMutateButtonClick}
181+
/>
176182
<WrapperPanel $isAnimated={!isDragging} data-testid="mutation-panel">
177183
{isModalOpen ? (
178184
<MutationEditorModal

apps/extension/src/contentscript/multitable-panel/mutable-overlay-container.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useMutableWeb, useMutationApp } from '@mweb/engine'
22
import { AppInstanceWithSettings } from '@mweb/backend'
33
import { AppSwitcher, MiniOverlay } from '@mweb/shared-components'
4-
import React from 'react'
4+
import React, { useState } from 'react'
55
import Background from '../../common/background'
66
import { NearNetworkId } from '../../common/networks'
77

@@ -15,21 +15,30 @@ function AppSwitcherContainer({ app }: { app: AppInstanceWithSettings }) {
1515
function MutableOverlayContainer({
1616
notchRef,
1717
networkId,
18+
setOpen,
19+
open,
20+
handleMutateButtonClick,
1821
}: {
1922
notchRef: React.RefObject<HTMLDivElement>
2023
networkId: NearNetworkId
24+
setOpen: React.Dispatch<React.SetStateAction<boolean>>
25+
open: boolean
26+
handleMutateButtonClick: () => void
2127
}) {
2228
const { selectedMutation, mutationApps } = useMutableWeb()
2329
const trackingRefs = new Set<React.RefObject<HTMLDivElement>>()
2430
trackingRefs.add(notchRef)
2531
return (
2632
<MiniOverlay
33+
setOpen={setOpen}
34+
open={open}
2735
baseMutation={selectedMutation}
2836
mutationApps={mutationApps}
2937
nearNetwork={networkId}
3038
connectWallet={Background.connectWallet}
3139
disconnectWallet={Background.disconnectWallet}
3240
trackingRefs={trackingRefs}
41+
handleMutateButtonClick={handleMutateButtonClick}
3342
>
3443
<>
3544
{mutationApps.map((app) => (

libs/engine/src/custom-elements/dapplet-overlay.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ const ModalBackdrop = styled.div`
1616
width: 100%;
1717
height: 100%;
1818
overflow-x: hidden;
19-
overflow-y: auto;
2019
outline: 0;
2120
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
2221
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;

libs/shared-components/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"@uiw/codemirror-extensions-langs": "^4.23.3",
3434
"@uiw/react-codemirror": "^4.23.3",
3535
"antd": "^5.18.3",
36+
"@ant-design/icons": "5.5.1",
3637
"codemirror": "^6.0.1",
3738
"ethereum-blockies-base64": "^1.0.2",
3839
"json-stringify-deterministic": "^1.0.12",

0 commit comments

Comments
 (0)