Skip to content

Commit c5616b4

Browse files
tabunaagoalofalife
andauthored
refs #113 Added search to docs
* добавление функционала по поиску * Changed detect `sections`, Changed UI --------- Co-authored-by: agoalofalife <[email protected]> Co-authored-by: tabuna <[email protected]>
1 parent 562efa6 commit c5616b4

19 files changed

+335
-70
lines changed

.env.example

+2
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,5 @@ QUIZ_STATUS=false
7171
TELEGRAM_BOT_TOKEN=
7272
TELEGRAM_CHAT_ID=
7373
TELEGRAM_CHANNEL_ID=
74+
75+
SCOUT_DRIVER=

app/Console/Commands/CompareDocument.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ protected function updateVersion(string $version): void
4242
{
4343
Docs::every($version)->each(function (Docs $docs) {
4444
try {
45-
$docs->update();
45+
dispatch(fn () => $docs->update());
4646
} catch (\Exception $exception) {
4747
// Log a warning if an error occurs during update
4848
$this->warn("Failed to update document: {$exception->getMessage()} {$exception->getFile()} {$exception->getLine()}");

app/Docs.php

+37-21
Original file line numberDiff line numberDiff line change
@@ -349,14 +349,13 @@ public function isOlderVersion()
349349
*/
350350
public function update()
351351
{
352-
353352
$this->getModel()->fill([
354353
'behind' => $this->fetchBehind(),
355354
'last_commit' => $this->fetchLastCommit(),
356355
'current_commit' => $this->variables('git'),
357356
])->save();
358357

359-
// $this->updateSections();
358+
$this->updateSections();
360359
}
361360

362361
/**
@@ -366,44 +365,61 @@ public function update()
366365
*/
367366
public function getSections(): Collection
368367
{
368+
$content = Str::of($this->content());
369+
369370
// Разбиваем HTML содержимое на разделы по заголовкам
370-
preg_match_all('/<h(\d)>(.+)<\/h\d>(.*)/sU', $this->content(), $matches, PREG_SET_ORDER);
371+
preg_match_all('/<h(\d)>(.+)<\/h\d>(.*)/sU', $content->toString(), $matches, PREG_SET_ORDER);
371372

372373
// Массив для хранения разделов
373374
$sections = collect();
374-
$prevEnd = 0;
375+
$titlePage = $this->title();
375376

376377
foreach ($matches as $index => $match) {
378+
$tag = $match[0];
379+
$level = (int) $match[1];
377380
$sectionTitle = $match[2];
378381

379-
// Получаем начальную и конечную позицию текущего заголовка в тексте
380-
$startPos = strpos($this->content(), $match[0], $prevEnd);
382+
if ($level === 1) {
383+
$titlePage = $sectionTitle;
384+
}
385+
386+
$sectionContent = $content->after($tag);
381387

382-
// Получаем текст между текущим и предыдущим заголовком
383-
if ($index > 0) {
384-
$prevMatch = $matches[$index - 1];
385-
$prevEnd = strpos($this->content(), $prevMatch[0]) + strlen($prevMatch[0]);
386-
$sectionContent = substr($this->content(), $prevEnd, $startPos - $prevEnd);
387-
} else {
388-
$sectionContent = substr($this->content(), 0, $startPos);
388+
// Если есть следующий заголовок - обрезаем контент до него
389+
if (isset($matches[$index + 1])) {
390+
$sectionContent = $sectionContent->before($matches[$index + 1][0]);
389391
}
390392

391393
$sections->push([
392-
'title' => $sectionTitle,
393-
'slug' => Str::of($sectionTitle)->slug()->toString(),
394-
'content' => $sectionContent,
395-
'file' => $this->file,
396-
'version' => $this->version,
397-
'id' => Str::uuid(),
394+
'title_page' => $titlePage,
395+
'title' => $sectionTitle,
396+
'slug' => Str::of($sectionTitle)->slug()->toString(),
397+
'content' => $sectionContent,
398+
'file' => $this->file,
399+
'version' => $this->version,
400+
'id' => Str::uuid(),
401+
'level' => $level,
402+
'created_at' => now(),
403+
'updated_at' => now(),
398404
]);
399405
}
400406

401407
return $sections;
402408
}
403409

410+
/**
411+
* @return void
412+
*/
404413
public function updateSections()
405414
{
406-
// DocumentationSection::where('file', $this->file)->where('version', $this->version)->delete();
407-
// DocumentationSection::insert($this->getSections()->toArray());
415+
if ($this->file === 'documentation.md') {
416+
return;
417+
}
418+
419+
DocumentationSection::where('file', $this->file)
420+
->where('version', $this->version)
421+
->delete();
422+
423+
DocumentationSection::insert($this->getSections()->toArray());
408424
}
409425
}

app/Http/Controllers/DocsController.php

+25
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use App\Docs;
66
use App\Models\Document;
7+
use App\Models\DocumentationSection;
8+
use Illuminate\Http\Request;
79

810
class DocsController extends Controller
911
{
@@ -58,4 +60,27 @@ public function status(string $version = Docs::DEFAULT_VERSION)
5860
'documents' => $documents,
5961
]);
6062
}
63+
64+
/**
65+
* @param string $version
66+
* @param \Illuminate\Http\Request $request
67+
*
68+
* @return \HotwiredLaravel\TurboLaravel\Http\MultiplePendingTurboStreamResponse|\HotwiredLaravel\TurboLaravel\Http\PendingTurboStreamResponse
69+
*/
70+
public function search(string $version, Request $request)
71+
{
72+
$searchOffers = [];
73+
74+
if ($request->filled('text')) {
75+
$searchOffers = DocumentationSection::search($request->text)
76+
->where('version', $version)
77+
->orderBy('level')
78+
->get()
79+
->take(6);
80+
}
81+
82+
return turbo_stream()->replace('found_candidates', view('docs._search_lines', [
83+
'searchOffer' => $searchOffers,
84+
]));
85+
}
6186
}

app/Models/DocumentationSection.php

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Casts\Attribute;
6+
use Illuminate\Database\Eloquent\Concerns\HasUuids;
7+
use Illuminate\Database\Eloquent\Factories\HasFactory;
8+
use Illuminate\Database\Eloquent\Model;
9+
use Laravel\Scout\Searchable;
10+
11+
class DocumentationSection extends Model
12+
{
13+
use HasFactory, HasUuids, Searchable;
14+
15+
/**
16+
* The attributes that are mass assignable.
17+
*
18+
* @var array
19+
*/
20+
protected $fillable = [
21+
'id',
22+
'title',
23+
'title_page',
24+
'slug',
25+
'version',
26+
'file',
27+
'content',
28+
'level',
29+
];
30+
31+
/**
32+
* @return \Illuminate\Database\Eloquent\Casts\Attribute
33+
*/
34+
protected function fileForUrl(): Attribute
35+
{
36+
return Attribute::make(
37+
get: fn (mixed $value, array $attributes) => str_replace('.md', '', $attributes['file']),
38+
);
39+
}
40+
41+
/**
42+
* @return array
43+
*/
44+
public function toSearchableArray()
45+
{
46+
return [
47+
'title' => $this->title,
48+
'content' => $this->content,
49+
'level' => $this->level,
50+
];
51+
}
52+
}

app/Services/TelegramBot.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ public static function notificationToTelegram(\Throwable $exception): void
129129
->line('*💪 Не сдавайтесь!*')
130130
->line('Каждая ошибка - это шанс стать лучше. Давайте использовать этот момент, чтобы улучшить наш код и стать еще сильнее. Удачи!')
131131
->send();
132-
} catch (\Exception|Throwable) {
132+
} catch (\Exception|\Throwable) {
133133
// without recursive
134134
}
135135
}

composer.lock

+21-21
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*/
12+
public function up(): void
13+
{
14+
Schema::create('documentation_sections', function (Blueprint $table) {
15+
$table->uuid('id')->primary();
16+
$table->string('title_page')->comment('Заголовок всей страницы');
17+
$table->string('title');
18+
$table->integer('level')->nullable()->comment('Уровень заголовка');
19+
$table->string('slug');
20+
$table->string('version');
21+
$table->string('file');
22+
$table->text('content');
23+
$table->timestamps();
24+
});
25+
}
26+
27+
/**
28+
* Reverse the migrations.
29+
*/
30+
public function down(): void
31+
{
32+
Schema::dropIfExists('documentation_sections');
33+
}
34+
};

public/build/assets/app-BUWIDZ8f.js renamed to public/build/assets/app-B-hWsIbj.js

+14-14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/build/assets/app-C5tVmPJ2.css

-5
This file was deleted.

public/build/assets/app-jsXsVF-0.css

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

public/build/manifest.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@
1212
"src": "public/img/ui/warning.svg"
1313
},
1414
"resources/css/app.scss": {
15-
"file": "assets/app-C5tVmPJ2.css",
15+
"file": "assets/app-jsXsVF-0.css",
1616
"src": "resources/css/app.scss",
1717
"isEntry": true
1818
},
1919
"resources/js/app.js": {
20-
"file": "assets/app-BUWIDZ8f.js",
20+
"file": "assets/app-B-hWsIbj.js",
2121
"src": "resources/js/app.js",
2222
"isEntry": true,
2323
"css": [

resources/css/app.scss

+2
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ $input-padding-x: 1rem;
6868

6969
$badge-font-weight: normal;
7070

71+
$modal-backdrop-opacity: 0.675;
72+
7173
$utilities: (
7274
'line-clamp': (
7375
property: -webkit-line-clamp,

0 commit comments

Comments
 (0)