switch to bootstrap-vue

This commit is contained in:
Nazar Kanaev 2020-06-26 23:56:24 +01:00
parent 312b4a54c1
commit 86afb37a53
7 changed files with 130 additions and 111 deletions

View File

@ -55,7 +55,7 @@
</div> </div>
</div> </div>
</div> </div>
<button class="btn btn-link" @click="settingsShow = true"> <button class="btn btn-link" v-b-modal.settings-modal>
<img src="./static/images/settings.svg" alt=""> <img src="./static/images/settings.svg" alt="">
</button> </button>
</div> </div>
@ -91,96 +91,84 @@
</div> </div>
</div> </div>
</div> </div>
<div class="modal" :class="{show: settingsShow, 'd-block': settingsShow}" tabindex="-1"> <b-modal id="settings-modal" hide-footer lazy header-class="settings-header">
<div class="modal-dialog"> <template v-slot:modal-header="{ close }">
<div class="modal-content"> <ul class="nav nav-tabs card-header-tabs mx-0 px-3">
<div class="card-header px-0"> <li class="nav-item">
<button type="button" <a class="nav-link" href="#" :class="{active: settings=='create'}" @click.prevent="settings='create'">New Feed</a>
class="close mr-3" </li>
@click="settingsShow = false"> <li class="nav-item">
<span aria-hidden="true">&times;</span> <a class="nav-link" href="#" :class="{active: settings=='manage'}" @click.prevent="settings='manage'">Manage Feeds</a>
</button> </li>
<ul class="nav nav-tabs card-header-tabs mx-0 px-3"> <li class="nav-item">
<li class="nav-item"> <a class="nav-link" href="#" :class="{active: settings=='import'}" @click.prevent="settings='import'">Import/Export</a>
<a class="nav-link" href="#" :class="{active: settings=='create'}" @click.prevent="settings='create'">New Feed</a> </li>
</li> </ul>
<li class="nav-item"> </template>
<a class="nav-link" href="#" :class="{active: settings=='manage'}" @click.prevent="settings='manage'">Manage Feeds</a> <div v-if="settings=='create'">
</li> <label for="feed-url">URL</label>
<li class="nav-item"> <input id="feed-url" type="text" class="form-control">
<a class="nav-link" href="#" :class="{active: settings=='import'}" @click.prevent="settings='import'">Import/Export</a> <label for="feed-folder" class="mt-3">Folder</label>
</li> <select class="form-control" id="feed-folder">
</ul> <option value=""></option>
<option :value="folder.id" v-for="folder in folders">{{ folder.title }}</option>
</select>
<button class="btn btn-block btn-outline-secondary mt-3" type="button">Add</button>
</div>
<div v-else-if="settings=='manage'">
<div v-for="folder in foldersWithFeeds" class="mb-4">
<div><strong>{{ folder.title || "Uncategorized" }}</strong></div>
<div v-for="feed in folder.feeds" class="d-flex align-items-center">
<div class="w-100">
{{ feed.title }}
</div>
<div class="flex-shrink-0">
<div class="dropdown d-inline-block">
<b-dropdown right no-caret lazy="true" variant="link" class="settings-dropdown" toggle-class="text-decoration-none">
<template v-slot:button-content>
<img src="./static/images/more-vertical.svg">
</template>
<b-dropdown-item @click.prevent="renameFeed(feed)">Rename</b-dropdown-item>
<b-dropdown-divider></b-dropdown-divider>
<b-dropdown-header>Move to...</b-dropdown-header>
<b-dropdown-item
v-if="folder.id != feed.folder_id"
v-for="folder in folders"
@click.prevent="moveFeed(feed, folder)">
{{ folder.title }}
</b-dropdown-item>
<b-dropdown-item
@click.prevent="moveFeed(feed, null)" v-if="feed.folder_id">
Uncategorized
</b-dropdown-item>
<b-dropdown-divider></b-dropdown-divider>
<b-dropdown-item class="dropdown-danger"
@click.prevent="deleteFeed(feed)">
Delete
</b-dropdown-item>
</b-dropdown>
</div>
</div>
</div> </div>
<div class="modal-body"> </div>
<div v-if="settings=='create'"> <div class="mt-5">
<label for="feed-url">URL</label> <label for="settings-new-folder">New Folder</label>
<input id="feed-url" type="text" class="form-control"> <div class="input-group">
<label for="feed-folder" class="mt-3">Folder</label> <input id="settings-new-folder" type="text" class="form-control" v-model="newFolderTitle">
<select class="form-control" id="feed-folder"> <div class="input-group-append">
<option value=""></option> <button class="btn btn-outline-secondary" @click="newFolderCreate()">Add</button>
<option :value="folder.id" v-for="folder in folders">{{ folder.title }}</option>
</select>
<button class="btn btn-block btn-outline-secondary mt-3" type="button">Add</button>
</div>
<div v-else-if="settings=='manage'">
<div v-for="folder in foldersWithFeeds" class="mb-4">
<div><strong>{{ folder.title || "Uncategorized" }}</strong></div>
<div v-for="feed in folder.feeds" class="d-flex align-items-center">
<div class="w-100">
{{ feed.title }}
</div>
<div class="flex-shrink-0">
<div class="dropdown d-inline-block">
<button class="btn btn-link p-1" @click="settingsManageDropdown='feed:'+feed.id">
<img src="./static/images/more-vertical.svg">
</button>
<div class="dropdown-menu menu-settings show overflow-hidden"
style="width: 200px; top: 0; left: 0; position: absolute; transform: translate3d(-160px, 38px, 0px);"
v-if="settingsManageDropdown=='feed:'+feed.id"
v-click-outside="hideSettingsMenu">
<a href="#" class="dropdown-item px-3" @click="renameFeed(feed)">
Rename
</a>
<div class="dropdown-divider"></div>
<h6 class="dropdown-header px-3">Move to...</h6>
<a href="#" class="dropdown-item px-3"
@click.prevent="moveFeed(feed, null)" v-if="feed.folder_id">Uncategorized</a>
<a href="#" class="dropdown-item px-3"
v-if="folder.id != feed.folder_id"
v-for="folder in folders"
@click.prevent="moveFeed(feed, folder)">
{{ folder.title }}
</a>
<div class="dropdown-divider"></div>
<a href="#" class="dropdown-item px-3 text-danger"
@click="deleteFeed(feed)">
Delete
</a>
</div>
</div>
</div>
</div>
</div>
<div class="mt-5">
<label for="settings-new-folder">New Folder</label>
<div class="input-group">
<input id="settings-new-folder" type="text" class="form-control" v-model="newFolderTitle">
<div class="input-group-append">
<button class="btn btn-outline-secondary" @click="newFolderCreate()">Add</button>
</div>
</div>
</div>
</div>
<div v-else-if="settings=='import'">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div v-else-if="settings=='import'">
</div>
</div> </div>
</div> </div>
<script src="./static/javascripts/vue.min.js"></script> <script src="./static/javascripts/vue.min.js"></script>
<script src="./static/javascripts/v-click-outside.umd.js"></script> <script src="./static/javascripts/popper.min.js"></script>
<!-- <script src="./static/javascripts/bootstrap.min.js"></script> -->
<script src="./static/javascripts/bootstrap-vue.min.js"></script>
<script src="./static/javascripts/app.js"></script> <script src="./static/javascripts/app.js"></script>
</body> </body>
</html> </html>

View File

@ -6,8 +6,6 @@ var FILTERS = [
{'title': 'Starred', 'value': 'starred', 'icon': 'star'}, {'title': 'Starred', 'value': 'starred', 'icon': 'star'},
] ]
Vue.use(window['v-click-outside'])
var vm = new Vue({ var vm = new Vue({
el: '#app', el: '#app',
data: function() { data: function() {
@ -32,10 +30,7 @@ var vm = new Vue({
{'id': '789', 'title': 'Marques Brownlee: Reflecting on the Color of My Skin', 'status': 'read', 'feed_id': 2, 'date': 1592250298}, {'id': '789', 'title': 'Marques Brownlee: Reflecting on the Color of My Skin', 'status': 'read', 'feed_id': 2, 'date': 1592250298},
], ],
'itemSelected': null, 'itemSelected': null,
'settingsShow': false,
'settings': 'manage', 'settings': 'manage',
'settingsManageDropdown': null,
'settingsManageEdit': null,
'newFolderTitle': null, 'newFolderTitle': null,
} }
}, },
@ -72,18 +67,6 @@ var vm = new Vue({
'itemSelected': function(newVal, oldVal) { 'itemSelected': function(newVal, oldVal) {
this.itemSelectedDetails = this.itemsById[newVal] this.itemSelectedDetails = this.itemsById[newVal]
}, },
'settingsShow': function(newVal) {
if (newVal === true) {
var vm = this
var backdrop = document.createElement('div')
backdrop.classList.add('modal-backdrop', 'fade', 'show')
document.body.classList.add('modal-open')
document.body.appendChild(backdrop)
} else {
document.body.classList.remove('modal-open')
document.body.querySelector('.modal-backdrop').remove()
}
},
}, },
methods: { methods: {
toggleFolderExpanded: function(folder) { toggleFolderExpanded: function(folder) {
@ -95,7 +78,6 @@ var vm = new Vue({
}, },
moveFeed: function(feed, folder) { moveFeed: function(feed, folder) {
feed.folder_id = folder ? folder.id : null feed.folder_id = folder ? folder.id : null
this.settingsManageDropdown = null
}, },
newFolderCreate: function() { newFolderCreate: function() {
this.folders.push({ this.folders.push({
@ -107,19 +89,11 @@ var vm = new Vue({
renameFeed: function(feed) { renameFeed: function(feed) {
var newTitle = prompt('Enter new title', feed.title) var newTitle = prompt('Enter new title', feed.title)
feed.title = newTitle feed.title = newTitle
this.settingsManageDropdown = null
}, },
deleteFeed: function(feed) { deleteFeed: function(feed) {
if (confirm('Are you sure you want to delete ' + feed.title + '?')) { if (confirm('Are you sure you want to delete ' + feed.title + '?')) {
this.feeds = this.feeds.filter(function(f) { f.id != feed.id }) this.feeds = this.feeds.filter(function(f) { f.id != feed.id })
} }
}, },
hideSettingsMenu: function() {
this.settingsManageDropdown = null
},
hideSettingsModal: function() {
this.settingsShow = false
},
} }
}) })
vm.settingsShow = true

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +0,0 @@
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n():"function"==typeof define&&define.amd?define(n):e["v-click-outside"]=n()}(this,function(){var e="__v-click-outside",n="undefined"!=typeof window,t="undefined"!=typeof navigator,i=n&&("ontouchstart"in window||t&&navigator.msMaxTouchPoints>0)?["touchstart"]:["click"];function o(n,t){var o=function(e){var n="function"==typeof e;if(!n&&"object"!=typeof e)throw new Error("v-click-outside: Binding value must be a function or an object");return{handler:n?e:e.handler,middleware:e.middleware||function(e){return e},events:e.events||i,isActive:!(!1===e.isActive)}}(t.value),r=o.handler,d=o.middleware;o.isActive&&(n[e]=o.events.map(function(e){return{event:e,handler:function(e){return function(e){var n=e.el,t=e.event,i=e.handler,o=e.middleware,r=t.path||t.composedPath&&t.composedPath(),d=r?r.indexOf(n)<0:!n.contains(t.target);t.target!==n&&d&&o(t)&&i(t)}({event:e,el:n,handler:r,middleware:d})}}}),n[e].forEach(function(t){var i=t.event,o=t.handler;return setTimeout(function(){n[e]&&document.documentElement.addEventListener(i,o,!1)},0)}))}function r(n){(n[e]||[]).forEach(function(e){return document.documentElement.removeEventListener(e.event,e.handler,!1)}),delete n[e]}var d=n?{bind:o,update:function(e,n){var t=n.value,i=n.oldValue;JSON.stringify(t)!==JSON.stringify(i)&&(r(e),o(e,{value:t}))},unbind:r}:{};return{install:function(e){e.directive("click-outside",d)},directive:d}});
//# sourceMappingURL=v-click-outside.umd.js.map

View File

@ -78,3 +78,38 @@ body {
.dropdown-header { .dropdown-header {
cursor: default; cursor: default;
} }
.dropdown-toggle-no-caret:after {
display: none;
}
.settings-dropdown .dropdown-toggle {
padding-left: 0;
padding-right: 0;
}
.settings-dropdown .dropdown-menu {
width: 200px;
box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.07);
}
.settings-dropdown .dropdown-menu:focus {
outline: none;
}
.settings-dropdown .dropdown-item, .settings-dropdown .dropdown-header {
padding-left: 1rem;
padding-right: 1rem;
}
.dropdown-danger .dropdown-item {
color: #dc3545!important;
}
.settings-header {
padding: .75rem 0 !important;
}
.modal-backdrop {
background-color: rgba(0, 0, 0, 0.7);
}