Skip to content

Commit

Permalink
Compatibility with nova Image::make
Browse files Browse the repository at this point in the history
  • Loading branch information
kongulov committed Oct 26, 2021
1 parent 51c5ae9 commit f163f17
Show file tree
Hide file tree
Showing 10 changed files with 306 additions and 19 deletions.
2 changes: 1 addition & 1 deletion dist/js/field.js

Large diffs are not rendered by default.

32 changes: 25 additions & 7 deletions resources/js/components/DetailField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,20 @@
</span>
</div>
<div class="tab-contents">
<div class="tab-content table">
<div class="table-row" v-for="(component, index) in field.fields" v-show="selectedLang === component.locale && component.showOnDetail">
<div class="table-cell p-2">{{ componentName(component) }}</div>
<div class="table-cell p-2">&nbsp;:&nbsp;</div>
<div class="table-cell p-2" v-html="component.value"></div>
</div>
<div v-for="(component, index) in field.fields" v-show="selectedLang === component.locale && component.showOnDetail">
<component
:key="index"
:class="{'remove-bottom-border ': (index + 1) % field.originalFieldsCount !== 0}"
:is="resolveComponentName(component)"
:resource-name="resourceName"
:resource-id="resourceId"
:resource="resource"
:field="fieldDefaultValue(component)"
:errors="errors"
:via-resource="viaResource"
:via-resource-id="viaResourceId"
:via-relationship="viaRelationship"
/>
</div>
</div>
</div>
Expand All @@ -23,6 +31,16 @@ import IndexMixin from '../mixins/index'
export default {
mixins: [IndexMixin],
props: ['resource', 'resourceName', 'resourceId', 'field'],
props: ['field', 'resource', 'resourceId', 'resourceName', 'errors', 'viaResource', 'viaRelationship', 'viaResourceId'],
methods:{
fieldDefaultValue(field) {
if (field.value === '' && field.defaultValue !== '') field.value = field.defaultValue;
return field;
},
resolveComponentName(field) {
return field.prefixComponent ? 'detail-' + field.component : field.component
},
}
}
</script>
29 changes: 26 additions & 3 deletions resources/js/components/IndexField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,22 @@
</span>
</div>
<div class="tab-contents">
<div class="tab-content" v-for="(component, index) in field.fields"
<div class="tab-content" style="display: flex" v-for="(component, index) in field.fields"
v-show="selectedLang === component.locale && component.showOnIndex">
{{ componentName(component) }}: {{ component.value }}
<span style="margin-right: 5px;">{{ componentName(component) }}:</span>
<component
:key="index"
:class="{'remove-bottom-border ': (index + 1) % field.originalFieldsCount !== 0}"
:is="resolveComponentName(component)"
:resource-name="resourceName"
:resource-id="resourceId"
:resource="resource"
:field="fieldDefaultValue(component)"
:errors="errors"
:via-resource="viaResource"
:via-resource-id="viaResourceId"
:via-relationship="viaRelationship"
/>
</div>
</div>
</div>
Expand All @@ -20,6 +33,16 @@ import IndexMixin from '../mixins/index'
export default {
mixins: [IndexMixin],
props: ['resourceName', 'field'],
props: ['field', 'resourceId', 'resourceName', 'errors', 'viaResource', 'viaRelationship', 'viaResourceId'],
methods:{
fieldDefaultValue(field) {
if (field.value === '' && field.defaultValue !== '') field.value = field.defaultValue;
return field;
},
resolveComponentName(field) {
return field.prefixComponent ? 'index-' + field.component : field.component
},
}
}
</script>
68 changes: 65 additions & 3 deletions resources/js/field.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,67 @@
import {Errors} from "laravel-nova";

Nova.booting((Vue, router, store) => {
Vue.component('index-nova-tab-translatable', require('./components/IndexField'))
Vue.component('detail-nova-tab-translatable', require('./components/DetailField'))
Vue.component('form-nova-tab-translatable', require('./components/FormField'))
Vue.component('index-nova-tab-translatable', require('./components/IndexField'))
Vue.component('detail-nova-tab-translatable', require('./components/DetailField'))
Vue.component('form-nova-tab-translatable', require('./components/FormField'))

const BaseFormFileField = Vue.options.components["form-file-field"];
const CustomFormFileField = BaseFormFileField.extend({
methods: {
async removeFile() {
this.uploadErrors = new Errors()

const {
resourceName,
resourceId,
relatedResourceName,
relatedResourceId,
viaRelationship,
} = this
const attribute = this.field.attribute



const uri =
this.viaRelationship &&
this.relatedResourceName &&
this.relatedResourceId
? `/nova-api/kongulov/nova-tab-translatable/${resourceName}/${resourceId}/${relatedResourceName}/${relatedResourceId}/field/${attribute}?viaRelationship=${viaRelationship}`
: `/nova-api/kongulov/nova-tab-translatable/${resourceName}/${resourceId}/field/${attribute}`

try {
await Nova.request().delete(uri)
this.closeRemoveModal()
this.deleted = true
this.$emit('file-deleted')
Nova.success(this.__('The file was deleted!'))
} catch (error) {
this.closeRemoveModal()

if (error.response.status == 422) {
this.uploadErrors = new Errors(error.response.data.errors)
}
}
},
}
})
Vue.component('form-file-field', CustomFormFileField)

const BaseDetailFileField = Vue.options.components["detail-file-field"];
const CustomDetailFileField = BaseDetailFileField.extend({
methods: {
download() {
const { resourceName, resourceId } = this
const attribute = this.field.attribute

let link = document.createElement('a')
link.href = `/nova-api/kongulov/nova-tab-translatable/${resourceName}/${resourceId}/download/${attribute}`
link.download = 'download'
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
},
}
})
Vue.component('detail-file-field', CustomDetailFileField)
})
8 changes: 8 additions & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

use Illuminate\Support\Facades\Route;

// Fields...
Route::get('/{resource}/{resourceId}/download/{field}', 'FieldDownloadController@show');
Route::delete('/{resource}/{resourceId}/field/{field}', 'FieldDestroyController@handle');
Route::delete('/{resource}/{resourceId}/{relatedResource}/{relatedResourceId}/field/{field}', 'PivotFieldDestroyController@handle');
20 changes: 20 additions & 0 deletions src/FieldServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Kongulov\NovaTabTranslatable;

use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
use Kongulov\NovaTabTranslatable\Http\Middleware\Authorize;
use Laravel\Nova\Events\ServingNova;
use Laravel\Nova\Nova;

Expand All @@ -20,11 +22,29 @@ public function boot()
Nova::style('nova-tab-translatable', __DIR__.'/../dist/css/field.css');
});

$this->app->booted(function () {
$this->routes();
});

$this->publishes([
__DIR__ . '/../config/tab-translatable.php' => config_path('tab-translatable.php'),
], 'tab-translatable-config');
}

protected function routes()
{
if ($this->app->routesAreCached()) {
return;
}



Route::middleware(['nova'])
->prefix('nova-api/kongulov/nova-tab-translatable')
->namespace('Kongulov\NovaTabTranslatable\Http\Controllers')
->group(__DIR__.'/../routes/api.php');
}

/**
* Register any application services.
*
Expand Down
37 changes: 37 additions & 0 deletions src/Http/Controllers/FieldDestroyController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Kongulov\NovaTabTranslatable\Http\Controllers;

use Illuminate\Routing\Controller;
use Laravel\Nova\Http\Requests\NovaRequest;

class FieldDestroyController extends Controller
{
/**
* Delete the file at the given field.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return \Illuminate\Http\Response
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public function handle(NovaRequest $request): \Illuminate\Http\Response
{
$resource = $request->findResourceOrFail();

$explode = explode('_', $request->field);
$locale = last($explode);
$fieldNameArray = array_slice($explode, 1, -1);
$fieldName = implode('_', $fieldNameArray);

if (!in_array($fieldName, $resource->translatable)) abort(404);

$resource->authorizeToUpdate($request);
$model = $resource->model();

$model->forgetTranslation($fieldName, $locale);
$model->timestamps = false;
$model->save();

return response(['success' => true]);
}
}
58 changes: 58 additions & 0 deletions src/Http/Controllers/FieldDownloadController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

namespace Kongulov\NovaTabTranslatable\Http\Controllers;

use Illuminate\Http\Response;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Storage;
use Kongulov\NovaTabTranslatable\NovaTabTranslatable;
use Laravel\Nova\Http\Requests\NovaRequest;
use Symfony\Component\HttpFoundation\BinaryFileResponse;

class FieldDownloadController extends Controller
{
/**
* Download the given field's contents.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return BinaryFileResponse
* @throws \Illuminate\Auth\Access\AuthorizationException
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function show(NovaRequest $request)
{
$resource = $request->findResourceOrFail();

$explode = explode('_', $request->field);
$locale = last($explode);
$fieldNameArray = array_slice($explode, 1, -1);
$fieldName = implode('_', $fieldNameArray);

if (!in_array($fieldName, $resource->translatable)) abort(404);

$resource->authorizeToView($request);
$model = $resource->model();
$value = $model->getTranslation($fieldName, $locale);

$tabs = $resource->updateFields($request)->whereInstanceOf(NovaTabTranslatable::class);

$field = false;

foreach ($tabs as $tab) {
$field = collect($tab->data)->first(function($field) use ($request){
return isset($field->attribute) &&
$field->attribute == $request->field;
});
}

if (!$field) abort(404);

$disk = $field->getStorageDisk();

if (!Storage::disk($disk)->exists($value)) abort(404);

$path = Storage::disk($disk)->get($value);

return response()->download($path);
}
}
33 changes: 33 additions & 0 deletions src/Http/Controllers/PivotFieldDestroyController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace Kongulov\NovaTabTranslatable\Http\Controllers;

use Illuminate\Routing\Controller;
use Laravel\Nova\DeleteField;
use Laravel\Nova\Http\Requests\PivotFieldDestroyRequest;
use Laravel\Nova\Nova;

class PivotFieldDestroyController extends Controller
{
/**
* Delete the file at the given field.
*
* @param \Laravel\Nova\Http\Requests\PivotFieldDestroyRequest $request
* @return \Illuminate\Http\Response
*/
public function handle(PivotFieldDestroyRequest $request)
{
abort(404);

$request->authorizeForAttachment();

DeleteField::forRequest(
$request, $request->findFieldOrFail(),
$pivot = $request->findPivotModel()
)->save();

Nova::actionEvent()->forAttachedResourceUpdate(
$request, $request->findModelOrFail(), $pivot
)->save();
}
}
38 changes: 33 additions & 5 deletions src/NovaTabTranslatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
use Epartment\NovaDependencyContainer\NovaDependencyContainer;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Laravel\Nova\Fields\Field;
use Laravel\Nova\Fields\Image;
use Laravel\Nova\Fields\Slug;
use Laravel\Nova\Http\Requests\NovaRequest;

Expand Down Expand Up @@ -120,13 +122,39 @@ protected function createTranslatedField(Field $originalField, string $locale):
return $model->translations[$originalAttribute][$locale] ?? '';
});

$translatedField->fillUsing(function ($request, $model, $attribute, $requestAttribute) use ($locale, $originalAttribute,$translatedField) {
$savedData = $request->get($requestAttribute);
if ($originalField instanceof Image){
$translatedField
->store(function ($request, $model, $attribute, $requestAttribute) use ($locale, $originalAttribute, $translatedField) {
$file = $request->file($requestAttribute)->store($translatedField->getStorageDir(), $translatedField->getStorageDisk());

if ($this->isJson($savedData)) $savedData = json_decode($savedData,true);
$model->setTranslation($originalAttribute, $locale, $file);

$model->setTranslation($originalAttribute, $locale, $savedData);
});
return true;
})
->thumbnail(function($value) use ($translatedField){
$disk = $translatedField->getStorageDisk();

if (!Storage::disk($disk)->exists($value)) return false;

return Storage::disk($disk)->url($value);
})
->preview(function($value) use ($translatedField){
$disk = $translatedField->getStorageDisk();

if (!Storage::disk($disk)->exists($value)) return false;

return Storage::disk($disk)->url($value);
});
}
else{
$translatedField->fillUsing(function ($request, $model, $attribute, $requestAttribute) use ($locale, $originalAttribute,$translatedField) {
$savedData = $request->get($requestAttribute);

if ($this->isJson($savedData)) $savedData = json_decode($savedData,true);

$model->setTranslation($originalAttribute, $locale, $savedData);
});
}

$translatedField = $this->compatibilityWithOtherPlugins($translatedField);

Expand Down

0 comments on commit f163f17

Please sign in to comment.