diff --git a/apps/extension/src/contentscript/multitable-panel/multitable-panel.tsx b/apps/extension/src/contentscript/multitable-panel/multitable-panel.tsx
index 683e83cc..7800280e 100644
--- a/apps/extension/src/contentscript/multitable-panel/multitable-panel.tsx
+++ b/apps/extension/src/contentscript/multitable-panel/multitable-panel.tsx
@@ -2,12 +2,8 @@ import { EntitySourceType } from '@mweb/backend'
import { useMutableWeb } from '@mweb/engine'
import { EventEmitter as NEventEmitter } from 'events'
import React, { FC, useEffect, useRef, useState } from 'react'
-import Draggable from 'react-draggable'
import styled from 'styled-components'
import { NearNetworkId } from '../../common/networks'
-import { getIsPanelUnpinned, removePanelUnpinnedFlag, setPanelUnpinnedFlag } from '../storage'
-import { PinOutlineIcon, PinSolidIcon } from './assets/vectors'
-import { Dropdown } from './components/dropdown'
import { MutationEditorModal } from './components/mutation-editor-modal'
import MutableOverlayContainer from './mutable-overlay-container'
@@ -54,62 +50,6 @@ const WrapperPanel = styled.div<{ $isAnimated?: boolean }>`
}
`
-const Notch = styled.div<{ $isAnimated?: boolean; $isOpen?: boolean }>`
- position: relative;
- display: flex;
- align-items: stretch;
- -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
- -webkit-tap-highlight-color: transparent;
- user-select: none;
- text-rendering: auto;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- -webkit-text-size-adjust: none;
- -webkit-overflow-scrolling: touch;
-
- width: 318px;
- height: 45px;
- border-radius: ${(props) => (props.$isOpen ? '0' : '0 0 6px 6px')};
- background: #384bff;
- box-shadow: 0 4px 5px rgb(45 52 60 / 10%), 0 4px 20px rgb(11 87 111 / 15%);
- opacity: 0;
- transform: translateY(-100%);
- transition: ${(props) =>
- props.$isAnimated ? 'opacity 0.3s ease-in-out, transform 0.3s ease-in-out' : 'initial'};
-
- justify-content: space-between;
- padding: 4px 5px;
- padding-top: 0;
-`
-
-const NotchButtonWrapper = styled.div`
- width: 16px;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
-
- &:hover,
- &:focus {
- opacity: 0.5;
- }
-`
-
-const IconWrapper = styled.div`
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: space-between;
-`
-
-const DragIcon = () => (
-
-)
-
interface MultitablePanelProps {
eventEmitter: NEventEmitter
}
@@ -117,20 +57,9 @@ interface MultitablePanelProps {
export const MultitablePanel: FC = ({ eventEmitter }) => {
const { mutations, allApps, selectedMutation, config } = useMutableWeb()
const [isOverlayOpened, setIsOverlayOpened] = useState(false)
- const [isPin, setPin] = useState(!getIsPanelUnpinned())
- const [isDragging, setIsDragging] = useState(false)
- const [isNotchDisplayed, setIsNotchDisplayed] = useState(true)
const [isModalOpen, setIsModalOpen] = useState(false)
const notchRef = useRef(null)
- useEffect(() => {
- const timer = setTimeout(() => {
- setIsNotchDisplayed(false)
- }, 5000)
-
- return () => clearTimeout(timer)
- }, [isPin])
-
useEffect(() => {
const openMutationPopupCallback = () => {
setIsModalOpen(true)
@@ -141,23 +70,6 @@ export const MultitablePanel: FC = ({ eventEmitter }) => {
}
}, [eventEmitter])
- const handleStartDrag = () => {
- setIsDragging(true)
- }
-
- const handleStopDrag = () => {
- setIsDragging(false)
- }
-
- const handlePin = () => {
- if (isPin) {
- setPanelUnpinnedFlag('unpin')
- } else {
- removePanelUnpinnedFlag()
- }
- setPin(!isPin)
- }
-
const handleMutateButtonClick = () => {
setIsModalOpen(true)
setIsOverlayOpened(false)
@@ -180,7 +92,7 @@ export const MultitablePanel: FC = ({ eventEmitter }) => {
open={isOverlayOpened}
handleMutateButtonClick={handleMutateButtonClick}
/>
-
+
{isModalOpen ? (
= ({ eventEmitter }) => {
localMutations={mutations.filter((m) => m.source === EntitySourceType.Local)}
onClose={handleModalClose}
/>
- ) : (
-
-
-
-
-
-
-
-
-
- {isPin ? : }
-
-
-
- )}
+ ) : null}
>
)
diff --git a/libs/shared-components/src/mini-overlay/assets/icons/icon-dropdown.tsx b/libs/shared-components/src/mini-overlay/assets/icons/icon-dropdown.tsx
new file mode 100644
index 00000000..d7d29436
--- /dev/null
+++ b/libs/shared-components/src/mini-overlay/assets/icons/icon-dropdown.tsx
@@ -0,0 +1,17 @@
+import React from 'react'
+
+const IconDropdown = () => (
+
+)
+
+export default IconDropdown
diff --git a/libs/shared-components/src/mini-overlay/assets/icons/index.ts b/libs/shared-components/src/mini-overlay/assets/icons/index.ts
index de426a00..ce32893b 100644
--- a/libs/shared-components/src/mini-overlay/assets/icons/index.ts
+++ b/libs/shared-components/src/mini-overlay/assets/icons/index.ts
@@ -13,6 +13,7 @@ import OpenOverlay from './open-overlay'
import OpenOverlayWithCircle from './open-overlay-with-circle'
import Logo from './logo'
import PersonAddAlt from './person-add-alt'
+import IconDropdown from './icon-dropdown'
export {
MutationFallbackIcon,
@@ -30,4 +31,5 @@ export {
OpenOverlayWithCircle,
Logo,
PersonAddAlt,
+ IconDropdown,
}
diff --git a/libs/shared-components/src/multitable-panel/assets/styles-dropdown.tsx b/libs/shared-components/src/multitable-panel/assets/styles-dropdown.tsx
index 548014e2..52ba14dd 100644
--- a/libs/shared-components/src/multitable-panel/assets/styles-dropdown.tsx
+++ b/libs/shared-components/src/multitable-panel/assets/styles-dropdown.tsx
@@ -69,9 +69,11 @@ export const ButtonBack = styled.div`
padding-bottom: 10px;
padding-top: 10px;
transition: all 0.2s ease;
+
svg {
margin-right: 5px;
}
+
&:hover {
background: rgba(56, 75, 255, 0.1);
border-radius: 4px;
@@ -94,47 +96,39 @@ export const ButtonMutation = styled.div`
padding-bottom: 10px;
padding-top: 10px;
transition: all 0.2s ease;
+
svg {
margin-left: 5px;
}
+
&:hover {
background: rgba(56, 75, 255, 0.1);
border-radius: 4px;
}
`
-export const ListMutations = styled.div`
- width: 100%;
- display: flex;
- flex-direction: column;
- gap: 3px;
- z-index: 1;
-`
-
export const InputBlock = styled.div<{ isActive?: boolean }>`
display: flex;
-
padding: 2px 4px;
cursor: pointer;
-
align-items: center;
width: 100%;
-
color: ${(props) => (props.isActive ? '#384BFF' : '#7A818B')};
border-radius: 4px;
- .inputMutation {
- color: ${(props) => (props.isActive ? '#384BFF' : '#7A818B')};
- }
-
&:hover {
background: #384bff;
+ color: #fff;
- div,
- span {
+ .inputMutation {
color: #fff;
}
+ .authorMutation {
+ color: #fff;
+ }
+
+ div,
svg {
fill: #fff;
@@ -143,6 +137,10 @@ export const InputBlock = styled.div<{ isActive?: boolean }>`
}
}
}
+
+ .inputMutation {
+ color: ${(props) => (props.isActive ? '#384BFF' : '#7A818B')};
+ }
`
export const InputIconWrapper = styled.div`
display: flex;
@@ -172,23 +170,20 @@ export const InputIconWrapper = styled.div`
export const InputInfoWrapper = styled.div`
display: flex;
-
padding: 4px;
- padding-left: 6px;
+ margin-left: 10px;
cursor: pointer;
-
position: relative;
-
flex-direction: column;
align-items: flex-start;
flex: 1;
.inputMutationSelected {
- color: rgba(34, 34, 34, 1);
+ color: #fff;
}
.authorMutationSelected {
- color: #384bff;
+ color: #fff;
}
`
export const ImageBlock = styled.div`
@@ -206,6 +201,77 @@ export const ImageBlock = styled.div`
}
`
+export const ListMutations = styled.div`
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ gap: 3px;
+ z-index: 1;
+
+ .active-mutation {
+ background: #384bff;
+ color: #fff;
+
+ svg path {
+ stroke: #fff;
+ fill: #384bff;
+ }
+
+ &:hover {
+ background: #fff;
+ color: #384bff;
+
+ svg path {
+ stroke: #384bff;
+ fill: #384bff;
+ }
+
+ .infoSelected{
+ .inputMutationSelected {
+ color: #384bff;
+ }
+
+ .authorMutationSelected {
+ color: #384bff;
+ }
+ }
+
+ .mutation-version-dropdown {
+ background: rgba(56, 75, 255, 0.1);
+ color: #384bff;
+
+ svg path {
+ stroke: #384bff;
+ }
+ }
+ }
+`
+
+export const SpanStyled = styled.span<{ $isWhite?: boolean }>`
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ position: relative;
+ top: 0;
+ cursor: pointer;
+ left: ${({ $isWhite }) => ($isWhite ? `0` : '-6px')};
+ justify-content: center;
+ padding: 2px 0;
+ padding-left: 4px;
+ width: 100%;
+ height: 100%;
+ border-radius: 4px;
+ font-size: 10px;
+ font-weight: 400;
+ text-align: left;
+ color: #ffffff;
+ background: ${({ $isWhite }) => ($isWhite ? `#FFFFFF` : '#384bff')};
+
+ svg path {
+ stroke: ${({ $isWhite }) => ($isWhite ? ` #7a818b` : '#FFFFFF')};
+ }
+`
+
export const AvalibleMutations = styled.div`
width: 100%;
background: #f8f9ff;
@@ -215,7 +281,6 @@ export const AvalibleMutations = styled.div`
flex-direction: column;
box-sizing: border-box;
padding: 10px;
- z-index: 1;
.avalibleMutationsInput {
background: rgba(248, 249, 255, 1);
@@ -236,6 +301,7 @@ export const AvalibleLableBlock = styled.div`
align-items: center;
justify-content: space-between;
width: 100%;
+
.iconRotate {
svg {
transform: rotate(0deg);
@@ -257,6 +323,7 @@ export const AvalibleArrowBlock = styled.div`
justify-content: space-between;
transition: all 0.2s ease;
cursor: pointer;
+
svg {
margin-left: 10px;
transform: rotate(180deg);
@@ -276,8 +343,8 @@ export const InputMutation = styled.span`
color: rgba(34, 34, 34, 0.6);
white-space: nowrap;
- overflow: hidden;
text-overflow: ellipsis;
+ column-gap: 8px;
width: 180px;
display: inline-flex;
align-items: center;
diff --git a/libs/shared-components/src/multitable-panel/components/dropdown.tsx b/libs/shared-components/src/multitable-panel/components/dropdown.tsx
index 7f38169f..5549e096 100644
--- a/libs/shared-components/src/multitable-panel/components/dropdown.tsx
+++ b/libs/shared-components/src/multitable-panel/components/dropdown.tsx
@@ -33,6 +33,7 @@ import {
import { Badge } from './badge'
import { Image } from './image'
import { ModalDelete } from './modal-delete'
+import { MutationVersionDropdown } from './mutation-version-dropdown'
const ModalConfirmBackground = styled.div`
position: absolute;
@@ -65,6 +66,8 @@ export const Dropdown: FC = ({ onMutateButtonClick }: DropdownPro
} = useMutableWeb()
const { deleteLocalMutation } = useDeleteLocalMutation()
+ const [expandedVersion, setExpandedVersion] = useState(false)
+ const toggleDropdown = () => setExpandedVersion(!expandedVersion)
const recentlyUsedMutations = useMemo(
() =>
@@ -168,11 +171,26 @@ export const Dropdown: FC = ({ onMutateButtonClick }: DropdownPro
// fallbackUrl={defaultIcon}
/>
- handleMutationClick(mut.id)}>
+ handleMutationClick(mut.id)}
+ >
{/* todo: mocked classname */}
+
+ {mut.id === selectedMutation?.id ? (
+
+ ) : null}
{mut.metadata ? mut.metadata.name : ''}{' '}
{recentlyUsedMutations[mut.id]?.length === 2 ? (
mut.source === EntitySourceType.Local ? (
@@ -188,9 +206,9 @@ export const Dropdown: FC = ({ onMutateButtonClick }: DropdownPro
{mut.authorId ? (
by {mut.authorId}
diff --git a/libs/shared-components/src/multitable-panel/components/mutation-version-dropdown.tsx b/libs/shared-components/src/multitable-panel/components/mutation-version-dropdown.tsx
new file mode 100644
index 00000000..9bddd354
--- /dev/null
+++ b/libs/shared-components/src/multitable-panel/components/mutation-version-dropdown.tsx
@@ -0,0 +1,207 @@
+import { useMutableWeb, useMutationVersions } from '@mweb/engine'
+import React, { useState } from 'react'
+import { FC } from 'react'
+import { IconDropdown } from '../../mini-overlay/assets/icons'
+import styled from 'styled-components'
+
+export const SpanStyled = styled.span<{ $isWhite?: boolean; $isExpanded?: boolean }>`
+ display: flex;
+ align-items: center;
+ gap: 2px;
+ cursor: pointer;
+ justify-content: ${({ $isExpanded }) => ($isExpanded ? `center` : 'flex-start')};
+ padding-left: ${({ $isExpanded }) => ($isExpanded ? `4px` : '6px')};
+ width: 100%;
+ height: 100%;
+ border-radius: 4px;
+ font-size: 10px;
+ font-weight: 400;
+ text-align: left;
+ color: #ffffff;
+ background: ${({ $isWhite }) => ($isWhite ? `#FFFFFF` : '#384bff')};
+
+ svg path {
+ stroke: ${({ $isWhite }) => ($isWhite ? ` #7a818b` : '#FFFFFF')};
+ }
+`
+
+export const OpenListDefault = styled.span`
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ @keyframes rotateIsClose {
+ 0% {
+ transform: rotate(180deg);
+ }
+
+ 50% {
+ transform: rotate(90deg);
+ }
+
+ 100% {
+ transform: rotate(0deg);
+ }
+ }
+ animation: rotateIsClose 0.2s ease forwards;
+ transition: all 0.3s;
+ &:hover {
+ svg {
+ transform: scale(1.2);
+ }
+ }
+`
+
+export const OpenList = styled.span`
+ cursor: pointer;
+
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ @keyframes rotateIsOpen {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 50% {
+ transform: rotate(90deg);
+ }
+
+ 100% {
+ transform: rotate(180deg);
+ }
+ }
+ animation: rotateIsOpen 0.2s ease forwards;
+ transition: all 0.3s;
+ &:hover {
+ svg {
+ transform: scale(1.2);
+ }
+ }
+`
+
+export const DropdownContainer = styled.div<{ $expanded?: boolean }>`
+ position: absolute;
+ width: 100%;
+ width: 50px;
+ height: auto;
+ top: 24px;
+ left: 2px;
+ padding: 2px;
+ border-radius: 4px;
+ background: #fff;
+ display: flex;
+ flex-direction: column;
+ z-index: 2;
+
+ box-shadow: ${({ $expanded }) =>
+ $expanded
+ ? `0px 3px 7px 0px #2222221A,
+ 0px 12px 12px 0px #22222217,
+ 0px 27px 16px 0px #2222220D,
+ 0px 48px 19px 0px #22222203,
+ 0px 76px 21px 0px #22222200`
+ : 'none'};
+
+ cursor: pointer;
+`
+
+export const DropdownItem = styled.div<{ $isActiveVersion?: boolean }>`
+ font-size: 10px;
+ font-weight: 400;
+ text-align: right;
+ color: ${({ $isActiveVersion }) => ($isActiveVersion ? `#384BFF` : '#7a818b')};
+ padding: 4px;
+
+ &:hover {
+ background: #1879ce1a;
+ color: #384bff;
+ }
+`
+
+const LatestKey = 'latest'
+
+export const MutationVersionDropdown: FC<{
+ mutationId: string | null
+ toggleDropdown: () => void
+ expanded: boolean
+ isWhite?: boolean
+}> = ({ mutationId, isWhite, toggleDropdown, expanded }) => {
+ const {
+ switchMutationVersion,
+ selectedMutation,
+ mutationVersions: currentMutationVersions,
+ } = useMutableWeb()
+ const { mutationVersions, areMutationVersionsLoading } = useMutationVersions(mutationId)
+
+ if (!mutationId) {
+ return null
+ }
+
+ if (!selectedMutation || areMutationVersionsLoading) {
+ return
+ }
+
+ const handleChange = (key: string) => {
+ if (selectedMutation?.id) {
+ switchMutationVersion(selectedMutation?.id, key === LatestKey ? null : key?.toString())
+ }
+ }
+
+ return (
+ <>
+ 0 ? '50px' : '40px',
+ width: '100%',
+ display: 'inline-flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ position: 'relative',
+ boxSizing: isWhite ? 'border-box' : undefined,
+ marginLeft: isWhite ? '10px' : '',
+ borderRadius: isWhite ? '4px' : '',
+ }}
+ onClick={toggleDropdown}
+ >
+ 0}
+ className="mutation-version-dropdown"
+ >
+ {currentMutationVersions[mutationId]
+ ? `v${currentMutationVersions[mutationId]}`
+ : LatestKey}
+ {mutationVersions && mutationVersions.length > 0 ? (
+ expanded ? (
+
+
+
+ ) : (
+
+
+
+ )
+ ) : null}
+
+
+ {mutationVersions && mutationVersions.length > 0
+ ? expanded && (
+
+ {mutationVersions.map((version) => (
+ handleChange(version.version)}
+ key={version.version}
+ >
+ v{version.version}
+
+ ))}
+
+ )
+ : null}
+
+ >
+ )
+}