endpoints WIP
This commit is contained in:
parent
273dbd2ec5
commit
7d0f8d4177
8 changed files with 174 additions and 46 deletions
|
|
@ -11,6 +11,7 @@ import Text from 'components/Text/Text';
|
|||
import WithConfirm from 'components/WithConfirm/WithConfirm';
|
||||
import { User as UserType } from 'models/user/user.types';
|
||||
import { WithStoreProps } from 'state/types';
|
||||
import { useStore } from 'state/useStore';
|
||||
import { withMobXProviderContext } from 'state/withStore';
|
||||
|
||||
import styles from './CloudPhoneSettings.module.css';
|
||||
|
|
@ -20,21 +21,22 @@ const cx = cn.bind(styles);
|
|||
interface CloudPhoneSettingsProps extends WithStoreProps {}
|
||||
|
||||
const CloudPhoneSettings = (props: CloudPhoneSettingsProps) => {
|
||||
const store = useStore();
|
||||
const [isAccountMatched, setIsAccountMatched] = useState<boolean>(true);
|
||||
const [isPhoneVerified, setIsPhoneVerified] = useState<boolean>(true);
|
||||
|
||||
const signUpGrafanaCloud = () => {
|
||||
console.log('Sign UP');
|
||||
};
|
||||
const handleLinkClick = (link: string) => {
|
||||
getLocationSrv().update({ partial: false, path: link });
|
||||
const handleLinkClick = () => {
|
||||
store.cloudStore.syncCloudUser(store.userStore.currentUserPk);
|
||||
};
|
||||
|
||||
return (
|
||||
<VerticalGroup spacing="lg">
|
||||
<HorizontalGroup justify="space-between">
|
||||
<Text.Title level={3}>OnCall use Grafana Cloud for SMS and phone call notifications</Text.Title>
|
||||
<Button variant="secondary" icon="sync" onClick={() => handleLinkClick('fillmewithcorrectlink')}>
|
||||
<Button variant="secondary" icon="sync" onClick={handleLinkClick}>
|
||||
Update
|
||||
</Button>
|
||||
</HorizontalGroup>
|
||||
|
|
|
|||
8
grafana-plugin/src/icons/cross-circled.svg
Normal file
8
grafana-plugin/src/icons/cross-circled.svg
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<svg width="15px" height="15px" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
clip-rule="evenodd"
|
||||
d="M0.877075 7.49988C0.877075 3.84219 3.84222 0.877045 7.49991 0.877045C11.1576 0.877045 14.1227 3.84219 14.1227 7.49988C14.1227 11.1575 11.1576 14.1227 7.49991 14.1227C3.84222 14.1227 0.877075 11.1575 0.877075 7.49988ZM7.49991 1.82704C4.36689 1.82704 1.82708 4.36686 1.82708 7.49988C1.82708 10.6329 4.36689 13.1727 7.49991 13.1727C10.6329 13.1727 13.1727 10.6329 13.1727 7.49988C13.1727 4.36686 10.6329 1.82704 7.49991 1.82704ZM9.85358 5.14644C10.0488 5.3417 10.0488 5.65829 9.85358 5.85355L8.20713 7.49999L9.85358 9.14644C10.0488 9.3417 10.0488 9.65829 9.85358 9.85355C9.65832 10.0488 9.34173 10.0488 9.14647 9.85355L7.50002 8.2071L5.85358 9.85355C5.65832 10.0488 5.34173 10.0488 5.14647 9.85355C4.95121 9.65829 4.95121 9.3417 5.14647 9.14644L6.79292 7.49999L5.14647 5.85355C4.95121 5.65829 4.95121 5.3417 5.14647 5.14644C5.34173 4.95118 5.65832 4.95118 5.85358 5.14644L7.50002 6.79289L9.14647 5.14644C9.34173 4.95118 9.65832 4.95118 9.85358 5.14644Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
24
grafana-plugin/src/icons/heart-line.svg
Normal file
24
grafana-plugin/src/icons/heart-line.svg
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg
|
||||
version="1.1"
|
||||
width="16"
|
||||
height="16"
|
||||
id="Capa_1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="0px"
|
||||
y="0px"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 490.4 490.4"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M222.5,453.7c6.1,6.1,14.3,9.5,22.9,9.5c8.5,0,16.9-3.5,22.9-9.5L448,274c27.3-27.3,42.3-63.6,42.4-102.1
|
||||
c0-38.6-15-74.9-42.3-102.2S384.6,27.4,346,27.4c-37.9,0-73.6,14.5-100.7,40.9c-27.2-26.5-63-41.1-101-41.1
|
||||
c-38.5,0-74.7,15-102,42.2C15,96.7,0,133,0,171.6c0,38.5,15.1,74.8,42.4,102.1L222.5,453.7z M59.7,86.8
|
||||
c22.6-22.6,52.7-35.1,84.7-35.1s62.2,12.5,84.9,35.2l7.4,7.4c2.3,2.3,5.4,3.6,8.7,3.6l0,0c3.2,0,6.4-1.3,8.7-3.6l7.2-7.2
|
||||
c22.7-22.7,52.8-35.2,84.9-35.2c32,0,62.1,12.5,84.7,35.1c22.7,22.7,35.1,52.8,35.1,84.8s-12.5,62.1-35.2,84.8L251,436.4
|
||||
c-2.9,2.9-8.2,2.9-11.2,0l-180-180c-22.7-22.7-35.2-52.8-35.2-84.8C24.6,139.6,37.1,109.5,59.7,86.8z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1 KiB |
|
|
@ -168,6 +168,42 @@ export const HeartRedIcon = (props: IconProps) => (
|
|||
</svg>
|
||||
);
|
||||
|
||||
export const HeartIcon = (props: IconProps) => (
|
||||
<svg
|
||||
version="1.1"
|
||||
width="16"
|
||||
height="16"
|
||||
id="Capa_1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
x="0px"
|
||||
y="0px"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 490.4 490.4"
|
||||
>
|
||||
<g>
|
||||
<path
|
||||
d="M222.5,453.7c6.1,6.1,14.3,9.5,22.9,9.5c8.5,0,16.9-3.5,22.9-9.5L448,274c27.3-27.3,42.3-63.6,42.4-102.1
|
||||
c0-38.6-15-74.9-42.3-102.2S384.6,27.4,346,27.4c-37.9,0-73.6,14.5-100.7,40.9c-27.2-26.5-63-41.1-101-41.1
|
||||
c-38.5,0-74.7,15-102,42.2C15,96.7,0,133,0,171.6c0,38.5,15.1,74.8,42.4,102.1L222.5,453.7z M59.7,86.8
|
||||
c22.6-22.6,52.7-35.1,84.7-35.1s62.2,12.5,84.9,35.2l7.4,7.4c2.3,2.3,5.4,3.6,8.7,3.6l0,0c3.2,0,6.4-1.3,8.7-3.6l7.2-7.2
|
||||
c22.7-22.7,52.8-35.2,84.9-35.2c32,0,62.1,12.5,84.7,35.1c22.7,22.7,35.1,52.8,35.1,84.8s-12.5,62.1-35.2,84.8L251,436.4
|
||||
c-2.9,2.9-8.2,2.9-11.2,0l-180-180c-22.7-22.7-35.2-52.8-35.2-84.8C24.6,139.6,37.1,109.5,59.7,86.8z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const CrossCircleIcon = (props: IconProps) => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M0.877075 7.49988C0.877075 3.84219 3.84222 0.877045 7.49991 0.877045C11.1576 0.877045 14.1227 3.84219 14.1227 7.49988C14.1227 11.1575 11.1576 14.1227 7.49991 14.1227C3.84222 14.1227 0.877075 11.1575 0.877075 7.49988ZM7.49991 1.82704C4.36689 1.82704 1.82708 4.36686 1.82708 7.49988C1.82708 10.6329 4.36689 13.1727 7.49991 13.1727C10.6329 13.1727 13.1727 10.6329 13.1727 7.49988C13.1727 4.36686 10.6329 1.82704 7.49991 1.82704ZM9.85358 5.14644C10.0488 5.3417 10.0488 5.65829 9.85358 5.85355L8.20713 7.49999L9.85358 9.14644C10.0488 9.3417 10.0488 9.65829 9.85358 9.85355C9.65832 10.0488 9.34173 10.0488 9.14647 9.85355L7.50002 8.2071L5.85358 9.85355C5.65832 10.0488 5.34173 10.0488 5.14647 9.85355C4.95121 9.65829 4.95121 9.3417 5.14647 9.14644L6.79292 7.49999L5.14647 5.85355C4.95121 5.65829 4.95121 5.3417 5.14647 5.14644C5.34173 4.95118 5.65832 4.95118 5.85358 5.14644L7.50002 6.79289L9.14647 5.14644C9.34173 4.95118 9.65832 4.95118 9.85358 5.14644Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const GrafanaIcon = (props: IconProps) => (
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { action, computed, observable } from 'mobx';
|
|||
|
||||
import BaseStore from 'models/base_store';
|
||||
import { NotificationPolicyType } from 'models/notification_policy';
|
||||
import { User } from 'models/user/user.types';
|
||||
import { makeRequest } from 'network';
|
||||
import { Mixpanel } from 'services/mixpanel';
|
||||
import { RootStore } from 'state';
|
||||
|
|
@ -24,11 +25,9 @@ export class CloudStore extends BaseStore {
|
|||
}
|
||||
|
||||
@action
|
||||
async updateItems(f: any = { searchTerm: '' }, page = 1) {
|
||||
const filters = typeof f === 'string' ? { searchTerm: f } : f; // for GSelect compatibility
|
||||
const { searchTerm: search } = filters;
|
||||
async updateItems(page = 1) {
|
||||
const { count, results } = await makeRequest(this.path, {
|
||||
params: { search, page },
|
||||
params: { page },
|
||||
});
|
||||
|
||||
this.items = {
|
||||
|
|
@ -51,14 +50,16 @@ export class CloudStore extends BaseStore {
|
|||
getSearchResult() {
|
||||
return {
|
||||
count: this.searchResult.count,
|
||||
results:
|
||||
this.searchResult.results &&
|
||||
this.searchResult.results.map((cloud_user_id: Cloud['id']) => this.items?.[cloud_user_id]),
|
||||
results: this.searchResult.results && this.searchResult.results.map((id: Cloud['id']) => this.items?.[id]),
|
||||
};
|
||||
}
|
||||
|
||||
async syncCloudUsers() {
|
||||
return await makeRequest(`${this.path}sync_with_cloud`, { method: 'POST' });
|
||||
return await makeRequest(`${this.path}`, { method: 'POST' });
|
||||
}
|
||||
|
||||
async syncCloudUser(id: string) {
|
||||
return await makeRequest(`${this.path}${id}/sync_with_cloud/`, { method: 'POST' });
|
||||
}
|
||||
|
||||
async getCloudConnectionStatus() {
|
||||
|
|
@ -66,9 +67,7 @@ export class CloudStore extends BaseStore {
|
|||
}
|
||||
|
||||
@action
|
||||
async connectToCloud(token: string) {
|
||||
return await makeRequest(`/live_settings/`, { method: 'PUT', params: { token } });
|
||||
}
|
||||
async connectToCloud(token: string) {}
|
||||
|
||||
@action
|
||||
async disconnectToCloud() {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
export interface Cloud {
|
||||
id: string;
|
||||
username: string;
|
||||
cloud_sync_status?: number;
|
||||
link?: string;
|
||||
email: string;
|
||||
cloud_data?: {
|
||||
status?: number;
|
||||
link?: string;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
.info-block {
|
||||
width: 70%;
|
||||
min-width: 1100px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.warning-message {
|
||||
|
|
@ -19,6 +21,10 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.user-row {
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.cloud-page-title {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
|
@ -26,3 +32,19 @@
|
|||
.cloud-oncall-name {
|
||||
color: #f55f3e;
|
||||
}
|
||||
|
||||
.block-icon {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
|
||||
.block-button {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.table-title {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.table-button {
|
||||
float: right;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import GTable from 'components/GTable/GTable';
|
|||
import PluginLink from 'components/PluginLink/PluginLink';
|
||||
import Text from 'components/Text/Text';
|
||||
import WithConfirm from 'components/WithConfirm/WithConfirm';
|
||||
import { HeartGreenIcon, HeartRedIcon } from 'icons';
|
||||
import { CrossCircleIcon, HeartIcon } from 'icons';
|
||||
import { Cloud } from 'models/cloud/cloud.types';
|
||||
import { WithStoreProps } from 'state/types';
|
||||
import { useStore } from 'state/useStore';
|
||||
|
|
@ -29,16 +29,19 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
|
||||
useEffect(() => {
|
||||
store.cloudStore.updateItems();
|
||||
store.cloudStore.getCloudConnectionStatus().then((cloudStatus) => {
|
||||
setCloudIsConnected(cloudStatus.cloud_connection_status);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const usersCount = 3;
|
||||
const data = [
|
||||
{ id: 'yshanyrova', username: 'y.shanyrova@grafana.com', cloud_sync_status: 2, link: '/test/abc' },
|
||||
{ id: 'amixradmin', username: 'amixr-admin@grafana.com', cloud_sync_status: 1, link: '/test/qwerty' },
|
||||
{ id: 'amixr', username: 'amixr@grafana.com', cloud_sync_status: undefined, link: undefined },
|
||||
{ id: 'yshanyrova', email: 'y.shanyrova@grafana.com', cloud_data: { status: 2, link: '/test/abc' } },
|
||||
{ id: 'amixradmin', email: 'amixr-admin@grafana.com', cloud_data: { status: 1, link: '/test/abc' } },
|
||||
{ id: 'amixr', email: 'amixr@grafana.com', cloud_data: { status: undefined, link: '/test/abc' } },
|
||||
];
|
||||
|
||||
// const data = store.cloudStore.getSearchResult();
|
||||
// const { count, results } = store.cloudStore.getSearchResult();
|
||||
|
||||
const handleChangeCloudApiKey = useCallback((e) => {
|
||||
setCloudApiKey(e.target.value);
|
||||
}, []);
|
||||
|
|
@ -56,11 +59,12 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
const connectToCloud = () => {
|
||||
setCloudIsConnected(true);
|
||||
setShowConfirmationModal(false);
|
||||
// store.cloudStore.update('')
|
||||
store.cloudStore.connectToCloud(cloudApiKey);
|
||||
};
|
||||
|
||||
const syncUsers = () => {
|
||||
console.log('Sync Users');
|
||||
store.cloudStore.syncCloudUsers();
|
||||
};
|
||||
|
||||
const handleLinkClick = (link: string) => {
|
||||
|
|
@ -68,18 +72,30 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
};
|
||||
|
||||
const renderButtons = (user: Cloud) => {
|
||||
switch (user.cloud_sync_status) {
|
||||
switch (user?.cloud_data?.status) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return (
|
||||
<Button variant="secondary" icon="external-link-alt" onClick={() => handleLinkClick(user.link)}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
icon="external-link-alt"
|
||||
size="sm"
|
||||
className={cx('table-button')}
|
||||
onClick={() => handleLinkClick(user?.cloud_data?.link)}
|
||||
>
|
||||
Configure notifications
|
||||
</Button>
|
||||
);
|
||||
case 2:
|
||||
return (
|
||||
<Button variant="secondary" icon="external-link-alt" onClick={() => handleLinkClick(user.link)}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
icon="external-link-alt"
|
||||
size="sm"
|
||||
className={cx('table-button')}
|
||||
onClick={() => handleLinkClick(user?.cloud_data?.link)}
|
||||
>
|
||||
Open profile in Cloud
|
||||
</Button>
|
||||
);
|
||||
|
|
@ -89,7 +105,7 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
};
|
||||
|
||||
const renderStatus = (user: Cloud) => {
|
||||
switch (user.cloud_sync_status) {
|
||||
switch (user?.cloud_data?.status) {
|
||||
case 0:
|
||||
return <Text className={cx('error-message')}>User not found in the Grafana Cloud</Text>;
|
||||
case 1:
|
||||
|
|
@ -103,41 +119,49 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
};
|
||||
|
||||
const renderStatusIcon = (user: Cloud) => {
|
||||
switch (user.cloud_sync_status) {
|
||||
switch (user?.cloud_data?.status) {
|
||||
case 0:
|
||||
return <Icon className={cx('error-message')} name="times" />;
|
||||
return (
|
||||
<span className={cx('error-message')}>
|
||||
<CrossCircleIcon />
|
||||
</span>
|
||||
);
|
||||
case 1:
|
||||
return <Icon className={cx('success-message')} name="check-circle" />;
|
||||
|
||||
case 2:
|
||||
return <Icon className={cx('warning-message')} name="exclamation-triangle" />;
|
||||
default:
|
||||
return <Icon className={cx('error-message')} name="times" />;
|
||||
return (
|
||||
<span className={cx('error-message')}>
|
||||
<CrossCircleIcon />
|
||||
</span>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const renderEmail = (user: Cloud) => {
|
||||
return <Text type="primary">{user.username}</Text>;
|
||||
return <Text type="primary">{user.email}</Text>;
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{
|
||||
width: '5%',
|
||||
width: '2%',
|
||||
render: renderStatusIcon,
|
||||
key: 'statusIcon',
|
||||
},
|
||||
{
|
||||
width: '30%',
|
||||
width: '28%',
|
||||
render: renderEmail,
|
||||
key: 'email',
|
||||
},
|
||||
{
|
||||
width: '35%',
|
||||
width: '50%',
|
||||
render: renderStatus,
|
||||
key: 'status',
|
||||
},
|
||||
{
|
||||
width: '30%',
|
||||
width: '20%',
|
||||
render: renderButtons,
|
||||
key: 'buttons',
|
||||
align: 'actions',
|
||||
|
|
@ -154,12 +178,12 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
{cloudIsConnected ? (
|
||||
<VerticalGroup>
|
||||
<Text.Title level={4}>
|
||||
<Icon name="check" className={cx('heart-icon')} /> Cloud OnCall API key
|
||||
<Icon name="check" className={cx('block-icon')} size="lg" /> Cloud OnCall API key
|
||||
</Text.Title>
|
||||
<Text type="secondary">Cloud OnCall is sucessfully connected.</Text>
|
||||
|
||||
<WithConfirm title="Are you sure to disconnect Cloud OnCall?" confirmText="Disconnect">
|
||||
<Button variant="destructive" onClick={disconnectCloudOncall} size="md">
|
||||
<Button variant="destructive" onClick={disconnectCloudOncall} size="md" className={cx('block-button')}>
|
||||
Disconnect
|
||||
</Button>
|
||||
</WithConfirm>
|
||||
|
|
@ -167,7 +191,7 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
) : (
|
||||
<VerticalGroup>
|
||||
<Text.Title level={4}>
|
||||
<Icon name="sync" className={cx('heart-icon')} /> Cloud OnCall API key
|
||||
<Icon name="sync" className={cx('block-icon')} size="lg" /> Cloud OnCall API key
|
||||
</Text.Title>
|
||||
<Field label="" description="Find it in you Cloud OnCall -> Settings page" style={{ width: '100%' }}>
|
||||
<Input id="cloudApiKey" onChange={handleChangeCloudApiKey} />
|
||||
|
|
@ -199,7 +223,10 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
<Block bordered withBackground className={cx('info-block')}>
|
||||
<VerticalGroup>
|
||||
<Text.Title level={4}>
|
||||
<Icon name="heart-break" className={cx('heart-icon')} /> Monitor cloud instance with heartbeat
|
||||
<span className={cx('block-icon')}>
|
||||
<HeartIcon />
|
||||
</span>{' '}
|
||||
Monitor cloud instance with heartbeat
|
||||
</Text.Title>
|
||||
<Text type="secondary">
|
||||
Once connected, current OnCall instance will send heartbeats every 3 minutes to the cloud Instance. If no
|
||||
|
|
@ -209,6 +236,7 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
<Button
|
||||
variant="secondary"
|
||||
icon="external-link-alt"
|
||||
className={cx('block-button')}
|
||||
onClick={() => handleLinkClick('fillmewithcorrectlink')}
|
||||
>
|
||||
Configure escalations in Cloud OnCall
|
||||
|
|
@ -220,7 +248,7 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
<Block bordered withBackground className={cx('info-block')}>
|
||||
<VerticalGroup>
|
||||
<Text.Title level={4}>
|
||||
<Icon name="bell" /> SMS and phone call notifications
|
||||
<Icon name="bell" className={cx('block-icon')} size="lg" /> SMS and phone call notifications
|
||||
</Text.Title>
|
||||
{cloudIsConnected ? (
|
||||
<div style={{ width: '100%' }}>
|
||||
|
|
@ -233,14 +261,20 @@ const CloudPage = (props: CloudPageProps) => {
|
|||
<GTable
|
||||
className={cx('user-table')}
|
||||
rowClassName={cx('user-row')}
|
||||
showHeader={false}
|
||||
emptyText={data ? 'No variables found' : 'Loading...'}
|
||||
title={() => (
|
||||
<HorizontalGroup justify="space-between">
|
||||
<Text type="secondary">{`${usersCount} users matched between OSS and Cloud OnCall`}</Text>
|
||||
<Button variant="primary" onClick={syncUsers} icon="sync">
|
||||
Sync users
|
||||
</Button>
|
||||
</HorizontalGroup>
|
||||
<div className={cx('table-title')}>
|
||||
<HorizontalGroup justify="space-between">
|
||||
<Text type="secondary">
|
||||
{/* {count ? count : 0} */}
|
||||
{`3 users matched between OSS and Cloud OnCall`}
|
||||
</Text>
|
||||
<Button variant="primary" onClick={syncUsers} icon="sync">
|
||||
Sync users
|
||||
</Button>
|
||||
</HorizontalGroup>
|
||||
</div>
|
||||
)}
|
||||
rowKey="id"
|
||||
// @ts-ignore
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue