Задать вопрос
  • Как правильно создать layout страницы с изменяемым состоянием?

    @iljaGolubev
    Не работаю с react, но есть проекты на inertia+vue. Думаю, общий подход от этого не изменится.

    Вы уже используете inertia state (`props.auth.user.name`) - можно использовать и для popup. Props реактивные. Добавьте нужные значения (textPopup,isVisiblePopup,typePopup) в shared-data.
    Изменяете значение на странице с кнопкой - в шаблоне отобразится popup.
    function showPopup можно вынести в отдельный файл и импортировать на нужных страницах. showPopup изменяет prop.popup.textPopup и прочие.

    Плюс подхода - можно с сервера сразу передать нужные значения в попап из контроллера.
    Ответ написан
    2 комментария
  • Как найти точный url сайта на javascript?

    @iljaGolubev
    Вариантов нет.
    Они появятся когда изменение любого (нужного) из "множество разделов и фильтров" будет менять url страницы. Параметры запросы или якорь.
    Ответ написан
    Комментировать
  • Vue is not a constructor возникло при переходе на VUE 3?

    @iljaGolubev
    https://vuejs.org/guide/quick-start.html#using-vue...

    И посмотрите что у вас в box.js
    Ответ написан
    Комментировать
  • Как правильно в Laravel объединить дату и время если они находятся в разных полях?

    @iljaGolubev
    use Illuminate\Database\Eloquent\Casts\Attribute;
    
    class Order extends Model{
    
        protected $casts = ['date_time' => 'datetime:Y-m-d H:00'];
    
        function dateTime(): Attribute
        {
             return Attribute::make(
                get: fn () => $this->castAttribute(
                      'date_time',
                      ($this->date ?: '1970-01-01') . ' ' . ($this->time ?: '10:00:01')
                   )
                )
            );
        }
    
    }

    # php artisan tinker
    App\Models\Order::first()->date_time;
    # = Illuminate\Support\Carbon @0 {#7053
    #   date: 1970-01-01 00:00:00.0 UTC (+00:00),
    #  }


    https://laravel.com/docs/10.x/eloquent-mutators#de...
    Ответ написан
    Комментировать
  • Как переместится на n-ную запись в большом xml при помощи XMLReader?

    @iljaGolubev
    В php XMLReader нет возможности перейти на произвольную строку. При каждом запуске чтение начинается с начала файла. Значит нужно читать последовательно до того продукта на котором закончилась прошлая обработка.
    //Псевдокод. не проверял.
    
    $lastProductIndex=100000;
    // сначала нужно дочитать до <products>
    // потом перебирать <product>
    while($xmlReader->next("product") && --$lastProductIndex) {
        // skip
    }
    if($lastProductIndex==0){
        // тут последний обработанный прошлый раз
    }else{
        // продуктов стало меньше? 
    }
    Ответ написан
  • Как сделать сортировку сначала по непрочитанным сообщениям а потом по дате?

    @iljaGolubev
    https://laravel.com/docs/10.x/queries#orderbyraw
    для postgres раб
    ->orderByRaw('CASE isread WHEN 0 THEN 0 ELSE 1 END, last_message_time DESC')


    Не ваш случай, но в MySql
    можно ещё и так
    (не могу найти ссылку на доку)
    если нужно отобрать сначала конкретные id
    ORDER BY FIELD(id, 100, 100500, 300), last_message_time
    Ответ написан
  • Как сделать фиксированную ширину таблицы datatables с одинаковой шириной колонок?

    @iljaGolubev
    Если речь об этих datatables , то в общем-то с помощью css и атрибутов html.
    Например, если в body кроме table больше ничего нет, то так:
    <table id="example" width="70%" style=" white-space: pre-wrap;">
        <thead>
            <tr><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th></tr>
        </thead>
        <!-- ... -->

    $('#example').DataTable( {
        autoWidth: false,
        columnDefs: [
            { targets: '_all', "width": "1%" }
        ]
    } );

    Если используете бутстрап - у таблицы не должно быть 'nowrap' css класса.
    Используйте style="overflow-wrap: anywhere;" eсли в датасете есть слишком_длинные_значения_которые_точно_не_влезут в конечную ширину колонки .
    Ответ написан
  • Почему не удается получить актуальное значение переменной из Pinia в компоненте?

    @iljaGolubev
    и так же имеется pinia такого вида:

    где там pinia? - у вас просто composeable.
    каждый раз когда вы вызываете const {search} useSearchStore () выполняется const search = ref(''). т.е. это новый search.
    А в первых двух компонентах вы это не заметили

    потому что @searchData = "updateSearchQuery" - обновляете свой отдельный инстанс search.
    И вообще неработающий код показали... или неполностью (search.searchQuery - что такое?)


    // вот pinia
    export const useSearchStore = defineStore('search', () => {
      const search= ref('')
     function updateSearch(v) {
        search.value=v
      }
    
      return { search, updateSearch }
    })
    Ответ написан
    Комментировать
  • Как лучше подключать svg иконки во vue js?

    @iljaGolubev
    Если точно нужны inline svg, то vue-svg-loader - он делает автоматически ваш 1-й вариант.

    Ещё есть vite-svg-loader - подключается как плагин к vite и удобен тем, что можно из vite.config менять как импортировать файл (url или raw).

    Можно написать свой компонент в который передавать имя иконки. Только не делайте свой 2-й вариант - его недостаток в том, что все иконки всегда загружаются в браузер даже если никогда не будут показаны.

    через "v-if/v-else-if" рендерить ту, которая равна "close".

    Если у вас всего 2-3 иконки - можно и так, но в общем случае - старайтесь не использовать длинные "портянки" if/else. Почти всегда можно обойтись без такого кода. (conponent is или defineAsyncComponent)
    Ответ написан
    Комментировать
  • Как отдельно сделать логирование в Laravel для отдельного пакета?

    @iljaGolubev
    В пакете можно держать свои конфиги в таком же точно виде как в приложении ларавель.
    Непонятно, для чего вам понадобился канал логера пакета в приложении (снаружи пакета) . Имхо, только пакет его должен использовать. Но если очень хочется, можно так:
    // пакет config/logging.php
    return [
          'channels' => [
            'my-packet-name-log-channel' => [
                'driver' => 'single',
                'path' => env('MY_P_N_LOG_PATH', storage_path('logs/my-packet-name.log')),
                'level' => env('LOG_LEVEL', 'debug'),
                'replace_placeholders' => true,
                'permission' => 0664
                // ...
            ],
        ],
    
    ];


    // сервис провайдер пакета
    public function register(): void
        {
            if (!($this->app instanceof CachesConfiguration && $this->app->configurationIsCached())) {
                $config = $this->app->make('config');
                $config->set('logging', array_merge_recursive(
                    require __DIR__ . '/../config/logging.php',
                    $config->get('logging', [])
                ));
            }
    
    }
    Ответ написан
    1 комментарий
  • Как делается такой эффект при скролле?

    @iljaGolubev
    если посмотреть в devtools network то видно кучу jpg и png.
    При прокрутке страницы нужно показывать нужное. Дальше пишите js управляющий логикой отображения.

    Можно через css background.
    Можно найти подходящую библиотеку (впрочем, сомневаюсь что именно такие существуют).
    Или использовать фреймворк: treejs, GSAP, konvajs. Последний, имхо, попроще будет для старта и ближе к решению на том сайте.
    Ответ написан
    Комментировать
  • Как разделить контент в блоке на две части?

    @iljaGolubev
    С трудом понял, что-же вам нужно, но, надеюсь, правильно:)
    Идея в том, чтобы рекурсивно перебирать все ноды спана, считать длину содержимого каждой ноды, и добавлять её в первую часть пока пока не превышен лимит количества. В начале итерации лимит - половина от всего текста спана.

    function aggregator (a, c, maxChars){
        if (a[0].textContent.length > maxChars) {
            a[1].appendChild(c)
        } else if (c.children?.length > 0) {
            const agg = spanParse(c, maxChars - a[0].textContent.length);
            a[0].appendChild(agg[0])
            if (agg[1]) {
                a[1].appendChild(agg[1])
            }
        } else {
            a[0].appendChild(c)
        }
        return a;
    }
    function spanParse(rootSpan, maxChars) {
        const aggregated = [document.createElement('span'), document.createElement('span')]
        return [...rootSpan.childNodes].reduce((a, c) => aggregator(a, c, maxChars), aggregated)
    }
    function split(elem) {
        const r = spanParse(elem, elem.textContent.length / 2)
        console.log(r[0].textContent.length, r[1].textContent.length)
    }
    
    split(document.getElementByTag('span'));


    С тем кодом который в вопросе работать будет если span с текстом есть на странице. Если с какой-то другой разметкой будут ошибки, то нужно докрутить логики в aggregator.
    Ответ написан
    Комментировать
  • Передать из родительского компонента в дочерний состояние?

    @iljaGolubev
    vue3 provide-inject а лучше через события
    vue2 state-management
    Ответ написан
    Комментировать
  • Как приостановить работу map до выполнения определённых условий пере return?

    @iljaGolubev
    Завернуть FileReader в Promise
    как-то так

    const readAsDataURL = (image) => {
      const fr= new FileReader();
      return new Promise((resolve, reject) => {
        fr.onerror = () => {  fr.abort();  reject(new Error( 'err msg' ));  };
    
        fr.onload = () => { resolve(fr.result); };
        fr.readAsDataURL(image)
      });
    };
    
    
    [...selectedImages].map( async (image, index) => {
       const data =  await readAsDataURL(image)
       return (<img src={data} alt="" key={`previewImage:${index}`} />
    })
    Ответ написан
  • Как запустить php скрипт в фоне?

    @iljaGolubev
    Как отдать ответ клиенту и продолжить выполнение долгого скрипта?

    или так.
    <?php
    ignore_user_abort(true);
    set_time_limit(0);
    ob_start();
    header('Connection: close'); 
    header('Content-Length: '.ob_get_length());
    // можно добавить http статус подходящий
    ob_end_flush();
    ob_flush();
    flush();
    // дальше запуск
    run_havy_task();


    оба варианта предполагают, что есть отдельный способ получения результатов выполнения запущенной задачи.

    UPD: после критики в комментариях, поясню.
    Предложенное мной решение - примитивный способ сказать web серверу вернуть клиенту ответ и после этого продолжить выполнение скрипта.
    При этом ресурсы ресурсы сервера не будут освобождены пока функция run_havy_task не закончит работу. Можно использовать fastcgi_finish_request - но она не на 100% гарантирует завершение процессов.
    Таким образом, если до этого вы не переживали о ресурсах выделенных на выполнение "тяжелого" скрипта, то можно продолжать и так - запихнуть всё тяжелое в внутрь run_havy_task.
    Но лучше будет "тяжелую" часть обрабатывать в отдельных процессах. Например, одним из способов из комментариев к вопросу или из другого ответа, ссылку на который я дал в начале своего.
    Ответ написан
  • Как правильно генерировать миниатюру изображения для Vue?

    @iljaGolubev
    Если предположить, что на самом деле Изображения хранятся на клиентской серверной стороне (Vue) (Laravel)., то становится более-менее понятно.

    Обычный подход такой:
    backend - (api) Laravel - методы для получения и сохранения данных.
    frontend - (vue) Nuxt - отображение данных api и взаимодействие с api.
    • Пользователь в браузере выбирает картинку для загрузки на сервер(средствами js её можно показать на странице до отправки (например)).
    • Пользователь жмёт кнопку "сохранить" и frontend отправляет картинку в api (например)
    • api сохраняет полученный файл
    • api делает из сохранённого превью (например)
    • api возвращает в браузер
      json {'img'=>full_image_url, 'tumb'=>tumb_image_url}

    • frontend показывает
      <img src=tumb_image_url @click=showImage(full_image_url)>


    ---
    Вариантов вывода несколько

    Обычно это реализуется с помощью css. Но можно генерировать несколько разных превью на сервере.

    "resizeImageGet", которая при первом вызове сжимает и обрезает изображение

    Можно и так сделать. Тогда в api будет 2 метода uploadUmage - просто сохраняет файл, и resizeImageGet - проверяет что есть превью, создаёт его если нет и отдаёт контент (картинку). Но тогда это уже не чисто api.
    Ответ написан
    5 комментариев
  • Откуда при рекурсии в консоли берутся B:1 и B:2?

    @iljaGolubev
    Если не нужно чтобы выводило B, добавьте return.
    if (counter != 0){
                    Operation(counter)
                    return
                }
    Ответ написан
    Комментировать
  • Как сортировать объект в алфавитном порядке в js?

    @iljaGolubev
    Вы не можете управлять порядком отображения свойств при переборе.
    В вашем объекте свойства указаны как число и js всегда будет перебирать такие свойства в порядке возрастания. Можно создать новый объект, но со строковыми именами свойств - тогда они будут в порядке добавления.
    var ordered = Object.entries({
      4889: "Скрипт ",   4914: "Ааа",   11994: "Сервис",   12344: "иииии",    12417: "Тестовая",  12432: "ТТТ ",   12446: "Ма"
    }).sort(
      (a,b)=>a[1]<b[1]?-1:a[1]>b[1]?1:0
    ).reduce(
      (a,c)=>{a[`'${c[0]}'`]=c[1]; return a},
      {}
    );
    Object.getOwnPropertyNames(ordered)
    // ["'4914'", "'12446'", "'11994'", "'4889'", "'12432'", "'12417'", "'12344'"]
    Ответ написан
  • Почему при прокрутке вниз прокручивается до конца страницы?

    @iljaGolubev
    Потому что scroll event появляется пока до конца не докрутит.
    handleScroll меняет this.start в сеттере которого вызывается vertulScroll() в которой меняется this.html.item[0].style.marginTop после чего срабатывает scroll event
    Ответ написан
    Комментировать