first upload all files

This commit is contained in:
NW
2023-06-11 13:14:03 +01:00
parent f14dbc52b5
commit c08b36d1b6
1705 changed files with 106852 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
export default class {
constructor() {
this.attributeId = 0;
this.valuesCount = 0;
this.addOldValues(FleetCart.data['attribute.values']);
if (this.valuesCount === 0) {
this.addAttributeValue();
}
this.eventListeners();
this.sortable();
window.admin.removeSubmitButtonOffsetOn('#values');
}
addOldValues(values = {}) {
for (let value of values) {
this.addAttributeValue(value);
}
}
addAttributeValue(value = { id: '', value: '' }) {
let template = _.template($('#attribute-value-template').html());
let html = template({ valueId: this.valuesCount++, value });
$('#attribute-values').append(html);
window.admin.tooltip();
}
eventListeners() {
$('#add-new-value').on('click', () => this.addAttributeValue());
$('#attribute-values').on('click', '.delete-row', (e) => {
$(e.currentTarget).closest('tr').remove();
});
}
sortable() {
Sortable.create(document.getElementById('attribute-values'), {
handle: '.drag-icon',
animation: 150,
});
}
}

View File

@@ -0,0 +1,92 @@
export default class {
constructor() {
this.attributeCount = 0;
this.addProductAttributes(FleetCart.data['product.attributes']);
if (this.attributeCount === 0) {
this.addProductAttribute();
}
this.addProductAttributesErrors(FleetCart.errors['product.attributes']);
this.eventListeners();
this.triggerSelected();
this.sortable();
}
addProductAttributes(attributes) {
for (let attribute of attributes) {
this.addProductAttribute(attribute);
}
}
addProductAttribute(attribute = {}) {
let template = _.template($('#product-attribute-template').html());
let html = template({ attributeId: this.attributeCount++, attribute });
$('#product-attributes').append(html);
window.admin.tooltip();
window.admin.selectize();
}
addProductAttributesErrors(errors) {
for (let key in errors) {
let id = $.escapeSelector(key);
let parent = $(`#${id}`).parent();
parent.addClass('has-error');
parent.append(`<span class="help-block">${errors[key][0]}</span>`);
}
}
deleteProductAttribute(e) {
$(e.currentTarget).closest('tr').remove();
}
changeProductAttributeValues(attributeEl, clearSelected = true) {
let values = $(attributeEl).find('option:selected').data('values');
let id = $.escapeSelector(`attributes.${attributeEl.dataset.attributeId}.values`);
let attributeValues = $(`#${id}`)[0].selectize;
if (clearSelected) {
attributeValues.clear();
}
attributeValues.clearOptions();
let options = attributeValues.options;
for (let id in values) {
attributeValues.addOption({ id, name: values[id] });
for (let i in options) {
attributeValues.addItem(options[i].value);
}
}
}
eventListeners() {
$('#add-new-attribute').on('click', () => this.addProductAttribute());
$('#product-attributes').on('click', '.delete-row', this.deleteProductAttribute);
$('#product-attributes-wrapper').on('change', '.attribute', (e) => {
this.changeProductAttributeValues(e.currentTarget);
});
}
triggerSelected() {
$('.attribute').has('option:selected').each((i, el) => {
this.changeProductAttributeValues(el, false);
});
}
sortable() {
Sortable.create(document.getElementById('product-attributes'), {
handle: '.drag-icon',
animation: 150,
});
}
}

View File

@@ -0,0 +1,10 @@
import AttributeValues from './AttributeValues';
import ProductAttributes from './ProductAttributes';
if ($('#attribute-values-wrapper').length !== 0) {
new AttributeValues();
}
if ($('#product-attributes-wrapper').length !== 0) {
new ProductAttributes();
}

View File

@@ -0,0 +1,90 @@
#product-attributes-wrapper,
#attribute-values-wrapper {
margin-bottom: 15px;
.table {
.form-group {
margin: 0;
}
thead th {
&:first-child {
width: 40px;
}
&:last-child {
width: 60px;
}
}
}
}
#product-attributes-wrapper {
.table-responsive {
overflow: visible;
}
.table {
> tbody > tr {
> td {
vertical-align: middle;
&:nth-child(2) {
width: 160px;
}
}
}
}
.options {
.drag-icon {
margin-top: 3px;
}
}
}
#attribute-values-wrapper {
.table {
> tbody > tr {
> td {
&:nth-child(2) {
min-width: 150px;
}
}
}
}
}
@media screen and (max-width: 767px) {
#product-attributes-wrapper {
.options {
.drag-icon {
margin-top: 0;
}
}
.table {
> tbody > tr {
border-top: 1px solid #e9e9e9;
> td {
&:nth-child(2),
&:nth-child(3),
&:nth-child(4) {
display: block;
border: none;
width: auto;
padding-left: 15px;
padding-right: 15px;
text-align: left;
vertical-align: initial;
}
&:nth-child(4) {
padding-bottom: 15px;
}
}
}
}
}
}

View File

@@ -0,0 +1,35 @@
<?php
return [
'attribute' => 'Attribute',
'attributes' => 'Attributes',
'table' => [
'name' => 'Name',
'attribute_set' => 'Attribute Set',
'filterable' => 'Filterable',
'yes' => 'Yes',
'no' => 'No',
],
'tabs' => [
'group' => [
'attribute_information' => 'Attribute Information',
],
'general' => 'General',
'values' => 'Values',
'product' => [
'attributes' => 'Attributes',
],
],
'form' => [
'use_this_attribute_for_filtering_products' => 'Use this attribute for filtering products',
'value' => 'Value',
'add_new_value' => 'Add New Value',
'delete_value' => 'Delete Value',
'product' => [
'attribute' => 'Attribute',
'values' => 'Values',
'add_new_attribute' => 'Add New Attribute',
'delete_attribute' => 'Delete Attribute',
],
],
];

View File

@@ -0,0 +1,15 @@
<?php
return [
'attribute_set' => 'Attribute Set',
'attribute_sets' => 'Attribute Sets',
'table' => [
'name' => 'Name',
],
'tabs' => [
'group' => [
'attribute_set_information' => 'Attribute Set Information',
],
'general' => 'General',
],
];

View File

@@ -0,0 +1,6 @@
<?php
return [
'attribute_value' => 'Attribute Value',
'attribute_values' => 'Attribute Values',
];

View File

@@ -0,0 +1,18 @@
<?php
return [
'attributes' => [
'attribute_set_id' => 'Attribute Set',
'name' => 'Name',
'categories' => 'Categories',
'slug' => 'URL',
'is_filterable' => 'Filterable',
],
'attribute_sets' => [
'name' => 'Name',
],
'product_attributes' => [
'attributes.*.attribute_id' => 'Attribute',
'attributes.*.values' => 'Values',
],
];

View File

@@ -0,0 +1,16 @@
<?php
return [
'attributes' => [
'index' => 'Index Attribute',
'create' => 'Create Attribute',
'edit' => 'Edit Attribute',
'destroy' => 'Delete Attribute',
],
'attribute_sets' => [
'index' => 'Index Attribute Set',
'create' => 'Create Attribute Set',
'edit' => 'Edit Attribute Set',
'destroy' => 'Delete Attribute Set',
],
];

View File

@@ -0,0 +1,6 @@
<?php
return [
'attribute_sets' => 'Attribute Sets',
'attributes' => 'Attributes',
];

View File

@@ -0,0 +1,18 @@
@extends('admin::layout')
@component('admin::components.page.header')
@slot('title', trans('admin::resource.create', ['resource' => trans('attribute::attribute_sets.attribute_set')]))
<li><a href="{{ route('admin.attribute_sets.index') }}">{{ trans('attribute::attribute_sets.attribute_sets') }}</a></li>
<li class="active">{{ trans('admin::resource.create', ['resource' => trans('attribute::attribute_sets.attribute_set')]) }}</li>
@endcomponent
@section('content')
<form method="POST" action="{{ route('admin.attribute_sets.store') }}" class="form-horizontal" id="attribute-set-create-form" novalidate>
{{ csrf_field() }}
{!! $tabs->render(compact('attributeSet')) !!}
</form>
@endsection
@include('attribute::admin.attributes.partials.shortcuts')

View File

@@ -0,0 +1,20 @@
@extends('admin::layout')
@component('admin::components.page.header')
@slot('title', trans('admin::resource.edit', ['resource' => trans('attribute::attribute_sets.attribute_set')]))
@slot('subtitle', $attributeSet->name)
<li><a href="{{ route('admin.attribute_sets.index') }}">{{ trans('attribute::attribute_sets.attribute_sets') }}</a></li>
<li class="active">{{ trans('admin::resource.edit', ['resource' => trans('attribute::attribute_sets.attribute_set')]) }}</li>
@endcomponent
@section('content')
<form method="POST" action="{{ route('admin.attribute_sets.update', $attributeSet) }}" class="form-horizontal" id="attribute-set-edit-form" novalidate>
{{ csrf_field() }}
{{ method_field('put') }}
{!! $tabs->render(compact('attributeSet')) !!}
</form>
@endsection
@include('attribute::admin.attributes.partials.shortcuts')

View File

@@ -0,0 +1,38 @@
@extends('admin::layout')
@component('admin::components.page.header')
@slot('title', trans('attribute::attribute_sets.attribute_sets'))
<li class="active">{{ trans('attribute::attribute_sets.attribute_sets') }}</li>
@endcomponent
@component('admin::components.page.index_table')
@slot('buttons', ['create'])
@slot('resource', 'attribute_sets')
@slot('name', trans('attribute::attribute_sets.attribute_set'))
@component('admin::components.table')
@slot('thead')
<tr>
@include('admin::partials.table.select_all')
<th>{{ trans('admin::admin.table.id') }}</th>
<th>{{ trans('attribute::attribute_sets.table.name') }}</th>
<th data-sort>{{ trans('admin::admin.table.created') }}</th>
</tr>
@endslot
@endcomponent
@endcomponent
@push('scripts')
<script>
new DataTable('#attribute_sets-table .table', {
columns: [
{ data: 'checkbox', orderable: false, searchable: false, width: '3%' },
{ data: 'id', width: '5%' },
{ data: 'name', name: 'translations.name', orderable: false, defaultContent: '' },
{ data: 'created', name: 'created_at', width: '30%' },
],
});
</script>
@endpush

View File

@@ -0,0 +1,14 @@
@push('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('admin::admin.shortcuts.back_to_index', ['name' => trans('attribute::attribute_sets.attribute_set')]) }}</dd>
</dl>
@endpush
@push('scripts')
<script>
keypressAction([
{ key: 'b', route: "{{ route('admin.attribute_sets.index') }}" }
]);
</script>
@endpush

View File

@@ -0,0 +1,5 @@
<div class="row">
<div class="col-md-8">
{{ Form::text('name', trans('attribute::attributes.attribute_sets.name'), $errors, $attributeSet, ['required' => true]) }}
</div>
</div>

View File

@@ -0,0 +1,18 @@
@extends('admin::layout')
@component('admin::components.page.header')
@slot('title', trans('admin::resource.create', ['resource' => trans('attribute::admin.attribute')]))
<li><a href="{{ route('admin.attributes.index') }}">{{ trans('attribute::admin.attributes') }}</a></li>
<li class="active">{{ trans('admin::resource.create', ['resource' => trans('attribute::admin.attribute')]) }}</li>
@endcomponent
@section('content')
<form method="POST" action="{{ route('admin.attributes.store') }}" class="form-horizontal" id="attribute-create-form" novalidate>
{{ csrf_field() }}
{!! $tabs->render(compact('attribute')) !!}
</form>
@endsection
@include('attribute::admin.attributes.partials.shortcuts')

View File

@@ -0,0 +1,20 @@
@extends('admin::layout')
@component('admin::components.page.header')
@slot('title', trans('admin::resource.edit', ['resource' => trans('attribute::admin.attribute')]))
@slot('subtitle', $attribute->name)
<li><a href="{{ route('admin.attributes.index') }}">{{ trans('attribute::admin.attributes') }}</a></li>
<li class="active">{{ trans('admin::resource.edit', ['resource' => trans('attribute::admin.attribute')]) }}</li>
@endcomponent
@section('content')
<form method="POST" action="{{ route('admin.attributes.update', $attribute) }}" class="form-horizontal" id="attribute-edit-form" novalidate>
{{ csrf_field() }}
{{ method_field('put') }}
{!! $tabs->render(compact('attribute')) !!}
</form>
@endsection
@include('attribute::admin.attributes.partials.shortcuts')

View File

@@ -0,0 +1,42 @@
@extends('admin::layout')
@component('admin::components.page.header')
@slot('title', trans('attribute::admin.attributes'))
<li class="active">{{ trans('attribute::admin.attributes') }}</li>
@endcomponent
@component('admin::components.page.index_table')
@slot('buttons', ['create'])
@slot('resource', 'attributes')
@slot('name', trans('attribute::admin.attribute'))
@component('admin::components.table')
@slot('thead')
<tr>
@include('admin::partials.table.select_all')
<th>{{ trans('admin::admin.table.id') }}</th>
<th>{{ trans('attribute::admin.table.name') }}</th>
<th>{{ trans('attribute::admin.table.attribute_set') }}</th>
<th>{{ trans('attribute::admin.table.filterable') }}</th>
<th data-sort>{{ trans('admin::admin.table.created') }}</th>
</tr>
@endslot
@endcomponent
@endcomponent
@push('scripts')
<script>
new DataTable('#attributes-table .table', {
columns: [
{ data: 'checkbox', orderable: false, searchable: false, width: '3%' },
{ data: 'id', width: '5%' },
{ data: 'name', name: 'translations.name', orderable: false, defaultContent: '' },
{ data: 'attribute_set', name: 'attributeSet.name', searchable: false, orderable: false, defaultContent: '' },
{ data: 'is_filterable', name: 'is_filterable', searchable: false, orderable: false },
{ data: 'created', name: 'created_at' },
],
});
</script>
@endpush

View File

@@ -0,0 +1,14 @@
@push('shortcuts')
<dl class="dl-horizontal">
<dt><code>b</code></dt>
<dd>{{ trans('admin::admin.shortcuts.back_to_index', ['name' => trans('attribute::admin.attribute')]) }}</dd>
</dl>
@endpush
@push('scripts')
<script>
keypressAction([
{ key: 'b', route: "{{ route('admin.attributes.index') }}" }
]);
</script>
@endpush

View File

@@ -0,0 +1,13 @@
<div class="row">
<div class="col-md-8">
{{ Form::select('attribute_set_id', trans('attribute::attributes.attributes.attribute_set_id'), $errors, $attributeSets, $attribute, ['required' => true]) }}
{{ Form::text('name', trans('attribute::attributes.attributes.name'), $errors, $attribute, ['required' => true]) }}
{{ Form::select('categories', trans('attribute::attributes.attributes.categories'), $errors, $categories, $attribute, ['class' => 'selectize prevent-creation', 'multiple' => true]) }}
@if ($attribute->exists)
{{ Form::text('slug', trans('attribute::attributes.attributes.slug'), $errors, $attribute, ['required' => true]) }}
@endif
{{ Form::checkbox('is_filterable', trans('attribute::attributes.attributes.is_filterable'), trans('attribute::admin.form.use_this_attribute_for_filtering_products'), $errors, $attribute) }}
</div>
</div>

View File

@@ -0,0 +1,24 @@
<script type="text/html" id="attribute-value-template">
<tr>
<td class="text-center">
<span class="drag-icon">
<i class="fa">&#xf142;</i>
<i class="fa">&#xf142;</i>
</span>
</td>
<td>
<input type="hidden" name="values[<%- valueId %>][id]" value="<%- value.id %>">
<div class="form-group">
<input type="text" name="values[<%- valueId %>][value]" value="<%- value.value %>" class="form-control">
</div>
</td>
<td class="text-center">
<button type="button" class="btn btn-default delete-row" data-toggle="tooltip" data-title="{{ trans('attribute::admin.form.delete_value') }}">
<i class="fa fa-trash"></i>
</button>
</td>
</tr>
</script>

View File

@@ -0,0 +1,29 @@
<div id="attribute-values-wrapper">
<div class="table-responsive">
<table class="options table table-bordered">
<thead>
<tr>
<th></th>
<th>{{ trans('attribute::admin.form.value') }}</th>
<th></th>
</tr>
</thead>
<tbody id="attribute-values">
</tbody>
</table>
</div>
<button type="button" class="btn btn-default" id="add-new-value">
{{ trans('attribute::admin.form.add_new_value') }}
</button>
</div>
@include('attribute::admin.attributes.tabs.templates.attribute_value')
@push('globals')
<script>
FleetCart.data['attribute.values'] = {!! old_json('values', $attribute->values) !!};
</script>
@endpush

View File

@@ -0,0 +1,31 @@
<div id="product-attributes-wrapper">
<div class="table-responsive">
<table class="options table table-bordered">
<thead class="hidden-xs">
<tr>
<th></th>
<th>{{ trans('attribute::admin.form.product.attribute') }}</th>
<th>{{ trans('attribute::admin.form.product.values') }}</th>
<th></th>
</tr>
</thead>
<tbody id="product-attributes">
{{-- Product attributes will be added here dynamically using JS --}}
</tbody>
</table>
</div>
<button type="button" class="btn btn-default" id="add-new-attribute">
{{ trans('attribute::admin.form.product.add_new_attribute') }}
</button>
</div>
@include('attribute::admin.products.tabs.templates.attribute')
@push('globals')
<script>
FleetCart.data['product.attributes'] = @json($productAttributes);
FleetCart.errors['product.attributes'] = @json($errors->get('attributes.*'), JSON_FORCE_OBJECT);
</script>
@endpush

View File

@@ -0,0 +1,48 @@
<script type="text/html" id="product-attribute-template">
<tr>
<td class="text-center">
<span class="drag-icon">
<i class="fa">&#xf142;</i>
<i class="fa">&#xf142;</i>
</span>
</td>
<td>
<div class="form-group">
<label for="attributes.<%- attributeId %>.attribute_id" class="visible-xs">{{ trans('attribute::admin.form.product.attribute') }}</label>
<select name="attributes[<%- attributeId %>][attribute_id]" class="form-control attribute custom-select-black" id="attributes.<%- attributeId %>.attribute_id" data-attribute-id="<%- attributeId %>">
<option value="">{{ trans('admin::admin.form.please_select') }}</option>
@foreach ($attributeSets as $attributeSet)
<optgroup label="{{ $attributeSet->name }}">
@foreach ($attributeSet->attributes as $attribute)
<option value="{{ $attribute->id }}" data-values="{{ json_encode($attribute->values->pluck('value', 'id'), JSON_FORCE_OBJECT) }}" <%= (attribute.attribute_id || attribute.id) == {{ $attribute->id }} ? 'selected' : '' %>>
{{ $attribute->name }}
</option>
@endforeach
</optgroup>
@endforeach
</select>
</div>
</td>
<td>
<div class="form-group">
<label for="attributes.<%- attributeId %>.values" class="visible-xs">{{ trans('attribute::admin.form.product.values') }}</label>
<select name="attributes[<%- attributeId %>][values][]" class="form-control selectize prevent-creation" id="attributes.<%- attributeId %>.values" multiple>
<% _.each(attribute.values, function (value) { %>
<option value="<%- value.attribute_value_id || value.id %>" selected>
<%- value.value || value.attribute_value.value %>
</option>
<% }); %>
</select>
</div>
</td>
<td class="text-center">
<button type="button" class="btn btn-default delete-row" data-toggle="tooltip" data-title="{{ trans('attribute::admin.form.product.delete_attribute') }}">
<i class="fa fa-trash"></i>
</button>
</td>
</tr>
</script>