$this->addField('links', 'Hidden');
$this->addField('langs', 'Hidden');
- $this->addField('user', 'SelectFromModel', __('Utilisateur'), ['optionsmodel' => User::class, 'attribute' => 'companyWithName', 'column' => true,]);
+ $this->addField('user', 'SelectFromModel', __('Utilisateur'),
+ ['optionsmodel' => User::class,
+ 'attribute' => 'companyWithName',
+ 'column_attribute' => 'CompanyWithNameOnTwoLines',
+ 'column' => true,
+ 'can_write' => 'fluidbook-quote:admin',
+ ]);
$this->addField(['name' => 'created_at',
'label' => __('Date'),
'filter' => true,
'column' => true,
'column_type' => 'date',
- 'column_format' => null]);
+ 'column_format' => null,
+ 'can_write' => 'fluidbook-quote:admin']);
$this->addField('contact_type', 'SelectFromArray', __('Type de client'), ['options' => [
'agency' => __('Agence de communication'),
'other' => __('Autre'),
]]);
- $this->addField('message', 'Textarea', __('Message'));
+ $this->addField('message', 'Textarea', __('Message'), [
+ 'can_write' => 'fluidbook-quote:admin'
+ ]
+ );
$this->addField('gclid', 'Text', 'Google Adwords ID (gclid)', ['can' => 'fluidbook-quote:admin',]);
$this->addField('status', 'SelectFromArray', __('Status'), ['options' => [
0 => __('Non traitée'),
- 1 => __('En attente de traitement'),
+ 1 => __('En attente'),
2 => __('Traitée'),
- ], 'column' => true, 'filter' => true]);
+ ], 'column' => true, 'filter' => true, 'can_write' => 'fluidbook-quote:admin']);
$this->addField('conversion', 'SelectFromArray', __('Conversion'), ['options' => [
0 => __('Pas de réponse'),
2 => __('Devis refusé'),
3 => __('Projet validé'),
4 => __('Déjà client'),
- ], 'column' => true, 'can' => 'fluidbook-quote:admin', 'filter' => true]);
+ ], 'column' => true, 'filter' => true]);
$this->addField('origin_column', FluidbookQuoteOrigin::class, __('Origine'), ['column' => true, 'filter' => true]);
$this->addField('fluidbooks', 'ModelAttribute', __('Fluidbooks'), ['column' => true, 'column_label' => '<img width="20" src="/images/icons/icon-fluidbook.svg">', 'attribute' => 'user.e1_ws_count']);
--- /dev/null
+<!-- DATA TABLES SCRIPT -->
+<script type="text/javascript" src="{{ asset('packages/datatables.net/js/jquery.dataTables.min.js') }}"></script>
+<script type="text/javascript"
+ src="{{ asset('packages/datatables.net-bs4/js/dataTables.bootstrap4.min.js') }}"></script>
+<script type="text/javascript"
+ src="{{ asset('packages/datatables.net-responsive/js/dataTables.responsive.min.js') }}"></script>
+<script type="text/javascript"
+ src="{{ asset('packages/datatables.net-responsive-bs4/js/responsive.bootstrap4.min.js') }}"></script>
+<script type="text/javascript"
+ src="{{ asset('packages/datatables.net-fixedheader/js/dataTables.fixedHeader.min.js') }}"></script>
+<script type="text/javascript"
+ src="{{ asset('packages/datatables.net-fixedheader-bs4/js/fixedHeader.bootstrap4.min.js') }}"></script>
+
+<script>
+ @if ($crud->getPersistentTable())
+
+ var saved_list_url = localStorage.getItem('{{ Str::slug($crud->getRoute()) }}_list_url');
+
+ //check if saved url has any parameter or is empty after clearing filters.
+
+ if (saved_list_url && saved_list_url.indexOf('?') < 1) {
+ var saved_list_url = false;
+ } else {
+ var persistentUrl = saved_list_url + '&persistent-table=true';
+ }
+
+ var arr = window.location.href.split('?');
+ //check if url has parameters.
+ if (arr.length > 1 && arr[1] !== '') {
+ // IT HAS! Check if it is our own persistence redirect.
+ if (window.location.search.indexOf('persistent-table=true') < 1) {
+ // IF NOT: we don't want to redirect the user.
+ saved_list_url = false;
+ }
+ }
+
+ @if($crud->getPersistentTableDuration())
+ var saved_list_url_time = localStorage.getItem('{{ Str::slug($crud->getRoute()) }}_list_url_time');
+
+ if (saved_list_url_time) {
+ var $current_date = new Date();
+ var $saved_time = new Date(parseInt(saved_list_url_time));
+ $saved_time.setMinutes($saved_time.getMinutes() + {{$crud->getPersistentTableDuration()}});
+
+ //if the save time is not expired we force the filter redirection.
+ if ($saved_time > $current_date) {
+ if (saved_list_url && persistentUrl != window.location.href) {
+ window.location.href = persistentUrl;
+ }
+ } else {
+ //persistent table expired, let's not redirect the user
+ saved_list_url = false;
+ }
+ }
+
+ @endif
+ if (saved_list_url && persistentUrl != window.location.href) {
+ window.location.href = persistentUrl;
+ }
+ @endif
+
+ var crud = {
+ exportButtons: JSON.parse('{!! json_encode($crud->get('list.export_buttons')) !!}'),
+ functionsToRunOnDataTablesDrawEvent: [],
+ addFunctionToDataTablesDrawEventQueue: function (functionName) {
+ if (this.functionsToRunOnDataTablesDrawEvent.indexOf(functionName) == -1) {
+ this.functionsToRunOnDataTablesDrawEvent.push(functionName);
+ }
+ },
+ responsiveToggle: function (dt) {
+ $(dt.table().header()).find('th').toggleClass('all');
+ dt.responsive.rebuild();
+ dt.responsive.recalc();
+ },
+ executeFunctionByName: function (str, args) {
+ var arr = str.split('.');
+ var fn = window[arr[0]];
+
+ for (var i = 1; i < arr.length; i++) {
+ fn = fn[arr[i]];
+ }
+ fn.apply(window, args);
+ },
+ updateUrl: function (new_url) {
+ url_start = "{{ url($crud->route) }}";
+ url_end = new_url.replace(url_start, '');
+ url_end = url_end.replace('/search', '');
+ new_url = url_start + url_end;
+
+ window.history.pushState({}, '', new_url);
+ localStorage.setItem('{{ Str::slug($crud->getRoute()) }}_list_url', new_url);
+ },
+ dataTableConfiguration: {
+
+ @if ($crud->getResponsiveTable())
+ responsive: {
+ details: {
+ display: $.fn.dataTable.Responsive.display.modal({
+ header: function (row) {
+ // show the content of the first column
+ // as the modal header
+ // var data = row.data();
+ // return data[0];
+ return '';
+ }
+ }),
+ renderer: function (api, rowIdx, columns) {
+
+ var data = $.map(columns, function (col, i) {
+ var columnHeading = crud.table.columns().header()[col.columnIndex];
+
+ // hide columns that have VisibleInModal false
+ if ($(columnHeading).attr('data-visible-in-modal') == 'false') {
+ return '';
+ }
+
+ return '<tr data-dt-row="' + col.rowIndex + '" data-dt-column="' + col.columnIndex + '">' +
+ '<td style="vertical-align:top; border:none;"><strong>' + col.title.trim() + ':' + '<strong></td> ' +
+ '<td style="padding-left:10px;padding-bottom:10px; border:none;">' + col.data + '</td>' +
+ '</tr>';
+ }).join('');
+
+ return data ?
+ $('<table class="table table-striped mb-0">').append('<tbody>' + data + '</tbody>') :
+ false;
+ },
+ }
+ },
+ fixedHeader: false,
+ @else
+ responsive: false,
+ scrollX: true,
+ @endif
+
+ @if ($crud->getPersistentTable())
+ stateSave: true,
+ /*
+ if developer forced field into table 'visibleInTable => true' we make sure when saving datatables state
+ that it reflects the developer decision.
+ */
+
+ stateSaveParams: function (settings, data) {
+
+ localStorage.setItem('{{ Str::slug($crud->getRoute()) }}_list_url_time', data.time);
+
+ data.columns.forEach(function (item, index) {
+ var columnHeading = crud.table.columns().header()[index];
+ if ($(columnHeading).attr('data-visible-in-table') == 'true') {
+ return item.visible = true;
+ }
+ });
+ },
+ @if($crud->getPersistentTableDuration())
+ stateLoadParams: function (settings, data) {
+ var $saved_time = new Date(data.time);
+ var $current_date = new Date();
+
+ $saved_time.setMinutes($saved_time.getMinutes() + {{$crud->getPersistentTableDuration()}});
+
+ //if the save time as expired we force datatabled to clear localStorage
+ if ($saved_time < $current_date) {
+ if (localStorage.getItem('{{ Str::slug($crud->getRoute())}}_list_url')) {
+ localStorage.removeItem('{{ Str::slug($crud->getRoute()) }}_list_url');
+ }
+ if (localStorage.getItem('{{ Str::slug($crud->getRoute())}}_list_url_time')) {
+ localStorage.removeItem('{{ Str::slug($crud->getRoute()) }}_list_url_time');
+ }
+ return false;
+ }
+ },
+ @endif
+ @endif
+ autoWidth: false,
+ pageLength: {{ $crud->getDefaultPageLength() }},
+ lengthMenu: @json($crud->getPageLengthMenu()),
+ /* Disable initial sort */
+ aaSorting: [],
+ language: {
+ "emptyTable": "{{ trans('backpack::crud.emptyTable') }}",
+ "info": "{{ trans('backpack::crud.info') }}",
+ "infoEmpty": "{{ trans('backpack::crud.infoEmpty') }}",
+ "infoFiltered": "{{ trans('backpack::crud.infoFiltered') }}",
+ "infoPostFix": "{{ trans('backpack::crud.infoPostFix') }}",
+ "thousands": "{{ trans('backpack::crud.thousands') }}",
+ "lengthMenu": "{{ trans('backpack::crud.lengthMenu') }}",
+ "loadingRecords": "{{ trans('backpack::crud.loadingRecords') }}",
+ "processing": "<img src='{{ asset('packages/backpack/crud/img/ajax-loader.gif') }}' alt='{{ trans('backpack::crud.processing') }}'>",
+ "search": "_INPUT_",
+ "searchPlaceholder": "{{ trans('backpack::crud.search') }}...",
+ "zeroRecords": "{{ trans('backpack::crud.zeroRecords') }}",
+ "paginate": {
+ "first": "{{ trans('backpack::crud.paginate.first') }}",
+ "last": "{{ trans('backpack::crud.paginate.last') }}",
+ "next": ">",
+ "previous": "<"
+ },
+ "aria": {
+ "sortAscending": "{{ trans('backpack::crud.aria.sortAscending') }}",
+ "sortDescending": "{{ trans('backpack::crud.aria.sortDescending') }}"
+ },
+ "buttons": {
+ "copy": "{{ trans('backpack::crud.export.copy') }}",
+ "excel": "{{ trans('backpack::crud.export.excel') }}",
+ "csv": "{{ trans('backpack::crud.export.csv') }}",
+ "pdf": "{{ trans('backpack::crud.export.pdf') }}",
+ "print": "{{ trans('backpack::crud.export.print') }}",
+ "colvis": "{{ trans('backpack::crud.export.column_visibility') }}"
+ },
+ },
+ processing: true,
+ serverSide: true,
+ searching: @json($crud->getOperationSetting('searchableTable') ?? true),
+ ajax: {
+ "url": "{!! url($crud->route.'/search').'?'.Request::getQueryString() !!}",
+ "type": "POST"
+ },
+ dom:
+ "<'row hidden'<'col-sm-6'i><'col-sm-6 d-print-none'f>>" +
+ "<'row'<'col-sm-12'tr>>" +
+ "<'row mt-2 d-print-none '<'col-sm-12 col-md-4'l><'col-sm-0 col-md-4 text-center'B><'col-sm-12 col-md-4 'p>>",
+ }
+ }
+</script>
+
+@include('crud::inc.export_buttons')
+
+<script type="text/javascript">
+ jQuery(document).ready(function ($) {
+
+ crud.table = $("#crudTable").DataTable(crud.dataTableConfiguration);
+
+ // move search bar
+ $("#crudTable_filter").appendTo($('#datatable_search_stack'));
+ $("#crudTable_filter input").removeClass('form-control-sm');
+
+ // move "showing x out of y" info to header
+ $("#datatable_info_stack").html($('#crudTable_info')).css('display', 'inline-flex').addClass('animated fadeIn');
+
+ @if($crud->getOperationSetting('resetButton') ?? true)
+ // create the reset button
+ var crudTableResetButton = '<a href="{{url($crud->route)}}" class="ml-1" id="crudTable_reset_button">{{ trans('backpack::crud.reset') }}</a>';
+
+ $('#datatable_info_stack').append(crudTableResetButton);
+
+ // when clicking in reset button we clear the localStorage for datatables.
+ $('#crudTable_reset_button').on('click', function () {
+
+ //clear the filters
+ if (localStorage.getItem('{{ Str::slug($crud->getRoute())}}_list_url')) {
+ localStorage.removeItem('{{ Str::slug($crud->getRoute()) }}_list_url');
+ }
+ if (localStorage.getItem('{{ Str::slug($crud->getRoute())}}_list_url_time')) {
+ localStorage.removeItem('{{ Str::slug($crud->getRoute()) }}_list_url_time');
+ }
+
+ //clear the table sorting/ordering/visibility
+ if (localStorage.getItem('DataTables_crudTable_/{{ $crud->getRoute() }}')) {
+ localStorage.removeItem('DataTables_crudTable_/{{ $crud->getRoute() }}');
+ }
+ });
+ @endif
+
+ // move the bottom buttons before pagination
+ $("#bottom_buttons").insertBefore($('#crudTable_wrapper .row:last-child'));
+
+ // override ajax error message
+ $.fn.dataTable.ext.errMode = 'none';
+ $('#crudTable').on('error.dt', function (e, settings, techNote, message) {
+ new Noty({
+ type: "error",
+ text: "<strong>{{ trans('backpack::crud.ajax_error_title') }}</strong><br>{{ trans('backpack::crud.ajax_error_text') }}"
+ }).show();
+ });
+
+ // make sure AJAX requests include XSRF token
+ $.ajaxPrefilter(function (options, originalOptions, xhr) {
+ var token = $('meta[name="csrf_token"]').attr('content');
+
+ if (token) {
+ return xhr.setRequestHeader('X-XSRF-TOKEN', token);
+ }
+ });
+
+ // on DataTable draw event run all functions in the queue
+ // (eg. delete and details_row buttons add functions to this queue)
+ $('#crudTable').on('draw.dt', function () {
+ crud.functionsToRunOnDataTablesDrawEvent.forEach(function (functionName) {
+ crud.executeFunctionByName(functionName);
+ });
+ }).dataTable();
+
+ // when datatables-colvis (column visibility) is toggled
+ // rebuild the datatable using the datatable-responsive plugin
+ $('#crudTable').on('column-visibility.dt', function (event) {
+ crud.table.responsive.rebuild();
+ }).dataTable();
+
+ @if ($crud->getResponsiveTable())
+ // when columns are hidden by reponsive plugin,
+ // the table should have the has-hidden-columns class
+ crud.table.on('responsive-resize', function (e, datatable, columns) {
+ if (crud.table.responsive.hasHidden()) {
+ $("#crudTable").addClass('has-hidden-columns');
+ crud.table.responsive.recalc();
+ }
+ });
+ @else
+ // make sure the column headings have the same width as the actual columns
+ // after the user manually resizes the window
+ var resizeTimer;
+
+ function resizeCrudTableColumnWidths() {
+ clearTimeout(resizeTimer);
+ resizeTimer = setTimeout(function () {
+ // Run code here, resizing has "stopped"
+ crud.table.columns.adjust();
+ }, 250);
+ }
+
+ $(window).on('resize', function (e) {
+ resizeCrudTableColumnWidths();
+ });
+ $('.sidebar-toggler').click(function () {
+ resizeCrudTableColumnWidths();
+ });
+ @endif
+
+ });
+</script>
+
+@include('crud::inc.details_row_logic')
--- /dev/null
+@extends(backpack_view('blank'))
+
+@php
+ $defaultBreadcrumbs = [
+ trans('backpack::crud.admin') => url(config('backpack.base.route_prefix'), 'dashboard'),
+ $crud->entity_name_plural => url($crud->route),
+ trans('backpack::crud.list') => false,
+ ];
+
+ // if breadcrumbs aren't defined in the CrudController, use the default breadcrumbs
+ $breadcrumbs = $breadcrumbs ?? $defaultBreadcrumbs;
+@endphp
+
+@section('header')
+ <div class="container-fluid">
+ <h2>
+ <span class="text-capitalize">{!! $crud->getHeading() ?? $crud->entity_name_plural !!}</span>
+ <small id="datatable_info_stack">{!! $crud->getSubheading() ?? '' !!}</small>
+ </h2>
+ </div>
+@endsection
+
+@section('content')
+ <!-- Default box -->
+ <div class="row">
+
+ <!-- THE ACTUAL CONTENT -->
+ <div class="{{ $crud->getListContentClass() }}">
+
+ <div class="row mb-0">
+ <div class="col-sm-6">
+ @if ( $crud->buttons()->where('stack', 'top')->count() || $crud->exportButtons())
+ <div class="d-print-none {{ $crud->hasAccess('create')?'with-border':'' }}">
+
+ @include('crud::inc.button_stack', ['stack' => 'top'])
+
+ </div>
+ @endif
+ </div>
+ <div class="col-sm-6">
+ <div id="datatable_search_stack" class="mt-sm-0 mt-2 d-print-none"></div>
+ </div>
+ </div>
+
+ {{-- Backpack List Filters --}}
+ @if ($crud->filtersEnabled())
+ @include('crud::inc.filters_navbar')
+ @endif
+
+ <table id="crudTable"
+ class="bg-white table table-striped table-hover nowrap rounded shadow-xs border-xs mt-2"
+ cellspacing="0">
+ <thead>
+ <tr>
+ {{-- Table columns --}}
+ @foreach ($crud->columns() as $column)
+ <th data-column-name="{{$column['name']}}"
+ data-column-type="{{$column['type']}}"
+ data-orderable="{{ var_export($column['orderable'], true) }}"
+ data-priority="{{ $column['priority'] }}"
+ {{--
+
+ data-visible-in-table => if developer forced field in table with 'visibleInTable => true'
+ data-visible => regular visibility of the field
+ data-can-be-visible-in-table => prevents the column to be loaded into the table (export-only)
+ data-visible-in-modal => if column apears on responsive modal
+ data-visible-in-export => if this field is exportable
+ data-force-export => force export even if field are hidden
+
+ --}}
+
+ {{-- If it is an export field only, we are done. --}}
+ @if(isset($column['exportOnlyField']) && $column['exportOnlyField'] === true)
+ data-visible="false"
+ data-visible-in-table="false"
+ data-can-be-visible-in-table="false"
+ data-visible-in-modal="false"
+ data-visible-in-export="true"
+ data-force-export="true"
+ @else
+ data-visible-in-table="{{var_export($column['visibleInTable'] ?? false)}}"
+ data-visible="{{var_export($column['visibleInTable'] ?? true)}}"
+ data-can-be-visible-in-table="true"
+ data-visible-in-modal="{{var_export($column['visibleInModal'] ?? true)}}"
+ @if(isset($column['visibleInExport']))
+ @if($column['visibleInExport'] === false)
+ data-visible-in-export="false"
+ data-force-export="false"
+ @else
+ data-visible-in-export="true"
+ data-force-export="true"
+ @endif
+ @else
+ data-visible-in-export="true"
+ data-force-export="false"
+ @endif
+ @endif
+ >
+ {!! $column['label'] !!}
+ </th>
+ @endforeach
+
+ @if ( $crud->buttons()->where('stack', 'line')->count() )
+ <th data-column-type="actions"
+ data-orderable="false"
+ data-priority="{{ $crud->getActionsColumnPriority() }}"
+ data-visible-in-export="false"
+ >{{ trans('backpack::crud.actions') }}</th>
+ @endif
+ </tr>
+ </thead>
+ <tbody>
+ </tbody>
+ <tfoot>
+ <tr>
+ {{-- Table columns --}}
+ @foreach ($crud->columns() as $column)
+ <th>{!! $column['label'] !!}</th>
+ @endforeach
+
+ @if ( $crud->buttons()->where('stack', 'line')->count() )
+ <th>{{ trans('backpack::crud.actions') }}</th>
+ @endif
+ </tr>
+ </tfoot>
+ </table>
+
+ @if ( $crud->buttons()->where('stack', 'bottom')->count() )
+ <div id="bottom_buttons" class="d-print-none text-center text-sm-left">
+ @include('crud::inc.button_stack', ['stack' => 'bottom'])
+
+ <div id="datatable_button_stack" class="float-right text-right hidden-xs"></div>
+ </div>
+ @endif
+
+ </div>
+
+ </div>
+
+@endsection
+
+@section('after_styles')
+ <!-- DATA TABLES -->
+ <link rel="stylesheet" type="text/css"
+ href="{{ asset('packages/datatables.net-bs4/css/dataTables.bootstrap4.min.css') }}">
+ <link rel="stylesheet" type="text/css"
+ href="{{ asset('packages/datatables.net-fixedheader-bs4/css/fixedHeader.bootstrap4.min.css') }}">
+ <link rel="stylesheet" type="text/css"
+ href="{{ asset('packages/datatables.net-responsive-bs4/css/responsive.bootstrap4.min.css') }}">
+
+ <link rel="stylesheet"
+ href="{{ asset('packages/backpack/crud/css/crud.css').'?v='.config('backpack.base.cachebusting_string') }}">
+ <link rel="stylesheet"
+ href="{{ asset('packages/backpack/crud/css/form.css').'?v='.config('backpack.base.cachebusting_string') }}">
+ <link rel="stylesheet"
+ href="{{ asset('packages/backpack/crud/css/list.css').'?v='.config('backpack.base.cachebusting_string') }}">
+
+ <!-- CRUD LIST CONTENT - crud_list_styles stack -->
+ @stack('crud_list_styles')
+@endsection
+
+@section('after_scripts')
+ @include('crud::inc.datatables_logic')
+ <script
+ src="{{ asset('packages/backpack/crud/js/crud.js').'?v='.config('backpack.base.cachebusting_string') }}"></script>
+ <script
+ src="{{ asset('packages/backpack/crud/js/form.js').'?v='.config('backpack.base.cachebusting_string') }}"></script>
+ <script
+ src="{{ asset('packages/backpack/crud/js/list.js').'?v='.config('backpack.base.cachebusting_string') }}"></script>
+
+ <!-- CRUD LIST CONTENT - crud_list_scripts stack -->
+ @stack('crud_list_scripts')
+@endsection