Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions app/data_sources/confluence_cloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from typing import List, Dict
from data_sources.confluence import ConfluenceDataSource

from atlassian import Confluence

from data_source_api.base_data_source import BaseDataSource, ConfigField, HTMLInputType
from data_source_api.exception import InvalidDataSourceConfig
from pydantic import BaseModel

class ConfluenceCloudConfig(BaseModel):
url: str
token: str
username: str

class ConfluenceCloudDataSource(ConfluenceDataSource):

@staticmethod
def get_config_fields() -> List[ConfigField]:
return [
ConfigField(label="Confluence URL", name="url", placeholder="https://example.confluence.com"),
ConfigField(label="Personal Access Token", name="token", input_type=HTMLInputType.PASSWORD),
ConfigField(label="Username", name="username", placeholder="example.user@email.com")
]

@staticmethod
def validate_config(config: Dict) -> None:
try:
parsed_config = ConfluenceCloudConfig(**config)
confluence = Confluence(url=parsed_config.url, username=parsed_config.username, password=parsed_config.token, cloud=True)
ConfluenceCloudDataSource.list_spaces(confluence=confluence)
except Exception as e:
raise InvalidDataSourceConfig from e

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
confluence_config = ConfluenceCloudConfig(**self._config)
self._confluence = Confluence(url=confluence_config.url, username=confluence_config.username, password=confluence_config.token, verify_ssl=False, cloud=True)
Binary file added app/static/data_source_icons/confluence_cloud.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
87 changes: 51 additions & 36 deletions ui/src/components/data-source-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ export interface ConfluenceConfig {
token: string;
}

export interface ConfluenceCloudConfig {
url: string;
token: string;
username: string;
}

export interface SlackConfig {
token: string;
}
Expand Down Expand Up @@ -99,7 +105,7 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
configFields: data_source.config_fields
}}
);

this.setState({
selectOptions: options,
selectedDataSource: options[0],
Expand Down Expand Up @@ -148,21 +154,21 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
})
}
{
Object.keys(this.props.dataSourceTypesDict).map((key) => {
let dataSource = this.props.dataSourceTypesDict[key];
if (!this.props.connectedDataSources.includes(dataSource.name)) {
return (
<div onClick={() => this.dataSourceToAddSelected(dataSource)} className="flex hover:text-[#9875d4] py-2 pl-5 pr-3 m-2 flex-row items-center justify-center bg-[#36323b] hover:border-[#9875d4] rounded-lg font-poppins leading-[28px] border-[#777777] border-b-[.5px] transition duration-300 ease-in-out">
<img alt="" className={"mr-2 h-[20px]"} src={dataSource.image_base64}></img>
{/* <h1 className="text-white">Add</h1> */}
<h1 className="text-gray-500">{dataSource.display_name}</h1>
<IoAddCircleOutline className="ml-6 text-white text-2xl hover:text-[#9875d4] hover:cursor-pointer transition duration-200 ease-in-out"></IoAddCircleOutline>
</div>
)
}
return null;
Object.keys(this.props.dataSourceTypesDict).map((key) => {
let dataSource = this.props.dataSourceTypesDict[key];
if (!this.props.connectedDataSources.includes(dataSource.name)) {
return (
<div onClick={() => this.dataSourceToAddSelected(dataSource)} className="flex hover:text-[#9875d4] py-2 pl-5 pr-3 m-2 flex-row items-center justify-center bg-[#36323b] hover:border-[#9875d4] rounded-lg font-poppins leading-[28px] border-[#777777] border-b-[.5px] transition duration-300 ease-in-out">
<img alt="" className={"mr-2 h-[20px]"} src={dataSource.image_base64}></img>
{/* <h1 className="text-white">Add</h1> */}
<h1 className="text-gray-500">{dataSource.display_name}</h1>
<IoAddCircleOutline className="ml-6 text-white text-2xl hover:text-[#9875d4] hover:cursor-pointer transition duration-200 ease-in-out"></IoAddCircleOutline>
</div>
)
}
return null;

})
})
}
</div>
</div>)
Expand Down Expand Up @@ -207,7 +213,16 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
{
this.state.selectedDataSource.value === 'confluence' && (
<span className="flex flex-col leading-9 text-xl text-white">
<span>1. {'Go to your Confluene -> top-right profile picture -> Settings'}</span>
<span>1. {'Go to your Confluence -> top-right profile picture -> Settings'}</span>
<span>2. {'Personal Access Tokens -> Create token -> Name it'}</span>
<span>3. {"Uncheck 'Automatic expiry', create and copy the token"}</span>
</span>
)
}
{
this.state.selectedDataSource.value === 'confluence_cloud' && (
<span className="flex flex-col leading-9 text-xl text-white">
<span>1. {'Go to your Confluence -> top-right profile picture -> Settings'}</span>
<span>2. {'Personal Access Tokens -> Create token -> Name it'}</span>
<span>3. {"Uncheck 'Automatic expiry', create and copy the token"}</span>
</span>
Expand Down Expand Up @@ -270,26 +285,26 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
<div className="flex flex-row flex-wrap items-end mt-4">
{/* for each field */}
{
this.state.selectedDataSource.configFields.map((field, index) => {
if(field.input_type === 'text' || field.input_type === 'password') {
return (
<div className="flex flex-col mr-10">
<h1 className="text-lg block text-white mb-4">{field.label}</h1>
<input value={field.value} onChange={(event) => {field.value = event.target.value }}
className="w-96 h-10 rounded-lg bg-[#352C45] text-white p-2"
placeholder={field.placeholder}></input>
</div>
)
} else if (field.input_type === 'textarea') {
return (
<div className="flex flex-col w-full">
<h1 className="text-lg block text-white mb-4">{field.label}</h1>
<textarea value={field.value} onChange={(event) => {field.value = event.target.value }}
className="w-full h-80 rounded-lg bg-[#352C45] text-white p-2 mb-5" placeholder={field.placeholder}></textarea>
</div>
)}
this.state.selectedDataSource.configFields.map((field, index) => {
if(field.input_type === 'text' || field.input_type === 'password') {
return (
<div className="flex flex-col mr-10">
<h1 className="text-lg block text-white mb-4">{field.label}</h1>
<input value={field.value} onChange={(event) => {field.value = event.target.value }}
className="w-96 h-10 rounded-lg bg-[#352C45] text-white p-2"
placeholder={field.placeholder}></input>
</div>
)
} else if (field.input_type === 'textarea') {
return (
<div className="flex flex-col w-full">
<h1 className="text-lg block text-white mb-4">{field.label}</h1>
<textarea value={field.value} onChange={(event) => {field.value = event.target.value }}
className="w-full h-80 rounded-lg bg-[#352C45] text-white p-2 mb-5" placeholder={field.placeholder}></textarea>
</div>
)}
return null;
})
})
}
<div onClick={this.submit} className="flex py-2 px-3 mx-2 w-30 h-10 mt-4 flex-row items-center justify-center bg-[#352C45]
hover:bg-[#7459a1] hover:cursor-pointer rounded-lg font-poppins leading-[28px] border-[#522b60] transition duration-300 ease-in-out">
Expand Down Expand Up @@ -330,7 +345,7 @@ export default class DataSourcePanel extends React.Component<DataSourcePanelProp
this.state.selectedDataSource.configFields.forEach(field => {
config[field.name] = field.value;
});

let payload = {
name: this.state.selectedDataSource.value,
config: config
Expand Down