|
|
@ -1,7 +1,6 @@ |
|
|
|
import React, { useState, useEffect, useCallback } from 'react'; |
|
|
|
import React, { useState, useEffect, useCallback } from 'react'; |
|
|
|
import { useAuth } from '../../../lib/useAuth'; |
|
|
|
import { useAuth } from '../../../lib/useAuth'; |
|
|
|
import { Box, CircularProgress, IconButton, Typography, FormControl, Select, MenuItem, TextField, Menu } from '@material-ui/core'; |
|
|
|
import { Box, CircularProgress, IconButton, Typography, FormControl, Select, MenuItem, TextField, Menu, Button } from '@material-ui/core'; |
|
|
|
import { IntegrationDetails } from '../../../api'; |
|
|
|
|
|
|
|
import { getIntegrations, createIntegration, modifyIntegration, deleteIntegration } from '../../../lib/backend/integrations'; |
|
|
|
import { getIntegrations, createIntegration, modifyIntegration, deleteIntegration } from '../../../lib/backend/integrations'; |
|
|
|
import AddIcon from '@material-ui/icons/Add'; |
|
|
|
import AddIcon from '@material-ui/icons/Add'; |
|
|
|
import EditIcon from '@material-ui/icons/Edit'; |
|
|
|
import EditIcon from '@material-ui/icons/Edit'; |
|
|
@ -10,6 +9,7 @@ import DeleteIcon from '@material-ui/icons/Delete'; |
|
|
|
import * as serverApi from '../../../api'; |
|
|
|
import * as serverApi from '../../../api'; |
|
|
|
import StoreLinkIcon, { ExternalStore } from '../../common/StoreLinkIcon'; |
|
|
|
import StoreLinkIcon, { ExternalStore } from '../../common/StoreLinkIcon'; |
|
|
|
import { v4 as genUuid } from 'uuid'; |
|
|
|
import { v4 as genUuid } from 'uuid'; |
|
|
|
|
|
|
|
import { getAuthToken } from '../../../lib/integration/spotify/spotify'; |
|
|
|
let _ = require('lodash') |
|
|
|
let _ = require('lodash') |
|
|
|
|
|
|
|
|
|
|
|
interface EditIntegrationProps { |
|
|
|
interface EditIntegrationProps { |
|
|
@ -22,9 +22,42 @@ interface EditIntegrationProps { |
|
|
|
onDelete: () => void, |
|
|
|
onDelete: () => void, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function EditSpotifyClientCredentialsDetails(props: { |
|
|
|
|
|
|
|
clientId: string, |
|
|
|
|
|
|
|
clientSecret: string, |
|
|
|
|
|
|
|
editing: boolean, |
|
|
|
|
|
|
|
onChangeClientId: (v: string) => void, |
|
|
|
|
|
|
|
onChangeClientSecret: (v: string) => void, |
|
|
|
|
|
|
|
}) { |
|
|
|
|
|
|
|
return <Box> |
|
|
|
|
|
|
|
<Box display="flex" alignItems="center"> |
|
|
|
|
|
|
|
<Typography>Client id:</Typography> |
|
|
|
|
|
|
|
{props.editing ? |
|
|
|
|
|
|
|
<TextField |
|
|
|
|
|
|
|
variant="outlined" |
|
|
|
|
|
|
|
value={props.clientId || ""} |
|
|
|
|
|
|
|
label="Client Id:" |
|
|
|
|
|
|
|
onChange={(e: any) => props.onChangeClientId(e.target.value)} |
|
|
|
|
|
|
|
/> : |
|
|
|
|
|
|
|
<Typography>{props.clientId}</Typography>} |
|
|
|
|
|
|
|
</Box> |
|
|
|
|
|
|
|
<Box display="flex" alignItems="center"> |
|
|
|
|
|
|
|
<Typography>Client secret:</Typography> |
|
|
|
|
|
|
|
{props.editing ? |
|
|
|
|
|
|
|
<TextField |
|
|
|
|
|
|
|
variant="outlined" |
|
|
|
|
|
|
|
value={props.clientSecret || ""} |
|
|
|
|
|
|
|
label="Client secret:" |
|
|
|
|
|
|
|
onChange={(e: any) => props.onChangeClientSecret(e.target.value)} |
|
|
|
|
|
|
|
/> : |
|
|
|
|
|
|
|
<Typography>{props.clientSecret}</Typography>} |
|
|
|
|
|
|
|
</Box> |
|
|
|
|
|
|
|
</Box>; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function EditIntegration(props: EditIntegrationProps) { |
|
|
|
function EditIntegration(props: EditIntegrationProps) { |
|
|
|
let IntegrationHeaders: Record<any, any> = { |
|
|
|
let IntegrationHeaders: Record<any, any> = { |
|
|
|
[serverApi.IntegrationType.spotify]: <Box display="flex" alignItems="center"> |
|
|
|
[serverApi.IntegrationType.SpotifyClientCredentials]: <Box display="flex" alignItems="center"> |
|
|
|
<StoreLinkIcon |
|
|
|
<StoreLinkIcon |
|
|
|
style={{ height: '40px', width: '40px' }} |
|
|
|
style={{ height: '40px', width: '40px' }} |
|
|
|
whichStore={ExternalStore.Spotify} |
|
|
|
whichStore={ExternalStore.Spotify} |
|
|
@ -49,41 +82,27 @@ function EditIntegration(props: EditIntegrationProps) { |
|
|
|
/> : |
|
|
|
/> : |
|
|
|
<Typography>{props.integration.name}</Typography>} |
|
|
|
<Typography>{props.integration.name}</Typography>} |
|
|
|
</Box> |
|
|
|
</Box> |
|
|
|
{props.integration.type === serverApi.IntegrationType.spotify && <> |
|
|
|
{props.integration.type === serverApi.IntegrationType.SpotifyClientCredentials && |
|
|
|
<Box display="flex" alignItems="center"> |
|
|
|
<EditSpotifyClientCredentialsDetails |
|
|
|
<Typography>Client id:</Typography> |
|
|
|
clientId={props.integration.details.clientId} |
|
|
|
{props.editing ? |
|
|
|
clientSecret={props.integration.details.clientSecret} |
|
|
|
<TextField |
|
|
|
editing={props.editing} |
|
|
|
variant="outlined" |
|
|
|
onChangeClientId={(v: string) => props.onChange({ |
|
|
|
value={props.integration.details.clientId || ""} |
|
|
|
|
|
|
|
label="Client Id:" |
|
|
|
|
|
|
|
onChange={(e: any) => props.onChange({ |
|
|
|
|
|
|
|
...props.integration, |
|
|
|
...props.integration, |
|
|
|
details: { |
|
|
|
details: { |
|
|
|
...props.integration.details, |
|
|
|
...props.integration.details, |
|
|
|
clientId: e.target.value, |
|
|
|
clientId: v, |
|
|
|
} |
|
|
|
} |
|
|
|
}, props.editing)} |
|
|
|
}, props.editing)} |
|
|
|
/> : |
|
|
|
onChangeClientSecret={(v: string) => props.onChange({ |
|
|
|
<Typography>{props.integration.details.clientId}</Typography>} |
|
|
|
|
|
|
|
</Box> |
|
|
|
|
|
|
|
<Box display="flex" alignItems="center"> |
|
|
|
|
|
|
|
<Typography>Client secret:</Typography> |
|
|
|
|
|
|
|
{props.editing ? |
|
|
|
|
|
|
|
<TextField |
|
|
|
|
|
|
|
variant="outlined" |
|
|
|
|
|
|
|
value={props.integration.details.clientSecret || ""} |
|
|
|
|
|
|
|
label="Client secret:" |
|
|
|
|
|
|
|
onChange={(e: any) => props.onChange({ |
|
|
|
|
|
|
|
...props.integration, |
|
|
|
...props.integration, |
|
|
|
details: { |
|
|
|
details: { |
|
|
|
...props.integration.details, |
|
|
|
...props.integration.details, |
|
|
|
clientSecret: e.target.value, |
|
|
|
clientSecret: v, |
|
|
|
} |
|
|
|
} |
|
|
|
}, props.editing)} |
|
|
|
}, props.editing)} |
|
|
|
/> : |
|
|
|
/> |
|
|
|
<Typography>{props.integration.details.clientSecret}</Typography>} |
|
|
|
} |
|
|
|
</Box> |
|
|
|
|
|
|
|
{!props.editing && !props.submitting && <IconButton |
|
|
|
{!props.editing && !props.submitting && <IconButton |
|
|
|
onClick={() => { props.onChange(props.integration, true); }} |
|
|
|
onClick={() => { props.onChange(props.integration, true); }} |
|
|
|
><EditIcon /></IconButton>} |
|
|
|
><EditIcon /></IconButton>} |
|
|
@ -93,8 +112,10 @@ function EditIntegration(props: EditIntegrationProps) { |
|
|
|
{!props.submitting && <IconButton |
|
|
|
{!props.submitting && <IconButton |
|
|
|
onClick={() => { props.onDelete(); }} |
|
|
|
onClick={() => { props.onDelete(); }} |
|
|
|
><DeleteIcon /></IconButton>} |
|
|
|
><DeleteIcon /></IconButton>} |
|
|
|
|
|
|
|
{!props.submitting && <Button |
|
|
|
|
|
|
|
onClick={() => { }} |
|
|
|
|
|
|
|
>Test</Button>} |
|
|
|
{props.submitting && <CircularProgress />} |
|
|
|
{props.submitting && <CircularProgress />} |
|
|
|
</>} |
|
|
|
|
|
|
|
</Box > |
|
|
|
</Box > |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -117,7 +138,7 @@ function AddIntegrationMenu(props: { |
|
|
|
> |
|
|
|
> |
|
|
|
<MenuItem |
|
|
|
<MenuItem |
|
|
|
onClick={() => { |
|
|
|
onClick={() => { |
|
|
|
props.onAdd(serverApi.IntegrationType.spotify); |
|
|
|
props.onAdd(serverApi.IntegrationType.SpotifyClientCredentials); |
|
|
|
props.onClose(); |
|
|
|
props.onClose(); |
|
|
|
}} |
|
|
|
}} |
|
|
|
>Spotify</MenuItem> |
|
|
|
>Spotify</MenuItem> |
|
|
@ -267,7 +288,7 @@ export default function IntegrationSettingsEditor(props: {}) { |
|
|
|
let cpy = _.cloneDeep(editors); |
|
|
|
let cpy = _.cloneDeep(editors); |
|
|
|
cpy.push({ |
|
|
|
cpy.push({ |
|
|
|
integration: { |
|
|
|
integration: { |
|
|
|
type: serverApi.IntegrationType.spotify, |
|
|
|
type: serverApi.IntegrationType.SpotifyClientCredentials, |
|
|
|
details: { |
|
|
|
details: { |
|
|
|
clientId: '', |
|
|
|
clientId: '', |
|
|
|
clientSecret: '', |
|
|
|
clientSecret: '', |
|
|
|