Skip to content

Commit 33e09b5

Browse files
committed
Migrate more core components
1 parent 136e4b5 commit 33e09b5

File tree

7 files changed

+223
-184
lines changed

7 files changed

+223
-184
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"dependencies": {
44
"cssnano": "^4.0.3",
55
"date-fns": "^1.29.0",
6+
"feather-icons": "^4.10.0",
67
"socket.io-client": "^2.1.1",
78
"vee-validate": "^2.1.0-beta.2",
89
"vue": "^2.5.7",
@@ -20,6 +21,7 @@
2021
"@babel/plugin-transform-async-to-generator": "^7.0.0-beta.49",
2122
"@babel/plugin-transform-runtime": "^7.0.0-beta.49",
2223
"@babel/preset-env": "^7.0.0-beta.49",
24+
"@types/feather-icons": "^4.7.0",
2325
"@types/lodash": "^4.14.119",
2426
"@types/node": "^10.12.15",
2527
"@types/socket.io-client": "^1.4.32",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Vue from 'vue';
2+
import { replace } from 'feather-icons';
3+
4+
export default Vue.component('icon', {
5+
props: {
6+
name: {type: String, default: 'circle'},
7+
},
8+
mounted: function () {
9+
replace();
10+
},
11+
template: `
12+
<i data-feather="{{ name }}"></i>
13+
`,
14+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import Vue from 'vue';
2+
import Icon from "./Icon";
3+
4+
export default Vue.component('modal', {
5+
components: {
6+
Icon,
7+
},
8+
9+
props: {
10+
modalName: { type: String, default: 'modal' },
11+
show: { type: Boolean, default: false },
12+
closeOnEsc: { type: Boolean, default: true },
13+
},
14+
15+
mounted: function () {
16+
if (this.$props.closeOnEsc) {
17+
document.addEventListener('keydown', e => {
18+
if (this.show && e.key === 'Escape') {
19+
this.close();
20+
}
21+
})
22+
}
23+
},
24+
25+
methods: {
26+
close: function () {
27+
this.$emit('close', this.$props.modalName);
28+
}
29+
},
30+
31+
template: `
32+
<transition name="modal">
33+
<div class="modal-mask" v-show="show" v-on:click="close">
34+
<div class="modal-container" @click.stop>
35+
<icon name="x"
36+
class="absolute pin-r pin-t m-2 text-grey cursor-pointer"
37+
aria-label="Close modal"
38+
role="button"
39+
v-on:click="close"
40+
/>
41+
<slot/>
42+
</div>
43+
</div>
44+
</transition>
45+
`
46+
})

resources/assets/scripts/components/core/Modal.vue

Lines changed: 0 additions & 40 deletions
This file was deleted.
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import Vue from 'vue';
2+
import { debounce, isObject } from 'lodash';
3+
import { mapState } from 'vuex';
4+
import {AxiosError} from "axios";
5+
6+
export default Vue.component('navigation', {
7+
data: function () {
8+
return {
9+
loadingResults: false,
10+
searchActive: false,
11+
};
12+
},
13+
14+
computed: {
15+
...mapState('dashboard', ['servers']),
16+
searchTerm: {
17+
get: function (): string {
18+
return this.$store.getters['dashboard/getSearchTerm'];
19+
},
20+
set: function (value: string): void {
21+
this.$store.dispatch('dashboard/setSearchTerm', value);
22+
}
23+
}
24+
},
25+
26+
created: function () {
27+
document.addEventListener('click', this.documentClick);
28+
},
29+
30+
beforeDestroy: function () {
31+
document.removeEventListener('click', this.documentClick);
32+
},
33+
34+
methods: {
35+
search: debounce(function (): void {
36+
// @todo why is this not liked?
37+
// if (this.searchTerm.length >= 3) {
38+
// this.loadingResults = true;
39+
// this.gatherSearchResults();
40+
// }
41+
}, 500),
42+
43+
gatherSearchResults: function (): void {
44+
this.$store.dispatch('dashboard/loadServers')
45+
.catch((err: AxiosError) => {
46+
console.error(err);
47+
48+
const response = err.response;
49+
if (response && isObject(response.data.errors)) {
50+
response.data.errors.forEach((error: any) => {
51+
this.$flash.error(error.detail);
52+
});
53+
}
54+
})
55+
.then(() => {
56+
this.loadingResults = false;
57+
});
58+
},
59+
60+
doLogout: function () {
61+
this.$store.commit('auth/logout');
62+
window.location.assign(this.route('auth.logout'));
63+
},
64+
65+
documentClick: function (e: Event) {
66+
if (this.$refs.searchContainer) {
67+
if (this.$refs.searchContainer !== e.target && !(this.$refs.searchContainer as HTMLElement).contains(e.target as HTMLElement)) {
68+
this.searchActive = false;
69+
}
70+
}
71+
},
72+
},
73+
74+
template: `
75+
<div class="nav flex">
76+
<div class="logo flex-1">
77+
<router-link :to="{ name: 'dashboard' }">
78+
Pterodactyl
79+
</router-link>
80+
</div>
81+
<div class="search-box flex-none" v-if="$route.name !== 'dashboard'" ref="searchContainer">
82+
<input type="text" class="search-input" id="searchInput" placeholder="Search..."
83+
:class="{ 'has-search-results': ((servers.length > 0 && searchTerm.length >= 3) || loadingResults) && searchActive }"
84+
v-on:focus="searchActive = true"
85+
v-on:input="search"
86+
v-model="searchTerm"
87+
/>
88+
<div class="search-results select-none" :class="{ 'hidden': (servers.length === 0 && !loadingResults) || !searchActive || searchTerm.length < 3 }">
89+
<div v-if="loadingResults">
90+
<a href="#">
91+
<div class="flex items-center">
92+
<div class="flex-1">
93+
<span class="text-sm text-grey-darker">Loading...</span>
94+
</div>
95+
<div class="flex-none">
96+
<span class="spinner spinner-relative"></span>
97+
</div>
98+
</div>
99+
</a>
100+
</div>
101+
<div v-else v-for="server in servers" :key="server.identifier">
102+
<router-link :to="{ name: 'server', params: { id: server.identifier }}" v-on:click.native="searchActive = false">
103+
<div class="flex items-center">
104+
<div class="flex-1">
105+
<span class="font-bold text-grey-darkest">{{ server.name }}</span><br />
106+
<span class="font-light text-grey-dark text-sm" v-if="server.description.length > 0">{{ server.description }}</span>
107+
</div>
108+
<div class="flex-none">
109+
<span class="pillbox bg-indigo">{{ server.node }}</span>
110+
</div>
111+
</div>
112+
</router-link>
113+
</div>
114+
</div>
115+
</div>
116+
<div class="menu flex-none">
117+
<ul>
118+
<li>
119+
<router-link :to="{ name: 'dashboard' }">
120+
<icon name="server" aria-label="Server dashboard" class="h-4"/>
121+
</router-link>
122+
</li>
123+
<li>
124+
<router-link :to="{ name: 'account' }">
125+
<icon name="user" aria-label="Profile management" class="h-4"/>
126+
</router-link>
127+
</li>
128+
<li>
129+
<a :href="this.route('admin.index')">
130+
<icon name="settings" aria-label="Administrative controls" class="h-4"/>
131+
</a>
132+
</li>
133+
<li>
134+
<a :href="this.route('auth.logout')" v-on:click.prevent="doLogout">
135+
<icon name="log-out" aria-label="Sign out" class="h-4"/>
136+
</a>
137+
</li>
138+
</ul>
139+
</div>
140+
</div>
141+
`
142+
})

0 commit comments

Comments
 (0)