mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-05 09:17:41 +03:00
F OpenNebula/one#6708: Fixed review of support tab in fireedge (#3227)
This commit is contained in:
parent
3858747958
commit
a00ac1822c
@ -13,9 +13,10 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { string, object, ObjectSchema } from 'yup'
|
||||
import { INPUT_TYPES, SEVERITIES, T } from 'client/constants'
|
||||
import { Field, arrayToOptions, getValidationFromFields } from 'client/utils'
|
||||
import { T, INPUT_TYPES, SEVERITIES } from 'client/constants'
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { ObjectSchema, mixed, object, string } from 'yup'
|
||||
|
||||
/** @type {Field} name field */
|
||||
export const SUBJECT = {
|
||||
@ -51,10 +52,23 @@ export const SEVERITY = {
|
||||
grid: { xs: 12, md: 12 },
|
||||
}
|
||||
|
||||
/** @type {Field} Attachment field */
|
||||
export const ATTACHMENTS = {
|
||||
name: 'ATTACHMENTS',
|
||||
label: T.Upload,
|
||||
type: INPUT_TYPES.FILE,
|
||||
validation: mixed()
|
||||
.notRequired()
|
||||
.test('fileSize', T.FileTooLarge, (value) =>
|
||||
value?.size ? value.size <= 50 * 1024 ** 2 : true
|
||||
),
|
||||
grid: { xs: 12, md: 12 },
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Field[]} Fields
|
||||
*/
|
||||
export const FIELDS = [SUBJECT, BODY, SEVERITY]
|
||||
export const FIELDS = [SUBJECT, BODY, SEVERITY, ATTACHMENTS]
|
||||
|
||||
/**
|
||||
* @param {object} [stepProps] - Step props
|
||||
|
@ -63,12 +63,14 @@ const Actions = () => {
|
||||
SUBJECT: subject,
|
||||
BODY: body,
|
||||
SEVERITY: severity,
|
||||
ATTACHMENTS: attachments,
|
||||
} = formData.template
|
||||
await createTicket({
|
||||
subject,
|
||||
body,
|
||||
version,
|
||||
severity,
|
||||
attachments,
|
||||
})
|
||||
},
|
||||
},
|
||||
|
@ -60,14 +60,14 @@ const CommentBar = ({
|
||||
resolver: yupResolver(FORM.SCHEMA),
|
||||
})
|
||||
|
||||
const onSubmit = (fields) => {
|
||||
const onSubmit = async (fields) => {
|
||||
const commentBody = {
|
||||
id: ticket.id,
|
||||
body: marked.parse(sanitize`${fields.BODY}`),
|
||||
// attachments: fields.ATTACHMENTS,
|
||||
attachments: fields.ATTACHMENTS,
|
||||
}
|
||||
fields.solved && (commentBody.solved = true)
|
||||
update(commentBody)
|
||||
fields.SOLVED && (commentBody.solved = true)
|
||||
await update(commentBody)
|
||||
setComments([
|
||||
...comments,
|
||||
{
|
||||
|
@ -13,9 +13,9 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { boolean, object, string } from 'yup'
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { INPUT_TYPES, T } from 'client/constants'
|
||||
import { boolean, mixed, object, string } from 'yup'
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { Field, ObjectSchema, getValidationFromFields } from 'client/utils'
|
||||
|
||||
/** @type {Field} Body message field */
|
||||
@ -31,16 +31,29 @@ export const BODY = {
|
||||
/** @type {Field} Solved field */
|
||||
export const SOLVED = {
|
||||
name: 'SOLVED',
|
||||
label: `${T.Description} (${T.WeSupportMarkdown})`,
|
||||
label: T.MarkAsclosed,
|
||||
type: INPUT_TYPES.CHECKBOX,
|
||||
validation: boolean().default(() => false),
|
||||
grid: { xs: 12, md: 12 },
|
||||
}
|
||||
|
||||
/** @type {Field} Attachment field */
|
||||
export const ATTACHMENTS = {
|
||||
name: 'ATTACHMENTS',
|
||||
label: T.Upload,
|
||||
type: INPUT_TYPES.FILE,
|
||||
validation: mixed()
|
||||
.notRequired()
|
||||
.test('fileSize', T.FileTooLarge, (value) =>
|
||||
value?.size ? value.size <= 50 * 1024 ** 2 : true
|
||||
),
|
||||
grid: { xs: 12, md: 12 },
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Field[]} Fields
|
||||
*/
|
||||
export const FIELDS = [BODY, SOLVED]
|
||||
export const FIELDS = [BODY, SOLVED, ATTACHMENTS]
|
||||
|
||||
/**
|
||||
* @param {object} [stepProps] - Step props
|
||||
|
@ -516,6 +516,7 @@ module.exports = {
|
||||
ResolutionTicket:
|
||||
'You should just use this. If you want to place the ticket as solved',
|
||||
AddComment: 'Add comment to close the ticket',
|
||||
MarkAsclosed: 'Please consider to this request resolved',
|
||||
|
||||
/* sections - system */
|
||||
User: 'User',
|
||||
@ -655,6 +656,7 @@ module.exports = {
|
||||
Images: 'Images',
|
||||
File: 'File',
|
||||
Files: 'Files',
|
||||
FileTooLarge: 'File too large',
|
||||
Marketplace: 'Marketplace',
|
||||
Marketplaces: 'Marketplaces',
|
||||
App: 'App',
|
||||
|
@ -13,15 +13,15 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { TicketComment } from 'client/constants'
|
||||
import { ONE_RESOURCES_POOL, oneApi } from 'client/features/OneApi'
|
||||
import http from 'client/utils/rest'
|
||||
import {
|
||||
Actions as ActionsSupport,
|
||||
Commands as CommandsSupport,
|
||||
} from 'server/routes/api/support/routes'
|
||||
import { Actions, Commands } from 'server/routes/api/zendesk/routes'
|
||||
|
||||
import { TicketComment } from 'client/constants'
|
||||
import { ONE_RESOURCES_POOL, oneApi } from 'client/features/OneApi'
|
||||
|
||||
const { SUPPORT_POOL } = ONE_RESOURCES_POOL
|
||||
|
||||
const authSupportApi = oneApi.injectEndpoints({
|
||||
@ -162,11 +162,29 @@ const authSupportApi = oneApi.injectEndpoints({
|
||||
* @returns {object} Response data from request
|
||||
* @throws Fails when response isn't code 200
|
||||
*/
|
||||
query: (params) => {
|
||||
const name = Actions.ZENDESK_UPDATE
|
||||
const command = { name, ...Commands[name] }
|
||||
queryFn: async (params) => {
|
||||
const { attachments, id, body, solved } = params
|
||||
try {
|
||||
const data = new FormData()
|
||||
attachments && data.append('attachments', attachments)
|
||||
solved && data.append('solved', solved)
|
||||
data.append('body', body)
|
||||
|
||||
return { params, command }
|
||||
const response = await http.request({
|
||||
url: `/api/zendesk/${id}`,
|
||||
method: 'PUT',
|
||||
data,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
})
|
||||
|
||||
return { data: response.data }
|
||||
} catch (axiosError) {
|
||||
const { response } = axiosError
|
||||
|
||||
return { error: { status: response?.status, data: response?.data } }
|
||||
}
|
||||
},
|
||||
invalidatesTags: (_, __, { id }) => [{ type: SUPPORT_POOL, id }],
|
||||
}),
|
||||
@ -182,11 +200,31 @@ const authSupportApi = oneApi.injectEndpoints({
|
||||
* @returns {object} Response data from request
|
||||
* @throws Fails when response isn't code 200
|
||||
*/
|
||||
query: (params) => {
|
||||
const name = Actions.ZENDESK_CREATE
|
||||
const command = { name, ...Commands[name] }
|
||||
queryFn: async (params) => {
|
||||
const { attachments, subject, body, version, severity } = params
|
||||
try {
|
||||
const data = new FormData()
|
||||
data.append('subject', subject)
|
||||
data.append('body', body)
|
||||
data.append('version', version)
|
||||
data.append('severity', severity)
|
||||
attachments && data.append('attachments', attachments)
|
||||
|
||||
return { params, command }
|
||||
const response = await http.request({
|
||||
url: `/api/zendesk`,
|
||||
method: 'POST',
|
||||
data,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
})
|
||||
|
||||
return { data: response.data }
|
||||
} catch (axiosError) {
|
||||
const { response } = axiosError
|
||||
|
||||
return { error: { status: response?.status, data: response?.data } }
|
||||
}
|
||||
},
|
||||
invalidatesTags: [SUPPORT_POOL],
|
||||
}),
|
||||
|
@ -26,11 +26,13 @@ const {
|
||||
defaultWebpackMode,
|
||||
defaultConfigErrorMessage,
|
||||
defaultTmpPath,
|
||||
from: fromData,
|
||||
} = require('server/utils/constants/defaults')
|
||||
const { writeInLogger } = require('server/utils/logger')
|
||||
const { getSunstoneConfig } = require('server/utils/yml')
|
||||
|
||||
genPathResources()
|
||||
const { postBody } = fromData
|
||||
|
||||
const appConfig = getSunstoneConfig()
|
||||
const optsMulter = { dest: appConfig.tmpdir || defaultTmpPath }
|
||||
@ -121,6 +123,7 @@ routes.forEach((file) => {
|
||||
})
|
||||
}
|
||||
serverDataSource.files = parseFiles(req && req.files)
|
||||
serverDataSource[postBody] = req.body
|
||||
|
||||
return action(
|
||||
res,
|
||||
|
@ -34,6 +34,7 @@ const httpBadRequest = httpResponse(badRequest, '', '')
|
||||
* @param {string} configFormatCreate.body - body
|
||||
* @param {string} configFormatCreate.version - one version
|
||||
* @param {string} configFormatCreate.severity - ticket severity
|
||||
* @param {object} configFormatCreate.attachments - attachment file
|
||||
* @returns {object|undefined} format message create ticket
|
||||
*/
|
||||
const formatCreate = ({
|
||||
@ -41,10 +42,11 @@ const formatCreate = ({
|
||||
body = '',
|
||||
version = '',
|
||||
severity = '',
|
||||
attachments = [],
|
||||
}) => {
|
||||
if (!(subject && body && version && severity)) return
|
||||
|
||||
return {
|
||||
const rtn = {
|
||||
request: {
|
||||
subject,
|
||||
comment: {
|
||||
@ -58,6 +60,11 @@ const formatCreate = ({
|
||||
tags: [severity],
|
||||
},
|
||||
}
|
||||
|
||||
attachments?.length > 0 &&
|
||||
(rtn.request.comment.uploads = attachments.filter((att) => att))
|
||||
|
||||
return rtn
|
||||
}
|
||||
|
||||
/**
|
||||
@ -313,7 +320,7 @@ const create = (
|
||||
params = {},
|
||||
userData = {}
|
||||
) => {
|
||||
const { subject, body, version, severity } = params
|
||||
const { subject, body, version, severity, attachments } = params
|
||||
const { user, password } = userData
|
||||
if (
|
||||
subject &&
|
||||
@ -326,21 +333,61 @@ const create = (
|
||||
) {
|
||||
const session = getSession(user, password)
|
||||
if (session.zendesk && session.zendesk.id) {
|
||||
/** CREATE TICKET ZENDESK */
|
||||
const zendeskClient = zendesk.createClient(session.zendesk)
|
||||
const ticket = formatCreate(params)
|
||||
zendeskClient.requests.create(ticket, (err, req, result) => {
|
||||
let method = ok
|
||||
let data = ''
|
||||
if (err) {
|
||||
method = internalServerError
|
||||
data = parseBufferError(err)
|
||||
} else if (result) {
|
||||
data = result
|
||||
}
|
||||
response.locals.httpCode = httpResponse(method, data)
|
||||
next()
|
||||
})
|
||||
|
||||
const sendRequest = (requestParams = {}) => {
|
||||
/** CREATE TICKET ZENDESK */
|
||||
const ticket = formatCreate(requestParams)
|
||||
zendeskClient.requests.create(ticket, (err, _, result) => {
|
||||
let method = ok
|
||||
let data = ''
|
||||
|
||||
if (err) {
|
||||
method = internalServerError
|
||||
data = parseBufferError(err)
|
||||
} else if (result) {
|
||||
data = result
|
||||
}
|
||||
response.locals.httpCode = httpResponse(method, data)
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
/** UPLOAD FILES */
|
||||
let uploadedAttachments
|
||||
if (
|
||||
attachments &&
|
||||
typeof zendeskClient?.attachments?.upload === 'function'
|
||||
) {
|
||||
attachments.forEach((att = {}) => {
|
||||
if (att && att.originalname && att.path) {
|
||||
zendeskClient.attachments.upload(
|
||||
att.path,
|
||||
{
|
||||
filename: att.originalname,
|
||||
},
|
||||
(err, _, result) => {
|
||||
const token =
|
||||
(result && result.upload && result.upload.token) || ''
|
||||
if (uploadedAttachments) {
|
||||
uploadedAttachments.push(token)
|
||||
} else {
|
||||
uploadedAttachments = [token]
|
||||
}
|
||||
if (
|
||||
!err &&
|
||||
token &&
|
||||
uploadedAttachments.length === attachments.length
|
||||
) {
|
||||
sendRequest({ ...params, attachments: uploadedAttachments })
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
sendRequest({ ...params, attachments })
|
||||
}
|
||||
} else {
|
||||
response.locals.httpCode = httpResponse(unauthorized)
|
||||
next()
|
||||
@ -374,6 +421,7 @@ const update = (
|
||||
) => {
|
||||
const { id, body, attachments } = params
|
||||
const { user, password } = userData
|
||||
|
||||
if (Number.isInteger(parseInt(id, 10)) && body && user && password) {
|
||||
const session = getSession(userData.user, userData.password)
|
||||
if (session.zendesk && session.zendesk.id) {
|
||||
@ -401,8 +449,7 @@ const update = (
|
||||
let uploadedAttachments
|
||||
if (
|
||||
attachments &&
|
||||
zendeskClient.attachments &&
|
||||
typeof zendeskClient.attachments.upload === 'function'
|
||||
typeof zendeskClient?.attachments?.upload === 'function'
|
||||
) {
|
||||
attachments.forEach((att = {}) => {
|
||||
if (att && att.originalname && att.path) {
|
||||
@ -411,7 +458,7 @@ const update = (
|
||||
{
|
||||
filename: att.originalname,
|
||||
},
|
||||
(err, req, result) => {
|
||||
(err, _, result) => {
|
||||
const token =
|
||||
(result && result.upload && result.upload.token) || ''
|
||||
if (uploadedAttachments) {
|
||||
|
@ -70,6 +70,9 @@ module.exports = {
|
||||
severity: {
|
||||
from: postBody,
|
||||
},
|
||||
attachments: {
|
||||
from: 'files',
|
||||
},
|
||||
},
|
||||
},
|
||||
[ZENDESK_UPDATE]: {
|
||||
|
Loading…
Reference in New Issue
Block a user