/home/bdqbpbxa/api-uniferx.goodface.com.ua/vendor/laravel/nova/resources/js/views/Update.vue
<template>
<LoadingView :loading="loading">
<template v-if="resourceInformation && title">
<Head
:title="
__('Update :resource: :title', {
resource: resourceInformation.singularLabel,
title: title,
})
"
/>
</template>
<form
v-if="panels"
@submit="submitViaUpdateResource"
@change="onUpdateFormStatus"
:data-form-unique-id="formUniqueId"
autocomplete="off"
ref="form"
>
<div class="mb-8 space-y-4">
<component
v-for="panel in panels"
:key="panel.id"
:is="'form-' + panel.component"
@update-last-retrieved-at-timestamp="updateLastRetrievedAtTimestamp"
@file-deleted="handleFileDeleted"
@field-changed="onUpdateFormStatus"
@file-upload-started="handleFileUploadStarted"
@file-upload-finished="handleFileUploadFinished"
:panel="panel"
:name="panel.name"
:resource-id="resourceId"
:resource-name="resourceName"
:fields="panel.fields"
:form-unique-id="formUniqueId"
mode="form"
:validation-errors="validationErrors"
:via-resource="viaResource"
:via-resource-id="viaResourceId"
:via-relationship="viaRelationship"
:show-help-text="true"
/>
</div>
<!-- Update Button -->
<div
class="flex flex-col md:flex-row md:items-center justify-center md:justify-end space-y-2 md:space-y-0 md:space-x-3"
>
<CancelButton
dusk="cancel-update-button"
type="button"
align="center"
@click="cancelUpdatingResource"
/>
<LoadingButton
dusk="update-and-continue-editing-button"
type="button"
@click="submitViaUpdateResourceAndContinueEditing"
:disabled="isWorking"
align="center"
:processing="wasSubmittedViaUpdateResourceAndContinueEditing"
>
{{ __('Update & Continue Editing') }}
</LoadingButton>
<LoadingButton
dusk="update-button"
type="submit"
:disabled="isWorking"
align="center"
:processing="wasSubmittedViaUpdateResource"
>
{{ updateButtonLabel }}
</LoadingButton>
</div>
</form>
</LoadingView>
</template>
<script>
import each from 'lodash/each'
import tap from 'lodash/tap'
import {
HandlesFormRequest,
HandlesUploads,
InteractsWithResourceInformation,
mapProps,
PreventsFormAbandonment,
} from '@/mixins'
import { mapActions } from 'vuex'
export default {
mixins: [
HandlesFormRequest,
HandlesUploads,
InteractsWithResourceInformation,
PreventsFormAbandonment,
],
provide() {
return {
removeFile: this.removeFile,
}
},
props: mapProps([
'resourceName',
'resourceId',
'viaResource',
'viaResourceId',
'viaRelationship',
]),
data: () => ({
relationResponse: null,
loading: true,
submittedViaUpdateResourceAndContinueEditing: false,
submittedViaUpdateResource: false,
title: null,
fields: [],
panels: [],
lastRetrievedAt: null,
}),
async created() {
if (Nova.missingResource(this.resourceName)) return Nova.visit('/404')
// If this update is via a relation index, then let's grab the field
// and use the label for that as the one we use for the title and buttons
if (this.isRelation) {
const { data } = await Nova.request().get(
`/nova-api/${this.viaResource}/field/${this.viaRelationship}`,
{ params: { relatable: true } }
)
this.relationResponse = data
}
this.getFields()
this.updateLastRetrievedAtTimestamp()
this.allowLeavingForm()
},
methods: {
...mapActions(['fetchPolicies']),
handleFileDeleted() {
//
},
removeFile(attribute) {
const { resourceName, resourceId } = this
Nova.request().delete(
`/nova-api/${resourceName}/${resourceId}/field/${attribute}`
)
},
/**
* Handle resource loaded event.
*/
handleResourceLoaded() {
this.loading = false
Nova.$emit('resource-loaded', {
resourceName: this.resourceName,
resourceId: this.resourceId.toString(),
mode: 'update',
})
},
/**
* Get the available fields for the resource.
*/
async getFields() {
this.loading = true
this.panels = []
this.fields = []
const {
data: { title, panels, fields },
} = await Nova.request()
.get(
`/nova-api/${this.resourceName}/${this.resourceId}/update-fields`,
{
params: {
editing: true,
editMode: 'update',
viaResource: this.viaResource,
viaResourceId: this.viaResourceId,
viaRelationship: this.viaRelationship,
},
}
)
.catch(error => {
if (error.response.status == 404) {
Nova.visit('/404')
return
}
})
this.title = title
this.panels = panels
this.fields = fields
this.handleResourceLoaded()
},
async submitViaUpdateResource(e) {
e.preventDefault()
this.submittedViaUpdateResource = true
this.submittedViaUpdateResourceAndContinueEditing = false
this.allowLeavingForm()
await this.updateResource()
},
async submitViaUpdateResourceAndContinueEditing(e) {
e.preventDefault()
this.submittedViaUpdateResourceAndContinueEditing = true
this.submittedViaUpdateResource = false
this.allowLeavingForm()
await this.updateResource()
},
cancelUpdatingResource() {
this.handleProceedingToPreviousPage()
this.allowLeavingForm()
this.proceedToPreviousPage(
this.isRelation
? `/resources/${this.viaResource}/${this.viaResourceId}`
: `/resources/${this.resourceName}/${this.resourceId}`
)
},
/**
* Update the resource using the provided data.
*/
async updateResource() {
this.isWorking = true
if (this.$refs.form.reportValidity()) {
try {
const {
data: { redirect, id },
} = await this.updateRequest()
await this.fetchPolicies()
Nova.success(
this.__('The :resource was updated!', {
resource: this.resourceInformation.singularLabel.toLowerCase(),
})
)
Nova.$emit('resource-updated', {
resourceName: this.resourceName,
resourceId: id,
})
await this.updateLastRetrievedAtTimestamp()
if (this.submittedViaUpdateResource) {
Nova.visit(redirect)
} else {
if (id != this.resourceId) {
Nova.visit(`/resources/${this.resourceName}/${id}/edit`)
} else {
window.scrollTo(0, 0)
this.disableNavigateBackUsingHistory()
// Reset the form by refetching the fields
this.getFields()
this.resetErrors()
this.submittedViaUpdateResource = false
this.submittedViaUpdateResourceAndContinueEditing = false
this.isWorking = false
}
return
}
} catch (error) {
window.scrollTo(0, 0)
this.submittedViaUpdateResource = false
this.submittedViaUpdateResourceAndContinueEditing = false
this.preventLeavingForm()
this.handleOnUpdateResponseError(error)
}
}
this.submittedViaUpdateResource = false
this.submittedViaUpdateResourceAndContinueEditing = false
this.isWorking = false
},
/**
* Send an update request for this resource
*/
updateRequest() {
return Nova.request().post(
`/nova-api/${this.resourceName}/${this.resourceId}`,
this.updateResourceFormData(),
{
params: {
viaResource: this.viaResource,
viaResourceId: this.viaResourceId,
viaRelationship: this.viaRelationship,
editing: true,
editMode: 'update',
},
}
)
},
/**
* Create the form data for creating the resource.
*/
updateResourceFormData() {
return tap(new FormData(), formData => {
each(this.panels, panel => {
each(panel.fields, field => {
field.fill(formData)
})
})
formData.append('_method', 'PUT')
formData.append('_retrieved_at', this.lastRetrievedAt)
})
},
/**
* Update the last retrieved at timestamp to the current UNIX timestamp.
*/
updateLastRetrievedAtTimestamp() {
this.lastRetrievedAt = Math.floor(new Date().getTime() / 1000)
},
/**
* Prevent accidental abandonment only if form was changed.
*/
onUpdateFormStatus() {
this.updateFormStatus()
},
},
computed: {
wasSubmittedViaUpdateResourceAndContinueEditing() {
return this.isWorking && this.submittedViaUpdateResourceAndContinueEditing
},
wasSubmittedViaUpdateResource() {
return this.isWorking && this.submittedViaUpdateResource
},
singularName() {
if (this.relationResponse) {
return this.relationResponse.singularLabel
}
return this.resourceInformation.singularLabel
},
updateButtonLabel() {
return this.resourceInformation.updateButtonLabel
},
isRelation() {
return Boolean(this.viaResourceId && this.viaRelationship)
},
},
}
</script>