(v4.2.0) Added 5 new question types

Added support for dropdown, radio select, checkbox select, file upload & text display question types.
This commit is contained in:
DJj123dj
2026-05-23 14:30:56 +02:00
parent 87c034d215
commit 4af9b9e17f
26 changed files with 837 additions and 401 deletions
+2
View File
@@ -50,6 +50,7 @@
{"sectionId":"contributor","name":"Ashish5180","pictureUrl":"https://github.com/Ashish5180.png","profileUrl":"https://github.com/Ashish5180"}, {"sectionId":"contributor","name":"Ashish5180","pictureUrl":"https://github.com/Ashish5180.png","profileUrl":"https://github.com/Ashish5180"},
{"sectionId":"contributor","name":"duboiss","pictureUrl":"https://github.com/duboiss.png","profileUrl":"https://github.com/duboiss"}, {"sectionId":"contributor","name":"duboiss","pictureUrl":"https://github.com/duboiss.png","profileUrl":"https://github.com/duboiss"},
{"sectionId":"contributor","name":"sdehaarte","pictureUrl":"https://github.com/sdehaarte.png","profileUrl":"https://github.com/sdehaarte"}, {"sectionId":"contributor","name":"sdehaarte","pictureUrl":"https://github.com/sdehaarte.png","profileUrl":"https://github.com/sdehaarte"},
{"sectionId":"contributor","name":"MauroDruwel","pictureUrl":"https://github.com/MauroDruwel.png","profileUrl":"https://github.com/MauroDruwel"},
{"sectionId":"support","name":"smetsliam","pictureUrl":"https://github.com/smetsliam.png","profileUrl":"https://github.com/smetsliam"}, {"sectionId":"support","name":"smetsliam","pictureUrl":"https://github.com/smetsliam.png","profileUrl":"https://github.com/smetsliam"},
{"sectionId":"support","name":"Sank34","pictureUrl":"https://github.com/Sank34.png","profileUrl":"https://github.com/Sank34"}, {"sectionId":"support","name":"Sank34","pictureUrl":"https://github.com/Sank34.png","profileUrl":"https://github.com/Sank34"},
{"sectionId":"support","name":"FrankVissers","pictureUrl":"https://github.com/FrankVissers.png","profileUrl":"https://github.com/FrankVissers"}, {"sectionId":"support","name":"FrankVissers","pictureUrl":"https://github.com/FrankVissers.png","profileUrl":"https://github.com/FrankVissers"},
@@ -58,6 +59,7 @@
{"sectionId":"plugin-dev","name":"Imperatorix17","pictureUrl":"https://github.com/imperatorix17.png","profileUrl":"https://github.com/imperatorix17"}, {"sectionId":"plugin-dev","name":"Imperatorix17","pictureUrl":"https://github.com/imperatorix17.png","profileUrl":"https://github.com/imperatorix17"},
{"sectionId":"plugin-dev","name":"DanoGlez","pictureUrl":"https://github.com/DanoGlez.png","profileUrl":"https://github.com/DanoGlez"}, {"sectionId":"plugin-dev","name":"DanoGlez","pictureUrl":"https://github.com/DanoGlez.png","profileUrl":"https://github.com/DanoGlez"},
{"sectionId":"plugin-dev","name":"yowsef","pictureUrl":"https://github.com/Yow-sef.png","profileUrl":"https://github.com/Yow-sef"}, {"sectionId":"plugin-dev","name":"yowsef","pictureUrl":"https://github.com/Yow-sef.png","profileUrl":"https://github.com/Yow-sef"},
{"sectionId":"plugin-dev","name":"MeneerSouf","pictureUrl":"https://github.com/MeneerSouf.png","profileUrl":"https://github.com/MeneerSouf"},
{"sectionId":"plugin-dev","name":"challenger_nova","pictureUrl":"https://apis.dj-dj.be/cdn/openticket/default-avatar.png","profileUrl":""}, {"sectionId":"plugin-dev","name":"challenger_nova","pictureUrl":"https://apis.dj-dj.be/cdn/openticket/default-avatar.png","profileUrl":""},
{"sectionId":"translator","name":"HanumeshGupta","pictureUrl":"https://github.com/HanumeshGupta.png","profileUrl":"https://github.com/HanumeshGupta"}, {"sectionId":"translator","name":"HanumeshGupta","pictureUrl":"https://github.com/HanumeshGupta.png","profileUrl":"https://github.com/HanumeshGupta"},
{"sectionId":"translator","name":"benzorich","pictureUrl":"https://github.com/benzorich.png","profileUrl":"https://github.com/benzorich"}, {"sectionId":"translator","name":"benzorich","pictureUrl":"https://github.com/benzorich.png","profileUrl":"https://github.com/benzorich"},
+100 -88
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 2.1 MiB

After

Width:  |  Height:  |  Size: 2.4 MiB

+1 -1
View File
@@ -27,7 +27,7 @@
"license": "GPL-3.0-only", "license": "GPL-3.0-only",
"dependencies": { "dependencies": {
"@discordjs/rest": "^2.6.1", "@discordjs/rest": "^2.6.1",
"@open-discord-bots/framework": "^0.4.4", "@open-discord-bots/framework": "^0.5.2",
"@types/node": "^22.5.0", "@types/node": "^22.5.0",
"@types/terminal-kit": "^2.5.7", "@types/terminal-kit": "^2.5.7",
"ansis": "^4.2.0", "ansis": "^4.2.0",
+11 -3
View File
@@ -626,11 +626,19 @@ const ticketEmbeds = () => {
if (generalConfig.data.ticketSystem.displayFieldsWithQuestions) instance.addFields(...embedOptions.fields) if (generalConfig.data.ticketSystem.displayFieldsWithQuestions) instance.addFields(...embedOptions.fields)
const answers = ticket.get("opendiscord:answers").value const answers = ticket.get("opendiscord:answers").value
answers.forEach((answer) => { for (const answer of answers){
if (!answer.value || answer.value.length == 0) return if (answer.type == "file-upload"){
//render file upload fields
if (!answer.files) continue
const renderedFiles = answer.files.map((file) => `- [${file.name}](${file.url})`).join("\n")
instance.addFields({name:answer.name,value:renderedFiles,inline:false})
}else if (typeof answer.value == "string" && answer.value.length > 0){
//render other fields
if (generalConfig.data.ticketSystem.questionFieldsInCodeBlock) instance.addFields({name:answer.name,value:"```"+answer.value.slice(0,1024-6)+"```",inline:false}) if (generalConfig.data.ticketSystem.questionFieldsInCodeBlock) instance.addFields({name:answer.name,value:"```"+answer.value.slice(0,1024-6)+"```",inline:false})
else instance.addFields({name:answer.name,value:answer.value,inline:false}) else instance.addFields({name:answer.name,value:answer.value,inline:false})
}) }
}
}else if (embedOptions.fields){ }else if (embedOptions.fields){
instance.setFields(embedOptions.fields) instance.setFields(embedOptions.fields)
} }
-173
View File
@@ -1,173 +0,0 @@
///////////////////////////////////////
//MODAL BUILDERS
///////////////////////////////////////
import {opendiscord, api, utilities} from "../index.js"
import * as discord from "discord.js"
const modals = opendiscord.builders.modals
const lang = opendiscord.languages
export async function registerAllModals(){
ticketModals()
}
const ticketModals = () => {
//TICKET QUESTIONS
modals.add(new api.ODModal("opendiscord:ticket-questions"))
modals.get("opendiscord:ticket-questions").workers.add(
new api.ODWorker("opendiscord:ticket-questions",0,async (instance,params,origin) => {
const {option} = params
instance.setCustomId("od:ticket-questions_"+option.id.value+"_"+origin)
instance.setTitle(option.exists("opendiscord:name") ? option.get("opendiscord:name").value : option.id.value)
const questionIds = option.get("opendiscord:questions").value
questionIds.forEach((id) => {
const question = opendiscord.questions.get(id)
if (!question) return
if (question instanceof api.ODShortQuestion) instance.addQuestion({
customId:question.id.value,
label:question.get("opendiscord:name").value,
style:"short",
required:question.get("opendiscord:required").value,
placeholder:(question.get("opendiscord:placeholder").value) ? question.get("opendiscord:placeholder").value : undefined,
minLength:(question.get("opendiscord:length-enabled").value) ? question.get("opendiscord:length-min").value : undefined,
maxLength:Math.min(1024-6,(question.get("opendiscord:length-enabled").value) ? question.get("opendiscord:length-max").value : (1024-6)) //embed field limit - 6x` characters
})
else if (question instanceof api.ODParagraphQuestion) instance.addQuestion({
customId:question.id.value,
label:question.get("opendiscord:name").value,
style:"paragraph",
required:question.get("opendiscord:required").value,
placeholder:(question.get("opendiscord:placeholder").value) ? question.get("opendiscord:placeholder").value : undefined,
minLength:(question.get("opendiscord:length-enabled").value) ? question.get("opendiscord:length-min").value : undefined,
maxLength:Math.min(1024-6,(question.get("opendiscord:length-enabled").value) ? question.get("opendiscord:length-max").value : (1024-6)) //embed field limit - 6x` characters
})
})
})
)
//CLOSE TICKET REASON
modals.add(new api.ODModal("opendiscord:close-ticket-reason"))
modals.get("opendiscord:close-ticket-reason").workers.add(
new api.ODWorker("opendiscord:close-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
instance.setCustomId("od:close-ticket-reason|"+channel.id+"|"+message.id)
instance.setTitle(lang.getTranslation("actions.buttons.close"))
instance.addQuestion({
customId:"reason",
label:lang.getTranslation("params.uppercase.reason"),
style:"paragraph",
required:true,
placeholder:lang.getTranslation("actions.modal.closePlaceholder")
})
})
)
//REOPEN TICKET REASON
modals.add(new api.ODModal("opendiscord:reopen-ticket-reason"))
modals.get("opendiscord:reopen-ticket-reason").workers.add(
new api.ODWorker("opendiscord:reopen-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
instance.setCustomId("od:reopen-ticket-reason|"+channel.id+"|"+message.id)
instance.setTitle(lang.getTranslation("actions.buttons.reopen"))
instance.addQuestion({
customId:"reason",
label:lang.getTranslation("params.uppercase.reason"),
style:"paragraph",
required:true,
placeholder:lang.getTranslation("actions.modal.reopenPlaceholder")
})
})
)
//DELETE TICKET REASON
modals.add(new api.ODModal("opendiscord:delete-ticket-reason"))
modals.get("opendiscord:delete-ticket-reason").workers.add(
new api.ODWorker("opendiscord:delete-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
instance.setCustomId("od:delete-ticket-reason|"+channel.id+"|"+message.id)
instance.setTitle(lang.getTranslation("actions.buttons.delete"))
instance.addQuestion({
customId:"reason",
label:lang.getTranslation("params.uppercase.reason"),
style:"paragraph",
required:true,
placeholder:lang.getTranslation("actions.modal.deletePlaceholder")
})
})
)
//CLAIM TICKET REASON
modals.add(new api.ODModal("opendiscord:claim-ticket-reason"))
modals.get("opendiscord:claim-ticket-reason").workers.add(
new api.ODWorker("opendiscord:claim-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
instance.setCustomId("od:claim-ticket-reason|"+channel.id+"|"+message.id)
instance.setTitle(lang.getTranslation("actions.buttons.claim"))
instance.addQuestion({
customId:"reason",
label:lang.getTranslation("params.uppercase.reason"),
style:"paragraph",
required:true,
placeholder:lang.getTranslation("actions.modal.claimPlaceholder")
})
})
)
//UNCLAIM TICKET REASON
modals.add(new api.ODModal("opendiscord:unclaim-ticket-reason"))
modals.get("opendiscord:unclaim-ticket-reason").workers.add(
new api.ODWorker("opendiscord:unclaim-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
instance.setCustomId("od:unclaim-ticket-reason|"+channel.id+"|"+message.id)
instance.setTitle(lang.getTranslation("actions.buttons.unclaim"))
instance.addQuestion({
customId:"reason",
label:lang.getTranslation("params.uppercase.reason"),
style:"paragraph",
required:true,
placeholder:lang.getTranslation("actions.modal.unclaimPlaceholder")
})
})
)
//PIN TICKET REASON
modals.add(new api.ODModal("opendiscord:pin-ticket-reason"))
modals.get("opendiscord:pin-ticket-reason").workers.add(
new api.ODWorker("opendiscord:pin-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
instance.setCustomId("od:pin-ticket-reason|"+channel.id+"|"+message.id)
instance.setTitle(lang.getTranslation("actions.buttons.pin"))
instance.addQuestion({
customId:"reason",
label:lang.getTranslation("params.uppercase.reason"),
style:"paragraph",
required:true,
placeholder:lang.getTranslation("actions.modal.pinPlaceholder")
})
})
)
//UNPIN TICKET REASON
modals.add(new api.ODModal("opendiscord:unpin-ticket-reason"))
modals.get("opendiscord:unpin-ticket-reason").workers.add(
new api.ODWorker("opendiscord:unpin-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
instance.setCustomId("od:unpin-ticket-reason|"+channel.id+"|"+message.id)
instance.setTitle(lang.getTranslation("actions.buttons.unpin"))
instance.addQuestion({
customId:"reason",
label:lang.getTranslation("params.uppercase.reason"),
style:"paragraph",
required:true,
placeholder:lang.getTranslation("actions.modal.unpinPlaceholder")
})
})
)
}
+1 -1
View File
@@ -169,7 +169,7 @@ export async function registerVerifyBars(){
} }
}else if (params.selectedButtonId == "accept-with-reason"){ }else if (params.selectedButtonId == "accept-with-reason"){
//CLAIM WITH REASON (MODAL) //CLAIM WITH REASON (MODAL)
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:claim-ticket-reason").build("other",{guild,channel,user,ticket,message})) instance.modal(await opendiscord.components.modals.get("opendiscord:claim-ticket-reason").build("other",{guild,channel,user,ticket,message}))
} }
}) })
]) ])
+1 -1
View File
@@ -177,7 +177,7 @@ export async function registerVerifyBars(){
} }
}else if (params.selectedButtonId == "accept-with-reason"){ }else if (params.selectedButtonId == "accept-with-reason"){
//CLOSE WITH REASON (MODAL) //CLOSE WITH REASON (MODAL)
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:close-ticket-reason").build("other",{guild,channel,user,ticket,message})) instance.modal(await opendiscord.components.modals.get("opendiscord:close-ticket-reason").build("other",{guild,channel,user,ticket,message}))
} }
}) })
]) ])
+1 -1
View File
@@ -202,7 +202,7 @@ export async function registerVerifyBars(){
} }
}else if (params.selectedButtonId == "accept-with-reason"){ }else if (params.selectedButtonId == "accept-with-reason"){
//DELETE WITH REASON (MODAL) //DELETE WITH REASON (MODAL)
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:delete-ticket-reason").build("other",{guild,channel,user,ticket,message})) instance.modal(await opendiscord.components.modals.get("opendiscord:delete-ticket-reason").build("other",{guild,channel,user,ticket,message}))
} }
}) })
]) ])
+1 -1
View File
@@ -169,7 +169,7 @@ export async function registerVerifyBars(){
} }
}else if (params.selectedButtonId == "accept-with-reason"){ }else if (params.selectedButtonId == "accept-with-reason"){
//PIN WITH REASON (MODAL) //PIN WITH REASON (MODAL)
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:pin-ticket-reason").build("other",{guild,channel,user,ticket,message})) instance.modal(await opendiscord.components.modals.get("opendiscord:pin-ticket-reason").build("other",{guild,channel,user,ticket,message}))
} }
}) })
]) ])
+1 -1
View File
@@ -185,7 +185,7 @@ export async function registerVerifyBars(){
} }
}else if (params.selectedButtonId == "accept-with-reason"){ }else if (params.selectedButtonId == "accept-with-reason"){
//REOPEN WITH REASON (MODAL) //REOPEN WITH REASON (MODAL)
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:reopen-ticket-reason").build("other",{guild,channel,user,ticket,message})) instance.modal(await opendiscord.components.modals.get("opendiscord:reopen-ticket-reason").build("other",{guild,channel,user,ticket,message}))
} }
}) })
]) ])
+39 -18
View File
@@ -50,7 +50,7 @@ export async function registerCommandResponders(){
//start ticket creation //start ticket creation
if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){ if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){
//SEND MODAL //SEND MODAL
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build(origin,{guild,channel,user,option})) instance.modal(await opendiscord.components.modals.get("opendiscord:ticket-questions").build(origin,{guild,channel,user,option}))
}else{ }else{
//check ticket permissions (modals need check after submit) //check ticket permissions (modals need check after submit)
if (!(await checkTicketCreationPerms(instance,origin,guild,user,option))) return cancel() if (!(await checkTicketCreationPerms(instance,origin,guild,user,option))) return cancel()
@@ -99,7 +99,7 @@ export async function registerButtonResponders(){
//start ticket creation //start ticket creation
if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){ if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){
//SEND MODAL //SEND MODAL
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build("panel-button",{guild,channel,user,option})) instance.modal(await opendiscord.components.modals.get("opendiscord:ticket-questions").build("panel-button",{guild,channel,user,option}))
}else{ }else{
//check ticket permissions (modals need check after submit) //check ticket permissions (modals need check after submit)
if (!(await checkTicketCreationPerms(instance,"panel-button",guild,user,option))) return cancel() if (!(await checkTicketCreationPerms(instance,"panel-button",guild,user,option))) return cancel()
@@ -141,7 +141,7 @@ export async function registerDropdownResponders(){
//start ticket creation //start ticket creation
if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){ if (option.exists("opendiscord:questions") && option.get("opendiscord:questions").value.length > 0){
//SEND MODAL //SEND MODAL
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:ticket-questions").build("panel-dropdown",{guild,channel,user,option})) instance.modal(await opendiscord.components.modals.get("opendiscord:ticket-questions").build("panel-dropdown",{guild,channel,user,option}))
}else{ }else{
//check ticket permissions (modals need check after submit) //check ticket permissions (modals need check after submit)
if (!(await checkTicketCreationPerms(instance,"panel-dropdown",guild,user,option))) return cancel() if (!(await checkTicketCreationPerms(instance,"panel-dropdown",guild,user,option))) return cancel()
@@ -193,26 +193,47 @@ export async function registerModalResponders(){
if (!(await checkTicketCreationPerms(instance,originalOrigin,guild,user,option))) return cancel() if (!(await checkTicketCreationPerms(instance,originalOrigin,guild,user,option))) return cancel()
//get answers //get answers
const answers: {id:string,name:string,type:"short"|"paragraph",value:string|null}[] = [] const answers: api.ODQuestionAnswer[] = []
option.get("opendiscord:questions").value.forEach((id) => { for (const questionId of option.get("opendiscord:questions").value){
const question = opendiscord.questions.get(id) const question = opendiscord.questions.get(questionId)
if (!question) return if (!question) continue
if (question instanceof api.ODShortQuestion){ if (question instanceof api.ODShortQuestion) answers.push({
answers.push({ id:questionId,
id, name:question.exists("opendiscord:name") ? question.get("opendiscord:name")?.value : questionId,
name:question.exists("opendiscord:name") ? question.get("opendiscord:name")?.value : id,
type:"short", type:"short",
value:instance.values.getTextField(id,false) value:instance.values.getTextField(questionId,false)
}) })
}else if (question instanceof api.ODParagraphQuestion){ else if (question instanceof api.ODParagraphQuestion) answers.push({
answers.push({ id:questionId,
id, name:question.exists("opendiscord:name") ? question.get("opendiscord:name")?.value : questionId,
name:question.exists("opendiscord:name") ? question.get("opendiscord:name")?.value : id,
type:"paragraph", type:"paragraph",
value:instance.values.getTextField(id,false) value:instance.values.getTextField(questionId,false)
})
else if (question instanceof api.ODDropdownQuestion) answers.push({
id:questionId,
name:question.exists("opendiscord:name") ? question.get("opendiscord:name")?.value : questionId,
type:"dropdown",
value:instance.values.getStringDropdownValues(questionId)[0] ?? null
})
else if (question instanceof api.ODRadioSelectQuestion) answers.push({
id:questionId,
name:question.exists("opendiscord:name") ? question.get("opendiscord:name")?.value : questionId,
type:"radio-select",
value:instance.values.getRadioGroup(questionId,false)
})
else if (question instanceof api.ODCheckboxSelectQuestion) answers.push({
id:questionId,
name:question.exists("opendiscord:name") ? question.get("opendiscord:name")?.value : questionId,
type:"checkbox-select",
value:(instance.values.getCheckboxGroup(questionId).length > 0) ? instance.values.getCheckboxGroup(questionId).map((opt) => "> "+opt).join("\n") : null
})
else if (question instanceof api.ODFileUploadQuestion) answers.push({
id:questionId,
name:question.exists("opendiscord:name") ? question.get("opendiscord:name")?.value : questionId,
type:"file-upload",
files:(instance.values.getUploadedFiles(questionId).length > 0) ? instance.values.getUploadedFiles(questionId).map(({id,url,name,title,description,contentType}) => ({id,url,name,title,description,contentType})) : []
}) })
} }
})
await instance.defer((generalConfig.data.ticketSystem.replyOnTicketCreation) ? "reply" : "update",true) await instance.defer((generalConfig.data.ticketSystem.replyOnTicketCreation) ? "reply" : "update",true)
+1 -1
View File
@@ -168,7 +168,7 @@ export async function registerVerifyBars(){
} }
}else if (params.selectedButtonId == "accept-with-reason"){ }else if (params.selectedButtonId == "accept-with-reason"){
//UNCLAIM WITH REASON (MODAL) //UNCLAIM WITH REASON (MODAL)
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:unclaim-ticket-reason").build("other",{guild,channel,user,ticket,message})) instance.modal(await opendiscord.components.modals.get("opendiscord:unclaim-ticket-reason").build("other",{guild,channel,user,ticket,message}))
} }
}) })
]) ])
+1 -1
View File
@@ -168,7 +168,7 @@ export async function registerVerifyBars(){
} }
}else if (params.selectedButtonId == "accept-with-reason"){ }else if (params.selectedButtonId == "accept-with-reason"){
//UNPIN WITH REASON (MODAL) //UNPIN WITH REASON (MODAL)
instance.modal(await opendiscord.builders.modals.getSafe("opendiscord:unpin-ticket-reason").build("other",{guild,channel,user,ticket,message})) instance.modal(await opendiscord.components.modals.get("opendiscord:unpin-ticket-reason").build("other",{guild,channel,user,ticket,message}))
} }
}) })
]) ])
+302
View File
@@ -0,0 +1,302 @@
///////////////////////////////////////
//REGISTER MODAL COMPONENTS
///////////////////////////////////////
import {opendiscord, api, utilities} from "../index.js"
import * as discord from "discord.js"
const modals = opendiscord.components.modals
const lang = opendiscord.languages
const generalConfig = opendiscord.configs.get("opendiscord:general")
export async function registerModalComponents(){
//TICKET QUESTIONS
modals.add(new api.ODComponentFactory("opendiscord:ticket-questions"))
modals.get("opendiscord:ticket-questions").workers.add(
new api.ODWorker("opendiscord:ticket-questions",0,(instance,params,origin) => {
const {option} = params
const modal = instance.setComponent(new api.ODModalComponent("opendiscord:questions-modal",{
customId:"od:ticket-questions|"+option.id.value+"|"+origin,
title:lang.getTranslation("params.uppercase.ticket")+": "+(option.exists("opendiscord:name")) ? option.get("opendiscord:name").value : option.id.value
}))
for (const questionId of option.get("opendiscord:questions").value){
const question = opendiscord.questions.get(questionId)
if (!question) continue
if (question instanceof api.ODShortQuestion){
//SHORT QUESTION
const component = new api.ODLabelComponent(question.id.value,{
title:question.get("opendiscord:name").value,
description:(question.get("opendiscord:description").value) ? question.get("opendiscord:description").value : undefined,
})
component.setComponent(new api.ODShortInputComponent(question.id.value,{
customId:question.id.value,
required:question.get("opendiscord:required").value,
placeholder:(question.get("opendiscord:placeholder").value) ? question.get("opendiscord:placeholder").value : undefined,
minLength:(question.get("opendiscord:length-enabled").value) ? question.get("opendiscord:length-min").value : undefined,
maxLength:Math.min(1024-6,(question.get("opendiscord:length-enabled").value) ? question.get("opendiscord:length-max").value : (1024-6)) //embed field limit - 6x` characters
}))
modal.addComponent(component,"end")
}else if (question instanceof api.ODParagraphQuestion){
//PARAGRAPH QUESTION
const component = new api.ODLabelComponent(question.id.value,{
title:question.get("opendiscord:name").value,
description:(question.get("opendiscord:description").value) ? question.get("opendiscord:description").value : undefined,
})
component.setComponent(new api.ODParagraphInputComponent(question.id.value,{
customId:question.id.value,
required:question.get("opendiscord:required").value,
placeholder:(question.get("opendiscord:placeholder").value) ? question.get("opendiscord:placeholder").value : undefined,
minLength:(question.get("opendiscord:length-enabled").value) ? question.get("opendiscord:length-min").value : undefined,
maxLength:Math.min(1024-6,(question.get("opendiscord:length-enabled").value) ? question.get("opendiscord:length-max").value : (1024-6)) //embed field limit - 6x` characters
}))
modal.addComponent(component,"end")
}else if (question instanceof api.ODDropdownQuestion){
//DROPDOWN QUESTION
const component = new api.ODLabelComponent(question.id.value,{
title:question.get("opendiscord:name").value,
description:(question.get("opendiscord:description").value) ? question.get("opendiscord:description").value : undefined,
})
component.setComponent(new api.ODDropdownComponent(question.id.value,{
type:"string",
customId:question.id.value,
required:question.get("opendiscord:required").value,
placeholder:(question.get("opendiscord:placeholder").value) ? question.get("opendiscord:placeholder").value : undefined,
maxValues:1,
options:question.get("opendiscord:choices").value.map((choice) => ({
label:choice.title,
emoji:choice.emoji,
description:choice.description,
value:choice.title
}))
}))
modal.addComponent(component,"end")
}else if (question instanceof api.ODRadioSelectQuestion){
//RADIO SELECT QUESTION
const component = new api.ODLabelComponent(question.id.value,{
title:question.get("opendiscord:name").value,
description:(question.get("opendiscord:description").value) ? question.get("opendiscord:description").value : undefined,
})
component.setComponent(new api.ODRadioGroupComponent(question.id.value,{
customId:question.id.value,
required:question.get("opendiscord:required").value,
options:question.get("opendiscord:choices").value.map((choice) => ({
label:choice.title,
default:choice.selectedByDefault,
description:choice.description,
value:choice.title
}))
}))
modal.addComponent(component,"end")
}else if (question instanceof api.ODCheckboxSelectQuestion){
//CHECKBOX SELECT QUESTION
const component = new api.ODLabelComponent(question.id.value,{
title:question.get("opendiscord:name").value,
description:(question.get("opendiscord:description").value) ? question.get("opendiscord:description").value : undefined,
})
component.setComponent(new api.ODCheckboxGroupComponent(question.id.value,{
customId:question.id.value,
required:question.get("opendiscord:required").value,
minValues:(question.get("opendiscord:limits-enabled").value) ? question.get("opendiscord:limits-min").value : undefined,
maxValues:(question.get("opendiscord:limits-enabled").value) ? question.get("opendiscord:limits-max").value : undefined,
options:question.get("opendiscord:choices").value.map((choice) => ({
label:choice.title,
default:choice.selectedByDefault,
description:choice.description,
value:choice.title
}))
}))
modal.addComponent(component,"end")
}else if (question instanceof api.ODFileUploadQuestion){
//FILE UPLOAD QUESTION
const component = new api.ODLabelComponent(question.id.value,{
title:question.get("opendiscord:name").value,
description:(question.get("opendiscord:description").value) ? question.get("opendiscord:description").value : undefined,
})
component.setComponent(new api.ODFileUploadComponent(question.id.value,{
customId:question.id.value,
required:question.get("opendiscord:required").value,
minAmount:(question.get("opendiscord:limits-enabled").value) ? question.get("opendiscord:limits-min").value : undefined,
maxAmount:(question.get("opendiscord:limits-enabled").value) ? question.get("opendiscord:limits-max").value : undefined,
}))
modal.addComponent(component,"end")
}else if (question instanceof api.ODTextDisplayQuestion){
//TEXT DISPLAY QUESTION
const component = new api.ODTextComponent(question.id.value,{
content:question.get("opendiscord:text-contents").value
})
modal.addComponent(component,"end")
}
}
})
)
//CLOSE TICKET REASON
modals.add(new api.ODComponentFactory("opendiscord:close-ticket-reason"))
modals.get("opendiscord:close-ticket-reason").workers.add(
new api.ODWorker("opendiscord:close-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
const modal = instance.setComponent(new api.ODModalComponent("opendiscord:close-ticket-reason",{
customId:"od:close-ticket-reason|"+channel.id+"|"+message.id,
title:lang.getTranslation("actions.buttons.close")
}))
const reasonComponent = new api.ODLabelComponent("reason",{
title:lang.getTranslation("params.uppercase.reason"),
description:lang.getTranslation("actions.modal.closePlaceholder")
})
reasonComponent.setComponent(new api.ODParagraphInputComponent("reason",{
customId:"reason",
required:true,
placeholder:lang.getTranslation("params.uppercase.reason")
}))
modal.addComponent(reasonComponent,"end")
})
)
//REOPEN TICKET REASON
modals.add(new api.ODComponentFactory("opendiscord:reopen-ticket-reason"))
modals.get("opendiscord:reopen-ticket-reason").workers.add(
new api.ODWorker("opendiscord:reopen-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
const modal = instance.setComponent(new api.ODModalComponent("opendiscord:reopen-ticket-reason",{
customId:"od:reopen-ticket-reason|"+channel.id+"|"+message.id,
title:lang.getTranslation("actions.buttons.reopen")
}))
const reasonComponent = new api.ODLabelComponent("reason",{
title:lang.getTranslation("params.uppercase.reason"),
description:lang.getTranslation("actions.modal.reopenPlaceholder")
})
reasonComponent.setComponent(new api.ODParagraphInputComponent("reason",{
customId:"reason",
required:true,
placeholder:lang.getTranslation("params.uppercase.reason")
}))
modal.addComponent(reasonComponent,"end")
})
)
//DELETE TICKET REASON
modals.add(new api.ODComponentFactory("opendiscord:delete-ticket-reason"))
modals.get("opendiscord:delete-ticket-reason").workers.add(
new api.ODWorker("opendiscord:delete-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
const modal = instance.setComponent(new api.ODModalComponent("opendiscord:delete-ticket-reason",{
customId:"od:delete-ticket-reason|"+channel.id+"|"+message.id,
title:lang.getTranslation("actions.buttons.delete")
}))
const reasonComponent = new api.ODLabelComponent("reason",{
title:lang.getTranslation("params.uppercase.reason"),
description:lang.getTranslation("actions.modal.deletePlaceholder")
})
reasonComponent.setComponent(new api.ODParagraphInputComponent("reason",{
customId:"reason",
required:true,
placeholder:lang.getTranslation("params.uppercase.reason")
}))
modal.addComponent(reasonComponent,"end")
})
)
//CLAIM TICKET REASON
modals.add(new api.ODComponentFactory("opendiscord:claim-ticket-reason"))
modals.get("opendiscord:claim-ticket-reason").workers.add(
new api.ODWorker("opendiscord:claim-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
const modal = instance.setComponent(new api.ODModalComponent("opendiscord:claim-ticket-reason",{
customId:"od:claim-ticket-reason|"+channel.id+"|"+message.id,
title:lang.getTranslation("actions.buttons.claim")
}))
const reasonComponent = new api.ODLabelComponent("reason",{
title:lang.getTranslation("params.uppercase.reason"),
description:lang.getTranslation("actions.modal.claimPlaceholder")
})
reasonComponent.setComponent(new api.ODParagraphInputComponent("reason",{
customId:"reason",
required:true,
placeholder:lang.getTranslation("params.uppercase.reason")
}))
modal.addComponent(reasonComponent,"end")
})
)
//UNCLAIM TICKET REASON
modals.add(new api.ODComponentFactory("opendiscord:unclaim-ticket-reason"))
modals.get("opendiscord:unclaim-ticket-reason").workers.add(
new api.ODWorker("opendiscord:unclaim-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
const modal = instance.setComponent(new api.ODModalComponent("opendiscord:unclaim-ticket-reason",{
customId:"od:unclaim-ticket-reason|"+channel.id+"|"+message.id,
title:lang.getTranslation("actions.buttons.unclaim")
}))
const reasonComponent = new api.ODLabelComponent("reason",{
title:lang.getTranslation("params.uppercase.reason"),
description:lang.getTranslation("actions.modal.unclaimPlaceholder")
})
reasonComponent.setComponent(new api.ODParagraphInputComponent("reason",{
customId:"reason",
required:true,
placeholder:lang.getTranslation("params.uppercase.reason")
}))
modal.addComponent(reasonComponent,"end")
})
)
//PIN TICKET REASON
modals.add(new api.ODComponentFactory("opendiscord:pin-ticket-reason"))
modals.get("opendiscord:pin-ticket-reason").workers.add(
new api.ODWorker("opendiscord:pin-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
const modal = instance.setComponent(new api.ODModalComponent("opendiscord:pin-ticket-reason",{
customId:"od:pin-ticket-reason|"+channel.id+"|"+message.id,
title:lang.getTranslation("actions.buttons.pin")
}))
const reasonComponent = new api.ODLabelComponent("reason",{
title:lang.getTranslation("params.uppercase.reason"),
description:lang.getTranslation("actions.modal.pinPlaceholder")
})
reasonComponent.setComponent(new api.ODParagraphInputComponent("reason",{
customId:"reason",
required:true,
placeholder:lang.getTranslation("params.uppercase.reason")
}))
modal.addComponent(reasonComponent,"end")
})
)
//UNPIN TICKET REASON
modals.add(new api.ODComponentFactory("opendiscord:unpin-ticket-reason"))
modals.get("opendiscord:unpin-ticket-reason").workers.add(
new api.ODWorker("opendiscord:unpin-ticket-reason",0,async (instance,params,origin) => {
const {channel,message} = params
const modal = instance.setComponent(new api.ODModalComponent("opendiscord:unpin-ticket-reason",{
customId:"od:unpin-ticket-reason|"+channel.id+"|"+message.id,
title:lang.getTranslation("actions.buttons.unpin")
}))
const reasonComponent = new api.ODLabelComponent("reason",{
title:lang.getTranslation("params.uppercase.reason"),
description:lang.getTranslation("actions.modal.unpinPlaceholder")
})
reasonComponent.setComponent(new api.ODParagraphInputComponent("reason",{
customId:"reason",
required:true,
placeholder:lang.getTranslation("params.uppercase.reason")
}))
modal.addComponent(reasonComponent,"end")
})
)
}
+196 -69
View File
@@ -2,6 +2,8 @@
//OPENTICKET OPTION MODULE //OPENTICKET OPTION MODULE
/////////////////////////////////////// ///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api" import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js"
import { ODQuestionsJsonConfig_BaseQuestion, ODQuestionsJsonConfig_DropdownChoice, ODQuestionsJsonConfig_RadioCheckboxChoice } from "../mappings/config.js"
/**## ODQuestionIdConstraint `type` /**## ODQuestionIdConstraint `type`
* The constraint/layout for id mappings/interfaces of the `ODQuestion` class. * The constraint/layout for id mappings/interfaces of the `ODQuestion` class.
@@ -14,9 +16,10 @@ export type ODQuestionIdConstraint = Record<string,ODQuestionData<api.ODValidJso
*/ */
export interface ODShortQuestionIdMappings extends ODQuestionIdConstraint { export interface ODShortQuestionIdMappings extends ODQuestionIdConstraint {
"opendiscord:name":ODQuestionData<string>, "opendiscord:name":ODQuestionData<string>,
"opendiscord:description":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>, "opendiscord:required":ODQuestionData<boolean>,
"opendiscord:placeholder":ODQuestionData<string>,
"opendiscord:placeholder":ODQuestionData<string>,
"opendiscord:length-enabled":ODQuestionData<boolean>, "opendiscord:length-enabled":ODQuestionData<boolean>,
"opendiscord:length-min":ODQuestionData<number>, "opendiscord:length-min":ODQuestionData<number>,
"opendiscord:length-max":ODQuestionData<number> "opendiscord:length-max":ODQuestionData<number>
@@ -28,14 +31,77 @@ export interface ODShortQuestionIdMappings extends ODQuestionIdConstraint {
*/ */
export interface ODParagraphQuestionIdMappings extends ODQuestionIdConstraint { export interface ODParagraphQuestionIdMappings extends ODQuestionIdConstraint {
"opendiscord:name":ODQuestionData<string>, "opendiscord:name":ODQuestionData<string>,
"opendiscord:description":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>, "opendiscord:required":ODQuestionData<boolean>,
"opendiscord:placeholder":ODQuestionData<string>,
"opendiscord:placeholder":ODQuestionData<string>,
"opendiscord:length-enabled":ODQuestionData<boolean>, "opendiscord:length-enabled":ODQuestionData<boolean>,
"opendiscord:length-min":ODQuestionData<number>, "opendiscord:length-min":ODQuestionData<number>,
"opendiscord:length-max":ODQuestionData<number> "opendiscord:length-max":ODQuestionData<number>
} }
/**## ODDropdownQuestionIdMappings `interface`
* A list of all available IDs in the default `ODDropdownQuestion` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODDropdownQuestionIdMappings extends ODQuestionIdConstraint {
"opendiscord:name":ODQuestionData<string>,
"opendiscord:description":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>,
"opendiscord:placeholder":ODQuestionData<string>,
"opendiscord:choices":ODQuestionData<ODQuestionsJsonConfig_DropdownChoice[]>
}
/**## ODRadioSelectQuestionIdMappings `interface`
* A list of all available IDs in the default `ODRadioSelectQuestion` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODRadioSelectQuestionIdMappings extends ODQuestionIdConstraint {
"opendiscord:name":ODQuestionData<string>,
"opendiscord:description":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>,
"opendiscord:choices":ODQuestionData<ODQuestionsJsonConfig_RadioCheckboxChoice[]>
}
/**## ODCheckboxSelectQuestionIdMappings `interface`
* A list of all available IDs in the default `ODCheckboxSelectQuestion` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODCheckboxSelectQuestionIdMappings extends ODQuestionIdConstraint {
"opendiscord:name":ODQuestionData<string>,
"opendiscord:description":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>,
"opendiscord:limits-enabled":ODQuestionData<boolean>,
"opendiscord:limits-min":ODQuestionData<number>,
"opendiscord:limits-max":ODQuestionData<number>
"opendiscord:choices":ODQuestionData<ODQuestionsJsonConfig_RadioCheckboxChoice[]>
}
/**## ODFileUploadQuestionIdMappings `interface`
* A list of all available IDs in the default `ODFileUploadQuestion` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODFileUploadQuestionIdMappings extends ODQuestionIdConstraint {
"opendiscord:name":ODQuestionData<string>,
"opendiscord:description":ODQuestionData<string>,
"opendiscord:required":ODQuestionData<boolean>,
"opendiscord:limits-enabled":ODQuestionData<boolean>,
"opendiscord:limits-min":ODQuestionData<number>,
"opendiscord:limits-max":ODQuestionData<number>
}
/**## ODTextDisplayQuestionIdMappings `interface`
* A list of all available IDs in the default `ODTextDisplayQuestion` class in `opendiscord`.
* It's used to generate typescript declarations for this class.
*/
export interface ODTextDisplayQuestionIdMappings extends ODQuestionIdConstraint {
"opendiscord:text-contents":ODQuestionData<string>
}
/**## ODQuestionManager `class` /**## ODQuestionManager `class`
* This is an Open Ticket question manager. * This is an Open Ticket question manager.
* *
@@ -81,20 +147,19 @@ export interface ODQuestionJson {
/**## ODQuestion `class` /**## ODQuestion `class`
* This is an Open Ticket question. * This is an Open Ticket question.
* *
* This class contains all data related to this question (parsed from the config). * This class contains all question data parsed from the config.
* *
* Use `ODShortQuestion` or `ODParagraphQuestion` instead! * This is an abstract class. Use instances like `ODShortQuestion` or `ODParagraphQuestion` instead.
*/ */
export class ODQuestion extends api.ODManager<ODQuestionData<api.ODValidJsonType>> { export abstract class ODQuestion<IdList extends ODQuestionIdConstraint = ODQuestionIdConstraint> extends api.ODManager<ODQuestionData<api.ODValidJsonType>> {
/**The id of this question. (from the config) */ /**The id of this question. (from the config) */
id:api.ODId id:api.ODId
/**The type of this question (e.g. `opendiscord:short` or `opendiscord:paragraph`) */ /**The type of this question (e.g. `opendiscord:short` or `opendiscord:paragraph`) */
type: string abstract readonly type: string
constructor(id:api.ODValidId, type:string, data:ODQuestionData<api.ODValidJsonType>[]){ constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super() super()
this.id = new api.ODId(id) this.id = new api.ODId(id)
this.type = type
data.forEach((data) => { data.forEach((data) => {
this.add(data) this.add(data)
}) })
@@ -117,9 +182,25 @@ export class ODQuestion extends api.ODManager<ODQuestionData<api.ODValidJsonType
} }
} }
/**Create a question from a JSON object in the database. */ get<QuestionId extends keyof api.ODNoGeneric<IdList>>(id:QuestionId): IdList[QuestionId]
static fromJson(json:ODQuestionJson): ODQuestion { get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
return new ODQuestion(json.id,json.type,json.data.map((data) => new ODQuestionData(data.id,data.value)))
get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<QuestionId extends keyof api.ODNoGeneric<IdList>>(id:QuestionId): IdList[QuestionId]
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof api.ODNoGeneric<IdList>): boolean
exists(id:api.ODValidId): boolean
exists(id:api.ODValidId): boolean {
return super.exists(id)
} }
} }
@@ -153,40 +234,36 @@ export class ODQuestionData<DataType extends api.ODValidJsonType> extends api.OD
} }
} }
/**## ODQuestionAnswer `type`
* A question answer stored in the database.
*/
export type ODQuestionAnswer = {
id:string,
name:string,
type:Exclude<ODQuestionsJsonConfig_BaseQuestion["type"],"text-display"|"file-upload">,
value:string|null
}|{
id:string,
name:string,
type:"file-upload",
files:{
id:string,
url:string,
name:string,
title:string|null,
description:string|null,
contentType:string|null,
}[]
}
/**## ODShortQuestion `class` /**## ODShortQuestion `class`
* This is an Open Ticket short question. * An Open Ticket short question. It contains all config properties of the short question type.
*
* This class contains all data related to an Open Ticket short question (parsed from the config).
*
* Use this question in an option to add a short text field to the modal!
*/ */
export class ODShortQuestion extends ODQuestion { export class ODShortQuestion extends ODQuestion<ODShortQuestionIdMappings> {
type: "opendiscord:short" = "opendiscord:short" readonly type: "opendiscord:short" = "opendiscord:short"
constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){ constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super(id,"opendiscord:short",data) super(id,data)
}
get<QuestionId extends keyof api.ODNoGeneric<ODShortQuestionIdMappings>>(id:QuestionId): ODShortQuestionIdMappings[QuestionId]
get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<QuestionId extends keyof api.ODNoGeneric<ODShortQuestionIdMappings>>(id:QuestionId): ODShortQuestionIdMappings[QuestionId]
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof api.ODNoGeneric<ODShortQuestionIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:api.ODValidId): boolean {
return super.exists(id)
} }
static fromJson(json: ODQuestionJson): ODShortQuestion { static fromJson(json: ODQuestionJson): ODShortQuestion {
@@ -195,41 +272,91 @@ export class ODShortQuestion extends ODQuestion {
} }
/**## ODParagraphQuestion `class` /**## ODParagraphQuestion `class`
* This is an Open Ticket paragraph question. * An Open Ticket paragraph question. It contains all config properties of the paragraph question type.
*
* This class contains all data related to an Open Ticket paragraph question (parsed from the config).
*
* Use this question in an option to add a paragraph text field to the modal!
*/ */
export class ODParagraphQuestion extends ODQuestion { export class ODParagraphQuestion extends ODQuestion<ODParagraphQuestionIdMappings> {
type: "opendiscord:paragraph" = "opendiscord:paragraph" readonly type: "opendiscord:paragraph" = "opendiscord:paragraph"
constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){ constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super(id,"opendiscord:paragraph",data) super(id,data)
}
get<QuestionId extends keyof api.ODNoGeneric<ODParagraphQuestionIdMappings>>(id:QuestionId): ODParagraphQuestionIdMappings[QuestionId]
get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
get(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.get(id)
}
remove<QuestionId extends keyof api.ODNoGeneric<ODParagraphQuestionIdMappings>>(id:QuestionId): ODParagraphQuestionIdMappings[QuestionId]
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null
remove(id:api.ODValidId): ODQuestionData<api.ODValidJsonType>|null {
return super.remove(id)
}
exists(id:keyof api.ODNoGeneric<ODParagraphQuestionIdMappings>): boolean
exists(id:api.ODValidId): boolean
exists(id:api.ODValidId): boolean {
return super.exists(id)
} }
static fromJson(json: ODQuestionJson): ODParagraphQuestion { static fromJson(json: ODQuestionJson): ODParagraphQuestion {
return new ODParagraphQuestion(json.id,json.data.map((data) => new ODQuestionData(data.id,data.value))) return new ODParagraphQuestion(json.id,json.data.map((data) => new ODQuestionData(data.id,data.value)))
} }
} }
/**## ODDropdownQuestion `class`
* An Open Ticket dropdown question. It contains all config properties of the dropdown question type.
*/
export class ODDropdownQuestion extends ODQuestion<ODDropdownQuestionIdMappings> {
readonly type: "opendiscord:dropdown" = "opendiscord:dropdown"
constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super(id,data)
}
static fromJson(json: ODQuestionJson): ODDropdownQuestion {
return new ODDropdownQuestion(json.id,json.data.map((data) => new ODQuestionData(data.id,data.value)))
}
}
/**## ODRadioSelectQuestion `class`
* An Open Ticket radio-select question. It contains all config properties of the radio-select question type.
*/
export class ODRadioSelectQuestion extends ODQuestion<ODRadioSelectQuestionIdMappings> {
readonly type: "opendiscord:radio-select" = "opendiscord:radio-select"
constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super(id,data)
}
static fromJson(json: ODQuestionJson): ODRadioSelectQuestion {
return new ODRadioSelectQuestion(json.id,json.data.map((data) => new ODQuestionData(data.id,data.value)))
}
}
/**## ODCheckboxSelectQuestion `class`
* An Open Ticket checkbox-select question. It contains all config properties of the checkbox-select question type.
*/
export class ODCheckboxSelectQuestion extends ODQuestion<ODCheckboxSelectQuestionIdMappings> {
readonly type: "opendiscord:checkbox-select" = "opendiscord:checkbox-select"
constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super(id,data)
}
static fromJson(json: ODQuestionJson): ODCheckboxSelectQuestion {
return new ODCheckboxSelectQuestion(json.id,json.data.map((data) => new ODQuestionData(data.id,data.value)))
}
}
/**## ODFileUploadQuestion `class`
* An Open Ticket file-upload question. It contains all config properties of the file-upload question type.
*/
export class ODFileUploadQuestion extends ODQuestion<ODFileUploadQuestionIdMappings> {
readonly type: "opendiscord:file-upload" = "opendiscord:file-upload"
constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super(id,data)
}
static fromJson(json: ODQuestionJson): ODFileUploadQuestion {
return new ODFileUploadQuestion(json.id,json.data.map((data) => new ODQuestionData(data.id,data.value)))
}
}
/**## ODTextDisplayQuestion `class`
* An Open Ticket text-display question. It contains all config properties of the text-display question type.
*/
export class ODTextDisplayQuestion extends ODQuestion<ODTextDisplayQuestionIdMappings> {
readonly type: "opendiscord:text-display" = "opendiscord:text-display"
constructor(id:api.ODValidId, data:ODQuestionData<api.ODValidJsonType>[]){
super(id,data)
}
static fromJson(json: ODQuestionJson): ODTextDisplayQuestion {
return new ODTextDisplayQuestion(json.id,json.data.map((data) => new ODQuestionData(data.id,data.value)))
}
}
+2 -1
View File
@@ -4,6 +4,7 @@
import * as api from "@open-discord-bots/framework/api" import * as api from "@open-discord-bots/framework/api"
import { ODTicketOption } from "./option.js" import { ODTicketOption } from "./option.js"
import * as discord from "discord.js" import * as discord from "discord.js"
import { ODQuestionAnswer } from "./question.js"
/**## ODTicketIdConstraint `type` /**## ODTicketIdConstraint `type`
* The constraint/layout for id mappings/interfaces of the `ODTicket` class. * The constraint/layout for id mappings/interfaces of the `ODTicket` class.
@@ -48,7 +49,7 @@ export interface ODTicketIdMappings extends ODTicketIdConstraint {
"opendiscord:autodelete-enabled":ODTicketData<boolean>, "opendiscord:autodelete-enabled":ODTicketData<boolean>,
"opendiscord:autodelete-days":ODTicketData<number>, "opendiscord:autodelete-days":ODTicketData<number>,
"opendiscord:answers":ODTicketData<{id:string,name:string,type:"short"|"paragraph",value:string|null}[]>, "opendiscord:answers":ODTicketData<ODQuestionAnswer[]>,
"opendiscord:priority":ODTicketData<number>, "opendiscord:priority":ODTicketData<number>,
"opendiscord:topic":ODTicketData<string>, "opendiscord:topic":ODTicketData<string>,
"opendiscord:message-sent":ODTicketData<boolean>, "opendiscord:message-sent":ODTicketData<boolean>,
+13
View File
@@ -1411,6 +1411,19 @@ async function saveQuickSetupConfig(){
{title:"Choice D",description:"Fear",selectedByDefault:false} {title:"Choice D",description:"Fear",selectedByDefault:false}
] ]
}, },
{
id:"example-question-6",
name:"Example Question 6",
description:"This is a file upload question.",
type:"file-upload",
required:true,
limits:{
enabled:false,
min:0,
max:1
}
},
{ {
id:"example-text-display", id:"example-text-display",
type:"text-display", type:"text-display",
+2 -1
View File
@@ -8,6 +8,7 @@ import { ODTicket, ODTicketClearFilter } from "../api/ticket.js"
import { ODTranscriptCompiler, ODTranscriptCompilerCompileResult } from "../api/transcript.js" import { ODTranscriptCompiler, ODTranscriptCompilerCompileResult } from "../api/transcript.js"
import { ODRole, ODRoleUpdateMode, ODRoleUpdateResult } from "../api/role.js" import { ODRole, ODRoleUpdateMode, ODRoleUpdateResult } from "../api/role.js"
import { ODPriorityLevel } from "../api/priority.js" import { ODPriorityLevel } from "../api/priority.js"
import { ODQuestionAnswer } from "../api/question.js"
/**## ODActionManagerIdMappings `interface` /**## ODActionManagerIdMappings `interface`
* A list of all available IDs in the default `ODActionManager` class in `opendiscord`. * A list of all available IDs in the default `ODActionManager` class in `opendiscord`.
@@ -28,7 +29,7 @@ export interface ODActionManagerIdMappings extends api.ODActionManagerIdConstrai
}, },
"opendiscord:create-ticket":{ "opendiscord:create-ticket":{
origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other", origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",
params:{guild:discord.Guild,user:discord.User,option:ODTicketOption,answers:{id:string,name:string,type:"short"|"paragraph",value:string|null}[]}, params:{guild:discord.Guild,user:discord.User,option:ODTicketOption,answers:ODQuestionAnswer[]},
result:{channel:discord.GuildTextBasedChannel,ticket:ODTicket}, result:{channel:discord.GuildTextBasedChannel,ticket:ODTicket},
workers:"opendiscord:create-ticket"|"opendiscord:send-ticket-message"|"opendiscord:discord-logs"|"opendiscord:logs" workers:"opendiscord:create-ticket"|"opendiscord:send-ticket-message"|"opendiscord:discord-logs"|"opendiscord:logs"
}, },
+1 -8
View File
@@ -235,14 +235,7 @@ export interface ODMessageManagerIdMappings extends api.ODMessageManagerIdConstr
* It's used to generate typescript declarations for this class. * It's used to generate typescript declarations for this class.
*/ */
export interface ODModalManagerIdMappings extends api.ODModalManagerIdConstraint { export interface ODModalManagerIdMappings extends api.ODModalManagerIdConstraint {
"opendiscord:ticket-questions":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,option:ODTicketOption},workers:"opendiscord:ticket-questions"} //Deprecated, moved to ODModalComponentManagerIdMappings
"opendiscord:close-ticket-reason":{origin:"ticket-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:close-ticket-reason"}
"opendiscord:reopen-ticket-reason":{origin:"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:reopen-ticket-reason"}
"opendiscord:delete-ticket-reason":{origin:"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:delete-ticket-reason"}
"opendiscord:claim-ticket-reason":{origin:"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:claim-ticket-reason"}
"opendiscord:unclaim-ticket-reason":{origin:"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:unclaim-ticket-reason"}
"opendiscord:pin-ticket-reason":{origin:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:pin-ticket-reason"}
"opendiscord:unpin-ticket-reason":{origin:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:unpin-ticket-reason"}
} }
///////////////////////////// /////////////////////////////
+10 -1
View File
@@ -3,6 +3,8 @@
/////////////////////////////////////// ///////////////////////////////////////
import * as api from "@open-discord-bots/framework/api" import * as api from "@open-discord-bots/framework/api"
import * as discord from "discord.js" import * as discord from "discord.js"
import { ODTicketOption } from "../api/option.js"
import { ODTicket } from "../api/ticket.js"
/**## ODSharedComponentManagerIdMappings `interface` /**## ODSharedComponentManagerIdMappings `interface`
* A list of all available IDs in the default `ODSharedComponentManager` class in `opendiscord`. * A list of all available IDs in the default `ODSharedComponentManager` class in `opendiscord`.
@@ -25,7 +27,14 @@ export interface ODMessageComponentManagerIdMappings extends api.ODComponentMana
* It's used to generate typescript declarations for this class. * It's used to generate typescript declarations for this class.
*/ */
export interface ODModalComponentManagerIdMappings extends api.ODComponentManagerIdConstraint { export interface ODModalComponentManagerIdMappings extends api.ODComponentManagerIdConstraint {
//"opendiscord:example-modal":{origin:"slash"|"text"|"other",params:{guild:discord.Guild|null,channel:discord.TextBasedChannel,user:discord.User},workers:"opendiscord:example-modal"}, "opendiscord:ticket-questions":{origin:"panel-button"|"panel-dropdown"|"slash"|"text"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,option:ODTicketOption},workers:"opendiscord:ticket-questions"},
"opendiscord:close-ticket-reason":{origin:"ticket-message"|"reopen-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:close-ticket-reason"}
"opendiscord:reopen-ticket-reason":{origin:"ticket-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:reopen-ticket-reason"}
"opendiscord:delete-ticket-reason":{origin:"ticket-message"|"reopen-message"|"close-message"|"autoclose-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:delete-ticket-reason"}
"opendiscord:claim-ticket-reason":{origin:"ticket-message"|"unclaim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:claim-ticket-reason"}
"opendiscord:unclaim-ticket-reason":{origin:"ticket-message"|"claim-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:unclaim-ticket-reason"}
"opendiscord:pin-ticket-reason":{origin:"ticket-message"|"unpin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:pin-ticket-reason"}
"opendiscord:unpin-ticket-reason":{origin:"ticket-message"|"pin-message"|"other",params:{guild:discord.Guild,channel:discord.TextBasedChannel,user:discord.User,ticket:ODTicket,message:discord.Message},workers:"opendiscord:unpin-ticket-reason"}
} }
/**## ODComponentModifierManagerIdMappings `interface` /**## ODComponentModifierManagerIdMappings `interface`
+25 -5
View File
@@ -619,6 +619,18 @@ export interface ODQuestionsJsonConfig_CheckboxLimits {
max:number max:number
} }
/**## ODQuestionsJsonConfig_FileUploadLimits `interface`
* Verify the amount of uploaded files in a question.
*/
export interface ODQuestionsJsonConfig_FileUploadLimits {
/**Enable file limits. */
enabled:boolean,
/**The minimum amount of uploaded files. */
min:number,
/**The maximum amount of uploaded files. */
max:number
}
/**## ODQuestionsJsonConfig_DropdownChoice `interface` /**## ODQuestionsJsonConfig_DropdownChoice `interface`
* A dropdown choice used in `ODQuestionsJsonConfig_DropdownQuestion` * A dropdown choice used in `ODQuestionsJsonConfig_DropdownQuestion`
*/ */
@@ -654,7 +666,7 @@ export interface ODQuestionsJsonConfig_BaseQuestion {
/**The description of this question. (Leave empty for none) */ /**The description of this question. (Leave empty for none) */
description:string, description:string,
/**The type of this question. */ /**The type of this question. */
type:"short"|"paragraph"|"text-display"|"dropdown"|"radio-select"|"checkbox-select", type:"short"|"paragraph"|"text-display"|"dropdown"|"radio-select"|"checkbox-select"|"file-upload",
/**Is this question required? */ /**Is this question required? */
required:boolean, required:boolean,
} }
@@ -662,9 +674,7 @@ export interface ODQuestionsJsonConfig_BaseQuestion {
/**## ODQuestionsJsonConfig_TextDisplayQuestion `interface` /**## ODQuestionsJsonConfig_TextDisplayQuestion `interface`
* All properties for a text-display in the `questions.jsonc` config! * All properties for a text-display in the `questions.jsonc` config!
*/ */
export interface ODQuestionsJsonConfig_TextDisplayQuestion { export interface ODQuestionsJsonConfig_TextDisplayQuestion extends Omit<ODQuestionsJsonConfig_BaseQuestion,"name"|"description"|"required"> {
/**The id of this text-display. */
id:string,
/**The type of this question. */ /**The type of this question. */
type:"text-display", type:"text-display",
/**The text contents to show in the modal. */ /**The text contents to show in the modal. */
@@ -724,6 +734,15 @@ export interface ODQuestionsJsonConfig_CheckboxSelectQuestion extends ODQuestion
choices:ODQuestionsJsonConfig_RadioCheckboxChoice[] choices:ODQuestionsJsonConfig_RadioCheckboxChoice[]
} }
/**## ODQuestionsJsonConfig_FileUploadQuestion `interface`
* All properties for checkbox select questions in the `questions.jsonc` config!
*/
export interface ODQuestionsJsonConfig_FileUploadQuestion extends ODQuestionsJsonConfig_BaseQuestion {
type:"file-upload",
/**Verify the amount of uploaded files (minimum/maximum). */
limits:ODQuestionsJsonConfig_FileUploadLimits
}
/**## ODQuestionsJsonConfig_QuestionsData `type` /**## ODQuestionsJsonConfig_QuestionsData `type`
* All contents of the `questions.jsonc` config file. * All contents of the `questions.jsonc` config file.
*/ */
@@ -733,7 +752,8 @@ export type ODQuestionsJsonConfig_QuestionsData = (
ODQuestionsJsonConfig_TextDisplayQuestion| ODQuestionsJsonConfig_TextDisplayQuestion|
ODQuestionsJsonConfig_DropdownQuestion| ODQuestionsJsonConfig_DropdownQuestion|
ODQuestionsJsonConfig_RadioSelectQuestion| ODQuestionsJsonConfig_RadioSelectQuestion|
ODQuestionsJsonConfig_CheckboxSelectQuestion ODQuestionsJsonConfig_CheckboxSelectQuestion|
ODQuestionsJsonConfig_FileUploadQuestion
)[] )[]
/////////////////////////////////////// ///////////////////////////////////////
+13
View File
@@ -311,6 +311,19 @@ export const migrations = [
{title:"Choice D",description:"Fear",selectedByDefault:false} {title:"Choice D",description:"Fear",selectedByDefault:false}
] ]
}, },
{
id:"example-file-upload",
name:"Example File Upload",
description:"With this question type, users can upload one or multiple files.",
type:"file-upload",
required:true,
limits:{
enabled:false,
min:0,
max:1
}
},
{ {
id:"example-text-display-question", id:"example-text-display-question",
type:"text-display", type:"text-display",
+15 -1
View File
@@ -686,7 +686,21 @@ export const defaultQuestionsStructure = new api.ODCheckerArrayStructure("opendi
],cliDisplayName:"Choice",cliDisplayDescription:"A choice for this checkbox select question."}),cliDisplayName:"Choices",cliDisplayPropertyName:"choice",cliDisplayDescription:"Manage all available choices of this checkbox select question."})} ],cliDisplayName:"Choice",cliDisplayDescription:"A choice for this checkbox select question."}),cliDisplayName:"Choices",cliDisplayPropertyName:"choice",cliDisplayDescription:"Manage all available choices of this checkbox select question."})}
],cliDisplayName:"Checkbox Select Question",cliDisplayDescription:"Manage, customise and configure the checkbox select question to your preference."})}, ],cliDisplayName:"Checkbox Select Question",cliDisplayDescription:"Manage, customise and configure the checkbox select question to your preference."})},
],cliDisplayName:"Question",cliDisplayDescription:"Manage a question of one of the 6 types: short, paragraph, text-display, dropdown, radio-select, checkbox-select."}),cliDisplayName:"Questions",cliDisplayDescription:"A list of all questions in the bot. Here you can add, modify & remove existing questions or customise them to your preference."}) //FILE UPLOAD QUESTION
{name:"File Upload Question",priority:0,properties:[{key:"type",value:"file-upload"}],checker:new api.ODCheckerObjectStructure("opendiscord:file-upload-question",{cliDisplayKeyInParentArray:"name",cliDisplayAdditionalKeysInParentArray:["id","type"],children:[
{key:"id",checker:new api.ODCheckerCustomStructure_UniqueId("opendiscord:question-id","openticket","question-ids",{regex:/^[A-Za-z0-9-éèçàêâôûî]+$/,minLength:3,maxLength:40,cliDisplayName:"Id",cliDisplayDescription:"The id of this question. Used in ticket options."})},
{key:"name",checker:new api.ODCheckerStringStructure("opendiscord:question-name",{minLength:3,maxLength:45,cliDisplayName:"Name",cliDisplayDescription:"The name of this question."})},
{key:"description",checker:new api.ODCheckerStringStructure("opendiscord:question-description",{maxLength:100,cliDisplayName:"Description",cliDisplayDescription:"The description of this question."})},
{key:"required",checker:new api.ODCheckerBooleanStructure("opendiscord:question-required",{cliDisplayName:"Required",cliDisplayDescription:"Is this question required? If not, it can be left empty."})},
{key:"limits",checker:new api.ODCheckerEnabledObjectStructure("opendiscord:amount",{property:"enabled",enabledValue:true,checker:new api.ODCheckerObjectStructure("opendiscord:amount",{children:[
{key:"enabled",checker:new api.ODCheckerBooleanStructure("opendiscord:amount-enabled",{cliDisplayName:"Enabled",cliDisplayDescription:"Enable/disable checking the min/max amount of uploaded files."})},
{key:"min",checker:new api.ODCheckerNumberStructure("opendiscord:amount-min",{min:0,max:10,floatAllowed:false,cliDisplayName:"Min Amount",cliDisplayDescription:"The minimum amount of uploaded files required."})},
{key:"max",checker:new api.ODCheckerNumberStructure("opendiscord:amount-max",{min:1,max:10,floatAllowed:false,cliInitDefaultValue:10,cliDisplayName:"Max Amount",cliDisplayDescription:"The maximum amount of uploaded files allowed."})},
],cliDisplayName:"Upload Limits",cliDisplayDescription:"Verify the minimum or maximum amount of uploaded files."}),cliDisplayName:"Checkbox Limits",cliDisplayDescription:"Verify the minimum or maximum amount of uploaded files."})},
],cliDisplayName:"Checkbox Select Question",cliDisplayDescription:"Manage, customise and configure the file upload question to your preference."})},
],cliDisplayName:"Question",cliDisplayDescription:"Manage a question of one of the 7 types: short, paragraph, text-display, dropdown, radio-select, checkbox-select, file-upload."}),cliDisplayName:"Questions",cliDisplayDescription:"A list of all questions in the bot. Here you can add, modify & remove existing questions or customise them to your preference."})
export const defaultTranscriptsStructure = new api.ODCheckerObjectStructure("opendiscord:transcripts",{children:[ export const defaultTranscriptsStructure = new api.ODCheckerObjectStructure("opendiscord:transcripts",{children:[
//GENERAL //GENERAL
+15
View File
@@ -286,6 +286,21 @@ export const defaultQuestionsFormatter = new fjs.TopLevelCommentFormatter(new fj
new fjs.PropertyFormatter("selectedByDefault"), new fjs.PropertyFormatter("selectedByDefault"),
])), ])),
])}, ])},
{key:"type",value:"file-upload",formatter:new fjs.ObjectFormatter(null,true,[
new fjs.MultiCommentFormatter("A file upload modal question where users can upload one or more files."),
new fjs.PropertyFormatter("id"),
new fjs.PropertyFormatter("name"),
new fjs.PropertyFormatter("description",new fjs.SingleCommentFormatter("Leave empty to disable")),
new fjs.PropertyFormatter("type"),
new fjs.PropertyFormatter("required"),
new fjs.TextFormatter(""),
new fjs.ObjectFormatter("limits",true,[
new fjs.MultiCommentFormatter("Configure minimum/maximum amount of files to upload."),
new fjs.PropertyFormatter("enabled"),
new fjs.PropertyFormatter("min"),
new fjs.PropertyFormatter("max"),
]),
])},
]))) ])))
+72 -14
View File
@@ -4,13 +4,15 @@ export async function loadAllQuestions(){
const questionConfig = opendiscord.configs.get("opendiscord:questions") const questionConfig = opendiscord.configs.get("opendiscord:questions")
if (!questionConfig) return if (!questionConfig) return
questionConfig.data.forEach((question) => { for (const question of questionConfig.data){
if (question.type == "short"){ if (question.type === "short") opendiscord.questions.add(loadShortQuestion(question))
opendiscord.questions.add(loadShortQuestion(question)) else if (question.type === "paragraph") opendiscord.questions.add(loadParagraphQuestion(question))
}else if (question.type == "paragraph"){ else if (question.type === "dropdown") opendiscord.questions.add(loadDropdownQuestion(question))
opendiscord.questions.add(loadParagraphQuestion(question)) else if (question.type === "radio-select") opendiscord.questions.add(loadRadioSelectQuestion(question))
else if (question.type === "checkbox-select") opendiscord.questions.add(loadCheckboxSelectQuestion(question))
else if (question.type === "file-upload") opendiscord.questions.add(loadFileUploadQuestion(question))
else if (question.type === "text-display") opendiscord.questions.add(loadTextDisplayQuestion(question))
} }
})
//update questions on config reload //update questions on config reload
questionConfig.onReload(async () => { questionConfig.onReload(async () => {
@@ -18,22 +20,25 @@ export async function loadAllQuestions(){
await opendiscord.questions.loopAll((data,id) => {opendiscord.questions.remove(id)}) await opendiscord.questions.loopAll((data,id) => {opendiscord.questions.remove(id)})
//add new questions //add new questions
questionConfig.data.forEach((question) => { for (const question of questionConfig.data){
if (question.type == "short"){ if (question.type === "short") opendiscord.questions.add(loadShortQuestion(question))
opendiscord.questions.add(loadShortQuestion(question)) else if (question.type === "paragraph") opendiscord.questions.add(loadParagraphQuestion(question))
}else if (question.type == "paragraph"){ else if (question.type === "dropdown") opendiscord.questions.add(loadDropdownQuestion(question))
opendiscord.questions.add(loadParagraphQuestion(question)) else if (question.type === "radio-select") opendiscord.questions.add(loadRadioSelectQuestion(question))
else if (question.type === "checkbox-select") opendiscord.questions.add(loadCheckboxSelectQuestion(question))
else if (question.type === "file-upload") opendiscord.questions.add(loadFileUploadQuestion(question))
else if (question.type === "text-display") opendiscord.questions.add(loadTextDisplayQuestion(question))
} }
}) })
})
} }
export const loadShortQuestion = (option:api.ODQuestionsJsonConfig_ShortQuestion) => { export const loadShortQuestion = (option:api.ODQuestionsJsonConfig_ShortQuestion) => {
return new api.ODShortQuestion(option.id,[ return new api.ODShortQuestion(option.id,[
new api.ODQuestionData("opendiscord:name",option.name), new api.ODQuestionData("opendiscord:name",option.name),
new api.ODQuestionData("opendiscord:description",option.description),
new api.ODQuestionData("opendiscord:required",option.required), new api.ODQuestionData("opendiscord:required",option.required),
new api.ODQuestionData("opendiscord:placeholder",option.placeholder),
new api.ODQuestionData("opendiscord:placeholder",option.placeholder),
new api.ODQuestionData("opendiscord:length-enabled",option.length.enabled), new api.ODQuestionData("opendiscord:length-enabled",option.length.enabled),
new api.ODQuestionData("opendiscord:length-min",option.length.min), new api.ODQuestionData("opendiscord:length-min",option.length.min),
new api.ODQuestionData("opendiscord:length-max",option.length.max), new api.ODQuestionData("opendiscord:length-max",option.length.max),
@@ -43,11 +48,64 @@ export const loadShortQuestion = (option:api.ODQuestionsJsonConfig_ShortQuestion
export const loadParagraphQuestion = (option:api.ODQuestionsJsonConfig_ParagraphQuestion) => { export const loadParagraphQuestion = (option:api.ODQuestionsJsonConfig_ParagraphQuestion) => {
return new api.ODParagraphQuestion(option.id,[ return new api.ODParagraphQuestion(option.id,[
new api.ODQuestionData("opendiscord:name",option.name), new api.ODQuestionData("opendiscord:name",option.name),
new api.ODQuestionData("opendiscord:description",option.description),
new api.ODQuestionData("opendiscord:required",option.required), new api.ODQuestionData("opendiscord:required",option.required),
new api.ODQuestionData("opendiscord:placeholder",option.placeholder),
new api.ODQuestionData("opendiscord:placeholder",option.placeholder),
new api.ODQuestionData("opendiscord:length-enabled",option.length.enabled), new api.ODQuestionData("opendiscord:length-enabled",option.length.enabled),
new api.ODQuestionData("opendiscord:length-min",option.length.min), new api.ODQuestionData("opendiscord:length-min",option.length.min),
new api.ODQuestionData("opendiscord:length-max",option.length.max), new api.ODQuestionData("opendiscord:length-max",option.length.max),
]) ])
} }
export const loadDropdownQuestion = (option:api.ODQuestionsJsonConfig_DropdownQuestion) => {
return new api.ODDropdownQuestion(option.id,[
new api.ODQuestionData("opendiscord:name",option.name),
new api.ODQuestionData("opendiscord:description",option.description),
new api.ODQuestionData("opendiscord:required",option.required),
new api.ODQuestionData("opendiscord:placeholder",option.placeholder),
new api.ODQuestionData("opendiscord:choices",option.choices)
])
}
export const loadRadioSelectQuestion = (option:api.ODQuestionsJsonConfig_RadioSelectQuestion) => {
return new api.ODRadioSelectQuestion(option.id,[
new api.ODQuestionData("opendiscord:name",option.name),
new api.ODQuestionData("opendiscord:description",option.description),
new api.ODQuestionData("opendiscord:required",option.required),
new api.ODQuestionData("opendiscord:choices",option.choices)
])
}
export const loadCheckboxSelectQuestion = (option:api.ODQuestionsJsonConfig_CheckboxSelectQuestion) => {
return new api.ODCheckboxSelectQuestion(option.id,[
new api.ODQuestionData("opendiscord:name",option.name),
new api.ODQuestionData("opendiscord:description",option.description),
new api.ODQuestionData("opendiscord:required",option.required),
new api.ODQuestionData("opendiscord:limits-enabled",option.limits.enabled),
new api.ODQuestionData("opendiscord:limits-min",option.limits.min),
new api.ODQuestionData("opendiscord:limits-max",option.limits.max),
new api.ODQuestionData("opendiscord:choices",option.choices)
])
}
export const loadFileUploadQuestion = (option:api.ODQuestionsJsonConfig_FileUploadQuestion) => {
return new api.ODFileUploadQuestion(option.id,[
new api.ODQuestionData("opendiscord:name",option.name),
new api.ODQuestionData("opendiscord:description",option.description),
new api.ODQuestionData("opendiscord:required",option.required),
new api.ODQuestionData("opendiscord:limits-enabled",option.limits.enabled),
new api.ODQuestionData("opendiscord:limits-min",option.limits.min),
new api.ODQuestionData("opendiscord:limits-max",option.limits.max),
])
}
export const loadTextDisplayQuestion = (option:api.ODQuestionsJsonConfig_TextDisplayQuestion) => {
return new api.ODTextDisplayQuestion(option.id,[
new api.ODQuestionData("opendiscord:text-contents",option.textContents)
])
}
+2 -2
View File
@@ -647,7 +647,7 @@ const main = async () => {
//load modal builders //load modal builders
opendiscord.log("Loading modals...","system") opendiscord.log("Loading modals...","system")
if (opendiscord.sharedFuses.getFuse("modalBuildersLoading")){ if (opendiscord.sharedFuses.getFuse("modalBuildersLoading")){
await (await import("./builders/modals.js")).registerAllModals() //Deprecated, moved to "modal components"
} }
await opendiscord.events.get("onModalBuilderLoad").emit([opendiscord.builders.modals,opendiscord.builders,opendiscord.actions]) await opendiscord.events.get("onModalBuilderLoad").emit([opendiscord.builders.modals,opendiscord.builders,opendiscord.actions])
await opendiscord.events.get("afterModalBuildersLoaded").emit([opendiscord.builders.modals,opendiscord.builders,opendiscord.actions]) await opendiscord.events.get("afterModalBuildersLoaded").emit([opendiscord.builders.modals,opendiscord.builders,opendiscord.actions])
@@ -671,7 +671,7 @@ const main = async () => {
//load modal components //load modal components
opendiscord.log("Loading modal components...","system") opendiscord.log("Loading modal components...","system")
if (opendiscord.sharedFuses.getFuse("modalComponentsLoading")){ if (opendiscord.sharedFuses.getFuse("modalComponentsLoading")){
//TODO!! await (await import("./components/modals.js")).registerModalComponents()
} }
await opendiscord.events.get("onModalComponentLoad").emit([opendiscord.components.modals,opendiscord.components,opendiscord.actions]) await opendiscord.events.get("onModalComponentLoad").emit([opendiscord.components.modals,opendiscord.components,opendiscord.actions])
await opendiscord.events.get("afterModalComponentsLoaded").emit([opendiscord.components.modals,opendiscord.components,opendiscord.actions]) await opendiscord.events.get("afterModalComponentsLoaded").emit([opendiscord.components.modals,opendiscord.components,opendiscord.actions])