Skip to content

Commit

Permalink
qna picker (no filtering yet)
Browse files Browse the repository at this point in the history
  • Loading branch information
emirotin committed Oct 6, 2019
1 parent 22f50eb commit e0ed627
Show file tree
Hide file tree
Showing 13 changed files with 509 additions and 66 deletions.
9 changes: 8 additions & 1 deletion modules/misunderstood/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,12 @@
"module-builder": "../../build/module-builder",
"tslint": "^5.20.0"
},
"dependencies": {}
"dependencies": {},
"webpack": {
"externals": {
"react": "React",
"react-dom": "ReactDOM",
"botpress/utils": "BotpressUtils"
}
}
}
116 changes: 79 additions & 37 deletions modules/misunderstood/src/views/full/MainScreen/AmendForm.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,91 @@
import { Button, ButtonGroup, Intent } from '@blueprintjs/core'
import { AxiosStatic } from 'axios'
import React from 'react'

import { RESOLUTION_TYPE } from '../../../types'

import style from './style.scss'
import QnAPicker from './QnAPicker'

const AmendForm = ({ mode, setMode }) => (
<div className={style.amendForm}>
<h5>What is this message type?</h5>
interface Props {
axios: AxiosStatic
language: string
mode: RESOLUTION_TYPE
resolution: string | null
resolutionParams: string | object | null
setMode: (mode: RESOLUTION_TYPE) => void
onUpdate: (resolution: string, resolutionParams?: string | object | null) => void
onSave: () => void
onCancel: () => void
}

<ButtonGroup>
<Button
onClick={() => {
if (mode === RESOLUTION_TYPE.intent) {
return
}
setMode(RESOLUTION_TYPE.intent)
}}
intent={mode === RESOLUTION_TYPE.intent ? Intent.SUCCESS : Intent.NONE}
>
Goal
</Button>
<Button
onClick={() => {
if (mode === RESOLUTION_TYPE.qna) {
return
}
setMode(RESOLUTION_TYPE.qna)
}}
intent={mode === RESOLUTION_TYPE.qna ? Intent.SUCCESS : Intent.NONE}
>
Query
</Button>
{mode != null && (
<Button
onClick={() => {
setMode(null)
}}
icon="undo"
>
Undo
const AmendForm = ({
axios,
language,
mode,
setMode,
resolution,
resolutionParams,
onUpdate,
onSave,
onCancel
}: Props) => (
<div className={style.amendForm}>
<h4>
What is this message type?&nbsp;
<ButtonGroup>
<Button
onClick={() => {
if (mode === RESOLUTION_TYPE.intent) {
return
}
setMode(RESOLUTION_TYPE.intent)
}}
intent={mode === RESOLUTION_TYPE.intent ? Intent.SUCCESS : Intent.NONE}
>
Goal
</Button>
<Button
onClick={() => {
if (mode === RESOLUTION_TYPE.qna) {
return
}
setMode(RESOLUTION_TYPE.qna)
}}
intent={mode === RESOLUTION_TYPE.qna ? Intent.SUCCESS : Intent.NONE}
>
Query
</Button>
{mode != null && (
<Button
onClick={() => {
setMode(null)
}}
icon="undo"
>
Undo
</Button>
)}
</ButtonGroup>
</h4>

{mode === RESOLUTION_TYPE.qna && (
<div className={style.amendFormPicker}>
<QnAPicker axios={axios} language={language} selected={resolution} onSelect={(id: string) => {
onUpdate(id)
}} />
</div>
)}
</ButtonGroup>
</div>
)

<ButtonGroup large>
<Button onClick={onSave} icon="tick" intent={Intent.SUCCESS} disabled={!mode || !resolution}>
Save
</Button>
<Button onClick={onCancel} icon="cross" intent={Intent.NONE}>
Cancel
</Button>
</ButtonGroup>
</div>
)

export default AmendForm
64 changes: 40 additions & 24 deletions modules/misunderstood/src/views/full/MainScreen/NewEventView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Button, ButtonGroup, Intent } from '@blueprintjs/core'
import { AxiosStatic } from 'axios'
import pick from 'lodash/pick'
import React from 'react'

import { ApiFlaggedEvent, RESOLUTION_TYPE, ResolutionData } from '../../../types'
Expand All @@ -8,6 +10,8 @@ import AmendForm from './AmendForm'
import ChatPreview from './ChatPreview'

interface Props {
axios: AxiosStatic
language: string
event: ApiFlaggedEvent
totalEventsCount: number
eventIndex: number
Expand All @@ -18,45 +22,55 @@ interface Props {

interface State {
isAmending: boolean
amendMode: RESOLUTION_TYPE | null
resolutionType: RESOLUTION_TYPE | null
resolution: string | null
resolutionParams: string | object | null
}

class NewEventView extends React.Component<Props, State> {
state = {
isAmending: false,
amendMode: null
resolutionType: null,
resolution: null,
resolutionParams: null
}

startAmend = () => {
this.setState({ isAmending: true })
}

finishAmend = () => {
this.setState({ isAmending: false })
cancelAmend = () => {
this.setState({ isAmending: false, resolutionType: null, resolution: null, resolutionParams: null })
}

confirmAmend = () => {
const { amendEvent } = this.props
if (false) {
amendEvent({
resolutionType: RESOLUTION_TYPE.qna,
resolution: 'xxx'
})
amendEvent(pick(this.state, 'resolutionType', 'resolution', 'resolutionParams'))
}
this.finishAmend()
this.setState({ isAmending: false, resolutionType: null, resolution: null, resolutionParams: null })
}

setAmendMode = (amendMode: RESOLUTION_TYPE) => {
this.setState({ amendMode })
setAmendMode = (resolutionType: RESOLUTION_TYPE) => {
this.setState({ resolutionType })
}

updateAmendData = (resolution: string, resolutionParams?: string | object | null) => {
this.setState({
resolution,
resolutionParams: resolutionParams || null
})
}

componentDidMount() {
// TODO: REMOVE THIS!
this.startAmend()
this.setAmendMode(RESOLUTION_TYPE.qna)
}

render() {
const { event, totalEventsCount, eventIndex, skipEvent, deleteEvent } = this.props
const { isAmending, amendMode } = this.state
const { axios, language, event, totalEventsCount, eventIndex, skipEvent, deleteEvent } = this.props
const { isAmending, resolutionType, resolution, resolutionParams } = this.state

return (
<>
Expand All @@ -83,18 +97,20 @@ class NewEventView extends React.Component<Props, State> {
<Button onClick={this.startAmend} icon="confirm" intent={Intent.PRIMARY} disabled={isAmending}>
Amend
</Button>
{isAmending && (
<>
<Button onClick={this.confirmAmend} icon="tick" intent={Intent.SUCCESS}>
Save
</Button>
<Button onClick={this.finishAmend} icon="cross" intent={Intent.NONE}>
Cancel
</Button>
</>
)}
</ButtonGroup>
{isAmending && <AmendForm mode={amendMode} setMode={this.setAmendMode} />}
{isAmending && (
<AmendForm
language={language}
axios={axios}
mode={resolutionType}
setMode={this.setAmendMode}
resolution={resolution}
resolutionParams={resolutionParams}
onUpdate={this.updateAmendData}
onSave={this.confirmAmend}
onCancel={this.cancelAmend}
/>
)}
</>
)
}
Expand Down
68 changes: 68 additions & 0 deletions modules/misunderstood/src/views/full/MainScreen/Pager.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { Button, ButtonGroup, Intent } from "@blueprintjs/core"
import range from "lodash/range"
import uniq from "lodash/uniq"
import React from "react"

const buildPager = ({ pagesCount, currentPage, depth = 5 }) => {
const pageNumbers = uniq(
[
0,
pagesCount - 1,
...range(currentPage - depth, currentPage + depth + 1)
].filter(n => n >= 0 && n < pagesCount)
).sort((a, b) => a - b)

const pager = []

for (let i = 0; i < pageNumbers.length; i++) {
if (i > 0 && pageNumbers[i] !== pageNumbers[i - 1] + 1) {
pager.push({ ellipsis: true })
}
pager.push({
index: pageNumbers[i],
displayIndex: pageNumbers[i] + 1,
isCurrent: pageNumbers[i] === currentPage
})
}

return pager
}

const Pager = ({ pagesCount, currentPage, depth = 5, goTo }) => {
if (pagesCount <= 1) {
return null
}

const pager = buildPager({ pagesCount, currentPage, depth })

return (
<div>
<ButtonGroup>
<Button
disabled={currentPage === 0}
onClick={() => goTo(currentPage - 1)}
>
&lt;
</Button>
{pager.map((el, i) => (
<Button
key={i}
intent={el.isCurrent ? Intent.PRIMARY : Intent.NONE}
onClick={el.isCurrent ? undefined : () => goTo(el.index)}
disabled={el.ellipsis}
>
{el.ellipsis ? <>&hellip;</> : el.displayIndex}
</Button>
))}
<Button
disabled={currentPage === pagesCount - 1}
onClick={() => goTo(currentPage + 1)}
>
&gt;
</Button>
</ButtonGroup>
</div>
)
}

export default Pager
58 changes: 58 additions & 0 deletions modules/misunderstood/src/views/full/MainScreen/QnAApiClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { AxiosRequestConfig, AxiosStatic } from "axios"

const MODULE_URL_PREFIX = "/mod/qna"

class QnAApiClient {
constructor(private axios: AxiosStatic) { }

async get(url: string, config?: AxiosRequestConfig) {
const res = await this.axios.get(MODULE_URL_PREFIX + url, config)
return res.data
}

getQuestion(id) {
return this.get(`/questions/${id}`)
}

async getQuestions({
page,
pageSize,
question,
categories
}: {
page: number;
pageSize: number;
question?: string;
categories?: { label: string; value: string }[];
}) {
const params = {
limit: pageSize,
offset: page * pageSize,
question: question || undefined,
categories:
categories && categories.length
? categories.map(({ value }) => value)
: undefined
}

const data = await this.get("/questions", { params })

return {
...data,
// TODO: this shouldn't be needed but the API is returning more results than requested
items: data.items.slice(0, pageSize)
}
}

async getCategories() {
const {
data: { categories }
} = await this.get("/categories")
return (
categories &&
categories.map(category => ({ label: category, value: category }))
)
}
}

export default QnAApiClient
Loading

0 comments on commit e0ed627

Please sign in to comment.