1
0
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:
Jorge Miguel Lobo Escalona 2024-09-12 18:59:08 +02:00 committed by GitHub
parent 3858747958
commit a00ac1822c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 163 additions and 41 deletions

View File

@ -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

View File

@ -63,12 +63,14 @@ const Actions = () => {
SUBJECT: subject,
BODY: body,
SEVERITY: severity,
ATTACHMENTS: attachments,
} = formData.template
await createTicket({
subject,
body,
version,
severity,
attachments,
})
},
},

View File

@ -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,
{

View File

@ -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

View File

@ -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',

View File

@ -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],
}),

View File

@ -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,

View File

@ -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) {

View File

@ -70,6 +70,9 @@ module.exports = {
severity: {
from: postBody,
},
attachments: {
from: 'files',
},
},
},
[ZENDESK_UPDATE]: {