feat(ui): create template types and components for bug report
This commit is contained in:
parent
138b0ef549
commit
2f0b5359b7
10 changed files with 447 additions and 34 deletions
|
|
@ -17,7 +17,7 @@ function Autoplay(props) {
|
|||
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<div onClick={props.toggleAutoplay} className="cursor-pointer flex items-center mr-2 hover:bg-gray-light-shade rounded-md p-1">
|
||||
<div onClick={props.toggleAutoplay} className="cursor-pointer flex items-center mr-2 hover:bg-gray-light-shade rounded-md p-2">
|
||||
<Toggler
|
||||
name="sessionsLive"
|
||||
onChange={ props.toggleAutoplay }
|
||||
|
|
|
|||
131
frontend/app/components/Session_/BugReport/BugReportModal.tsx
Normal file
131
frontend/app/components/Session_/BugReport/BugReportModal.tsx
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
import React from 'react';
|
||||
import PlayLink from 'Shared/SessionItem/PlayLink';
|
||||
import { connect } from 'react-redux';
|
||||
import { countries } from 'App/constants';
|
||||
import { session as sessionRoute } from 'App/routes';
|
||||
|
||||
interface Props {
|
||||
hideModal: () => void;
|
||||
session: Record<string, any>;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
function BugReportModal({ hideModal, session, width, height }: Props) {
|
||||
const {
|
||||
userBrowser,
|
||||
userDevice,
|
||||
userCountry,
|
||||
userBrowserVersion,
|
||||
userOs,
|
||||
userOsVersion,
|
||||
userDisplayName,
|
||||
userDeviceType,
|
||||
revId,
|
||||
metadata,
|
||||
sessionId,
|
||||
} = session;
|
||||
|
||||
console.log(session.toJS())
|
||||
const envObject = {
|
||||
Device: `${userDevice}${userDeviceType !== userDevice ? ` ${userDeviceType}` : ''}`,
|
||||
Resolution: `${width}x${height}`,
|
||||
Browser: `${userBrowser} v${userBrowserVersion}`,
|
||||
OS: `${userOs} v${userOsVersion}`,
|
||||
// @ts-ignore
|
||||
Country: countries[userCountry],
|
||||
};
|
||||
if (revId) {
|
||||
Object.assign(envObject, { Rev: revId })
|
||||
}
|
||||
return (
|
||||
<div
|
||||
className="flex flex-col p-4 gap-4 bg-white"
|
||||
style={{ maxWidth: '70vw', width: 620, height: '100vh' }}
|
||||
>
|
||||
<Title />
|
||||
<MetaInfo envObject={envObject} metadata={metadata} />
|
||||
<Session user={userDisplayName} sessionId={sessionId} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Title() {
|
||||
return (
|
||||
<div className="flex items-center py-2 px-3 justify-between bg-gray-lightest rounded">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div>Title</div>
|
||||
<div className="text-gray-medium">By author</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>Severity</div>
|
||||
<div>select here</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface EnvObj {
|
||||
Device: string;
|
||||
Resolution: string;
|
||||
Browser: string;
|
||||
OS: string;
|
||||
Country: string;
|
||||
Rev?: string;
|
||||
}
|
||||
|
||||
function MetaInfo({ envObject, metadata }: { envObject: EnvObj, metadata: Record<string, any> }) {
|
||||
return (
|
||||
<div className="flex gap-8">
|
||||
<div className="flex flex-col gap-2">
|
||||
<SectionTitle>Environment</SectionTitle>
|
||||
{Object.keys(envObject).map((envTag) => (
|
||||
<div className="flex items-center">
|
||||
<div className="py-1 px-2">{envTag}</div>
|
||||
<div className="py-1 px-2 text-gray-medium bg-light-blue-bg rounded">
|
||||
{/* @ts-ignore */}
|
||||
{envObject[envTag]}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<SectionTitle>Metadata</SectionTitle>
|
||||
{Object.keys(metadata).map((meta) => (
|
||||
<div className="flex items-center rounded overflow-hidden bg-gray-lightest">
|
||||
<div className="bg-gray-light-shade py-1 px-2">{meta}</div>
|
||||
<div className="py-1 px-2 text-gray-medium">{metadata[meta]}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Session({ user, sessionId }: { user: string, sessionId: string }) {
|
||||
return (
|
||||
<div>
|
||||
<SectionTitle>Session recording</SectionTitle>
|
||||
<div className="border rounded flex items-center justify-between p-2">
|
||||
<div className="flex flex-col">
|
||||
<div className="text-lg">{user}</div>
|
||||
<div className="text-disabled-text">
|
||||
{`${window.location.origin}/${window.location.pathname.split('/')[1]}${sessionRoute(sessionId)}`}
|
||||
</div>
|
||||
</div>
|
||||
<PlayLink isAssist={false} viewed={false} sessionId={sessionId} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function SectionTitle({ children }: { children: React.ReactNode }) {
|
||||
return <div className="text-xl font-semibold mb-2">{children}</div>;
|
||||
}
|
||||
|
||||
const WithUIState = connect((state) => ({ session: state.getIn(['sessions', 'current']) }))(
|
||||
BugReportModal
|
||||
);
|
||||
|
||||
export default WithUIState
|
||||
69
frontend/app/components/Session_/BugReport/types.ts
Normal file
69
frontend/app/components/Session_/BugReport/types.ts
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
export interface BugReportPdf {
|
||||
author: string;
|
||||
env: EnvData;
|
||||
meta: {
|
||||
[key: string]: string;
|
||||
};
|
||||
session: {
|
||||
user: string;
|
||||
url: string;
|
||||
id: string;
|
||||
};
|
||||
comment?: string;
|
||||
steps: Step[];
|
||||
activity: {
|
||||
network: NetworkError[];
|
||||
console: ConsoleError[];
|
||||
clickRage: ClickRage[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface EnvData {
|
||||
browser: string;
|
||||
os: string;
|
||||
country: string;
|
||||
device: string;
|
||||
resolution: string;
|
||||
}
|
||||
|
||||
export interface NetworkError {
|
||||
time: number;
|
||||
}
|
||||
|
||||
export interface ConsoleError {
|
||||
time: number;
|
||||
}
|
||||
|
||||
export interface ClickRage {
|
||||
time: number;
|
||||
}
|
||||
|
||||
export interface Step {
|
||||
type: string;
|
||||
icon: string;
|
||||
details: string;
|
||||
substeps?: SubStep[];
|
||||
}
|
||||
|
||||
export type SubStep = Note | Error | Request;
|
||||
|
||||
export interface Note {
|
||||
author: string;
|
||||
message: string;
|
||||
step: 'note';
|
||||
}
|
||||
|
||||
export interface Error {
|
||||
timestamp: string;
|
||||
error: string;
|
||||
step: 'error';
|
||||
}
|
||||
|
||||
export interface Request {
|
||||
url: string;
|
||||
status: number;
|
||||
type: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
||||
time: number;
|
||||
name: string;
|
||||
step: 'request';
|
||||
}
|
||||
|
|
@ -110,13 +110,6 @@ function UserCard({ className, request, session, width, height, similarSessions,
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <SlideModal
|
||||
title={ <div>User Sessions</div> }
|
||||
isDisplayed={ showUserSessions }
|
||||
content={ showUserSessions && <SessionList similarSessions={ similarSessions } loading={ loading } /> }
|
||||
onClose={ () => showUserSessions ? setShowUserSessions(false) : null }
|
||||
/> */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,14 @@ import copy from 'copy-to-clipboard';
|
|||
import { Tooltip } from 'react-tippy';
|
||||
import Issues from './Issues/Issues';
|
||||
import NotePopup from './components/NotePopup';
|
||||
import { connectPlayer } from 'Player';
|
||||
import { connectPlayer, pause } from 'Player';
|
||||
import ItemMenu from './components/HeaderMenu';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import BugReportModal from './BugReport/BugReportModal';
|
||||
|
||||
function SubHeader(props) {
|
||||
const [isCopied, setCopied] = React.useState(false);
|
||||
|
||||
const { showModal, hideModal } = useModal();
|
||||
const isAssist = window.location.pathname.includes('/assist/');
|
||||
|
||||
const location =
|
||||
|
|
@ -19,6 +22,11 @@ function SubHeader(props) {
|
|||
? `${props.currentLocation.slice(0, 60)}...`
|
||||
: props.currentLocation;
|
||||
|
||||
const showReportModal = () => {
|
||||
pause();
|
||||
showModal(<BugReportModal width={props.width} height={props.height} hideModal={hideModal} />, { right: true });
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full px-4 py-2 flex items-center border-b">
|
||||
{location && (
|
||||
|
|
@ -45,39 +53,62 @@ function SubHeader(props) {
|
|||
)}
|
||||
{!isAssist ? (
|
||||
<div
|
||||
className="ml-auto text-sm flex items-center color-gray-medium"
|
||||
className="ml-auto text-sm flex items-center color-gray-medium gap-2"
|
||||
style={{ width: 'max-content' }}
|
||||
>
|
||||
<NotePopup />
|
||||
<div className="cursor-pointer mr-4 hover:bg-gray-light-shade rounded-md p-1">
|
||||
{props.jiraConfig && props.jiraConfig.token && <Issues sessionId={props.sessionId} />}
|
||||
</div>
|
||||
<div className="cursor-pointer">
|
||||
<SharePopup
|
||||
entity="sessions"
|
||||
id={props.sessionId}
|
||||
showCopyLink={true}
|
||||
trigger={
|
||||
<div className="flex items-center hover:bg-gray-light-shade rounded-md p-1">
|
||||
<Icon className="mr-2" disabled={props.disabled} name="share-alt" size="16" />
|
||||
<span>Share</span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="mx-4 hover:bg-gray-light-shade rounded-md p-1">
|
||||
<Bookmark noMargin sessionId={props.sessionId} />
|
||||
<div
|
||||
onClick={showReportModal}
|
||||
className="cursor-pointer rounded flex items-center p-2 gap-1 hover:bg-gray-light-shade"
|
||||
>
|
||||
<Icon name="file-pdf" size={16} />
|
||||
<span>Create Bug Report</span>
|
||||
</div>
|
||||
<ItemMenu
|
||||
items={[
|
||||
{ key: 1, component: <NotePopup /> },
|
||||
{
|
||||
key: 2,
|
||||
component: props.jiraConfig && props.jiraConfig.token && (
|
||||
<Issues sessionId={props.sessionId} />
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
component: (
|
||||
<SharePopup
|
||||
entity="sessions"
|
||||
id={props.sessionId}
|
||||
showCopyLink={true}
|
||||
trigger={
|
||||
<div className="flex items-center">
|
||||
<Icon
|
||||
className="mr-2"
|
||||
disabled={props.disabled}
|
||||
name="share-alt"
|
||||
size="16"
|
||||
/>
|
||||
<span>Share</span>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
component: <Bookmark noMargin sessionId={props.sessionId} />,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<div>
|
||||
<Autoplay />
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const SubH = connectPlayer((state) => ({ currentLocation: state.location }))(SubHeader);
|
||||
const SubH = connectPlayer((state) => ({ width: state.width, height: state.height, currentLocation: state.location }))(SubHeader);
|
||||
|
||||
export default React.memo(SubH);
|
||||
|
|
|
|||
75
frontend/app/components/Session_/components/HeaderMenu.tsx
Normal file
75
frontend/app/components/Session_/components/HeaderMenu.tsx
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import React from 'react';
|
||||
import { Icon } from 'UI';
|
||||
import styles from './menu.module.css';
|
||||
import cn from 'classnames';
|
||||
|
||||
interface MenuItem {
|
||||
key: number;
|
||||
component?: React.ReactElement;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
items: MenuItem[];
|
||||
}
|
||||
|
||||
export default class ItemMenu extends React.PureComponent<Props> {
|
||||
state = {
|
||||
displayed: false,
|
||||
};
|
||||
|
||||
handleEsc = (e: KeyboardEvent) => e.key === 'Escape' && this.state.displayed && this.toggleMenu();
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('keydown', this.handleEsc, false);
|
||||
}
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this.handleEsc, false);
|
||||
}
|
||||
|
||||
toggleMenu = () => {
|
||||
this.setState({ displayed: !this.state.displayed });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { items } = this.props;
|
||||
const { displayed } = this.state;
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<div
|
||||
onClick={this.toggleMenu}
|
||||
className={cn(
|
||||
'flex items-center cursor-pointer select-none',
|
||||
'rounded p-2 hover:bg-gray-light-shade',
|
||||
{
|
||||
'bg-gray-light': displayed,
|
||||
}
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={cn('rounded-full flex items-center justify-center', {
|
||||
'bg-gray-light': displayed,
|
||||
})}
|
||||
role="button"
|
||||
>
|
||||
<Icon name="ellipsis-v" size="16" />
|
||||
</div>
|
||||
<span className={'mr-1 text-disabled-text'}>More</span>
|
||||
</div>
|
||||
<div className={cn(styles.menu, styles.menuDim)} data-displayed={displayed}>
|
||||
{items.map((item) =>
|
||||
item.component ? (
|
||||
<div
|
||||
key={item.key}
|
||||
role="menuitem"
|
||||
className="w-full h-full p-3 hover:bg-gray-light-shade cursor-pointer flex items-center"
|
||||
>
|
||||
{item.component}
|
||||
</div>
|
||||
) : null
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ function NotePopup({
|
|||
<div
|
||||
onClick={toggleNotePopup}
|
||||
className={cn(
|
||||
'mr-4 hover:bg-gray-light-shade rounded-md p-1 flex items-center',
|
||||
'mr-4 hover:bg-gray-light-shade rounded-md flex items-center',
|
||||
tooltipActive ? 'cursor-not-allowed' : 'cursor-pointer'
|
||||
)}
|
||||
>
|
||||
|
|
|
|||
102
frontend/app/components/Session_/components/menu.module.css
Normal file
102
frontend/app/components/Session_/components/menu.module.css
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
@import 'icons.css';
|
||||
|
||||
.wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.menuBtn {
|
||||
@mixin icon-before ellipsis-v, $gray-darkest, 18px {
|
||||
margin: 5px;
|
||||
}
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 18px;
|
||||
border: 1px solid transparent;
|
||||
transition: all 0.2s;
|
||||
margin: 0 auto;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
border-color: $active-blue-border;
|
||||
transition: all 0.2s;
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.menuDim {
|
||||
border: none!important;
|
||||
box-shadow: 0 1px 3px 0 $gray-light!important;
|
||||
|
||||
& .menuItem {
|
||||
color: $gray-dark!important;
|
||||
}
|
||||
}
|
||||
|
||||
.menu {
|
||||
&[data-displayed=false] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
white-space: nowrap;
|
||||
z-index: 20;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 37px;
|
||||
min-width: 150px;
|
||||
background-color: $white;
|
||||
border-radius: 3px;
|
||||
border: 1px solid rgba(34,36,38,.15);
|
||||
box-shadow: 0 2px 3px 0 rgb(34 36 38 / 15%);
|
||||
|
||||
|
||||
& .menuItem {
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
color: black;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid $gray-light;
|
||||
position: relative;
|
||||
|
||||
& .iconWrapper {
|
||||
width: 13px;
|
||||
height: 13px ;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $active-blue;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
& .edit {
|
||||
@mixin icon pencil, $gray-medium, 15px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
& .copy {
|
||||
@mixin icon copy, $gray-medium, 15px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
& .remove {
|
||||
@mixin icon trash, $gray-medium, 15px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
& .enabled {
|
||||
@mixin icon eye, $gray-medium, 15px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
& .disabled {
|
||||
@mixin icon eye-slash, $gray-medium, 15px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
11
frontend/app/svg/icons/file-pdf.svg
Normal file
11
frontend/app/svg/icons/file-pdf.svg
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<svg viewBox="0 0 13 14" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_2148_10595)">
|
||||
<path d="M3.49328 0.66217C3.07306 0.66217 2.67005 0.829104 2.3729 1.12625C2.07576 1.42339 1.90883 1.8264 1.90883 2.24662V11.7533C1.90883 12.1736 2.07576 12.5766 2.3729 12.8737C2.67005 13.1709 3.07306 13.3378 3.49328 13.3378H9.8311C10.2513 13.3378 10.6543 13.1709 10.9515 12.8737C11.2486 12.5766 11.4156 12.1736 11.4156 11.7533V2.24662C11.4156 1.8264 11.2486 1.42339 10.9515 1.12625C10.6543 0.829104 10.2513 0.66217 9.8311 0.66217H3.49328ZM3.49328 1.4544H9.8311C10.0412 1.4544 10.2427 1.53786 10.3913 1.68644C10.5399 1.83501 10.6233 2.03651 10.6233 2.24662V11.7533C10.6233 11.9635 10.5399 12.165 10.3913 12.3135C10.2427 12.4621 10.0412 12.5456 9.8311 12.5456H3.49328C3.28317 12.5456 3.08167 12.4621 2.93309 12.3135C2.78452 12.165 2.70106 11.9635 2.70106 11.7533V2.24662C2.70106 2.03651 2.78452 1.83501 2.93309 1.68644C3.08167 1.53786 3.28317 1.4544 3.49328 1.4544Z" fill-opacity="0.6"/>
|
||||
<path d="M3.97099 10.2378C3.81658 10.1761 3.69217 10.0568 3.62399 9.9051C3.46951 9.59772 3.521 9.29033 3.68737 9.03207C3.84423 8.78885 4.10408 8.58208 4.398 8.40859C4.7703 8.19743 5.16384 8.02616 5.57208 7.8976C5.88911 7.32766 6.17011 6.73841 6.41343 6.13331C6.26796 5.80277 6.1539 5.45928 6.07277 5.10738C6.00464 4.79048 5.97849 4.47676 6.03633 4.20741C6.09574 3.92696 6.2534 3.67503 6.55127 3.5554C6.70338 3.4944 6.86816 3.46034 7.02819 3.4944C7.10869 3.51154 7.18437 3.54638 7.24973 3.59639C7.31509 3.64641 7.3685 3.71034 7.40609 3.78356C7.4758 3.91349 7.50115 4.0656 7.5067 4.20978C7.51224 4.35793 7.49719 4.52271 7.46946 4.69621C7.40292 5.10024 7.25556 5.59459 7.05751 6.11746C7.27607 6.58489 7.5359 7.0319 7.83389 7.45316C8.18651 7.42531 8.54117 7.4386 8.89072 7.49277C9.17909 7.54427 9.47221 7.64725 9.65126 7.86116C9.74632 7.97524 9.80416 8.11467 9.8097 8.27153C9.81525 8.42364 9.77247 8.57416 9.70038 8.71755C9.63793 8.85044 9.5411 8.96422 9.41993 9.04712C9.30015 9.12525 9.15873 9.16352 9.01589 9.15645C8.75366 9.14536 8.49777 9.00117 8.27674 8.82609C8.00799 8.60385 7.76581 8.3513 7.55502 8.07347C7.01928 8.13424 6.48989 8.24186 5.97295 8.39512C5.73595 8.81498 5.46545 9.21504 5.16408 9.59138C4.93434 9.86866 4.68241 10.1103 4.43048 10.2149C4.28573 10.2803 4.12155 10.2886 3.97099 10.2378ZM5.06347 8.73181C4.93196 8.79202 4.80996 8.8554 4.69984 8.92036C4.43999 9.07406 4.27124 9.22379 4.18727 9.35371C4.1128 9.46859 4.11121 9.55177 4.15558 9.63971C4.1635 9.65714 4.17142 9.66823 4.17618 9.67456C4.18563 9.67203 4.19489 9.66886 4.2039 9.66506C4.31244 9.62069 4.48514 9.47888 4.70697 9.2119C4.83313 9.05744 4.95209 8.89724 5.06347 8.73181ZM6.36272 7.67815C6.62726 7.61636 6.89419 7.56535 7.16287 7.52525C7.01856 7.30454 6.88376 7.07776 6.75884 6.84552C6.6346 7.12645 6.50251 7.40384 6.36272 7.67736V7.67815ZM8.30051 8.03465C8.41934 8.16299 8.53501 8.27232 8.64513 8.35947C8.83526 8.50999 8.96757 8.5599 9.03966 8.56228C9.05896 8.5648 9.07854 8.56061 9.09511 8.55039C9.12807 8.52437 9.15373 8.49025 9.16958 8.45137C9.19775 8.40311 9.21379 8.34874 9.21632 8.29292C9.21587 8.27431 9.20853 8.25653 9.19573 8.24301C9.15453 8.19389 9.03728 8.12259 8.78535 8.07743C8.6251 8.05065 8.46298 8.03661 8.30051 8.03545V8.03465ZM6.72398 5.25711C6.79065 5.04203 6.84358 4.82294 6.88242 4.60114C6.90698 4.4522 6.91649 4.32941 6.91253 4.23276C6.91275 4.17943 6.90418 4.12644 6.88718 4.0759C6.84755 4.0808 6.80885 4.09148 6.7723 4.10758C6.70338 4.13531 6.64713 4.19156 6.61703 4.33178C6.58534 4.48389 6.59326 4.70334 6.65347 4.983C6.67248 5.07093 6.69625 5.16283 6.72477 5.25711H6.72398Z" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2148_10595">
|
||||
<rect width="12.6756" height="12.6756" fill="white" transform="translate(0.324371 0.66217)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
Loading…
Add table
Reference in a new issue