ui: migrating old components -> ant (#3060)
* ui: migrating old components -> ant * ui: moving input, tooltip, toggler, checkbox... -> Toggler\s*(.)? from 'UI * ui: more components moved * ui: move popover to ant
This commit is contained in:
parent
1122ced4c3
commit
968a3eefde
142 changed files with 525 additions and 2352 deletions
|
|
@ -18,11 +18,6 @@ const components: any = {
|
|||
AssistPure: lazy(() => import('Components/Assist/AssistRouter')),
|
||||
SessionsOverviewPure: lazy(() => import('Components/Overview')),
|
||||
DashboardPure: lazy(() => import('Components/Dashboard/NewDashboard')),
|
||||
FunnelDetailsPure: lazy(() => import('Components/Funnels/FunnelDetails')),
|
||||
FunnelIssueDetails: lazy(
|
||||
() => import('Components/Funnels/FunnelIssueDetails')
|
||||
),
|
||||
FunnelPagePure: lazy(() => import('Components/Funnels/FunnelPage')),
|
||||
MultiviewPure: lazy(() => import('Components/Session_/Multiview/Multiview')),
|
||||
UsabilityTestingPure: lazy(
|
||||
() => import('Components/UsabilityTesting/UsabilityTesting')
|
||||
|
|
@ -47,9 +42,6 @@ const enhancedComponents: any = {
|
|||
Assist: withSiteIdUpdater(components.AssistPure),
|
||||
Client: withSiteIdUpdater(components.ClientPure),
|
||||
Onboarding: withSiteIdUpdater(components.OnboardingPure),
|
||||
FunnelPage: withSiteIdUpdater(components.FunnelPagePure),
|
||||
FunnelsDetails: withSiteIdUpdater(components.FunnelDetailsPure),
|
||||
FunnelIssue: withSiteIdUpdater(components.FunnelIssueDetails),
|
||||
Multiview: withSiteIdUpdater(components.MultiviewPure),
|
||||
UsabilityTesting: withSiteIdUpdater(components.UsabilityTestingPure),
|
||||
UsabilityTestEdit: withSiteIdUpdater(components.UsabilityTestEditPure),
|
||||
|
|
@ -85,9 +77,6 @@ const FFLAG_READ_PATH = routes.fflagRead();
|
|||
const NOTES_PATH = routes.notes();
|
||||
const BOOKMARKS_PATH = routes.bookmarks();
|
||||
const RECORDINGS_PATH = routes.recordings();
|
||||
const FUNNEL_PATH = routes.funnels();
|
||||
const FUNNEL_CREATE_PATH = routes.funnelsCreate();
|
||||
const FUNNEL_ISSUE_PATH = routes.funnelIssue();
|
||||
const SESSION_PATH = routes.session();
|
||||
const CLIENT_PATH = routes.client();
|
||||
const ONBOARDING_PATH = routes.onboarding();
|
||||
|
|
@ -246,24 +235,6 @@ function PrivateRoutes() {
|
|||
path={withSiteId(HIGHLIGHTS_PATH, siteIdList)}
|
||||
component={enhancedComponents.Highlights}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
strict
|
||||
path={withSiteId(FUNNEL_PATH, siteIdList)}
|
||||
component={enhancedComponents.FunnelPage}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
strict
|
||||
path={withSiteId(FUNNEL_CREATE_PATH, siteIdList)}
|
||||
component={enhancedComponents.FunnelsDetails}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
strict
|
||||
path={withSiteId(FUNNEL_ISSUE_PATH, siteIdList)}
|
||||
component={enhancedComponents.FunnelIssue}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
strict
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import stl from './notifications.module.css';
|
||||
import { Icon, Tooltip } from 'UI';
|
||||
import { Icon } from 'UI';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import AlertTriggersModal from 'Shared/AlertTriggersModal';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Badge, Button } from 'antd';
|
||||
import { Badge, Button, Tooltip } from 'antd';
|
||||
import { BellOutlined } from '@ant-design/icons';
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import React, { useState } from 'react'
|
||||
import stl from './ChatControls.module.css'
|
||||
import cn from 'classnames'
|
||||
import { Button, Icon } from 'UI'
|
||||
import { Icon } from 'UI'
|
||||
import { Button } from 'antd'
|
||||
import type { LocalStream } from 'Player';
|
||||
|
||||
|
||||
interface Props {
|
||||
stream: LocalStream | null,
|
||||
endCall: () => void,
|
||||
|
|
@ -35,17 +35,15 @@ function ChatControls({ stream, endCall, videoEnabled, setVideoEnabled, isPresta
|
|||
|
||||
return (
|
||||
<div className={cn(stl.controls, "flex items-center w-full justify-start bottom-0 px-2")}>
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className={cn(stl.btnWrapper, { [stl.disabled]: audioEnabled})}>
|
||||
<Button variant="text" onClick={toggleAudio} hover>
|
||||
<Icon name={audioEnabled ? 'mic' : 'mic-mute'} size="16" />
|
||||
<Button size={'small'} variant="text" onClick={toggleAudio} icon={<Icon name={audioEnabled ? 'mic' : 'mic-mute'} size="16" />}>
|
||||
<span className={cn("ml-1 color-gray-medium text-sm", { 'color-red' : audioEnabled })}>{audioEnabled ? 'Mute' : 'Unmute'}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className={cn(stl.btnWrapper, { [stl.disabled]: videoEnabled})}>
|
||||
<Button variant="text" onClick={toggleVideo} hover>
|
||||
<Icon name={ videoEnabled ? 'camera-video' : 'camera-video-off' } size="16" />
|
||||
<Button size={'small'} variant="text" onClick={toggleVideo} icon={<Icon name={ videoEnabled ? 'camera-video' : 'camera-video-off' } size="16" />}>
|
||||
<span className={cn("ml-1 color-gray-medium text-sm", { 'color-red' : videoEnabled })}>{videoEnabled ? 'Stop Video' : 'Start Video'}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useObserver } from 'mobx-react-lite';
|
||||
import React from 'react';
|
||||
import { Button, Modal, Form, Icon, Input } from 'UI';
|
||||
import { Modal, Form, Icon, Input } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
|
||||
interface Props {
|
||||
show: boolean;
|
||||
|
|
@ -57,7 +58,7 @@ function EditRecordingModal(props: Props) {
|
|||
<Modal.Footer>
|
||||
<div className="-mx-2 px-2">
|
||||
<Button
|
||||
variant="primary"
|
||||
type="primary"
|
||||
onClick={ save }
|
||||
className="float-left mr-2"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { INDEXES } from 'App/constants/zindex';
|
||||
import { Button, Loader, Icon } from 'UI';
|
||||
import { Loader, Icon } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import { useStore } from "App/mstore";
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
|
@ -76,7 +77,7 @@ function RequestingWindow({ getWindowType }: Props) {
|
|||
</div>
|
||||
<span>{WIN_VARIANTS[windowType].text}</span>
|
||||
<Loader size={30} style={{ minHeight: 60 }} />
|
||||
<Button variant="text-primary" onClick={actions[WIN_VARIANTS[windowType].action]}>
|
||||
<Button variant="text" onClick={actions[WIN_VARIANTS[windowType].action]}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Button, Tooltip } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import cn from 'classnames';
|
||||
import ChatWindow from '../../ChatWindow';
|
||||
import { CallingState, ConnectionStatus, RemoteControlStatus, RequestLocalStream } from 'Player';
|
||||
|
|
@ -7,7 +7,7 @@ import type { LocalStream } from 'Player';
|
|||
import { PlayerContext, ILivePlayerContext } from 'App/components/Session/playerContext';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { toast } from 'react-toastify';
|
||||
import { confirm } from 'UI';
|
||||
import { confirm, Icon, Tooltip } from 'UI';
|
||||
import stl from './AassistActions.module.css';
|
||||
import ScreenRecorder from 'App/components/Session_/ScreenRecorder/ScreenRecorder';
|
||||
import { audioContextManager } from 'App/utils/screenRecorder';
|
||||
|
|
@ -213,9 +213,10 @@ function AssistActions({
|
|||
role="button"
|
||||
>
|
||||
<Button
|
||||
icon={annotating ? 'pencil-stop' : 'pencil'}
|
||||
variant={annotating ? 'text-red' : 'text-primary'}
|
||||
icon={<Icon name={annotating ? 'pencil-stop' : 'pencil'} size={16} />}
|
||||
type={'text'}
|
||||
style={{ height: '28px' }}
|
||||
className={annotating ? 'text-red' : 'text-main'}
|
||||
>
|
||||
Annotate
|
||||
</Button>
|
||||
|
|
@ -238,8 +239,9 @@ function AssistActions({
|
|||
role="button"
|
||||
>
|
||||
<Button
|
||||
icon={remoteActive ? 'window-x' : 'remote-control'}
|
||||
variant={remoteActive ? 'text-red' : 'text-primary'}
|
||||
icon={<Icon name={remoteActive ? 'window-x' : 'remote-control'} size={16} />}
|
||||
type={'text'}
|
||||
className={remoteActive ? 'text-red' : 'text-main'}
|
||||
style={{ height: '28px' }}
|
||||
>
|
||||
Remote Control
|
||||
|
|
@ -264,8 +266,9 @@ function AssistActions({
|
|||
role="button"
|
||||
>
|
||||
<Button
|
||||
icon="headset"
|
||||
variant={onCall ? 'text-red' : isPrestart ? 'green' : 'primary'}
|
||||
icon={<Icon name={'headset'} size={16} />}
|
||||
type={'text'}
|
||||
className={onCall ? 'text-red' : isPrestart ? 'text-green' : 'text-main'}
|
||||
style={{ height: '28px' }}
|
||||
>
|
||||
{onCall ? 'End' : isPrestart ? 'Join Call' : 'Call'}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { PageTitle, Icon, Button } from 'UI';
|
||||
import { PageTitle, Icon } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import AuditList from '../AuditList';
|
||||
import AuditSearchField from '../AuditSearchField';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
|
@ -61,8 +62,7 @@ function AuditView() {
|
|||
auditStore.updateKey('page', 1)
|
||||
} }/>
|
||||
<div>
|
||||
<Button variant="text-primary" className="ml-3" onClick={exportToCsv}>
|
||||
<Icon name="grid-3x3" color="teal" />
|
||||
<Button type="text" icon={<Icon name="grid-3x3" color="teal" />} className="ml-3" onClick={exportToCsv}>
|
||||
<span className="ml-2">Export to CSV</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import { Button } from 'UI';
|
||||
import { Icon } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import styles from './listItem.module.css';
|
||||
|
||||
const ListItem = ({ field, onEdit, disabled }) => {
|
||||
|
|
@ -17,7 +18,7 @@ const ListItem = ({ field, onEdit, disabled }) => {
|
|||
>
|
||||
<span>{field.key}</span>
|
||||
<div className="invisible group-hover:visible" data-hidden={field.index === 0}>
|
||||
<Button variant="text-primary" icon="pencil" />
|
||||
<Button type="text" icon={<Icon name={"pencil"} size={16} />} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ import React from 'react';
|
|||
|
||||
import { useStore } from 'App/mstore';
|
||||
import { namedStore } from 'App/mstore/integrationsStore';
|
||||
import { Button, Checkbox, Form, Input, Loader } from 'UI';
|
||||
import { Checkbox, Form, Input, Loader } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
function IntegrationForm(props: any) {
|
||||
|
|
@ -97,7 +98,7 @@ function IntegrationForm(props: any) {
|
|||
onClick={save}
|
||||
disabled={!config?.validate()}
|
||||
loading={loading}
|
||||
variant="primary"
|
||||
type="primary"
|
||||
className="float-left mr-2"
|
||||
>
|
||||
{config?.exists() ? 'Update' : 'Add'}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Form, Input, Button, Message } from 'UI';
|
||||
import { confirm } from 'UI';
|
||||
import { Form, Input, Message, confirm } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useStore } from 'App/mstore'
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ function SlackAddForm(props) {
|
|||
onClick={save}
|
||||
disabled={!instance.validate()}
|
||||
loading={saving}
|
||||
variant="primary"
|
||||
type="primary"
|
||||
className="float-left mr-2"
|
||||
>
|
||||
{instance.exists() ? 'Update' : 'Add'}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import SlackChannelList from './SlackChannelList/SlackChannelList';
|
||||
import SlackAddForm from './SlackAddForm';
|
||||
import { Button } from 'UI';
|
||||
import { Icon } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useStore } from 'App/mstore'
|
||||
|
||||
|
|
@ -34,7 +35,7 @@ const SlackForm = () => {
|
|||
<div className="shrink-0" style={{ width: '350px' }}>
|
||||
<div className="flex items-center p-5">
|
||||
<h3 className="text-2xl mr-3">Slack</h3>
|
||||
<Button rounded={true} icon="plus" iconSize={24} variant="outline" onClick={onNew}/>
|
||||
<Button shape={'circle'} type={'text'} icon={<Icon name={"plus"} size={24} />} onClick={onNew}/>
|
||||
</div>
|
||||
<SlackChannelList onEdit={onEdit} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import { observer } from 'mobx-react-lite';
|
|||
import React from 'react';
|
||||
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Button, Form, Input, Message } from 'UI';
|
||||
import { confirm } from 'UI';
|
||||
import { confirm, Form, Input, Message } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
|
||||
interface Props {
|
||||
onClose: () => void;
|
||||
|
|
@ -83,7 +83,7 @@ function TeamsAddForm({ onClose }: Props) {
|
|||
onClick={save}
|
||||
disabled={!instance?.validate()}
|
||||
loading={saving}
|
||||
variant="primary"
|
||||
type="primary"
|
||||
className="float-left mr-2"
|
||||
>
|
||||
{instance?.exists() ? 'Update' : 'Add'}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import TeamsChannelList from './TeamsChannelList';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Icon } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
|
||||
import TeamsChannelList from './TeamsChannelList';
|
||||
import TeamsAddForm from './TeamsAddForm';
|
||||
import { Button } from 'UI';
|
||||
|
||||
const MSTeams = () => {
|
||||
const { integrationsStore } = useStore();
|
||||
|
|
@ -35,7 +36,7 @@ const MSTeams = () => {
|
|||
<div className="shrink-0" style={{ width: '350px' }}>
|
||||
<div className="flex items-center p-5">
|
||||
<h3 className="text-2xl mr-3">Microsoft Teams</h3>
|
||||
<Button rounded={true} icon="plus" iconSize={24} variant="outline" onClick={onNew}/>
|
||||
<Button shape={'circle'} icon={<Icon name={'plus'} size={24} />} type="text" onClick={onNew}/>
|
||||
</div>
|
||||
<TeamsChannelList onEdit={onEdit} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import cn from 'classnames';
|
||||
import stl from './notifications.module.css';
|
||||
import { Toggler } from 'UI';
|
||||
import { Switch } from 'antd'
|
||||
import { useStore } from "App/mstore";
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import withPageTitle from 'HOCs/withPageTitle';
|
||||
|
|
@ -25,12 +25,13 @@ function Notifications() {
|
|||
<div className="">
|
||||
<div className="text-lg font-medium">Weekly project summary</div>
|
||||
<div className="mb-4">Receive weekly report for each project on email.</div>
|
||||
<Toggler
|
||||
<div className={'flex items-center gap-2'}>
|
||||
<Switch
|
||||
checked={weeklyReportStore.weeklyReport}
|
||||
name="test"
|
||||
onChange={onChange}
|
||||
label={weeklyReportStore.weeklyReport ? 'Yes' : 'No'}
|
||||
/>
|
||||
<span>{weeklyReportStore.weeklyReport ? 'Yes' : 'No'}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useState, useCallback } from 'react';
|
||||
import { Button, Message, Form, Input } from 'UI';
|
||||
import { Message, Form, Input } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import styles from './profileSettings.module.css';
|
||||
import { validatePassword } from 'App/validate';
|
||||
import { PASSWORD_POLICY } from 'App/constants';
|
||||
|
|
@ -121,7 +122,7 @@ const ChangePassword = () => {
|
|||
{PASSWORD_POLICY}
|
||||
</Message>
|
||||
<div className="flex items-center pt-3">
|
||||
<Button type="submit" variant="outline" disabled={isSubmitDisabled()} loading={loading}>
|
||||
<Button htmlType="submit" type="default" disabled={isSubmitDisabled()} loading={loading}>
|
||||
Change Password
|
||||
</Button>
|
||||
<Button
|
||||
|
|
@ -139,7 +140,7 @@ const ChangePassword = () => {
|
|||
</Form>
|
||||
) : (
|
||||
<div onClick={() => setShow(true)}>
|
||||
<Button variant="text-primary">Change Password</Button>
|
||||
<Button type="text">Change Password</Button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Button, Input, Form } from 'UI';
|
||||
import { Input, Form } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import styles from './profileSettings.module.css';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
|
@ -61,7 +62,7 @@ function Settings() {
|
|||
/>
|
||||
</Form.Field>
|
||||
|
||||
<Button variant="outline" loading={loading} disabled={!changed} type="submit">
|
||||
<Button type="default" loading={loading} disabled={!changed} htmlType="submit">
|
||||
{'Update'}
|
||||
</Button>
|
||||
</Form>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import { Form, Input, Button } from "UI";
|
||||
import { Form, Input } from "UI";
|
||||
import { Button } from 'antd';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
||||
|
|
@ -29,8 +30,7 @@ function TenantKey() {
|
|||
value={ tenantKey }
|
||||
leadingButton={
|
||||
<Button
|
||||
variant="text-primary"
|
||||
role="button"
|
||||
type="text"
|
||||
onClick={ copyHandler }
|
||||
>
|
||||
{ copied ? 'Copied' : 'Copy' }
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import React, { useEffect } from 'react';
|
|||
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Button, Loader, NoContent, Tooltip } from 'UI';
|
||||
import { confirm } from 'UI';
|
||||
import { Loader, NoContent, Tooltip, confirm } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
|
||||
import RoleForm from './components/RoleForm';
|
||||
import RoleItem from './components/RoleItem';
|
||||
|
|
@ -68,7 +68,7 @@ function Roles() {
|
|||
title="You don’t have the permissions to perform this action."
|
||||
disabled={isAdmin}
|
||||
>
|
||||
<Button variant="primary" onClick={() => editHandler({})}>
|
||||
<Button type="primary" onClick={() => editHandler({})}>
|
||||
Add
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ import { observer } from 'mobx-react-lite';
|
|||
import React, { useEffect, useRef } from 'react';
|
||||
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Button, Checkbox, Form, Icon, Input } from 'UI';
|
||||
import { Checkbox, Form, Icon, Input } from 'UI';
|
||||
|
||||
import stl from './roleForm.module.css';
|
||||
import { Select } from 'antd';
|
||||
import { Select, Button } from 'antd';
|
||||
import { SelectProps } from 'antd/es/select';
|
||||
|
||||
interface Props {
|
||||
|
|
@ -220,7 +220,7 @@ const RoleForm = (props: Props) => {
|
|||
onClick={_save}
|
||||
disabled={!role.validate}
|
||||
loading={saving}
|
||||
variant="primary"
|
||||
type="primary"
|
||||
className="float-left mr-2"
|
||||
>
|
||||
{role.exists() ? 'Update' : 'Add'}
|
||||
|
|
@ -228,7 +228,7 @@ const RoleForm = (props: Props) => {
|
|||
{role.exists() && <Button onClick={closeModal}>{'Cancel'}</Button>}
|
||||
</div>
|
||||
{role.exists() && (
|
||||
<Button variant="text" onClick={() => props.deleteHandler(role)}>
|
||||
<Button type="text" onClick={() => props.deleteHandler(role)}>
|
||||
<Icon name="trash" size="18" />
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Icon, Link, Button } from 'UI';
|
||||
import { Icon, Link } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import stl from './roleItem.module.css';
|
||||
import cn from 'classnames';
|
||||
import { CLIENT_TABS, client as clientRoute } from 'App/routes';
|
||||
|
|
@ -46,7 +47,7 @@ function RoleItem({ role, editHandler, isAdmin, permissions, projects }: Props)
|
|||
|
||||
<div className={cn(stl.actions, 'absolute right-0 top-0 bottom-0 mr-8 invisible group-hover:visible')}>
|
||||
{isAdmin && !!editHandler && (
|
||||
<Button variant="text-primary" icon="pencil" disabled={role.protected} onClick={() => editHandler(role)} />
|
||||
<Button type="text" icon={<Icon name={"pencil"} />} disabled={role.protected} onClick={() => editHandler(role)} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Tooltip, Button } from 'UI';
|
||||
import { Tooltip } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
|
|
@ -24,7 +25,7 @@ function AddProjectButton({ isAdmin = false }: any) {
|
|||
title={`${!isAdmin ? PERMISSION_WARNING : !canAddProject ? LIMIT_WARNING : 'Add a Project'}`}
|
||||
disabled={isAdmin || canAddProject}
|
||||
>
|
||||
<Button variant="primary" onClick={onClick} disabled={!canAddProject || !isAdmin}>
|
||||
<Button type="primary" onClick={onClick} disabled={!canAddProject || !isAdmin}>
|
||||
Add Project
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
import React from 'react';
|
||||
import { Input, Button, Icon } from 'UI';
|
||||
import styles from './blockedIps.module.css';
|
||||
|
||||
class BlockedIps extends React.PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<div className={ styles.wrapper }>
|
||||
<h4>{ 'Block IP' }</h4>
|
||||
<div className={ styles.content }>
|
||||
<label>{ 'List of IPs or Subnets to be blocked.' }</label>
|
||||
<div className={ styles.inputWrapper }>
|
||||
<Input type="text" />
|
||||
<Button primary outline >{ 'Block' }</Button>
|
||||
</div>
|
||||
|
||||
<div className={ styles.list }>
|
||||
<div className={ styles.item }>
|
||||
<div>{ '192.128.2.1' }</div>
|
||||
<div className={ styles.actions }>
|
||||
<Icon name="trash" size="14" color="gray-medium" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default BlockedIps;
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import React from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from "App/mstore";
|
||||
import { Form, Button, Input, Icon } from 'UI';
|
||||
import { Form, Input, Icon } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { validateNumber } from 'App/validate';
|
||||
import styles from './siteForm.module.css';
|
||||
import Select from 'Shared/Select';
|
||||
|
|
@ -115,12 +116,13 @@ function GDPRForm(props) {
|
|||
|
||||
<div className={ styles.footer }>
|
||||
<Button
|
||||
variant="outline"
|
||||
type="primary"
|
||||
className="float-left mr-2"
|
||||
loading={ saving }
|
||||
content="Update"
|
||||
/>
|
||||
<Button onClick={ onClose } content="Cancel" />
|
||||
>
|
||||
Update
|
||||
</Button>
|
||||
<Button onClick={ onClose }>Close</Button>
|
||||
</div>
|
||||
</Form>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useModal } from 'App/components/Modal';
|
||||
import React from 'react';
|
||||
import TrackingCodeModal from 'Shared/TrackingCodeModal';
|
||||
import { Button } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
|
||||
interface Props {
|
||||
site: any;
|
||||
|
|
@ -16,7 +16,7 @@ function InstallButton(props: Props) {
|
|||
);
|
||||
};
|
||||
return (
|
||||
<Button size="small" variant="text-primary" onClick={onClick}>
|
||||
<Button size="small" type="text" onClick={onClick}>
|
||||
{'Installation Steps'}
|
||||
</Button>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ import React, { ChangeEvent, FormEvent, useEffect, useState } from 'react';
|
|||
import { RouteComponentProps, withRouter } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Button, Form, Icon, Input } from 'UI';
|
||||
import { confirm } from 'UI';
|
||||
import { confirm, Form, Icon, Input } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
import styles from './siteForm.module.css';
|
||||
|
|
@ -141,8 +141,8 @@ const NewSiteForm = ({ location: { pathname }, onClose }: Props) => {
|
|||
</Form.Field>
|
||||
<div className="mt-6 flex justify-between">
|
||||
<Button
|
||||
variant="primary"
|
||||
type="submit"
|
||||
type="primary"
|
||||
htmlType="submit"
|
||||
className="float-left mr-2"
|
||||
loading={loading}
|
||||
disabled={!site.validate}
|
||||
|
|
@ -151,8 +151,7 @@ const NewSiteForm = ({ location: { pathname }, onClose }: Props) => {
|
|||
</Button>
|
||||
{site.exists() && (
|
||||
<Button
|
||||
variant="text"
|
||||
type="button"
|
||||
type="text"
|
||||
onClick={handleRemove}
|
||||
disabled={!canDelete}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React, { useState } from 'react';
|
||||
import { Tag } from 'antd';
|
||||
import cn from 'classnames';
|
||||
import { Loader, Button, TextLink, NoContent, Pagination, PageTitle, Divider, Icon } from 'UI';
|
||||
import { Loader, TextLink, NoContent, Pagination, PageTitle, Divider, Icon } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import withPageTitle from 'HOCs/withPageTitle';
|
||||
import stl from './sites.module.css';
|
||||
import NewSiteForm from './NewSiteForm';
|
||||
|
|
@ -52,7 +53,7 @@ const Sites = () => {
|
|||
showModal(<NewSiteForm onClose={hideModal} />, { right: true });
|
||||
};
|
||||
|
||||
return <Button icon="edit" variant="text-primary" disabled={!isAdmin} onClick={_onClick} />;
|
||||
return <Button icon={<Icon name={"edit"} />} type="text" disabled={!isAdmin} onClick={_onClick} />;
|
||||
};
|
||||
|
||||
const captureRateClickHandler = (project: Project) => {
|
||||
|
|
@ -88,12 +89,12 @@ const Sites = () => {
|
|||
<ProjectKey value={project.projectKey} tooltip="Project key copied to clipboard" />
|
||||
</div>
|
||||
<div className="col-span-3 flex items-center">
|
||||
<Button variant="text-primary" onClick={() => captureRateClickHandler(project)}>
|
||||
<Button type="text" onClick={() => captureRateClickHandler(project)}>
|
||||
{project.sampleRate}%
|
||||
</Button>
|
||||
{project.conditionsCount > 0 ? (
|
||||
<Button
|
||||
variant="text-primary"
|
||||
variant="text"
|
||||
onClick={() => captureRateClickHandler(project)}
|
||||
className="ml-2"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
.wrapper {
|
||||
width: 300px;
|
||||
padding: 20px;
|
||||
& label {
|
||||
color: $gray-medium;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.inputWrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.list {
|
||||
margin-top: 20px;
|
||||
display: none; /* TODO enable this once the API is Ready */
|
||||
& .item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: solid thin $gray-light;
|
||||
padding: 8px 5px;
|
||||
|
||||
&:hover {
|
||||
background-color: $active-blue;
|
||||
& .actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
& .actions {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Tooltip, Button } from 'UI';
|
||||
import { Tooltip } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { useStore } from 'App/mstore';
|
||||
import { useObserver } from 'mobx-react-lite';
|
||||
|
||||
|
|
@ -17,7 +18,7 @@ function AddUserButton({ isAdmin = false, onClick, btnVariant = 'primary' }: any
|
|||
title={`${!isAdmin ? PERMISSION_WARNING : !cannAddUser ? LIMIT_WARNING : 'Add team member'}`}
|
||||
disabled={isAdmin || cannAddUser}
|
||||
>
|
||||
<Button disabled={!cannAddUser || !isAdmin} variant={btnVariant} onClick={onClick}>
|
||||
<Button disabled={!cannAddUser || !isAdmin} type={btnVariant} onClick={onClick}>
|
||||
Add Team Member
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import React from 'react';
|
|||
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Button, CopyButton, Form, Icon, Input } from 'UI';
|
||||
import { confirm } from 'UI';
|
||||
import { confirm, CopyButton, Form, Icon, Input } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
|
||||
import Select from 'Shared/Select';
|
||||
|
||||
|
|
@ -139,22 +139,20 @@ function UserForm() {
|
|||
onClick={onSave}
|
||||
disabled={!user.valid(isEnterprise) || isSaving}
|
||||
loading={isSaving}
|
||||
variant="primary"
|
||||
type="primary"
|
||||
className="float-left mr-2"
|
||||
>
|
||||
{user.exists() ? 'Update' : 'Invite'}
|
||||
</Button>
|
||||
{user.exists() && <Button onClick={hideModal}>{'Cancel'}</Button>}
|
||||
</div>
|
||||
<div>
|
||||
<Button
|
||||
disabled={user.isSuperAdmin}
|
||||
data-hidden={!user.exists()}
|
||||
onClick={deleteHandler}
|
||||
>
|
||||
<Icon name="trash" size="16" />
|
||||
</Button>
|
||||
</div>
|
||||
{!user.exists() ? null :
|
||||
<div>
|
||||
<Button disabled={user.isSuperAdmin} onClick={deleteHandler}>
|
||||
<Icon name="trash" size="16" />
|
||||
</Button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
{!user.isJoined && user.invitationLink && (
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//@ts-nocheck
|
||||
import React from 'react';
|
||||
import { Button, Tooltip } from 'UI';
|
||||
import { Tooltip, Icon } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { checkForRecent } from 'App/date';
|
||||
import cn from 'classnames';
|
||||
|
||||
|
|
@ -79,9 +80,8 @@ function UserListItem(props: Props) {
|
|||
{!user.isJoined && user.invitationLink && !user.isExpiredInvite && (
|
||||
<Tooltip title="Copy Invite Code" hideOnClick={true}>
|
||||
<Button
|
||||
variant="text-primary"
|
||||
icon="link-45deg"
|
||||
className=""
|
||||
type="text"
|
||||
icon={<Icon name={"link-45deg"} />}
|
||||
onClick={copyInviteCode}
|
||||
/>
|
||||
</Tooltip>
|
||||
|
|
@ -90,15 +90,14 @@ function UserListItem(props: Props) {
|
|||
{!user.isJoined && user.isExpiredInvite && (
|
||||
<Tooltip title="Generate Invite" hideOnClick={true}>
|
||||
<Button
|
||||
icon="link-45deg"
|
||||
variant="text-primary"
|
||||
className=""
|
||||
icon={<Icon name={"link-45deg"} />}
|
||||
variant="text"
|
||||
onClick={generateInvite}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
<Button variant="text-primary" icon="pencil" />
|
||||
<Button variant="text" icon={<Icon name={"pencil"} />} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import { Button } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import stl from './table.module.css';
|
||||
|
||||
export default class Table extends React.PureComponent {
|
||||
|
|
@ -56,7 +56,7 @@ export default class Table extends React.PureComponent {
|
|||
<div className="w-full flex justify-center mt-2">
|
||||
<Button
|
||||
onClick={ this.onLoadMoreClick }
|
||||
variant="text-primary"
|
||||
type="text"
|
||||
>
|
||||
{ rows.size + ' More' }
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react'
|
||||
import { Button, Icon } from 'UI'
|
||||
import { Icon } from 'UI'
|
||||
import { Button } from 'antd'
|
||||
|
||||
interface IBottomButtons {
|
||||
loading: boolean
|
||||
|
|
@ -14,8 +15,7 @@ function BottomButtons({ loading, instance, deleting, onDelete }: IBottomButtons
|
|||
<div className="flex items-center">
|
||||
<Button
|
||||
loading={loading}
|
||||
variant="primary"
|
||||
type="submit"
|
||||
type="primary"
|
||||
disabled={loading || !instance.validate()}
|
||||
id="submit-button"
|
||||
>
|
||||
|
|
@ -25,10 +25,8 @@ function BottomButtons({ loading, instance, deleting, onDelete }: IBottomButtons
|
|||
<div>
|
||||
{instance.exists() && (
|
||||
<Button
|
||||
hover
|
||||
variant="text"
|
||||
type="text"
|
||||
loading={deleting}
|
||||
type="button"
|
||||
onClick={() => onDelete(instance)}
|
||||
id="trash-button"
|
||||
className="!text-teal !fill-teal"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer, useObserver } from 'mobx-react-lite';
|
||||
import { Button, Loader, NoContent, Pagination } from 'UI';
|
||||
import { Loader, NoContent, Pagination } from 'UI';
|
||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||
import { InfoCircleOutlined } from '@ant-design/icons';
|
||||
import { debounce } from 'App/utils';
|
||||
|
|
@ -10,7 +10,7 @@ import CardIssueItem from './CardIssueItem';
|
|||
import SessionsModal from '../SessionsModal';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import Issue from 'App/mstore/types/issue';
|
||||
import { List } from 'antd';
|
||||
import { List, Button } from 'antd';
|
||||
|
||||
function CardIssues() {
|
||||
const { metricStore, dashboardStore } = useStore();
|
||||
|
|
@ -104,8 +104,8 @@ function CardIssues() {
|
|||
)}
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
{hasFilters && <Button variant="text-primary" onClick={clearFilters}>Clear Filters</Button>}
|
||||
<Button variant="text-primary" onClick={() => handleClick()}>All Sessions</Button>
|
||||
{hasFilters && <Button type="text" onClick={clearFilters}>Clear Filters</Button>}
|
||||
<Button type="text" onClick={() => handleClick()}>All Sessions</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import { useModal } from 'App/components/Modal';
|
|||
import { observer } from 'mobx-react-lite';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { RouteComponentProps, withRouter } from 'react-router';
|
||||
import { Loader, Pagination, Button } from 'UI';
|
||||
import { Loader, Pagination } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import SessionsModal from './SessionsModal';
|
||||
import CardUserItem from './CardUserItem';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
|
@ -45,7 +46,7 @@ function CardUserList(props: RouteComponentProps<Props>) {
|
|||
<div className="flex justify-between">
|
||||
<h1 className="font-medium text-2xl">Returning users between</h1>
|
||||
<div>
|
||||
<Button variant="text-primary">All Sessions</Button>
|
||||
<Button type="text">All Sessions</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { useObserver } from 'mobx-react-lite';
|
||||
import DashboardMetricSelection from '../DashboardMetricSelection';
|
||||
import DashboardForm from '../DashboardForm';
|
||||
import { Button } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import { withRouter, RouteComponentProps } from 'react-router-dom';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
|
|
@ -67,7 +67,7 @@ function DashboardModal(props: Props) {
|
|||
|
||||
<div className="flex items-center absolute bottom-0 left-0 right-0 bg-white border-t p-3">
|
||||
<Button
|
||||
variant="primary"
|
||||
type="primary"
|
||||
disabled={!dashboard.isValid || loading}
|
||||
onClick={onSave}
|
||||
className="flaot-left mr-2"
|
||||
|
|
|
|||
|
|
@ -1,83 +0,0 @@
|
|||
import {useObserver} from 'mobx-react-lite';
|
||||
import React from 'react';
|
||||
import {Button, Modal, Form, Icon} from 'UI';
|
||||
|
||||
import {useStore} from 'App/mstore'
|
||||
import Select from 'Shared/Select';
|
||||
|
||||
interface Props {
|
||||
metricId: string,
|
||||
show: boolean;
|
||||
closeHandler?: () => void;
|
||||
}
|
||||
|
||||
function DashboardSelectionModal(props: Props) {
|
||||
const {show, metricId, closeHandler} = props;
|
||||
const {dashboardStore} = useStore();
|
||||
const dashboardOptions = dashboardStore.dashboards.map((i: any) => ({
|
||||
key: i.id,
|
||||
label: i.name,
|
||||
value: i.dashboardId,
|
||||
}));
|
||||
const [selectedId, setSelectedId] = React.useState(dashboardOptions[0].value);
|
||||
|
||||
const onSave = () => {
|
||||
const dashboard = dashboardStore.getDashboard(selectedId)
|
||||
if (dashboard) {
|
||||
dashboardStore.addWidgetToDashboard(dashboard, [metricId]).then(closeHandler)
|
||||
}
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleEsc = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Escape' || e.key === 'Esc') {
|
||||
closeHandler();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', handleEsc, false);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('keydown', handleEsc, false);
|
||||
}
|
||||
}, [])
|
||||
|
||||
return useObserver(() => (
|
||||
<Modal size="small" open={show} onClose={closeHandler}>
|
||||
<Modal.Header className="flex items-center justify-between">
|
||||
<div className='text-xl font-medium'>{'Add to selected dashboard'}</div>
|
||||
<Icon
|
||||
role="button"
|
||||
tabIndex="-1"
|
||||
color="gray-dark"
|
||||
size="14"
|
||||
name="close"
|
||||
onClick={closeHandler}
|
||||
/>
|
||||
</Modal.Header>
|
||||
|
||||
<Modal.Content>
|
||||
<Form.Field>
|
||||
<label className="mb-2">{'Dashbaord:'}</label>
|
||||
<Select
|
||||
options={dashboardOptions}
|
||||
defaultValue={dashboardOptions[0].value}
|
||||
onChange={({value}: any) => setSelectedId(value.value)}
|
||||
/>
|
||||
</Form.Field>
|
||||
</Modal.Content>
|
||||
<Modal.Footer>
|
||||
<Button
|
||||
variant="primary"
|
||||
onClick={onSave}
|
||||
className="float-left mr-2 "
|
||||
>
|
||||
Add
|
||||
</Button>
|
||||
<Button className="mr-2" onClick={closeHandler}>{'Cancel'}</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
));
|
||||
}
|
||||
|
||||
export default DashboardSelectionModal;
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Button, Loader } from 'UI';
|
||||
import { Loader } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import WidgetWrapper from 'App/components/Dashboard/components/WidgetWrapper';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
|
|
@ -63,7 +64,7 @@ function AddMetric({ history, siteId, title, description }: IProps) {
|
|||
<div className="text-disabled-text">{description}</div>
|
||||
</div>
|
||||
|
||||
<Button variant="text-primary" className="font-medium ml-2" onClick={onCreateNew}>
|
||||
<Button variant="text" className="text-main font-medium ml-2" onClick={onCreateNew}>
|
||||
+ Create New
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -100,7 +101,7 @@ function AddMetric({ history, siteId, title, description }: IProps) {
|
|||
{' out of '}
|
||||
<span className="font-medium">{metrics ? metrics.length : 0}</span>
|
||||
</div>
|
||||
<Button variant="primary" disabled={selectedWidgetIds.length === 0} onClick={onSave}>
|
||||
<Button type="primary" disabled={selectedWidgetIds.length === 0} onClick={onSave}>
|
||||
Add Selected
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Button, Loader } from 'UI';
|
||||
import { Loader } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import WidgetWrapper from 'App/components/Dashboard/components/WidgetWrapper';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
|
|
@ -79,7 +80,7 @@ function AddPredefinedMetric({ history, siteId, title, description }: IProps) {
|
|||
</div>
|
||||
|
||||
<div className="flex flex-col items-end">
|
||||
<Button variant="text-primary" className="font-medium ml-2" onClick={onCreateNew}>
|
||||
<Button type="text" className="text-main font-medium ml-2" onClick={onCreateNew}>
|
||||
+ Create Custom Metric
|
||||
</Button>
|
||||
<div className="text-disabled-text">Past 7 Days</div>
|
||||
|
|
@ -145,7 +146,7 @@ function AddPredefinedMetric({ history, siteId, title, description }: IProps) {
|
|||
{' out of '}
|
||||
<span className="font-medium">{totalMetricCount}</span>
|
||||
</div>
|
||||
<Button variant="primary" disabled={selectedWidgetIds.length === 0} onClick={onSave}>
|
||||
<Button type="primary" disabled={selectedWidgetIds.length === 0} onClick={onSave}>
|
||||
Add Selected
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { useModal } from 'App/components/Modal';
|
|||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import React, { useMemo } from 'react';
|
||||
import { Button } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
|
||||
function FooterContent({ dashboardId, selected }: any) {
|
||||
const { hideModal } = useModal();
|
||||
|
|
@ -27,10 +27,10 @@ function FooterContent({ dashboardId, selected }: any) {
|
|||
<span className="font-medium">{total}</span>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<Button variant="text-primary" className="mr-2" onClick={hideModal}>
|
||||
<Button type="text" className="mr-2" onClick={hideModal}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button disabled={selected.length === 0} variant="primary" onClick={addSelectedToDashboard}>
|
||||
<Button disabled={selected.length === 0} type="primary" onClick={addSelectedToDashboard}>
|
||||
Add Selected to Dashboard
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,15 +1,13 @@
|
|||
import React, {useEffect, useState} from 'react';
|
||||
import {metricOf, issueOptions, issueCategories} from 'App/constants/filterOptions';
|
||||
import { metricOf } from 'App/constants/filterOptions';
|
||||
import {FilterKey} from 'Types/filter/filterType';
|
||||
import {useStore} from 'App/mstore';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
import {Button, Icon, confirm, Tooltip} from 'UI';
|
||||
import {Input, Alert} from 'antd'
|
||||
import { Icon, confirm, Tooltip } from 'UI';
|
||||
import { Input, Alert, Button } from 'antd'
|
||||
import FilterSeries from '../FilterSeries';
|
||||
import Select from 'Shared/Select';
|
||||
import {withSiteId, dashboardMetricDetails, metricDetails} from 'App/routes';
|
||||
import MetricTypeDropdown from './components/MetricTypeDropdown';
|
||||
import MetricSubtypeDropdown from './components/MetricSubtypeDropdown';
|
||||
import { withSiteId, dashboardMetricDetails, metricDetails } from 'App/routes';
|
||||
|
||||
import {
|
||||
TIMESERIES,
|
||||
TABLE,
|
||||
|
|
@ -285,8 +283,8 @@ function WidgetForm(props: Props) {
|
|||
{`${isTable || isFunnel || isClickmap || isInsights || isPathAnalysis || isRetention ? 'Filter by' : 'Chart Series'}`}
|
||||
{!isTable && !isFunnel && !isClickmap && !isInsights && !isPathAnalysis && !isRetention && (
|
||||
<Button
|
||||
className='ml-2'
|
||||
variant='text-primary'
|
||||
className='ml-2 text-main'
|
||||
type='text'
|
||||
onClick={() => metric.addSeries()}
|
||||
disabled={!canAddSeries}
|
||||
>
|
||||
|
|
@ -327,7 +325,7 @@ function WidgetForm(props: Props) {
|
|||
disabled={!cannotSaveFunnel}
|
||||
>
|
||||
<div className='flex items-center'>
|
||||
<Button variant='primary' onClick={onSave} disabled={isSaving || cannotSaveFunnel}>
|
||||
<Button type='primary' onClick={onSave} disabled={isSaving || cannotSaveFunnel}>
|
||||
{metric.exists()
|
||||
? 'Update'
|
||||
: parseInt(dashboardId) > 0
|
||||
|
|
@ -335,7 +333,7 @@ function WidgetForm(props: Props) {
|
|||
: 'Create'}
|
||||
</Button>
|
||||
{metric.exists() && metric.hasChanged && (
|
||||
<Button onClick={undoChanges} variant='text' icon='arrow-counterclockwise' className='ml-2'>
|
||||
<Button onClick={undoChanges} type='text' icon={<Icon name={'arrow-counterclockwise'} />} className='ml-2'>
|
||||
Undo
|
||||
</Button>
|
||||
)}
|
||||
|
|
@ -343,8 +341,7 @@ function WidgetForm(props: Props) {
|
|||
</Tooltip>
|
||||
<div className='flex items-center'>
|
||||
{metric.exists() && (
|
||||
<Button variant='text-primary' onClick={onDelete}>
|
||||
<Icon name='trash' size='14' className='mr-2' color='teal'/>
|
||||
<Button type='text' className={'text-main'} icon={<Icon name='trash' size='14' className='mr-2' color='teal'/>} onClick={onDelete}>
|
||||
Delete
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ import { sessions as sessionsRoute } from 'App/routes';
|
|||
import Divider from 'Components/Errors/ui/Divider';
|
||||
import ErrorName from 'Components/Errors/ui/ErrorName';
|
||||
import Label from 'Components/Errors/ui/Label';
|
||||
import { Button, ErrorDetails, Icon, Loader } from 'UI';
|
||||
import { ErrorDetails, Icon, Loader } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
|
||||
import SessionBar from './SessionBar';
|
||||
|
||||
|
|
@ -81,11 +82,12 @@ function MainSection(props) {
|
|||
</span>
|
||||
<Button
|
||||
className="ml-auto"
|
||||
variant="text-primary"
|
||||
variant="text"
|
||||
onClick={findSessions}
|
||||
icon={<Icon className="ml-1" name="next1" color="teal" />}
|
||||
iconPosition={'end'}
|
||||
>
|
||||
Find all sessions with this error
|
||||
<Icon className="ml-1" name="next1" color="teal" />
|
||||
</Button>
|
||||
</div>
|
||||
<SessionBar className="my-4" session={error.lastHydratedSession} />
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
import React from 'react';
|
||||
import FeatureFlag from 'App/mstore/types/FeatureFlag';
|
||||
import { Icon, Toggler, Link, TextEllipsis, Tooltip } from 'UI';
|
||||
import { Icon, Link, TextEllipsis, Tooltip } from 'UI';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { resentOrDate } from 'App/date';
|
||||
import { toast } from 'react-toastify';
|
||||
import { fflagRead } from "App/routes";
|
||||
import { Switch } from 'antd';
|
||||
|
||||
function FFlagItem({ flag }: { flag: FeatureFlag }) {
|
||||
const { featureFlagsStore, userStore } = useStore();
|
||||
|
|
@ -35,7 +36,10 @@ function FFlagItem({ flag }: { flag: FeatureFlag }) {
|
|||
<div className={'flex items-center'}>
|
||||
<Link style={{ flex: 1 }} to={fflagRead(flag.featureFlagId.toString())}>
|
||||
<div className={'flex items-center gap-2'}>
|
||||
<Tooltip delay={150} title={flag.isSingleOption ? 'Single variant' : 'Multivariant'}>
|
||||
<Tooltip
|
||||
delay={150}
|
||||
title={flag.isSingleOption ? 'Single variant' : 'Multivariant'}
|
||||
>
|
||||
<Icon name={flagIcon} size={32} />
|
||||
</Tooltip>
|
||||
<div className="flex flex-col gap-1" style={{ width: 300 }}>
|
||||
|
|
@ -50,18 +54,27 @@ function FFlagItem({ flag }: { flag: FeatureFlag }) {
|
|||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
<div style={{ flex: 1 }}>{resentOrDate(flag.updatedAt || flag.createdAt)}</div>
|
||||
<div style={{ flex: 1 }} className={'flex items-center gap-2 capitalize'}>
|
||||
<div style={{ flex: 1 }}>
|
||||
{resentOrDate(flag.updatedAt || flag.createdAt)}
|
||||
</div>
|
||||
<div
|
||||
style={{ flex: 1 }}
|
||||
className={'flex items-center gap-2 capitalize'}
|
||||
>
|
||||
<Icon name={'person-fill'} />
|
||||
{user}
|
||||
</div>
|
||||
<div style={{ marginLeft: 'auto', width: 115 }}>
|
||||
<Toggler
|
||||
checked={flag.isActive}
|
||||
name={'persist-flag'}
|
||||
label={flag.isActive ? 'Enabled' : 'Disabled'}
|
||||
onChange={toggleActivity}
|
||||
/>
|
||||
<div
|
||||
style={{
|
||||
marginLeft: 'auto',
|
||||
width: 115,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '0.25rem',
|
||||
}}
|
||||
>
|
||||
<Switch checked={flag.isActive} onChange={toggleActivity} />
|
||||
<div>{flag.isActive ? 'Enabled' : 'Disabled'}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react'
|
||||
import { Button, PageTitle } from 'UI'
|
||||
import { PageTitle } from 'UI'
|
||||
import { Button } from 'antd'
|
||||
import FFlagsSearch from "Components/FFlags/FFlagsSearch";
|
||||
import { useHistory } from "react-router";
|
||||
import { newFFlag, withSiteId } from 'App/routes';
|
||||
|
|
@ -13,7 +14,7 @@ function FFlagsListHeader({ siteId }: { siteId: string }) {
|
|||
<PageTitle title="Feature Flags" />
|
||||
</div>
|
||||
<div className="ml-auto flex items-center">
|
||||
<Button variant="primary" onClick={() => history.push(withSiteId(newFFlag(), siteId))}>
|
||||
<Button type="primary" onClick={() => history.push(withSiteId(newFFlag(), siteId))}>
|
||||
Create Feature Flag
|
||||
</Button>
|
||||
<div className="mx-2"></div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Toggler, Loader, Button, NoContent, ItemMenu } from 'UI';
|
||||
import { Loader, NoContent, ItemMenu } from 'UI';
|
||||
import { Button, Switch } from 'antd'
|
||||
import Breadcrumb from 'Shared/Breadcrumb';
|
||||
import { useHistory } from 'react-router';
|
||||
import { withSiteId, fflag, fflags } from 'App/routes';
|
||||
|
|
@ -59,11 +60,16 @@ function FlagView({ siteId, fflagId }: { siteId: string; fflagId: string }) {
|
|||
<div className={'flex items-center gap-2'}>
|
||||
<div className={'text-2xl'}>{current.flagKey}</div>
|
||||
<Button
|
||||
className={'ml-auto'}
|
||||
variant={'text-primary'}
|
||||
className={'ml-auto text-main'}
|
||||
type={'text'}
|
||||
onClick={() =>
|
||||
history.push(
|
||||
withSiteId(fflag(featureFlagsStore.currentFflag?.featureFlagId.toString()), siteId)
|
||||
withSiteId(
|
||||
fflag(
|
||||
featureFlagsStore.currentFflag?.featureFlagId.toString()
|
||||
),
|
||||
siteId
|
||||
)
|
||||
)
|
||||
}
|
||||
>
|
||||
|
|
@ -72,17 +78,16 @@ function FlagView({ siteId, fflagId }: { siteId: string; fflagId: string }) {
|
|||
<ItemMenu bold items={menuItems} />
|
||||
</div>
|
||||
<div className={'border-b'} style={{ color: 'rgba(0,0,0, 0.6)' }}>
|
||||
{current.description || 'There is no description for this feature flag.'}
|
||||
{current.description ||
|
||||
'There is no description for this feature flag.'}
|
||||
</div>
|
||||
|
||||
<div className={'mt-4'}>
|
||||
<label className={'font-semibold'}>Status</label>
|
||||
<Toggler
|
||||
checked={current.isActive}
|
||||
name={'persist-flag'}
|
||||
onChange={toggleActivity}
|
||||
label={current.isActive ? 'Enabled' : 'Disabled'}
|
||||
/>
|
||||
<div className={'flex items-center gap-2'}>
|
||||
<Switch checked={current.isActive} onChange={toggleActivity} />
|
||||
<div>{current.isActive ? 'Enabled' : 'Disabled'}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={'mt-4'}>
|
||||
<label className={'font-semibold'}>Persistence</label>
|
||||
|
|
@ -92,28 +97,25 @@ function FlagView({ siteId, fflagId }: { siteId: string; fflagId: string }) {
|
|||
: 'This flag is not persistent across authentication events.'}
|
||||
</div>
|
||||
</div>
|
||||
{!current.isSingleOption ? (
|
||||
<Multivariant readonly />
|
||||
{!current.isSingleOption ? <Multivariant readonly /> : null}
|
||||
{current.conditions.length > 0 ? (
|
||||
<div className="mt-6 p-4 rounded bg-gray-lightest">
|
||||
<label className={'font-semibold'}>Rollout Conditions</label>
|
||||
{current.conditions.map((condition, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<RolloutCondition
|
||||
set={index + 1}
|
||||
readonly
|
||||
index={index}
|
||||
conditions={condition}
|
||||
removeCondition={current.removeCondition}
|
||||
/>
|
||||
<div className={'mt-2'} />
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
{current.conditions.length > 0 ? (
|
||||
<div className="mt-6 p-4 rounded bg-gray-lightest">
|
||||
<label className={'font-semibold'}>Rollout Conditions</label>
|
||||
{current.conditions.map((condition, index) => (
|
||||
<React.Fragment key={index}>
|
||||
<RolloutCondition
|
||||
set={index + 1}
|
||||
readonly
|
||||
index={index}
|
||||
conditions={condition}
|
||||
removeCondition={current.removeCondition}
|
||||
/>
|
||||
<div className={'mt-2'} />
|
||||
</React.Fragment>
|
||||
))}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Button } from 'UI';
|
||||
import { Icon } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import cn from 'classnames';
|
||||
import FeatureFlag from 'App/mstore/types/FeatureFlag';
|
||||
|
||||
|
|
@ -46,8 +47,8 @@ function Description({
|
|||
</div>
|
||||
) : (
|
||||
<Button
|
||||
variant={'text-primary'}
|
||||
icon={'edit'}
|
||||
type={'text'}
|
||||
icon={<Icon name={'edit'} size={16} />}
|
||||
onClick={() => setEditing({ isDescrEditing: true })}
|
||||
>
|
||||
Add
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import React from 'react';
|
||||
import { Button } from 'UI';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import cn from 'classnames';
|
||||
import { ItemMenu } from 'UI';
|
||||
|
|
@ -7,6 +6,7 @@ import { useStore } from 'App/mstore';
|
|||
import { useHistory } from 'react-router';
|
||||
import { toast } from 'react-toastify';
|
||||
import { fflags, withSiteId } from "App/routes";
|
||||
import { Button } from 'antd';
|
||||
|
||||
function Header({ current, onCancel, onSave, isNew, siteId }: any) {
|
||||
const { featureFlagsStore } = useStore();
|
||||
|
|
@ -29,10 +29,10 @@ function Header({ current, onCancel, onSave, isNew, siteId }: any) {
|
|||
</div>
|
||||
|
||||
<div className={'flex items-center gap-2'}>
|
||||
<Button variant="text-primary" onClick={onCancel}>
|
||||
<Button type="text" onClick={onCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button variant="primary" onClick={onSave}>
|
||||
<Button type="primary" onClick={onSave}>
|
||||
Save
|
||||
</Button>
|
||||
{!isNew ? <ItemMenu bold items={menuItems} /> : null}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import { Rollout, Payload } from './Helpers';
|
||||
import { Input, Button, Icon } from 'UI';
|
||||
import { Input, Icon } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
import cn from 'classnames';
|
||||
|
|
@ -164,7 +165,7 @@ function Multivariant({ readonly }: { readonly?: boolean }) {
|
|||
{readonly ? null : (
|
||||
<div className={'mt-2 flex justify-between w-full'}>
|
||||
{featureFlagsStore.currentFflag!.variants.length < 10 ? (
|
||||
<Button variant={'text-primary'} onClick={featureFlagsStore.currentFflag!.addVariant}>
|
||||
<Button type={'text'} onClick={featureFlagsStore.currentFflag!.addVariant}>
|
||||
+ Add Variant
|
||||
</Button>
|
||||
) : null}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import React from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Input, SegmentSelection, Toggler, Loader, Button, NoContent } from 'UI';
|
||||
import { Input, SegmentSelection, Loader, NoContent } from 'UI';
|
||||
import Breadcrumb from 'Shared/Breadcrumb';
|
||||
import { Button, Switch } from 'antd'
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import HowTo from 'Components/FFlags/NewFFlag/HowTo';
|
||||
import {Prompt, useHistory} from 'react-router';
|
||||
|
|
@ -92,7 +93,13 @@ function NewFFlag({ siteId, fflagId }: { siteId: string; fflagId?: string }) {
|
|||
/>
|
||||
<div className={'w-full bg-white rounded p-4 widget-wrapper'}>
|
||||
<div className="flex justify-between items-center">
|
||||
<Header siteId={siteId} current={current} onCancel={onCancel} onSave={onSave} isNew={!fflagId} />
|
||||
<Header
|
||||
siteId={siteId}
|
||||
current={current}
|
||||
onCancel={onCancel}
|
||||
onSave={onSave}
|
||||
isNew={!fflagId}
|
||||
/>
|
||||
</div>
|
||||
<div className={'w-full border-b border-light-gray my-2'} />
|
||||
|
||||
|
|
@ -106,7 +113,9 @@ function NewFFlag({ siteId, fflagId }: { siteId: string; fflagId?: string }) {
|
|||
current.setFlagKey(e.target.value.replace(/\s/g, '-'));
|
||||
}}
|
||||
/>
|
||||
<div className={'text-sm text-disabled-text mt-1 flex items-center gap-1'}>
|
||||
<div
|
||||
className={'text-sm text-disabled-text mt-1 flex items-center gap-1'}
|
||||
>
|
||||
Feature flag keys must be unique.
|
||||
<div className={'link'} onClick={onImplementClick}>
|
||||
Learn how to implement feature flags
|
||||
|
|
@ -142,10 +151,16 @@ function NewFFlag({ siteId, fflagId }: { siteId: string; fflagId?: string }) {
|
|||
</div>
|
||||
{current.isSingleOption ? (
|
||||
<>
|
||||
<div className={'text-sm text-disabled-text mt-1 flex items-center gap-1'}>
|
||||
<div
|
||||
className={
|
||||
'text-sm text-disabled-text mt-1 flex items-center gap-1'
|
||||
}
|
||||
>
|
||||
Users will be served
|
||||
<code className={'p-1 text-red rounded bg-gray-lightest'}>true</code> if they match
|
||||
one or more rollout conditions.
|
||||
<code className={'p-1 text-red rounded bg-gray-lightest'}>
|
||||
true
|
||||
</code>{' '}
|
||||
if they match one or more rollout conditions.
|
||||
</div>
|
||||
<div className={'mt-6'}>
|
||||
<Payload />
|
||||
|
|
@ -156,7 +171,6 @@ function NewFFlag({ siteId, fflagId }: { siteId: string; fflagId?: string }) {
|
|||
}}
|
||||
placeholder={"E.g. red button, {'buttonColor': 'red'}"}
|
||||
className={'mt-2'}
|
||||
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
|
@ -166,50 +180,65 @@ function NewFFlag({ siteId, fflagId }: { siteId: string; fflagId?: string }) {
|
|||
</div>
|
||||
|
||||
<div className={'mt-6'}>
|
||||
<label className={'font-semibold'}>Persist flag across authentication</label>
|
||||
<Toggler
|
||||
checked={current.isPersist}
|
||||
name={'persist-flag'}
|
||||
onChange={() => {
|
||||
current.setIsPersist(!current.isPersist);
|
||||
}}
|
||||
label={current.isPersist ? 'Yes' : 'No'}
|
||||
/>
|
||||
<label className={'font-semibold'}>
|
||||
Persist flag across authentication
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
checked={current.isPersist}
|
||||
onChange={() => {
|
||||
current.setIsPersist(!current.isPersist);
|
||||
}}
|
||||
/>
|
||||
<div>{current.isPersist ? 'Yes' : 'No'}</div>
|
||||
</div>
|
||||
<div className={'text-sm text-disabled-text flex items-center gap-1'}>
|
||||
Persist flag to not reset this feature flag status after a user is identified.
|
||||
Persist flag to not reset this feature flag status after a user is
|
||||
identified.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={'mt-6'}>
|
||||
<label className={'font-semibold'}>Enable this feature flag (Status)?</label>
|
||||
<Toggler
|
||||
checked={current.isActive}
|
||||
name={'persist-flag'}
|
||||
onChange={() => {
|
||||
!fflagId && !current.isActive ? toast.success("Feature flag will be enabled upon saving it.") : ""
|
||||
current.setIsEnabled(!current.isActive);
|
||||
}}
|
||||
label={current.isActive ? 'Enabled' : 'Disabled'}
|
||||
/>
|
||||
<label className={'font-semibold'}>
|
||||
Enable this feature flag (Status)?
|
||||
</label>
|
||||
<div className="flex items-center gap-2">
|
||||
<Switch
|
||||
checked={current.isActive}
|
||||
onChange={() => {
|
||||
!fflagId && !current.isActive
|
||||
? toast.success(
|
||||
'Feature flag will be enabled upon saving it.'
|
||||
)
|
||||
: '';
|
||||
current.setIsEnabled(!current.isActive);
|
||||
}}
|
||||
/>
|
||||
<div>{current.isActive ? 'Enabled' : 'Disabled'}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={'mt-6 p-4 rounded bg-gray-lightest'}>
|
||||
<label className={'font-semibold'}>Rollout Conditions</label>
|
||||
{current.conditions.length === 0 ? null : (
|
||||
<div className={'text-sm text-disabled-text mb-2'}>
|
||||
Indicate the users for whom you intend to make this flag available. Keep in mind that
|
||||
each set of conditions will be deployed separately from one another.
|
||||
Indicate the users for whom you intend to make this flag
|
||||
available. Keep in mind that each set of conditions will be
|
||||
deployed separately from one another.
|
||||
</div>
|
||||
)}
|
||||
<NoContent
|
||||
show={current.conditions.length === 0}
|
||||
title={'The flag will be available for 100% of the user sessions.'}
|
||||
subtext={
|
||||
<div className={'flex flex-col items-center'} style={{ fontSize: 14 }}>
|
||||
<div
|
||||
className={'flex flex-col items-center'}
|
||||
style={{ fontSize: 14 }}
|
||||
>
|
||||
<div className={'text-sm mb-1'}>
|
||||
Set up condition sets to restrict the rollout.
|
||||
</div>
|
||||
<Button onClick={() => current!.addCondition()} variant={'text-primary'}>
|
||||
<Button onClick={() => current!.addCondition()} type={'text'}>
|
||||
+ Create Condition Set
|
||||
</Button>
|
||||
</div>
|
||||
|
|
@ -237,7 +266,7 @@ function NewFFlag({ siteId, fflagId }: { siteId: string; fflagId?: string }) {
|
|||
'flex items-center justify-center w-full bg-white rounded border mt-2 p-2'
|
||||
}
|
||||
>
|
||||
<Button variant={'text-primary'}>+ Create Condition Set</Button>
|
||||
<Button type={'text'}>+ Create Condition Set</Button>
|
||||
</div>
|
||||
) : null}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import React, { useEffect } from 'react';
|
|||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
import ReCAPTCHA from 'react-google-recaptcha';
|
||||
import { Form, Input, Loader, Button, Icon, Message } from 'UI';
|
||||
import { Form, Input, Loader, Icon, Message } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import stl from './forgotPassword.module.css';
|
||||
import { validatePassword } from 'App/validate';
|
||||
import { PASSWORD_POLICY } from 'App/constants';
|
||||
|
|
@ -112,7 +113,10 @@ function CreatePassword(props: Props) {
|
|||
</div>
|
||||
</Loader>
|
||||
<div className="mt-4">
|
||||
<div data-hidden={!updated} className="flex items-center flex-col text-center">
|
||||
<div
|
||||
data-hidden={!updated}
|
||||
className="flex items-center flex-col text-center"
|
||||
>
|
||||
<div className="w-10 h-10 bg-tealx-lightest rounded-full flex items-center justify-center mb-3">
|
||||
<Icon name="check" size="30" color="tealx" />
|
||||
</div>
|
||||
|
|
@ -122,9 +126,16 @@ function CreatePassword(props: Props) {
|
|||
|
||||
{validationError && <Message error>{validationError}</Message>}
|
||||
|
||||
<Button type="submit" data-hidden={updated} variant="primary" loading={loading} className="w-full mt-4">
|
||||
Create
|
||||
</Button>
|
||||
{updated ? null :
|
||||
<Button
|
||||
htmlType="submit"
|
||||
type="primary"
|
||||
loading={loading}
|
||||
className="w-full mt-4"
|
||||
>
|
||||
Create
|
||||
</Button>
|
||||
}
|
||||
</>
|
||||
)}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
import React from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
interface Props {
|
||||
|
||||
}
|
||||
function FunnelDetails(props: Props) {
|
||||
return (
|
||||
<div>
|
||||
Create View/Detail View
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withRouter(FunnelDetails);
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { default } from './FunnelDetails'
|
||||
|
|
@ -1 +0,0 @@
|
|||
//export { default } from './FunnelIssueDetails'
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
import { PageTitle, Button, Pagination, Icon, Loader } from 'UI';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { useObserver } from 'mobx-react-lite';
|
||||
import React, { useEffect } from 'react';
|
||||
import { sliceListPerPage } from 'App/utils';
|
||||
import FunnelItem from '../FunnelItem/FunnelItem';
|
||||
import FunnelSearch from '../FunnelSearch';
|
||||
|
||||
function FunnelList(props) {
|
||||
const { funnelStore } = useStore()
|
||||
const list = useObserver(() => funnelStore.list)
|
||||
const loading = useObserver(() => funnelStore.isLoading)
|
||||
|
||||
useEffect(() => {
|
||||
if (list.length === 0) {
|
||||
funnelStore.fetchFunnels()
|
||||
}
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Loader loading={loading}>
|
||||
<div className="flex items-center">
|
||||
<div className="flex items-center">
|
||||
<PageTitle title='Funnels' className="mr-3" />
|
||||
<Button primary size="small" onClick={() => {}}>New Funnel</Button>
|
||||
</div>
|
||||
<div className="ml-auto w-1/4">
|
||||
<FunnelSearch />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="color-gray-medium mt-2 mb-4">Funnels make it easy to uncover the most significant issues that impacted conversions.</div>
|
||||
|
||||
<div className="mt-3 border rounded bg-white">
|
||||
<div className="grid grid-cols-12 p-3 font-medium">
|
||||
<div className="col-span-4 flex items-center">
|
||||
<Icon name="funnel-fill"/> <span className="ml-2">Title</span>
|
||||
</div>
|
||||
<div className="col-span-3">Owner</div>
|
||||
<div className="col-span-3">Last Modified</div>
|
||||
</div>
|
||||
|
||||
{sliceListPerPage(list, funnelStore.page - 1, funnelStore.pageSize).map((funnel: any) => (
|
||||
<FunnelItem funnel={funnel} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="w-full flex items-center justify-center py-8">
|
||||
<Pagination
|
||||
page={funnelStore.page}
|
||||
total={list.length}
|
||||
onPageChange={(page) => funnelStore.updateKey('page', page)}
|
||||
limit={funnelStore.pageSize}
|
||||
debounceRequest={100}
|
||||
/>
|
||||
</div>
|
||||
</Loader>
|
||||
);
|
||||
}
|
||||
|
||||
export default FunnelList;
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { default } from './FunnelList';
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
import React from 'react';
|
||||
import { Switch, Route } from 'react-router';
|
||||
import FunnelDetails from '../FunnelDetails/FunnelDetails';
|
||||
import FunnelList from '../FunnelList';
|
||||
|
||||
function FunnelPage(props) {
|
||||
return (
|
||||
<div className="page-margin container-70">
|
||||
<Switch>
|
||||
<Route path="/">
|
||||
<FunnelList />
|
||||
</Route>
|
||||
|
||||
<Route path="/funnel/create">
|
||||
<FunnelDetails />
|
||||
</Route>
|
||||
|
||||
{/* <Route path="/funnel/:id">
|
||||
<FunnelDetail />
|
||||
</Route> */}
|
||||
</Switch>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FunnelPage;
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { default } from './FunnelPage';
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import React from 'react';
|
||||
// @ts-ignore
|
||||
import slide from 'App/svg/cheers.svg';
|
||||
import { Button, Loader } from 'UI';
|
||||
import { Loader } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import Footer from './Footer';
|
||||
import { getHighest } from 'App/constants/zindex';
|
||||
import Category from 'Components/Header/HealthStatus/ServiceCategory';
|
||||
|
|
@ -81,7 +82,8 @@ function HealthModal({
|
|||
disabled={isLoading}
|
||||
onClick={getHealth}
|
||||
icon={'arrow-repeat'}
|
||||
variant={'text-primary'}
|
||||
type={'text'}
|
||||
className={'text-main'}
|
||||
>
|
||||
Recheck
|
||||
</Button>
|
||||
|
|
@ -132,7 +134,7 @@ function HealthModal({
|
|||
<Button
|
||||
disabled={!healthResponse?.overallHealth}
|
||||
loading={isLoading}
|
||||
variant={'primary'}
|
||||
type={'primary'}
|
||||
className={'ml-auto'}
|
||||
onClick={() => setPassed?.()}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@ import { Segmented } from 'antd';
|
|||
import React from 'react';
|
||||
import CircleNumber from '../CircleNumber';
|
||||
import MetadataList from '../MetadataList/MetadataList';
|
||||
import { HighlightCode, Icon, Button } from 'UI';
|
||||
import { HighlightCode, Icon } from 'UI';
|
||||
import DocCard from 'Shared/DocCard/DocCard';
|
||||
import withOnboarding, { WithOnboardingProps } from '../withOnboarding';
|
||||
import { OB_TABS } from 'App/routes';
|
||||
import withPageTitle from 'App/components/hocs/withPageTitle';
|
||||
import { Button as AntButton } from 'antd'
|
||||
import { Button } from 'antd'
|
||||
|
||||
interface Props extends WithOnboardingProps {
|
||||
platforms: Array<{
|
||||
|
|
@ -42,10 +42,10 @@ function IdentifyUsersTab(props: Props) {
|
|||
href={`https://docs.openreplay.com/en/installation/identify-user${platform.value === "web" ? "/#with-npm" : "/#with-ios-app"}`}
|
||||
target="_blank"
|
||||
>
|
||||
<AntButton size={'small'} type={'text'} className="ml-2 flex items-center gap-2">
|
||||
<Button size={'small'} type={'text'} className="ml-2 flex items-center gap-2">
|
||||
<Icon name={'question-circle'} />
|
||||
<div className={'text-main'}>See Documentation</div>
|
||||
</AntButton>
|
||||
</Button>
|
||||
</a>
|
||||
</h1>
|
||||
<div className="p-4 flex gap-2 items-center">
|
||||
|
|
@ -142,11 +142,11 @@ function IdentifyUsersTab(props: Props) {
|
|||
</div>
|
||||
|
||||
<div className="border-t px-4 py-3 flex justify-end gap-4">
|
||||
<Button variant="text-primary" onClick={() => (props.skip ? props.skip() : null)}>
|
||||
<Button type="text" onClick={() => (props.skip ? props.skip() : null)}>
|
||||
Skip
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
type="primary"
|
||||
className=""
|
||||
onClick={() => (props.navTo ? props.navTo(OB_TABS.MANAGE_USERS) : null)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ import React from 'react';
|
|||
import OnboardingTabs from '../OnboardingTabs';
|
||||
import MobileOnboardingTabs from '../OnboardingTabs/OnboardingMobileTabs';
|
||||
import ProjectFormButton from '../ProjectFormButton';
|
||||
import { Button, Icon } from 'UI';
|
||||
import { Icon } from 'UI';
|
||||
import withOnboarding from '../withOnboarding';
|
||||
import { WithOnboardingProps } from '../withOnboarding';
|
||||
import { OB_TABS } from 'App/routes';
|
||||
import withPageTitle from 'App/components/hocs/withPageTitle';
|
||||
import { Segmented } from 'antd';
|
||||
import { Button as AntButton } from 'antd'
|
||||
import { Button } from 'antd'
|
||||
|
||||
interface Props extends WithOnboardingProps {
|
||||
platforms: Array<{
|
||||
|
|
@ -41,10 +41,10 @@ function InstallOpenReplayTab(props: Props) {
|
|||
</div>
|
||||
</div>
|
||||
<a href={"https://docs.openreplay.com/en/using-or/"} target="_blank">
|
||||
<AntButton size={"small"} type={"text"} className="ml-2 flex items-center gap-2">
|
||||
<Button size={"small"} type={"text"} className="ml-2 flex items-center gap-2">
|
||||
<Icon name={"question-circle"} />
|
||||
<div className={"text-main"}>See Documentation</div>
|
||||
</AntButton>
|
||||
</Button>
|
||||
</a>
|
||||
</h1>
|
||||
<div className="p-4 flex gap-2 items-center">
|
||||
|
|
@ -62,7 +62,7 @@ function InstallOpenReplayTab(props: Props) {
|
|||
</div>
|
||||
<div className="border-t px-4 py-3 flex justify-end">
|
||||
<Button
|
||||
variant="primary"
|
||||
type="primary"
|
||||
className=""
|
||||
onClick={() => (props.navTo ? props.navTo(OB_TABS.IDENTIFY_USERS) : null)}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import { Button as AntButton } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
import { Icon } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import Integrations from 'App/components/Client/Integrations/Integrations';
|
||||
import withPageTitle from 'App/components/hocs/withPageTitle';
|
||||
import { Button, Icon } from 'UI';
|
||||
|
||||
import withOnboarding, { WithOnboardingProps } from '../withOnboarding';
|
||||
|
||||
|
|
@ -21,21 +20,20 @@ function IntegrationsTab(props: Props) {
|
|||
href="https://docs.openreplay.com/en/integrations/"
|
||||
target="_blank"
|
||||
>
|
||||
<AntButton
|
||||
<Button
|
||||
size={'small'}
|
||||
type={'text'}
|
||||
className="ml-2 flex items-center gap-2"
|
||||
icon={<Icon name={'question-circle'} />}
|
||||
>
|
||||
<Icon name={'question-circle'} />
|
||||
<div className={'text-main'}>See Documentation</div>
|
||||
</AntButton>
|
||||
</Button>
|
||||
</a>
|
||||
</h1>
|
||||
<Integrations hideHeader={true} />
|
||||
<div className="border-t px-4 py-3 flex justify-end">
|
||||
<Button
|
||||
variant="primary"
|
||||
className=""
|
||||
type="primary"
|
||||
onClick={() => (props.skip ? props.skip() : null)}
|
||||
>
|
||||
Complete Setup
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import UsersView from 'App/components/Client/Users/UsersView';
|
||||
import DocCard from 'Shared/DocCard/DocCard';
|
||||
import React from 'react';
|
||||
import { Button, Icon } from 'UI';
|
||||
import { Icon } from 'UI';
|
||||
import withOnboarding, { WithOnboardingProps } from '../withOnboarding';
|
||||
import { OB_TABS } from 'App/routes';
|
||||
import withPageTitle from 'App/components/hocs/withPageTitle';
|
||||
import { Button as AntButton } from 'antd'
|
||||
import { Button } from 'antd'
|
||||
|
||||
interface Props extends WithOnboardingProps {}
|
||||
|
||||
|
|
@ -22,10 +22,10 @@ function ManageUsersTab(props: Props) {
|
|||
href="https://docs.openreplay.com/en/tutorials/adding-users/"
|
||||
target="_blank"
|
||||
>
|
||||
<AntButton size={'small'} type={'text'} className="ml-2 flex items-center gap-2">
|
||||
<Button size={'small'} type={'text'} className="ml-2 flex items-center gap-2">
|
||||
<Icon name={'question-circle'} />
|
||||
<div className={'text-main'}>See Documentation</div>
|
||||
</AntButton>
|
||||
</Button>
|
||||
</a>
|
||||
</h1>
|
||||
<div className="grid grid-cols-6 gap-4 p-4">
|
||||
|
|
@ -48,16 +48,16 @@ function ManageUsersTab(props: Props) {
|
|||
</div>
|
||||
</div>
|
||||
<div className="border-t px-4 py-3 flex justify-end">
|
||||
<Button variant="text-primary" onClick={() => (props.skip ? props.skip() : null)}>
|
||||
<Button type="text" onClick={() => (props.skip ? props.skip() : null)}>
|
||||
Skip
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
className=""
|
||||
type="primary"
|
||||
onClick={() => (props.navTo ? props.navTo(OB_TABS.INTEGRATIONS) : null)}
|
||||
icon={<Icon name="arrow-right-short" color="white" size={20} />}
|
||||
iconPosition={'end'}
|
||||
>
|
||||
Configure Integrations
|
||||
<Icon name="arrow-right-short" color="white" size={20} />
|
||||
</Button>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { Button, TagBadge } from 'UI';
|
||||
import { TagBadge, confirm } from 'UI';
|
||||
import CustomFieldForm from '../../../Client/CustomFields/CustomFieldForm';
|
||||
import { confirm } from 'UI';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Button } from 'antd'
|
||||
|
||||
const MetadataList = () => {
|
||||
const { customFieldStore, projectsStore } = useStore();
|
||||
|
|
@ -47,7 +47,7 @@ const MetadataList = () => {
|
|||
|
||||
return (
|
||||
<div className="py-2 flex">
|
||||
<Button variant="outline" onClick={() => openModal()}>
|
||||
<Button type="default" onClick={() => openModal()}>
|
||||
Add Metadata
|
||||
</Button>
|
||||
<div className="flex ml-2">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react'
|
||||
import { withRouter } from 'react-router'
|
||||
import { Button } from 'UI'
|
||||
import { Button } from 'antd'
|
||||
import { OB_TABS, onboarding as onboardingRoute, withSiteId } from 'App/routes'
|
||||
import { sessions } from 'App/routes';
|
||||
import { useStore } from 'App/mstore'
|
||||
|
|
@ -36,7 +36,7 @@ const OnboardingNavButton = ({ match: { params: { activeTab, siteId } }, history
|
|||
<div className="flex items-center">
|
||||
<Button
|
||||
size="small"
|
||||
variant="outline"
|
||||
type="outline"
|
||||
onClick={onDone}
|
||||
className="float-left mr-2"
|
||||
>
|
||||
|
|
@ -44,7 +44,7 @@ const OnboardingNavButton = ({ match: { params: { activeTab, siteId } }, history
|
|||
</Button>
|
||||
|
||||
<Button
|
||||
variant="primary"
|
||||
type="primary"
|
||||
onClick={setTab}
|
||||
>
|
||||
{BTN_MSGS[activeIndex]}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import stl from './installDocs.module.css';
|
|||
import cn from 'classnames';
|
||||
import CircleNumber from '../../CircleNumber';
|
||||
import { CopyButton, CodeBlock } from 'UI';
|
||||
import { Toggler } from 'UI';
|
||||
import { Switch } from 'antd'
|
||||
|
||||
const installationCommand = 'npm i @openreplay/tracker';
|
||||
const usageCode = `import Tracker from '@openreplay/tracker';
|
||||
|
|
@ -57,11 +57,10 @@ function InstallDocs({ site }) {
|
|||
<div className="mr-2" onClick={() => setIsSpa(!isSpa)}>
|
||||
Server-Side-Rendered (SSR)?
|
||||
</div>
|
||||
<Toggler
|
||||
<Switch
|
||||
checked={!isSpa}
|
||||
name="sessionsLive"
|
||||
onChange={() => setIsSpa(!isSpa)}
|
||||
// style={{ lineHeight: '23px' }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Checkbox, Loader, Toggler } from 'UI';
|
||||
import GDPR from 'App/mstore/types/gdpr';
|
||||
import { Checkbox, Loader } from 'UI';
|
||||
import { Switch } from 'antd'
|
||||
import cn from 'classnames';
|
||||
import stl from './projectCodeSnippet.module.css';
|
||||
import CircleNumber from '../../CircleNumber';
|
||||
|
|
@ -119,13 +119,14 @@ const ProjectCodeSnippet = () => {
|
|||
instantly hopping on call (WebRTC) with them without requiring any 3rd-party screen
|
||||
sharing software.
|
||||
</p>
|
||||
<Toggler
|
||||
label="Yes"
|
||||
checked={isAssistEnabled}
|
||||
name="test"
|
||||
className="font-medium mr-2"
|
||||
onChange={() => setAssistEnabled(!isAssistEnabled)}
|
||||
/>
|
||||
<div className={'flex items-center gap-2'}>
|
||||
<Switch
|
||||
checked={isAssistEnabled}
|
||||
className="font-medium mr-2"
|
||||
onChange={() => setAssistEnabled(!isAssistEnabled)}
|
||||
/>
|
||||
<span>Yes</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={cn(stl.instructions, 'mt-8')}>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React, {useEffect, useState} from 'react';
|
||||
import cn from 'classnames';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
import {Button} from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import stl from './AutoplayTimer.module.css';
|
||||
import clsOv from './overlay.module.css';
|
||||
import AutoplayToggle from 'Shared/AutoplayToggle';
|
||||
|
|
@ -11,7 +11,7 @@ function AutoplayTimer({history}: any) {
|
|||
let timer: NodeJS.Timer;
|
||||
const [cancelled, setCancelled] = useState(false);
|
||||
const [counter, setCounter] = useState(5);
|
||||
const {clipStore} = useStore();
|
||||
const { clipStore } = useStore();
|
||||
|
||||
useEffect(() => {
|
||||
if (counter > 0) {
|
||||
|
|
@ -46,11 +46,11 @@ function AutoplayTimer({history}: any) {
|
|||
<AutoplayToggle/>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<Button variant="text-primary" onClick={cancel}>
|
||||
<Button type="text" onClick={cancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<div className="px-2"/>
|
||||
<Button variant="outline" onClick={() => clipStore.next()}>Play Now</Button>
|
||||
<Button type="default" onClick={() => clipStore.next()}>Play Now</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { ErrorInfo } from 'react'
|
||||
import { Button } from 'UI'
|
||||
import React, { ErrorInfo } from 'react';
|
||||
import { Button } from 'antd';
|
||||
import { Icon } from 'UI';
|
||||
|
||||
class PlayerErrorBoundary extends React.Component<any> {
|
||||
state = { hasError: false, error: '' };
|
||||
|
|
@ -10,21 +11,20 @@ class PlayerErrorBoundary extends React.Component<any> {
|
|||
componentDidCatch(error: Error, info: ErrorInfo) {
|
||||
this.setState({
|
||||
hasError: true,
|
||||
error: error + info.componentStack
|
||||
})
|
||||
error: error + info.componentStack,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
// You can render any custom fallback UI
|
||||
return (
|
||||
<div className={"flex flex-col p-4 gap-4"}>
|
||||
<div className={'flex flex-col p-4 gap-4'}>
|
||||
<h4>Something went wrong during player rendering.</h4>
|
||||
<p>{this.state.error}</p>
|
||||
<Button
|
||||
onClick={() => window.location.reload()}
|
||||
icon={"spinner"}
|
||||
variant={"primary"}
|
||||
icon={<Icon name={'spinner'} size={16} />}
|
||||
type={'primary'}
|
||||
style={{ width: 'fit-content' }}
|
||||
>
|
||||
Reload
|
||||
|
|
@ -37,4 +37,4 @@ class PlayerErrorBoundary extends React.Component<any> {
|
|||
}
|
||||
}
|
||||
|
||||
export default PlayerErrorBoundary
|
||||
export default PlayerErrorBoundary;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
|||
import { List } from 'immutable';
|
||||
import cn from 'classnames';
|
||||
import { withRequest, withToggle } from 'HOCs';
|
||||
import { Button, Icon, SlideModal, TextEllipsis } from 'UI';
|
||||
import { Icon, SlideModal, TextEllipsis } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import stl from './metadataItem.module.css';
|
||||
import SessionList from './SessionList';
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ export default class extends React.PureComponent {
|
|||
</div>
|
||||
<Button
|
||||
onClick={ this.switchOpen }
|
||||
variant="text"
|
||||
type="text"
|
||||
className={ stl.searchButton }
|
||||
id="metadata-item"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
|||
import { List } from 'immutable';
|
||||
import cn from 'classnames';
|
||||
import { withRequest, withToggle } from 'HOCs';
|
||||
import { Button, Icon, SlideModal, TextEllipsis } from 'UI';
|
||||
import { Icon, SlideModal, TextEllipsis } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import stl from './metadataItem.module.css';
|
||||
import SessionList from './SessionList';
|
||||
|
||||
|
|
@ -62,7 +63,7 @@ export default class extends React.PureComponent {
|
|||
</div>
|
||||
<Button
|
||||
onClick={ this.switchOpen }
|
||||
variant="text"
|
||||
type="text"
|
||||
className={ stl.searchButton }
|
||||
id="metadata-item"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,10 @@
|
|||
import React from 'react';
|
||||
import { List } from 'immutable';
|
||||
import { countries } from 'App/constants';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { browserIcon, osIcon, deviceTypeIcon } from 'App/iconNames';
|
||||
import { formatTimeOrDate } from 'App/date';
|
||||
import { Avatar, TextEllipsis, CountryFlag, Icon, Tooltip, Popover } from 'UI';
|
||||
import cn from 'classnames';
|
||||
import { withRequest } from 'HOCs';
|
||||
import SessionInfoItem from '../../SessionInfoItem';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
import UserSessionsModal from 'Shared/UserSessionsModal';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { JSONTree, NoContent, Button, Tabs } from 'UI'
|
||||
import { JSONTree, NoContent, Tabs } from 'UI'
|
||||
import { Button } from 'antd'
|
||||
import cn from 'classnames';
|
||||
import stl from './fetchDetails.module.css';
|
||||
import Headers from './components/Headers'
|
||||
|
|
@ -158,10 +159,10 @@ export default class FetchDetails extends React.PureComponent {
|
|||
</div>
|
||||
|
||||
<div className="flex justify-between absolute bottom-0 left-0 right-0 p-3 border-t bg-white">
|
||||
<Button variant="outline" onClick={prevClick} disabled={first}>
|
||||
<Button type="outline" onClick={prevClick} disabled={first}>
|
||||
Prev
|
||||
</Button>
|
||||
<Button variant="outline" onClick={nextClick} disabled={last}>
|
||||
<Button type="outline" onClick={nextClick} disabled={last}>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Loader, Pagination, Tooltip, Button } from 'UI';
|
||||
import { Loader, Pagination, Tooltip, Icon } from 'UI';
|
||||
import SessionItem from 'Shared/SessionItem';
|
||||
import Select from 'Shared/Select';
|
||||
import SortOrderButton from 'Shared/SortOrderButton';
|
||||
|
|
@ -11,7 +11,7 @@ import AssistSearchActions from 'App/components/Assist/AssistSearchActions';
|
|||
import LiveSessionSearch from 'Shared/LiveSessionSearch';
|
||||
import cn from 'classnames';
|
||||
import Session from 'App/mstore/types/session';
|
||||
|
||||
import { Button } from 'antd'
|
||||
const PER_PAGE = 10;
|
||||
|
||||
interface ConnectProps {
|
||||
|
|
@ -65,9 +65,9 @@ function AssistSessionsModal(props: ConnectProps) {
|
|||
<Button
|
||||
loading={loading}
|
||||
className="mr-2"
|
||||
variant="text"
|
||||
type="text"
|
||||
onClick={reloadSessions}
|
||||
icon="arrow-repeat"
|
||||
icon={<Icon name={"arrow-repeat"} />}
|
||||
/>
|
||||
</Tooltip>
|
||||
<AssistSearchActions />
|
||||
|
|
|
|||
|
|
@ -67,9 +67,10 @@ export function IntervalSelector({
|
|||
distance={20}
|
||||
render={({ close }: any) => (
|
||||
<div
|
||||
style={{ margin: -12 }}
|
||||
className={cn(
|
||||
'flex flex-col bg-white border',
|
||||
'border-borderColor-gray-light-shade text-figmaColors-text-primary rounded'
|
||||
'flex flex-col bg-white',
|
||||
'text-figmaColors-text-primary rounded'
|
||||
)}
|
||||
>
|
||||
<div className="font-semibold py-2 px-4 w-full text-left">
|
||||
|
|
@ -84,8 +85,7 @@ export function IntervalSelector({
|
|||
}}
|
||||
className={cn(
|
||||
'py-2 px-4 cursor-pointer w-full text-left font-semibold',
|
||||
'hover:text-main hover:shadow-border-main border-t',
|
||||
'border-borderColor-gray-light-shade'
|
||||
'hover:bg-active-blue border-t border-borderColor-gray-light-shade'
|
||||
)}
|
||||
>
|
||||
{interval}
|
||||
|
|
@ -149,10 +149,11 @@ export function SpeedOptions({
|
|||
theme="nopadding"
|
||||
animation="none"
|
||||
duration={0}
|
||||
placement={'top'}
|
||||
className="cursor-pointer select-none"
|
||||
distance={20}
|
||||
render={({ close }: any) => (
|
||||
<div className="flex flex-col bg-white border border-borderColor-gray-light-shade text-figmaColors-text-primary rounded">
|
||||
<div style={{ margin: -12 }} className="flex flex-col bg-white text-figmaColors-text-primary rounded">
|
||||
<div className="font-semibold py-2 px-4 w-full text-left">Playback speed</div>
|
||||
{Object.keys(SPEED_OPTIONS).map((index: any) => (
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -1,332 +0,0 @@
|
|||
import { Tag, Input } from 'antd';
|
||||
import { Duration } from 'luxon';
|
||||
import React from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
import {
|
||||
Note,
|
||||
TAGS,
|
||||
WriteNote,
|
||||
iTag,
|
||||
tagProps,
|
||||
} from 'App/services/NotesService';
|
||||
import { Button, Checkbox, Icon } from 'UI';
|
||||
import { shortDurationFromMs } from 'App/date';
|
||||
|
||||
import Select from 'Shared/Select';
|
||||
|
||||
interface Props {
|
||||
time: number;
|
||||
isEdit?: boolean;
|
||||
editNote?: WriteNote;
|
||||
hideModal: () => void;
|
||||
}
|
||||
|
||||
function CreateNote({
|
||||
time,
|
||||
isEdit,
|
||||
editNote,
|
||||
hideModal,
|
||||
}: Props) {
|
||||
const { notesStore, integrationsStore, sessionStore } = useStore();
|
||||
const sessionId = sessionStore.current.sessionId;
|
||||
const updateNote = sessionStore.updateNote;
|
||||
const slackChannels = integrationsStore.slack.list;
|
||||
const fetchSlack = integrationsStore.slack.fetchIntegrations;
|
||||
const teamsChannels = integrationsStore.msteams.list;
|
||||
const fetchTeams = integrationsStore.msteams.fetchIntegrations;
|
||||
const [text, setText] = React.useState('');
|
||||
const [slackChannel, setSlackChannel] = React.useState('');
|
||||
const [teamsChannel, setTeamsChannel] = React.useState('');
|
||||
const [isPublic, setPublic] = React.useState(false);
|
||||
const [tag, setTag] = React.useState<iTag>(TAGS[0]);
|
||||
const [useTimestamp, setUseTs] = React.useState(true);
|
||||
const [useSlack, setSlack] = React.useState(false);
|
||||
const [useTeams, setTeams] = React.useState(false);
|
||||
|
||||
const inputRef = React.createRef<HTMLTextAreaElement>();
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isEdit && editNote) {
|
||||
setTag(editNote.tag);
|
||||
setText(editNote.message);
|
||||
setPublic(editNote.isPublic);
|
||||
if (editNote.timestamp > 0) {
|
||||
setUseTs(true);
|
||||
}
|
||||
}
|
||||
}, [isEdit]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (inputRef.current) {
|
||||
inputRef.current.focus();
|
||||
fetchSlack();
|
||||
fetchTeams();
|
||||
}
|
||||
}, []);
|
||||
|
||||
const duration = Duration.fromMillis(time || 0).toFormat('mm:ss');
|
||||
|
||||
const cleanUp = () => {
|
||||
setText('');
|
||||
setTag(TAGS[0]);
|
||||
hideModal();
|
||||
};
|
||||
const onSubmit = () => {
|
||||
if (text === '') return;
|
||||
|
||||
const note: WriteNote = {
|
||||
message: text,
|
||||
tag,
|
||||
timestamp: useTimestamp
|
||||
? Math.floor(isEdit && editNote ? editNote.timestamp : time)
|
||||
: -1,
|
||||
isPublic,
|
||||
};
|
||||
const onSuccess = (noteId: string) => {
|
||||
if (slackChannel) {
|
||||
notesStore.sendSlackNotification(noteId, slackChannel);
|
||||
}
|
||||
if (teamsChannel) {
|
||||
notesStore.sendMsTeamsNotification(noteId, teamsChannel);
|
||||
}
|
||||
};
|
||||
if (isEdit && editNote) {
|
||||
return notesStore
|
||||
.updateNote(editNote.noteId!, note)
|
||||
.then((r) => {
|
||||
toast.success('Note updated');
|
||||
notesStore.fetchSessionNotes(sessionId).then(() => {
|
||||
onSuccess(editNote.noteId!);
|
||||
updateNote(r as Note);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
toast.error('Error updating note');
|
||||
console.error(e);
|
||||
})
|
||||
.finally(() => {
|
||||
cleanUp();
|
||||
});
|
||||
} else {
|
||||
return notesStore
|
||||
.addNote(sessionId, note)
|
||||
.then((r) => {
|
||||
onSuccess(r!.noteId as unknown as string);
|
||||
toast.success('Note added');
|
||||
})
|
||||
.catch((e) => {
|
||||
toast.error('Error adding note');
|
||||
console.error(e);
|
||||
})
|
||||
.finally(() => {
|
||||
cleanUp();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const closeTooltip = () => {
|
||||
hideModal();
|
||||
};
|
||||
|
||||
const tagActive = (noteTag: iTag) => tag === noteTag;
|
||||
|
||||
const addTag = (tag: iTag) => {
|
||||
setTag(tag);
|
||||
};
|
||||
|
||||
const slackChannelsOptions = slackChannels
|
||||
.map(({ webhookId, name }) => ({
|
||||
value: webhookId,
|
||||
label: name,
|
||||
})) as unknown as { value: string; label: string }[];
|
||||
const teamsChannelsOptions = teamsChannels
|
||||
.map(({ webhookId, name }) => ({
|
||||
value: webhookId,
|
||||
label: name,
|
||||
})) as unknown as { value: string; label: string }[];
|
||||
|
||||
slackChannelsOptions.unshift({
|
||||
// @ts-ignore
|
||||
value: null,
|
||||
// @ts-ignore
|
||||
label: <div className={'text-disabled-text'}>Pick a channel</div>,
|
||||
disabled: true,
|
||||
});
|
||||
teamsChannelsOptions.unshift({
|
||||
// @ts-ignore
|
||||
value: null,
|
||||
// @ts-ignore
|
||||
label: <div className={'text-disabled-text'}>Pick a channel</div>,
|
||||
disabled: true,
|
||||
});
|
||||
|
||||
const changeSlackChannel = ({
|
||||
value,
|
||||
}: {
|
||||
value: Record<string, string>;
|
||||
name: string;
|
||||
}) => {
|
||||
if (value) {
|
||||
setSlackChannel(value.value);
|
||||
}
|
||||
};
|
||||
|
||||
const changeTeamsChannel = ({
|
||||
value,
|
||||
}: {
|
||||
value: Record<string, string>;
|
||||
name: string;
|
||||
}) => {
|
||||
if (value) {
|
||||
setTeamsChannel(value.value);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className={'bg-white h-screen w-full p-4 flex flex-col gap-4'}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<Icon name="quotes" size={20} />
|
||||
<h3 className="text-xl ml-2 mr-4 font-semibold">
|
||||
{isEdit ? 'Edit Note' : 'Add Note'}
|
||||
</h3>
|
||||
<div className="ml-auto cursor-pointer" onClick={closeTooltip}>
|
||||
<Icon name="close" size={20} />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center cursor-pointer gap-2"
|
||||
onClick={() => setUseTs(!useTimestamp)}
|
||||
>
|
||||
<Checkbox checked={useTimestamp} />
|
||||
<span>Add note at current time frame</span>
|
||||
<div className={'border px-1 bg-gray-lightest rounded'}>{duration}</div>
|
||||
</div>
|
||||
|
||||
<div className="">
|
||||
<div className={'font-semibold'}>Note</div>
|
||||
<Input.TextArea
|
||||
ref={inputRef}
|
||||
name="message"
|
||||
id="message"
|
||||
placeholder="Enter your note here..."
|
||||
rows={3}
|
||||
value={text}
|
||||
autoFocus
|
||||
onChange={(e) => {
|
||||
setText(e.target.value);
|
||||
}}
|
||||
className="text-area"
|
||||
/>
|
||||
<div className={'flex w-full items-center gap-1 my-2'}>
|
||||
{editNote && editNote?.startAt ? (
|
||||
<>
|
||||
<span>From: </span>
|
||||
<Input disabled readOnly value={shortDurationFromMs(editNote?.startAt)} />
|
||||
<span>To: </span>
|
||||
<Input disabled readOnly value={shortDurationFromMs(editNote?.endAt)} />
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-1" style={{ lineHeight: '15px' }}>
|
||||
{TAGS.map((tag) => (
|
||||
<Tag
|
||||
onClick={() => addTag(tag)}
|
||||
key={tag}
|
||||
className='cursor-pointer rounded-lg hover:bg-indigo-50'
|
||||
color={tagActive(tag) ? tagProps[tag] : undefined}
|
||||
bordered={false}
|
||||
|
||||
>
|
||||
<div className={'flex items-center gap-2'}>
|
||||
{tagActive(tag) ? (
|
||||
<Icon name="check-circle-fill" color="inherit" size={13} />
|
||||
) : null}
|
||||
{tag}
|
||||
</div>
|
||||
</Tag>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={'flex items-center gap-2 cursor-pointer'}
|
||||
onClick={() => setPublic(!isPublic)}
|
||||
>
|
||||
<Checkbox checked={isPublic} />
|
||||
<div>Visible to team members</div>
|
||||
</div>
|
||||
{slackChannelsOptions.length > 1 ? (
|
||||
<div className="flex flex-col">
|
||||
<div
|
||||
className="flex items-center cursor-pointer"
|
||||
onClick={() => setSlack(!useSlack)}
|
||||
>
|
||||
<Checkbox checked={useSlack} />
|
||||
<span className="ml-1 mr-3"> Share via Slack </span>
|
||||
</div>
|
||||
|
||||
{useSlack && (
|
||||
<div>
|
||||
<Select
|
||||
options={slackChannelsOptions}
|
||||
// @ts-ignore
|
||||
defaultValue
|
||||
// @ts-ignore
|
||||
onChange={changeSlackChannel}
|
||||
value={slackChannel}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{teamsChannelsOptions.length > 1 ? (
|
||||
<div className="flex flex-col">
|
||||
<div
|
||||
className="flex items-center cursor-pointer"
|
||||
onClick={() => setTeams(!useTeams)}
|
||||
>
|
||||
<Checkbox checked={useTeams} />
|
||||
<span className="ml-1 mr-3"> Share via MS Teams </span>
|
||||
</div>
|
||||
|
||||
{useTeams && (
|
||||
<div>
|
||||
<Select
|
||||
options={teamsChannelsOptions}
|
||||
// @ts-ignore
|
||||
defaultValue
|
||||
// @ts-ignore
|
||||
onChange={changeTeamsChannel}
|
||||
value={teamsChannel}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="flex">
|
||||
<Button
|
||||
variant="primary"
|
||||
className="mr-4"
|
||||
disabled={text === ''}
|
||||
onClick={onSubmit}
|
||||
>
|
||||
{isEdit
|
||||
? 'Save Note'
|
||||
: `Add Note ${useTeams || useSlack ? '& Share' : ''}`}
|
||||
</Button>
|
||||
<Button variant={'text'} onClick={closeTooltip}>
|
||||
Cancel
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(CreateNote);
|
||||
|
|
@ -31,6 +31,7 @@ function PlayingTime({ timeMode, setTimeMode, startedAt, sessionTz }: Props) {
|
|||
distance={20}
|
||||
render={({ close }) => (
|
||||
<div
|
||||
style={{ margin: -12 }}
|
||||
className={
|
||||
'flex flex-col gap-2 bg-white py-2 rounded color-gray-darkest text-left'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ import {
|
|||
import { Icon } from 'UI';
|
||||
|
||||
import { useModal } from '../../Modal';
|
||||
import CreateNote from './Controls/components/CreateNote';
|
||||
import AutoplayTimer from './Overlay/AutoplayTimer';
|
||||
import ElementsMarker from './Overlay/ElementsMarker';
|
||||
import Loader from './Overlay/Loader';
|
||||
|
|
@ -68,11 +67,11 @@ const menuItems: MenuProps['items'] = [
|
|||
icon: <Icon name={'redux'} size={14} />,
|
||||
},
|
||||
{ type: 'divider' },
|
||||
{
|
||||
key: ItemKey.AddNote,
|
||||
label: 'Add Note',
|
||||
icon: <Icon name={'quotes'} size={14} />,
|
||||
},
|
||||
// {
|
||||
// key: ItemKey.AddNote,
|
||||
// label: 'Add Note',
|
||||
// icon: <Icon name={'quotes'} size={14} />,
|
||||
// },
|
||||
{
|
||||
key: ItemKey.CopySessionUrl,
|
||||
label: 'Copy Session URL',
|
||||
|
|
@ -131,16 +130,16 @@ function Overlay({ nextId, isClickmap }: Props) {
|
|||
case ItemKey.State:
|
||||
toggleBottomBlock(STORAGE);
|
||||
break;
|
||||
case ItemKey.AddNote:
|
||||
showModal(
|
||||
<CreateNote
|
||||
hideModal={hideModal}
|
||||
isEdit={false}
|
||||
time={Math.round(store.get().time)}
|
||||
/>,
|
||||
{ right: true, width: 380 }
|
||||
);
|
||||
break;
|
||||
// case ItemKey.AddNote:
|
||||
// showModal(
|
||||
// <CreateNote
|
||||
// hideModal={hideModal}
|
||||
// isEdit={false}
|
||||
// time={Math.round(store.get().time)}
|
||||
// />,
|
||||
// { right: true, width: 380 }
|
||||
// );
|
||||
// break;
|
||||
case ItemKey.CopySessionUrl:
|
||||
copy(window.location.origin + window.location.pathname);
|
||||
toast.success('Session URL copied to clipboard');
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import React, { useEffect, useState } from 'react';
|
|||
import cn from 'classnames';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import { Button, Link } from 'UI';
|
||||
import { Link } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { session as sessionRoute, withSiteId } from 'App/routes';
|
||||
import stl from './AutoplayTimer.module.css';
|
||||
import clsOv from './overlay.module.css';
|
||||
|
|
@ -50,12 +51,12 @@ function AutoplayTimer({ history }: any) {
|
|||
<AutoplayToggle />
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<Button variant="text-primary" onClick={cancel}>
|
||||
<Button variant="text" onClick={cancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<div className="px-2" />
|
||||
<Link to={sessionRoute(nextId)} disabled={!nextId}>
|
||||
<Button variant="outline">Play Now</Button>
|
||||
<Button type="default">Play Now</Button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from 'react';
|
||||
import { screenRecorder } from 'App/utils/screenRecorder';
|
||||
import { Tooltip } from 'antd'
|
||||
import { Button } from 'UI';
|
||||
import { Tooltip, Button } from 'antd'
|
||||
import { Icon } from 'UI';
|
||||
import { SessionRecordingStatus } from 'Player';
|
||||
let stopRecorderCb: () => void;
|
||||
import { recordingsService } from 'App/services';
|
||||
|
|
@ -116,7 +116,7 @@ function ScreenRecorder() {
|
|||
<Tooltip
|
||||
title={isEnterprise ? supportedMessage : ENTERPRISE_REQUEIRED}
|
||||
>
|
||||
<Button icon="record-circle" disabled variant="text-primary">
|
||||
<Button icon={<Icon name={"record-circle"} size={16} />} disabled type="text">
|
||||
Record Activity
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
|
@ -127,8 +127,9 @@ function ScreenRecorder() {
|
|||
return (
|
||||
<div onClick={!isRecording ? recordingRequest : stopRecordingHandler} className="p-2">
|
||||
<Button
|
||||
icon={!isRecording ? 'stop-record-circle' : 'record-circle'}
|
||||
variant={isRecording ? 'text-red' : 'text-primary'}
|
||||
icon={<Icon name={!isRecording ? 'stop-record-circle' : 'record-circle'} size={16} />}
|
||||
type={'text'}
|
||||
className={isRecording ? 'text-red' : 'text-main'}
|
||||
>
|
||||
{isRecording ? 'Stop Recording' : 'Record Activity'}
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
import React from 'react';
|
||||
import { Button, Icon } from 'UI';
|
||||
import styles from './menu.module.css';
|
||||
import cn from 'classnames';
|
||||
import OutsideClickDetectingDiv from 'Shared/OutsideClickDetectingDiv';
|
||||
|
||||
interface MenuItem {
|
||||
key: number;
|
||||
autoclose?: boolean;
|
||||
component?: React.ReactElement;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
items: MenuItem[];
|
||||
useSc?: boolean;
|
||||
}
|
||||
|
||||
export default class ItemMenu extends React.PureComponent<Props> {
|
||||
state = {
|
||||
displayed: false,
|
||||
};
|
||||
|
||||
handleEsc = (e: KeyboardEvent) => e.key === 'Escape' && this.state.displayed && this.toggleMenu();
|
||||
handleSc = (e: KeyboardEvent) => e.key === 'M' && e.shiftKey ? this.toggleMenu() : null;
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('keydown', this.handleEsc, false);
|
||||
if (this.props.useSc) {
|
||||
document.addEventListener('keydown', this.handleSc, false)
|
||||
}
|
||||
}
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('keydown', this.handleEsc, false);
|
||||
if (this.props.useSc) {
|
||||
document.removeEventListener('keydown', this.handleSc, false)
|
||||
}
|
||||
}
|
||||
|
||||
toggleMenu = () => {
|
||||
this.setState({ displayed: !this.state.displayed });
|
||||
};
|
||||
|
||||
closeMenu = () => {
|
||||
this.setState({ displayed: false });
|
||||
};
|
||||
|
||||
render() {
|
||||
const { items } = this.props;
|
||||
const { displayed } = this.state;
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper}>
|
||||
<OutsideClickDetectingDiv onClickOutside={this.closeMenu}>
|
||||
<Button variant="text" onClick={this.toggleMenu}>
|
||||
<div className="flex items-center">
|
||||
<Icon name="ellipsis-v" size={18} className="mr-1" />
|
||||
<span>More</span>
|
||||
</div>
|
||||
</Button>
|
||||
<div className={cn(styles.menu, styles.menuDim)} data-displayed={displayed}>
|
||||
{items.map((item) =>
|
||||
item.component ? (
|
||||
<div
|
||||
key={item.key}
|
||||
onClick={item.autoclose ? this.closeMenu : undefined}
|
||||
role="menuitem"
|
||||
className="hover:bg-gray-light-shade cursor-pointer flex items-center w-full"
|
||||
>
|
||||
{item.component}
|
||||
</div>
|
||||
) : null
|
||||
)}
|
||||
</div>
|
||||
</OutsideClickDetectingDiv>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
import CreateNote from 'Components/Session_/Player/Controls/components/CreateNote';
|
||||
import React from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
import { MessageOutlined } from '@ant-design/icons';
|
||||
import { useModal } from 'App/components/Modal';
|
||||
|
||||
function NotePopup() {
|
||||
const { sessionStore } = useStore();
|
||||
const tooltipActive = sessionStore.createNoteTooltip.isVisible;
|
||||
const { player, store } = React.useContext(PlayerContext);
|
||||
const { showModal, hideModal } = useModal();
|
||||
const toggleNotePopup = () => {
|
||||
if (tooltipActive) return;
|
||||
player.pause();
|
||||
showModal(
|
||||
<CreateNote hideModal={hideModal} isEdit={false} time={Math.round(store.get().time)} />,
|
||||
{
|
||||
right: true,
|
||||
width: 380,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Tooltip title={'Add Note'} placement='bottom'>
|
||||
<Button
|
||||
size={'small'}
|
||||
className={'flex items-center justify-center'}
|
||||
onClick={toggleNotePopup}
|
||||
disabled={tooltipActive}
|
||||
>
|
||||
<MessageOutlined />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(NotePopup)
|
||||
|
|
@ -15,7 +15,8 @@ import { SITE_ID_STORAGE_KEY } from 'App/constants/storageKeys';
|
|||
import { useStore } from 'App/mstore';
|
||||
import { login } from 'App/routes';
|
||||
import { validatePassword } from 'App/validate';
|
||||
import { Button, Form, Input, Link } from 'UI';
|
||||
import { Form, Input, Link } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
|
||||
import Select from 'Shared/Select';
|
||||
|
||||
|
|
@ -221,8 +222,8 @@ const SignupForm = () => {
|
|||
) : null}
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
variant="primary"
|
||||
htmlType="submit"
|
||||
type="primary"
|
||||
loading={loading}
|
||||
className="w-full rounded-lg"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,120 +0,0 @@
|
|||
import withPageTitle from 'HOCs/withPageTitle';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import React from 'react';
|
||||
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Button, Loader, Message } from 'UI';
|
||||
|
||||
import styles from './updatePassword.module.css';
|
||||
|
||||
const ERROR_DOESNT_MATCH = "Passwords doesn't match";
|
||||
const MIN_LENGTH = 8;
|
||||
const PASSWORD_POLICY = `Password should contain at least ${MIN_LENGTH} symbols`;
|
||||
|
||||
const checkDoesntMatch = (newPassword, newPasswordRepeat) =>
|
||||
newPasswordRepeat.length > 0 && newPasswordRepeat !== newPassword;
|
||||
|
||||
function UpdatePassword() {
|
||||
const { userStore } = useStore();
|
||||
const updatePassword = userStore.updatePassword;
|
||||
const errors = userStore.updatePasswordRequest.errors;
|
||||
const loading = userStore.updatePasswordRequest.loading;
|
||||
const [oldPassword, setOldPassword] = React.useState('');
|
||||
const [newPassword, setNewPassword] = React.useState('');
|
||||
const [newPasswordRepeat, setNewPasswordRepeat] = React.useState('');
|
||||
|
||||
const handleSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
if (isSubmitDisabled()) return;
|
||||
|
||||
void updatePassword({ oldPassword, newPassword });
|
||||
};
|
||||
|
||||
const writeOldPass = ({ target: { value } }) => setOldPassword(value);
|
||||
const writeNewPass = ({ target: { value } }) => setNewPassword(value);
|
||||
const writeNewPassRepeat = ({ target: { value } }) =>
|
||||
setNewPasswordRepeat(value);
|
||||
|
||||
const isSubmitDisabled = () => {
|
||||
if (
|
||||
newPassword !== newPasswordRepeat ||
|
||||
newPassword.length < MIN_LENGTH ||
|
||||
oldPassword.length < MIN_LENGTH
|
||||
)
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
const doesntMatch = checkDoesntMatch(newPassword, newPasswordRepeat);
|
||||
|
||||
return (
|
||||
<div className={styles.form}>
|
||||
<div className={styles.logo} />
|
||||
<form onSubmit={handleSubmit}>
|
||||
<h2>{'Password Change'}</h2>
|
||||
<Loader loading={loading}>
|
||||
<div>
|
||||
<div className={styles.inputWithIcon}>
|
||||
<i className={styles.inputIconPassword} />
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Old Password"
|
||||
name="oldPassword"
|
||||
onChange={writeOldPass}
|
||||
className={styles.password}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.inputWithIcon}>
|
||||
<i className={styles.inputIconPassword} />
|
||||
<input
|
||||
type="password"
|
||||
placeholder="New Password"
|
||||
name="newPassword"
|
||||
onChange={writeNewPass}
|
||||
className={styles.password}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={styles.passwordPolicy}
|
||||
data-hidden={newPassword.length > 7}
|
||||
>
|
||||
{PASSWORD_POLICY}
|
||||
</div>
|
||||
<div className={styles.inputWithIcon}>
|
||||
<i className={styles.inputIconPassword} />
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Repeat New Password"
|
||||
name="newPasswordRepeat"
|
||||
onChange={writeNewPassRepeat}
|
||||
className={styles.password}
|
||||
/>
|
||||
</div>
|
||||
<Message error hidden={!doesntMatch}>
|
||||
{ERROR_DOESNT_MATCH}
|
||||
</Message>
|
||||
</div>
|
||||
</Loader>
|
||||
{errors && (
|
||||
<div className={styles.errors}>
|
||||
{errors.map((error) => (
|
||||
<span>
|
||||
{error}
|
||||
<br />
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<div className={styles.formFooter}>
|
||||
<Button type="submit" variant="primary">
|
||||
{'Update'}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default withPageTitle('Password Change - OpenReplay')(
|
||||
observer(UpdatePassword)
|
||||
);
|
||||
|
|
@ -1,127 +0,0 @@
|
|||
@import 'icons.css';
|
||||
|
||||
.form {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -300px;
|
||||
width: 520px;
|
||||
left: 50%;
|
||||
margin-left: -260px;
|
||||
|
||||
& .passwordPolicy {
|
||||
color: $gray-medium;
|
||||
padding: 5px 0 10px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
& form {
|
||||
padding: 10px 70px;
|
||||
border: solid 2px $gray-light;
|
||||
border-radius: 2px;
|
||||
background-color: white;
|
||||
}
|
||||
& h2 {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
color: #555555;
|
||||
margin: 35px 0;
|
||||
font-weight: 300;
|
||||
}
|
||||
}
|
||||
|
||||
.formFooter {
|
||||
text-align: center;
|
||||
padding: 15px 0;
|
||||
}
|
||||
|
||||
.links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 10px 0;
|
||||
margin-top: 20px;
|
||||
|
||||
& .divider {
|
||||
width: 1px;
|
||||
height: 12px;
|
||||
background-color: $gray-medium;
|
||||
margin: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.logo {
|
||||
background-image: svg-load('logo.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
background-position: center center;
|
||||
height: 50px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
.email, .password {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
width: 100%;
|
||||
height: 45px;
|
||||
line-height: 45px;
|
||||
border: $gray-light solid 1px;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
padding: 0 10px;
|
||||
transition: all 0.2s;
|
||||
|
||||
&::placeholder {
|
||||
color: #AAA;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
border-color: $teal;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
}
|
||||
|
||||
.errors {
|
||||
border-radius: 5px;
|
||||
width: 400px;
|
||||
margin: auto;
|
||||
border: 2px solid $red;
|
||||
padding: 15px;
|
||||
background-color: $white;
|
||||
}
|
||||
|
||||
.submit {
|
||||
display: block;
|
||||
border-radius: 5px;
|
||||
background: $teal;
|
||||
width: 135px;
|
||||
height: 45px;
|
||||
margin: 20px auto;
|
||||
color: $white;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.inputWithIcon {
|
||||
position: relative;
|
||||
|
||||
& input {
|
||||
padding-left: 45px;
|
||||
}
|
||||
}
|
||||
|
||||
@define-mixin inputIcon $name {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: calc(50% - 8px);
|
||||
@mixin icon $name, $gray-medium, 15px;
|
||||
}
|
||||
|
||||
.inputIconUser {
|
||||
@mixin inputIcon user-alt;
|
||||
}
|
||||
|
||||
.inputIconPassword {
|
||||
@mixin inputIcon lock-alt;
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { Button, NoContent, Loader } from 'UI';
|
||||
import { NoContent, Loader } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import cn from 'classnames';
|
||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||
import ListItem from './ListItem'
|
||||
|
|
@ -37,7 +38,6 @@ function AlertTriggersModal(props: Props) {
|
|||
{ count > 0 && (
|
||||
<div className="">
|
||||
<Button
|
||||
// loading={loading} // TODO should use the different loading state for this
|
||||
variant="text"
|
||||
onClick={onClearAll}
|
||||
disabled={count === 0}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from 'react';
|
||||
import { Button } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import stl from './listItem.module.css';
|
||||
import cn from 'classnames';
|
||||
import AlertTypeLabel from '../AlertTypeLabel';
|
||||
|
|
@ -10,7 +10,7 @@ const ListItem = ({ alert, onClear, loading }: any) => {
|
|||
<div className="flex justify-between items-center">
|
||||
<div className="text-sm">{alert.createdAt && alert.createdAt.toFormat('LLL dd, yyyy, hh:mm a')}</div>
|
||||
<div className={ cn("invisible", { 'group-hover:visible' : !alert.viewed})} >
|
||||
<Button variant="text" loading={loading}>
|
||||
<Button type="text" loading={loading}>
|
||||
<span className={ cn("text-sm color-gray-medium", { 'invisible' : loading })} onClick={onClear}>{'IGNORE'}</span>
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import React from 'react';
|
|||
import { VList, VListHandle } from 'virtua';
|
||||
import cn from 'classnames';
|
||||
import { Duration } from 'luxon';
|
||||
import { NoContent, Button } from 'UI';
|
||||
import { NoContent, Icon } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { percentOf } from 'App/utils';
|
||||
|
||||
import BarRow from './BarRow';
|
||||
|
|
@ -214,21 +215,13 @@ function TimeTable(props: Props) {
|
|||
{navigation && (
|
||||
<div className={cn(autoscrollStl.navButtons, 'flex items-center')}>
|
||||
<Button
|
||||
variant="text-primary"
|
||||
icon="chevron-up"
|
||||
tooltip={{
|
||||
title: 'Previous Error',
|
||||
delay: 0,
|
||||
}}
|
||||
type="text"
|
||||
icon={<Icon name={'chevron-up'} />}
|
||||
onClick={onPrevClick}
|
||||
/>
|
||||
<Button
|
||||
variant="text-primary"
|
||||
icon="chevron-down"
|
||||
tooltip={{
|
||||
title: 'Next Error',
|
||||
delay: 0,
|
||||
}}
|
||||
type="text"
|
||||
icon={<Icon name={'chevron-down'} />}
|
||||
onClick={onNextClick}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react'
|
||||
import { Button, Icon } from 'UI'
|
||||
import { Icon } from 'UI'
|
||||
import { Button } from 'antd'
|
||||
|
||||
export default function DocLink({ className = '', url, label }) {
|
||||
const openLink = () => {
|
||||
|
|
@ -8,7 +9,7 @@ export default function DocLink({ className = '', url, label }) {
|
|||
|
||||
return (
|
||||
<div className={className}>
|
||||
<Button variant="text-primary" onClick={openLink}>
|
||||
<Button type="text" onClick={openLink} className={'flex items-center gap-2'}>
|
||||
<span className="mr-2">{ label }</span>
|
||||
<Icon name="external-link-alt" color="teal" />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
import React, { useState } from 'react'
|
||||
import { Button } from 'UI';
|
||||
|
||||
export default function ImageViewer(
|
||||
{ source, activeIndex, onClose }
|
||||
) {
|
||||
const [currentIndex, setCurrentIndex] = useState(activeIndex)
|
||||
const onPrevClick = () => {
|
||||
setCurrentIndex(currentIndex - 1);
|
||||
}
|
||||
const onNextClick = () => {
|
||||
setCurrentIndex(currentIndex + 1);
|
||||
}
|
||||
return (
|
||||
<div className="absolute bg-gray-light inset-0 z-50">
|
||||
<div className="flex justify-between absolute bottom-0 left-0 right-0 p-3 border-t bg-white">
|
||||
<Button variant="outline" onClick={onPrevClick} disabled={currentIndex === 0}>
|
||||
Prev
|
||||
</Button>
|
||||
<Button variant="outline" onClick={onClose}>
|
||||
CLOSE
|
||||
</Button>
|
||||
<Button variant="outline" onClick={onNextClick} disabled={currentIndex === source.length - 1}>
|
||||
Next
|
||||
</Button>
|
||||
</div>
|
||||
<img src={source[currentIndex]} className="border p-3"/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
export { default } from './ImageViewer';
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react'
|
||||
import { Button, Icon } from 'UI'
|
||||
import { Icon } from 'UI'
|
||||
import { Button } from 'antd'
|
||||
import { CLIENT_TABS, client as clientRoute } from 'App/routes';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
|
|
@ -14,7 +15,7 @@ function IntegrateSlackTeamsButton({ history }) {
|
|||
<Button
|
||||
className="my-auto mt-2 mb-2 flex items-center gap-2"
|
||||
onClick={gotoPreferencesIntegrations}
|
||||
variant="text-primary"
|
||||
type="text"
|
||||
>
|
||||
<Icon name="integrations/slack" size={16} />
|
||||
<Icon name="integrations/teams" size={24} className="mr-2 ml-1" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import LiveSessionSearchField from 'Shared/LiveSessionSearchField';
|
||||
import { Button, Tooltip } from 'UI';
|
||||
import { Tooltip } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
||||
|
|
@ -20,9 +21,9 @@ const LiveSearchBar = (props: Props) => {
|
|||
<div className="flex items-center" style={{ width: '40%' }}>
|
||||
<Tooltip title={'Clear Steps'}>
|
||||
<Button
|
||||
variant="text-primary"
|
||||
type="text"
|
||||
disabled={!hasFilters}
|
||||
className="ml-auto font-medium"
|
||||
className="text-main ml-auto font-medium"
|
||||
onClick={() => searchStoreLive.clearSearch()}
|
||||
>
|
||||
Clear
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { NoContent, Loader, Pagination, Button } from 'UI';
|
||||
import { NoContent, Loader, Pagination, Icon } from 'UI';
|
||||
import SessionItem from 'Shared/SessionItem';
|
||||
import withPermissions from 'HOCs/withPermissions';
|
||||
import { KEYS } from 'Types/filter/customFilter';
|
||||
|
|
@ -13,6 +13,7 @@ import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
|||
import { numberWithCommas } from 'App/utils';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { Button } from 'antd'
|
||||
|
||||
const AUTOREFRESH_INTERVAL = 2 * 60 * 1000;
|
||||
const PER_PAGE = 10;
|
||||
|
|
@ -144,10 +145,9 @@ function LiveSessionList() {
|
|||
</span>
|
||||
|
||||
<Button
|
||||
variant="text-primary"
|
||||
variant="text"
|
||||
className="mt-4"
|
||||
icon="arrow-repeat"
|
||||
iconSize={20}
|
||||
icon={<Icon name="arrow-repeat" size={20} />}
|
||||
onClick={refetch}
|
||||
>
|
||||
Refresh
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Button, Modal, Form, Icon, Checkbox, Input } from 'UI';
|
||||
import { confirm } from 'UI';
|
||||
import { confirm, Modal, Form, Icon, Checkbox, Input } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import stl from './SaveSearchModal.module.css';
|
||||
import cn from 'classnames';
|
||||
import { toast } from 'react-toastify';
|
||||
|
|
@ -96,14 +96,14 @@ function SaveSearchModal({ show, closeHandler, rename = false }: Props) {
|
|||
</Modal.Content>
|
||||
<Modal.Footer className="flex items-center px-6">
|
||||
<div className="mr-auto flex items-center">
|
||||
<Button variant="primary" onClick={onSave} loading={loading} disabled={!savedSearch.validate()}
|
||||
<Button type="primary" onClick={onSave} loading={loading} disabled={!savedSearch.validate()}
|
||||
className="mr-2">
|
||||
{savedSearch.exists() ? 'Update' : 'Save'}
|
||||
</Button>
|
||||
<Button onClick={closeHandler}>{'Cancel'}</Button>
|
||||
</div>
|
||||
{savedSearch.exists() && (
|
||||
<Button variant="text" onClick={onDelete}>
|
||||
<Button type="text" onClick={onDelete}>
|
||||
<Icon name="trash" size="18" />
|
||||
</Button>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import React from 'react';
|
||||
import { Popover, Button } from 'UI';
|
||||
import { Popover } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import MetaItem from '../MetaItem';
|
||||
|
||||
interface Props {
|
||||
|
|
@ -23,7 +24,7 @@ export default function MetaMoreButton(props: Props) {
|
|||
placement="bottom"
|
||||
>
|
||||
<div className="flex items-center">
|
||||
<Button variant="text-primary">+{list.length - maxLength} More</Button>
|
||||
<Button variant="text">+{list.length - maxLength} More</Button>
|
||||
</div>
|
||||
</Popover>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { Conditions } from 'App/mstore/types/FeatureFlag';
|
||||
import React from 'react';
|
||||
import ConditionSet from 'Shared/ConditionSet';
|
||||
import { Button } from 'UI';
|
||||
import { Icon } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import { nonConditionalFlagFilters } from 'Types/filter/newFilter';
|
||||
|
||||
function ConditionalRecordingSettings({
|
||||
|
|
@ -43,7 +44,7 @@ function ConditionalRecordingSettings({
|
|||
/>
|
||||
<div className={'flex gap-1 items-center'}>
|
||||
<span className={'font-semibold'}>matching</span>
|
||||
<Button variant={'text-primary'} icon={'plus'} onClick={addConditionSet}>
|
||||
<Button type={'text'} icon={<Icon name={'plus'} size={16} />} onClick={addConditionSet}>
|
||||
Condition Set
|
||||
</Button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import { toast } from 'react-toastify';
|
|||
|
||||
import { useStore } from 'App/mstore';
|
||||
import { Timezone } from 'App/mstore/types/sessionSettings';
|
||||
import { Button, Icon } from 'UI';
|
||||
|
||||
import { Icon } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import Select from 'Shared/Select';
|
||||
|
||||
type TimezonesDropdown = Timezone[];
|
||||
|
|
@ -104,8 +104,7 @@ function DefaultTimezone() {
|
|||
<div className="col-span-3 ml-3">
|
||||
<Button
|
||||
disabled={!changed}
|
||||
variant="outline"
|
||||
size="medium"
|
||||
type="default"
|
||||
onClick={onTimezoneSave}
|
||||
>
|
||||
Update
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
import Select from 'Shared/Select';
|
||||
import { Button, Input } from 'UI';
|
||||
import { Input } from 'UI';
|
||||
import { Button } from 'antd';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { toast } from 'react-toastify';
|
||||
|
|
@ -66,7 +67,7 @@ function ListingVisibility() {
|
|||
/>
|
||||
</div>
|
||||
<div className="col-span-3">
|
||||
<Button variant="outline" size="medium" disabled={!changed} onClick={saveSettings}>Update</Button>
|
||||
<Button type="default" disabled={!changed} onClick={saveSettings}>Update</Button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { FilterKey } from 'Types/filter/filterType';
|
||||
import SessionItem from 'Shared/SessionItem';
|
||||
import { NoContent, Loader, Pagination, Button } from 'UI';
|
||||
import { NoContent, Loader, Pagination, Icon } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
import { useLocation, withRouter } from 'react-router-dom';
|
||||
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
|
||||
import { numberWithCommas } from 'App/utils';
|
||||
|
|
@ -188,10 +189,9 @@ function SessionList() {
|
|||
</div>
|
||||
)}
|
||||
<Button
|
||||
variant="text-primary"
|
||||
variant="text"
|
||||
className="mt-4"
|
||||
icon="arrow-repeat"
|
||||
iconSize={20}
|
||||
icon={<Icon name={"arrow-repeat"} size={20} />}
|
||||
onClick={() => {
|
||||
void searchStore.fetchSessions(true, isBookmark);
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import { useModal } from 'App/components/Modal';
|
||||
import React from 'react';
|
||||
import SessionSettings from 'Shared/SessionSettings';
|
||||
import { Button, Tooltip } from 'UI';
|
||||
import { Icon, Tooltip } from 'UI';
|
||||
import { Button } from 'antd'
|
||||
|
||||
function SessionSettingButton(props: any) {
|
||||
const { showModal } = useModal();
|
||||
|
|
@ -13,7 +14,7 @@ function SessionSettingButton(props: any) {
|
|||
return (
|
||||
<div className="cursor-pointer ml-4" onClick={handleClick}>
|
||||
<Tooltip title="Session Settings">
|
||||
<Button icon="sliders" variant="text" id="btn-session-settings" />
|
||||
<Button icon={<Icon name={'sliders'} />} type="text" id="btn-session-settings" />
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue