Skip to content

Commit 10305a4

Browse files
committed
Converted entity-dash from vue to a component
1 parent a5fa745 commit 10305a4

10 files changed

Lines changed: 111 additions & 90 deletions

dev/docs/components.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,22 @@
11
# JavaScript Components
22

3-
This document details the format for JavaScript components in BookStack.
3+
This document details the format for JavaScript components in BookStack. This is a really simple class-based setup with a few helpers provided.
44

55
#### Defining a Component in JS
66

77
```js
88
class Dropdown {
99
setup() {
10+
this.toggle = this.$refs.toggle;
11+
this.menu = this.$refs.menu;
12+
13+
this.speed = parseInt(this.$opts.speed);
1014
}
1115
}
1216
```
1317

18+
All usage of $refs, $manyRefs and $opts should be done at the top of the `setup` function so any requirements can be easily seen.
19+
1420
#### Using a Component in HTML
1521

1622
A component is used like so:
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import {onSelect} from "../services/dom";
2+
3+
/**
4+
* Class EntitySearch
5+
* @extends {Component}
6+
*/
7+
class EntitySearch {
8+
setup() {
9+
this.entityId = this.$opts.entityId;
10+
this.entityType = this.$opts.entityType;
11+
12+
this.contentView = this.$refs.contentView;
13+
this.searchView = this.$refs.searchView;
14+
this.searchResults = this.$refs.searchResults;
15+
this.searchInput = this.$refs.searchInput;
16+
this.searchForm = this.$refs.searchForm;
17+
this.clearButton = this.$refs.clearButton;
18+
this.loadingBlock = this.$refs.loadingBlock;
19+
20+
this.setupListeners();
21+
}
22+
23+
setupListeners() {
24+
this.searchInput.addEventListener('change', this.runSearch.bind(this));
25+
this.searchForm.addEventListener('submit', e => {
26+
e.preventDefault();
27+
this.runSearch();
28+
});
29+
30+
onSelect(this.clearButton, this.clearSearch.bind(this));
31+
}
32+
33+
runSearch() {
34+
const term = this.searchInput.value.trim();
35+
if (term.length === 0) {
36+
return this.clearSearch();
37+
}
38+
39+
this.searchView.classList.remove('hidden');
40+
this.contentView.classList.add('hidden');
41+
this.loadingBlock.classList.remove('hidden');
42+
43+
const url = window.baseUrl(`/search/${this.entityType}/${this.entityId}`);
44+
window.$http.get(url, {term}).then(resp => {
45+
this.searchResults.innerHTML = resp.data;
46+
}).catch(console.error).then(() => {
47+
this.loadingBlock.classList.add('hidden');
48+
});
49+
}
50+
51+
clearSearch() {
52+
this.searchView.classList.add('hidden');
53+
this.contentView.classList.remove('hidden');
54+
this.loadingBlock.classList.add('hidden');
55+
this.searchInput.value = '';
56+
}
57+
}
58+
59+
export default EntitySearch;

resources/js/vues/entity-dashboard.js

Lines changed: 0 additions & 44 deletions
This file was deleted.

resources/js/vues/vues.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@ function exists(id) {
44
return document.getElementById(id) !== null;
55
}
66

7-
import entityDashboard from "./entity-dashboard";
87
import imageManager from "./image-manager";
98
import tagManager from "./tag-manager";
109
import attachmentManager from "./attachment-manager";
1110
import pageEditor from "./page-editor";
1211

1312
let vueMapping = {
14-
'entity-dashboard': entityDashboard,
1513
'image-manager': imageManager,
1614
'tag-manager': tagManager,
1715
'attachment-manager': attachmentManager,

resources/views/books/show.blade.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
@extends('tri-layout')
22

33
@section('container-attrs')
4-
id="entity-dashboard"
5-
entity-id="{{ $book->id }}"
6-
entity-type="book"
4+
component="entity-search"
5+
option:entity-search:entity-id="{{ $book->id }}"
6+
option:entity-search:entity-type="book"
77
@stop
88

99
@section('body')
@@ -15,11 +15,11 @@
1515
</div>
1616

1717
<main class="content-wrap card">
18-
<h1 class="break-text" v-pre>{{$book->name}}</h1>
19-
<div class="book-content" v-show="!searching">
20-
<p class="text-muted" v-pre>{!! nl2br(e($book->description)) !!}</p>
18+
<h1 class="break-text">{{$book->name}}</h1>
19+
<div refs="entity-search@contentView" class="book-content">
20+
<p class="text-muted">{!! nl2br(e($book->description)) !!}</p>
2121
@if(count($bookChildren) > 0)
22-
<div class="entity-list book-contents" v-pre>
22+
<div class="entity-list book-contents">
2323
@foreach($bookChildren as $childElement)
2424
@if($childElement->isA('chapter'))
2525
@include('chapters.list-item', ['chapter' => $childElement])
@@ -29,7 +29,7 @@
2929
@endforeach
3030
</div>
3131
@else
32-
<div class="mt-xl" v-pre>
32+
<div class="mt-xl">
3333
<hr>
3434
<p class="text-muted italic mb-m mt-xl">{{ trans('entities.books_empty_contents') }}</p>
3535

@@ -52,7 +52,7 @@
5252
@endif
5353
</div>
5454

55-
@include('partials.entity-dashboard-search-results')
55+
@include('partials.entity-search-results')
5656
</main>
5757

5858
@stop
@@ -126,7 +126,7 @@
126126

127127
@section('left')
128128

129-
@include('partials.entity-dashboard-search-box')
129+
@include('partials.entity-search-form', ['label' => trans('entities.books_search_this')])
130130

131131
@if($book->tags->count() > 0)
132132
<div class="mb-xl">

resources/views/chapters/show.blade.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
@extends('tri-layout')
22

33
@section('container-attrs')
4-
id="entity-dashboard"
5-
entity-id="{{ $chapter->id }}"
6-
entity-type="chapter"
4+
component="entity-search"
5+
option:entity-search:entity-id="{{ $chapter->id }}"
6+
option:entity-search:entity-type="chapter"
77
@stop
88

99
@section('body')
@@ -16,17 +16,17 @@
1616
</div>
1717

1818
<main class="content-wrap card">
19-
<h1 class="break-text" v-pre>{{ $chapter->name }}</h1>
20-
<div class="chapter-content" v-show="!searching">
21-
<p v-pre class="text-muted break-text">{!! nl2br(e($chapter->description)) !!}</p>
19+
<h1 class="break-text">{{ $chapter->name }}</h1>
20+
<div refs="entity-search@contentView" class="chapter-content">
21+
<p class="text-muted break-text">{!! nl2br(e($chapter->description)) !!}</p>
2222
@if(count($pages) > 0)
23-
<div v-pre class="entity-list book-contents">
23+
<div class="entity-list book-contents">
2424
@foreach($pages as $page)
2525
@include('pages.list-item', ['page' => $page])
2626
@endforeach
2727
</div>
2828
@else
29-
<div class="mt-xl" v-pre>
29+
<div class="mt-xl">
3030
<hr>
3131
<p class="text-muted italic mb-m mt-xl">{{ trans('entities.chapters_empty') }}</p>
3232

@@ -49,7 +49,7 @@
4949
@endif
5050
</div>
5151

52-
@include('partials.entity-dashboard-search-results')
52+
@include('partials.entity-search-results')
5353
</main>
5454

5555
@stop
@@ -130,7 +130,7 @@
130130

131131
@section('left')
132132

133-
@include('partials.entity-dashboard-search-box')
133+
@include('partials.entity-search-form', ['label' => trans('entities.chapters_search_this')])
134134

135135
@if($chapter->tags->count() > 0)
136136
<div class="mb-xl">

resources/views/partials/entity-dashboard-search-box.blade.php

Lines changed: 0 additions & 8 deletions
This file was deleted.

resources/views/partials/entity-dashboard-search-results.blade.php

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{{--
2+
@label - Placeholder/aria-label text
3+
--}}
4+
<div class="mb-xl">
5+
<form refs="entity-search@searchForm" class="search-box flexible" role="search">
6+
<input refs="entity-search@searchInput" type="text"
7+
aria-label="{{ $label }}" name="term" placeholder="{{ $label }}">
8+
<button type="submit" aria-label="{{ trans('common.search') }}">@icon('search')</button>
9+
</form>
10+
</div>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<div refs="entity-search@searchView" class="search-results hidden">
2+
<div class="grid half v-center">
3+
<h3 class="text-muted px-none">
4+
{{ trans('entities.search_results') }}
5+
</h3>
6+
<div class="text-right">
7+
<a refs="entity-search@clearButton" class="button outline">{{ trans('entities.search_clear') }}</a>
8+
</div>
9+
</div>
10+
11+
<div refs="entity-search@loadingBlock">
12+
@include('partials.loading-icon')
13+
</div>
14+
<div class="book-contents" refs="entity-search@searchResults"></div>
15+
</div>

0 commit comments

Comments
 (0)