2024-04-15 19:39:03 +02:00
|
|
|
import { serialize } from "object-to-formdata"
|
|
|
|
|
import Errors from "./Errors"
|
|
|
|
|
import cloneDeep from "clone-deep"
|
|
|
|
|
import { opnFetch } from "~/composables/useOpnApi.js"
|
2023-12-14 16:53:05 +01:00
|
|
|
function hasFiles(data) {
|
2024-04-15 19:39:03 +02:00
|
|
|
return (
|
|
|
|
|
data instanceof File ||
|
2023-12-14 16:53:05 +01:00
|
|
|
data instanceof Blob ||
|
|
|
|
|
data instanceof FileList ||
|
2024-04-15 19:39:03 +02:00
|
|
|
(typeof data === "object" &&
|
|
|
|
|
data !== null &&
|
|
|
|
|
Object.values(data).find((value) => hasFiles(value)) !== undefined)
|
|
|
|
|
)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Form {
|
|
|
|
|
constructor(data = {}) {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.originalData = {}
|
|
|
|
|
this.busy = false
|
|
|
|
|
this.successful = false
|
|
|
|
|
this.recentlySuccessful = false
|
|
|
|
|
this.recentlySuccessfulTimeoutId = undefined
|
|
|
|
|
this.errors = new Errors()
|
|
|
|
|
this.update(data)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static errorMessage = "Something went wrong. Please try again."
|
|
|
|
|
static recentlySuccessfulTimeout = 2000
|
|
|
|
|
static ignore = [
|
|
|
|
|
"busy",
|
|
|
|
|
"successful",
|
|
|
|
|
"errors",
|
|
|
|
|
"originalData",
|
|
|
|
|
"recentlySuccessful",
|
|
|
|
|
"recentlySuccessfulTimeoutId",
|
|
|
|
|
]
|
2023-12-14 16:53:05 +01:00
|
|
|
|
|
|
|
|
static make(augment) {
|
2024-04-15 19:39:03 +02:00
|
|
|
return new this(augment)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
update(data) {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.originalData = Object.assign({}, this.originalData, cloneDeep(data))
|
|
|
|
|
Object.assign(this, data)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fill(data = {}) {
|
|
|
|
|
this.keys().forEach((key) => {
|
2024-04-15 19:39:03 +02:00
|
|
|
this[key] = data[key]
|
|
|
|
|
})
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data() {
|
2024-04-15 19:39:03 +02:00
|
|
|
return this.keys().reduce(
|
|
|
|
|
(data, key) => ({ ...data, [key]: this[key] }),
|
|
|
|
|
{},
|
|
|
|
|
)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
keys() {
|
2024-04-15 19:39:03 +02:00
|
|
|
return Object.keys(this).filter((key) => !Form.ignore.includes(key))
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
startProcessing() {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.errors.clear()
|
|
|
|
|
this.busy = true
|
|
|
|
|
this.successful = false
|
|
|
|
|
this.recentlySuccessful = false
|
|
|
|
|
clearTimeout(this.recentlySuccessfulTimeoutId)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
finishProcessing() {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.busy = false
|
|
|
|
|
this.successful = true
|
|
|
|
|
this.recentlySuccessful = true
|
2023-12-14 16:53:05 +01:00
|
|
|
this.recentlySuccessfulTimeoutId = setTimeout(() => {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.recentlySuccessful = false
|
|
|
|
|
}, Form.recentlySuccessfulTimeout)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
clear() {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.errors.clear()
|
|
|
|
|
this.successful = false
|
|
|
|
|
this.recentlySuccessful = false
|
|
|
|
|
clearTimeout(this.recentlySuccessfulTimeoutId)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reset() {
|
|
|
|
|
Object.keys(this)
|
2024-04-15 19:39:03 +02:00
|
|
|
.filter((key) => !Form.ignore.includes(key))
|
2023-12-14 16:53:05 +01:00
|
|
|
.forEach((key) => {
|
2024-04-15 19:39:03 +02:00
|
|
|
this[key] = JSON.parse(JSON.stringify(this.originalData[key]))
|
|
|
|
|
})
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
get(url, config = {}) {
|
2024-04-15 19:39:03 +02:00
|
|
|
return this.submit("get", url, config)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
post(url, config = {}) {
|
2024-04-15 19:39:03 +02:00
|
|
|
return this.submit("post", url, config)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
patch(url, config = {}) {
|
2024-04-15 19:39:03 +02:00
|
|
|
return this.submit("patch", url, config)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
put(url, config = {}) {
|
2024-04-15 19:39:03 +02:00
|
|
|
return this.submit("put", url, config)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete(url, config = {}) {
|
2024-04-15 19:39:03 +02:00
|
|
|
return this.submit("delete", url, config)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
submit(method, url, config = {}) {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.startProcessing()
|
2023-12-14 16:53:05 +01:00
|
|
|
|
|
|
|
|
config = {
|
|
|
|
|
body: {},
|
|
|
|
|
params: {},
|
|
|
|
|
url: url,
|
|
|
|
|
method: method,
|
2024-04-15 19:39:03 +02:00
|
|
|
...config,
|
|
|
|
|
}
|
2023-12-14 16:53:05 +01:00
|
|
|
|
2024-04-15 19:39:03 +02:00
|
|
|
if (method.toLowerCase() === "get") {
|
|
|
|
|
config.params = { ...this.data(), ...config.params }
|
2023-12-14 16:53:05 +01:00
|
|
|
} else {
|
2024-04-15 19:39:03 +02:00
|
|
|
config.body = { ...this.data(), ...config.data }
|
2023-12-14 16:53:05 +01:00
|
|
|
|
|
|
|
|
if (hasFiles(config.data) && !config.transformRequest) {
|
2024-04-15 19:39:03 +02:00
|
|
|
config.transformRequest = [(data) => serialize(data)]
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return new Promise((resolve, reject) => {
|
2023-12-19 13:46:55 +01:00
|
|
|
opnFetch(config.url, config)
|
|
|
|
|
.then((data) => {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.finishProcessing()
|
|
|
|
|
resolve(data)
|
|
|
|
|
})
|
|
|
|
|
.catch((error) => {
|
|
|
|
|
this.handleErrors(error)
|
2024-01-02 13:09:41 +01:00
|
|
|
reject(error)
|
2023-12-14 16:53:05 +01:00
|
|
|
})
|
2024-04-15 19:39:03 +02:00
|
|
|
})
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
handleErrors(error) {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.busy = false
|
2023-12-14 16:53:05 +01:00
|
|
|
|
2023-12-19 13:46:55 +01:00
|
|
|
if (error) {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.errors.set(this.extractErrors(error.data))
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extractErrors(data) {
|
2024-04-15 19:39:03 +02:00
|
|
|
if (!data || typeof data !== "object") {
|
|
|
|
|
return { error: Form.errorMessage }
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data.errors) {
|
2024-04-15 19:39:03 +02:00
|
|
|
return { ...data.errors }
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (data.message) {
|
2024-04-15 19:39:03 +02:00
|
|
|
return { error: data.message }
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
2024-04-15 19:39:03 +02:00
|
|
|
return { ...data }
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onKeydown(event) {
|
2024-04-15 19:39:03 +02:00
|
|
|
const target = event.target
|
2023-12-14 16:53:05 +01:00
|
|
|
|
|
|
|
|
if (target.name) {
|
2024-04-15 19:39:03 +02:00
|
|
|
this.errors.clear(target.name)
|
2023-12-14 16:53:05 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-15 19:39:03 +02:00
|
|
|
export default Form
|