Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Platform
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Platform
Commits
7de48576
Unverified
Commit
7de48576
authored
Nov 20, 2017
by
Nicolas Widart
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Publishing module assets
parent
6bbcd522
Changes
29
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
1639 additions
and
309 deletions
+1639
-309
DeleteComponent.vue
public/modules/core/js/components/DeleteComponent.vue
+15
-14
EditButtonComponent.vue
public/modules/core/js/components/EditButtonComponent.vue
+20
-0
ActiveEditor.js
public/modules/core/js/mixins/ActiveEditor.js
+3
-3
ShortcutHelper.js
public/modules/core/js/mixins/ShortcutHelper.js
+3
-3
Slugify.js
public/modules/core/js/mixins/Slugify.js
+6
-6
StringHelpers.vue
public/modules/core/js/mixins/StringHelpers.vue
+4
-3
TranslationHelper.js
public/modules/core/js/mixins/TranslationHelper.js
+6
-6
MediaRoutes.js
public/modules/media/js/MediaRoutes.js
+4
-4
MediaForm.vue
public/modules/media/js/components/MediaForm.vue
+22
-24
MediaList.vue
public/modules/media/js/components/MediaList.vue
+66
-52
MediaManager.vue
public/modules/media/js/components/MediaManager.vue
+3
-3
MoveMediaDialog.vue
public/modules/media/js/components/MoveMediaDialog.vue
+98
-0
NewFolder.vue
public/modules/media/js/components/NewFolder.vue
+16
-16
RenameFolder.vue
public/modules/media/js/components/RenameFolder.vue
+13
-13
SingleMedia.vue
public/modules/media/js/components/SingleMedia.vue
+24
-22
UploadButton.vue
public/modules/media/js/components/UploadButton.vue
+13
-13
UploadZone.vue
public/modules/media/js/components/UploadZone.vue
+6
-6
PageRoutes.js
public/modules/page/js/PageRoutes.js
+5
-5
PageForm.vue
public/modules/page/js/components/PageForm.vue
+56
-52
PageTable.vue
public/modules/page/js/components/PageTable.vue
+13
-13
PageTableServerSide.vue
public/modules/page/js/components/PageTableServerSide.vue
+67
-51
UserRoutes.js
public/modules/user/js/UserRoutes.js
+71
-0
ApiKeys.vue
public/modules/user/js/components/ApiKeys.vue
+100
-0
AsgardPermissions.vue
public/modules/user/js/components/AsgardPermissions.vue
+126
-0
RoleForm.vue
public/modules/user/js/components/RoleForm.vue
+157
-0
RoleTable.vue
public/modules/user/js/components/RoleTable.vue
+167
-0
UserForm.vue
public/modules/user/js/components/UserForm.vue
+240
-0
UserProfile.vue
public/modules/user/js/components/UserProfile.vue
+141
-0
UserTable.vue
public/modules/user/js/components/UserTable.vue
+174
-0
No files found.
public/modules/core/js/components/DeleteComponent.vue
View file @
7de48576
<
template
>
<
button
class=
"btn btn-danger btn-flat"
@
click=
"deleteRow"
><i
class=
"fa fa-trash"
></i></
button>
<
el-button
type=
"danger"
@
click=
"deleteRow"
size=
"mini"
><i
class=
"fa fa-trash"
></i></el-
button>
</
template
>
<
script
>
export
default
{
props
:
{
rows
:
{
default
:
null
},
scope
:
{
default
:
null
},
rows
:
{
default
:
null
},
scope
:
{
default
:
null
},
},
data
()
{
return
{
deleteMessage
:
''
,
deleteTitle
:
''
,
}
}
;
},
methods
:
{
deleteRow
(
event
)
{
this
.
$confirm
(
this
.
deleteMessage
,
this
.
deleteTitle
,
{
confirmButtonText
:
this
.
trans
(
'
core.button.delete
'
),
cancelButtonText
:
this
.
trans
(
'
core.button.cancel
'
),
type
:
'
warning
'
type
:
'
warning
'
,
confirmButtonClass
:
'
el-button--danger
'
,
}).
then
(()
=>
{
le
t
vm
=
this
;
cons
t
vm
=
this
;
axios
.
delete
(
this
.
scope
.
row
.
urls
.
delete_url
)
.
then
(
response
=>
{
.
then
(
(
response
)
=>
{
if
(
response
.
data
.
errors
===
false
)
{
vm
.
$message
({
type
:
'
success
'
,
message
:
response
.
data
.
message
message
:
response
.
data
.
message
,
});
vm
.
rows
.
splice
(
vm
.
scope
.
$index
,
1
);
}
})
.
catch
(
error
=>
{
.
catch
(
(
error
)
=>
{
vm
.
$message
({
type
:
'
error
'
,
message
:
error
.
data
.
message
message
:
error
.
data
.
message
,
});
});
}).
catch
(()
=>
{
this
.
$message
({
type
:
'
info
'
,
message
:
this
.
trans
(
'
core.delete cancelled
'
)
message
:
this
.
trans
(
'
core.delete cancelled
'
)
,
});
});
}
}
,
},
mounted
()
{
this
.
deleteMessage
=
this
.
trans
(
'
core.modal.confirmation-message
'
);
this
.
deleteTitle
=
this
.
trans
(
'
core.modal.title
'
);
}
}
}
,
}
;
</
script
>
public/modules/core/js/components/EditButtonComponent.vue
0 → 100644
View file @
7de48576
<
template
>
<el-button
size=
"mini"
@
click
.
prevent=
"goToEditPage()"
>
<i
class=
"fa fa-pencil"
></i>
</el-button>
</
template
>
<
script
>
export
default
{
props
:
{
to
:
{
type
:
Object
,
required
:
true
},
},
methods
:
{
goToEditPage
()
{
this
.
$router
.
push
(
this
.
to
);
},
},
};
</
script
>
public/modules/core/js/mixins/ActiveEditor.js
View file @
7de48576
...
...
@@ -8,7 +8,7 @@ export default {
if
(
configuredEditor
===
'
ckeditor
'
)
{
return
'
ckeditor
'
;
}
return
'
ckeditor
'
return
'
ckeditor
'
;
},
}
}
}
,
}
;
public/modules/core/js/mixins/ShortcutHelper.js
View file @
7de48576
...
...
@@ -2,6 +2,6 @@ export default {
methods
:
{
pushRoute
(
route
)
{
this
.
$router
.
push
(
route
);
}
}
}
}
,
}
,
}
;
public/modules/core/js/mixins/Slugify.js
View file @
7de48576
...
...
@@ -6,9 +6,9 @@ export default {
value
=
value
.
toLowerCase
();
// remove accents, swap ñ for n, etc
var
from
=
"
ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;
"
;
var
to
=
"
aaaaaeeeeeiiiiooooouuuunc------
"
;
for
(
var
i
=
0
,
l
=
from
.
length
;
i
<
l
;
i
++
)
{
const
from
=
'
ãàáäâẽèéëêìíïîõòóöôùúüûñç·/_,:;
'
;
const
to
=
'
aaaaaeeeeeiiiiooooouuuunc------
'
;
for
(
let
i
=
0
,
l
=
from
.
length
;
i
<
l
;
i
++
)
{
value
=
value
.
replace
(
new
RegExp
(
from
.
charAt
(
i
),
'
g
'
),
to
.
charAt
(
i
));
}
...
...
@@ -17,6 +17,6 @@ export default {
.
replace
(
/-+/g
,
'
-
'
);
// collapse dashes
return
value
;
}
}
}
}
,
}
,
}
;
public/modules/core/js/mixins/StringHelpers.vue
View file @
7de48576
<
template
>
<div></div>
</
template
>
<
script
>
...
...
@@ -8,8 +9,8 @@
return
string
[
0
].
toUpperCase
()
+
string
.
substr
(
1
);
},
ucwords
(
string
)
{
return
string
.
replace
(
/
\w\S
*/g
,
function
(
txt
){
return
txt
.
charAt
(
0
).
toUpperCase
()
+
txt
.
substr
(
1
).
toLowerCase
();});
}
return
string
.
replace
(
/
\w\S
*/g
,
txt
=>
txt
.
charAt
(
0
).
toUpperCase
()
+
txt
.
substr
(
1
).
toLowerCase
());
},
}
},
};
</
script
>
public/modules/core/js/mixins/TranslationHelper.js
View file @
7de48576
...
...
@@ -3,14 +3,14 @@ export default {
trans
(
string
)
{
// Makes a string: core.button.cancel | core.button.created at
// to: core["button.cancel"] | core["button.created at"]
le
t
array
=
string
.
split
(
'
.
'
);
cons
t
array
=
string
.
split
(
'
.
'
);
if
(
array
.
length
<
2
)
{
return
this
.
$t
(
string
)
}
if
(
array
.
length
<
2
)
{
return
this
.
$t
(
string
)
;
}
let
first
=
array
.
splice
(
0
,
1
);
le
t
key
=
array
.
join
(
'
.
'
);
const
first
=
array
.
splice
(
0
,
1
);
cons
t
key
=
array
.
join
(
'
.
'
);
return
this
.
$t
(
`
${
first
}
['
${
key
}
']`
);
},
}
}
}
,
}
;
public/modules/media/js/MediaRoutes.js
View file @
7de48576
...
...
@@ -12,7 +12,7 @@ export default [
{
path
:
''
,
component
:
MediaList
,
name
:
'
admin.media.media.index
'
name
:
'
admin.media.media.index
'
,
},
{
path
:
'
:mediaId/edit
'
,
...
...
@@ -20,8 +20,8 @@ export default [
name
:
'
admin.media.media.edit
'
,
props
:
{
locales
,
}
},
]
}
},
],
},
];
public/modules/media/js/components/MediaForm.vue
View file @
7de48576
...
...
@@ -21,7 +21,7 @@
<div
class=
"col-md-8"
>
<div
class=
"box box-primary"
>
<div
class=
"box-body"
>
<el-tabs
type=
"card"
v-model=
"activeTab"
>
<el-tabs
v-model=
"activeTab"
>
<el-tab-pane
:label=
"localeArray.name"
v-for=
"(localeArray, locale) in locales"
:key=
"localeArray.name"
:name=
"locale"
>
...
...
@@ -48,7 +48,7 @@
<hr>
<tags-input
namespace=
"asgardcms/media"
v-model=
"tags"
:
value=
"tags"
:
current-tags=
"tags"
></tags-input>
<tags-input
namespace=
"asgardcms/media"
v-model=
"tags"
:current-tags=
"tags"
></tags-input>
<el-form-item>
<el-button
type=
"primary"
@
click=
"onSubmit()"
:loading=
"loading"
>
...
...
@@ -64,7 +64,7 @@
</div>
<div
class=
"col-md-4"
>
<img
:src=
"media.path"
alt=
""
v-if=
"media.is_image"
style=
"width: 100%;"
/>
<i
class=
"fa fa-file"
style=
"font-size: 50px;"
v-else
=
""
></i>
<i
class=
"fa fa-file"
style=
"font-size: 50px;"
v-else
></i>
</div>
</div>
</el-form>
...
...
@@ -84,12 +84,12 @@
</
template
>
<
script
>
import
Form
from
'
form-backend-validation
'
import
axios
from
'
axios
'
import
Form
from
'
form-backend-validation
'
;
import
axios
from
'
axios
'
;
export
default
{
props
:
{
locales
:
{
default
:
null
},
locales
:
{
default
:
null
},
},
data
()
{
return
{
...
...
@@ -101,62 +101,60 @@
keywords
:
''
,
}])
.
fromPairs
()
//.merge({template: 'default', is_home: 0, medias_single: []})
//
.merge({template: 'default', is_home: 0, medias_single: []})
.
value
(),
form
:
new
Form
(),
loading
:
false
,
tags
:
{},
activeTab
:
window
.
AsgardCMS
.
currentLocale
||
'
en
'
,
}
}
;
},
methods
:
{
fetchMedia
()
{
this
.
loading
=
true
;
axios
.
get
(
route
(
'
api.media.media.find
'
,
{
media
:
this
.
$route
.
params
.
mediaId
}))
.
then
(
response
=>
{
axios
.
get
(
route
(
'
api.media.media.find
'
,
{
media
:
this
.
$route
.
params
.
mediaId
}))
.
then
(
(
response
)
=>
{
this
.
loading
=
false
;
this
.
media
=
response
.
data
.
data
;
this
.
tags
=
response
.
data
.
data
.
tags
;
})
.
catch
(
error
=>
{
})
});
},
onSubmit
()
{
this
.
form
=
new
Form
(
_
.
merge
(
this
.
media
,
{
tags
:
this
.
tags
}));
this
.
form
=
new
Form
(
_
.
merge
(
this
.
media
,
{
tags
:
this
.
tags
}));
this
.
loading
=
true
;
this
.
form
.
put
(
route
(
'
api.media.media.update
'
,
{
file
:
this
.
media
.
id
}))
.
then
(
response
=>
{
this
.
form
.
put
(
route
(
'
api.media.media.update
'
,
{
file
:
this
.
media
.
id
}))
.
then
(
(
response
)
=>
{
this
.
loading
=
false
;
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
message
message
:
response
.
message
,
});
this
.
$router
.
push
({
name
:
'
admin.media.media.index
'
,
query
:
{
folder_id
:
this
.
media
.
folder_id
}})
this
.
$router
.
push
({
name
:
'
admin.media.media.index
'
,
query
:
{
folder_id
:
this
.
media
.
folder_id
}
});
})
.
catch
(
error
=>
{
.
catch
(
(
error
)
=>
{
console
.
log
(
error
);
this
.
loading
=
false
;
this
.
$notify
.
error
({
title
:
'
Error
'
,
message
:
'
There are some errors in the form.
'
message
:
'
There are some errors in the form.
'
,
});
});
},
onCancel
()
{
if
(
this
.
media
.
folder_id
==
0
)
{
this
.
$router
.
push
({
name
:
'
admin.media.media.index
'
,
query
:
{}
});
this
.
$router
.
push
({
name
:
'
admin.media.media.index
'
,
query
:
{}
});
return
;
}
this
.
$router
.
push
({
name
:
'
admin.media.media.index
'
,
query
:
{
folder_id
:
this
.
media
.
folder_id
}})
this
.
$router
.
push
({
name
:
'
admin.media.media.index
'
,
query
:
{
folder_id
:
this
.
media
.
folder_id
}
});
},
},
mounted
()
{
if
(
this
.
$route
.
params
.
mediaId
!==
undefined
)
{
this
.
fetchMedia
();
}
}
}
}
,
}
;
</
script
>
<
style
>
.el-select
{
...
...
public/modules/media/js/components/MediaList.vue
View file @
7de48576
...
...
@@ -23,16 +23,20 @@
<div
class=
"actions el-col el-col-14"
>
<new-folder
:parent-id=
"folderId"
></new-folder>
<upload-button
:parent-id=
"folderId"
></upload-button>
<el-button-group
v-if=
"false"
>
<el-button
type=
"primary"
:disabled=
"selectedMedia.length === 0"
>
Move
</el-button>
</el-button-group>
<el-button-group
style=
"width: 30%"
>
<el-button
type=
"warning"
:disabled=
"selectedMedia.length === 0"
@
click=
"showMoveMedia"
>
{{
trans
(
'
core.move
'
)
}}
</el-button>
<el-button
type=
"danger"
:disabled=
"selectedMedia.length === 0"
@
click
.
pre
ent=
"batchDelete"
:loading=
"filesAreDeleting"
>
Delete
@
click
.
prev
ent=
"batchDelete"
:loading=
"filesAreDeleting"
>
{{
trans
(
'
core.button.delete
'
)
}}
</el-button>
</el-button-group>
</div>
<div
class=
"search el-col el-col-5"
>
<el-input
icon=
"search"
@
chang
e=
"performSearch"
v-model=
"searchQuery"
>
<el-input
prefix-icon=
"el-icon-search"
@
keyup
.
nativ
e=
"performSearch"
v-model=
"searchQuery"
>
</el-input>
</div>
</div>
...
...
@@ -58,7 +62,7 @@
width=
"55"
>
</el-table-column>
<el-table-column
label=
""
width=
"150"
>
<template
scope=
"scope"
>
<template
s
lot-s
cope=
"scope"
>
<img
:src=
"scope.row.small_thumb"
alt=
""
v-if=
"scope.row.is_image"
/>
<i
:class=
"`fa $
{scope.row.fa_icon}`" style="font-size: 38px;"
v-if="! scope.row.is_image
&&
! scope.row.is_folder">
</i>
...
...
@@ -68,7 +72,7 @@
</el-table-column>
<el-table-column
prop=
"filename"
:label=
"trans('media.table.filename')"
sortable=
"custom"
>
<
template
scope=
"scope"
>
<
template
s
lot-s
cope=
"scope"
>
<strong
v-if=
"scope.row.is_folder"
style=
"cursor: pointer;"
@
click=
"enterFolder(scope)"
>
{{
scope
.
row
.
filename
}}
</strong>
...
...
@@ -82,7 +86,7 @@
width=
"150"
>
</el-table-column>
<el-table-column
prop=
"actions"
label=
""
width=
"150"
>
<
template
scope=
"scope"
>
<
template
s
lot-s
cope=
"scope"
>
<div
class=
"pull-right"
>
<el-button
type=
"primary"
...
...
@@ -96,7 +100,7 @@
<edit-button
:to=
"
{name: 'admin.media.media.edit', params: {mediaId: scope.row.id}}"
v-if="! scope.row.is_folder">
</edit-button>
<el-button
size=
"
small
"
size=
"
mini
"
@
click
.
prevent=
"showEditFolder(scope.row)"
v-if=
"scope.row.is_folder && canEditFolders"
>
<i
class=
"fa fa-pencil"
></i>
...
...
@@ -124,23 +128,26 @@
</div>
</div>
<rename-folder></rename-folder>
<move-dialog></move-dialog>
</div>
</template>
<
script
>
import
axios
from
'
axios
'
import
axios
from
'
axios
'
;
import
NewFolder
from
'
./NewFolder.vue
'
;
import
UploadButton
from
'
./UploadButton.vue
'
;
import
RenameFolder
from
'
./RenameFolder.vue
'
;
import
MoveMediaDialog
from
'
./MoveMediaDialog.vue
'
;
export
default
{
components
:
{
'
new-folder
'
:
NewFolder
,
'
upload-button
'
:
UploadButton
,
'
rename-folder
'
:
RenameFolder
,
'
move-dialog
'
:
MoveMediaDialog
,
},
props
:
{
singleModal
:
{
type
:
Boolean
},
singleModal
:
{
type
:
Boolean
},
eventName
:
{},
},
data
()
{
...
...
@@ -158,17 +165,17 @@
links
:
{},
searchQuery
:
''
,
folderId
:
0
,
selectedMedia
:
{}
,
selectedMedia
:
[]
,
folderBreadcrumb
:
[
{
id
:
0
,
name
:
'
Home
'
},
{
id
:
0
,
name
:
'
Home
'
},
],
filesAreDeleting
:
false
,
canEditFolders
:
true
,
}
}
;
},
methods
:
{
queryServer
(
customProperties
)
{
le
t
properties
=
{
cons
t
properties
=
{
page
:
this
.
meta
.
current_page
,
per_page
:
this
.
meta
.
per_page
,
order_by
:
this
.
order_meta
.
order_by
,
...
...
@@ -178,7 +185,7 @@
};
axios
.
get
(
route
(
'
api.media.all-vue
'
,
_
.
merge
(
properties
,
customProperties
)))
.
then
(
response
=>
{
.
then
(
(
response
)
=>
{
this
.
tableIsLoading
=
false
;
this
.
data
=
response
.
data
.
data
;
this
.
meta
=
response
.
data
.
meta
;
...
...
@@ -191,7 +198,7 @@
fetchMediaData
()
{
this
.
tableIsLoading
=
true
;
if
(
this
.
$route
.
query
.
folder_id
!==
undefined
)
{
this
.
queryServer
({
folder_id
:
this
.
$route
.
query
.
folder_id
});
this
.
queryServer
({
folder_id
:
this
.
$route
.
query
.
folder_id
});
this
.
fetchFolderBreadcrumb
(
this
.
$route
.
query
.
folder_id
);
return
;
}
...
...
@@ -200,40 +207,40 @@
fetchFolderBreadcrumb
(
folderId
)
{
if
(
folderId
===
0
)
{
this
.
folderBreadcrumb
=
[
{
id
:
0
,
name
:
'
Home
'
},
{
id
:
0
,
name
:
'
Home
'
},
];
return
;
}
axios
.
get
(
route
(
'
api.media.folders.breadcrumb
'
,
{
folder
:
folderId
}))
.
then
(
response
=>
{
axios
.
get
(
route
(
'
api.media.folders.breadcrumb
'
,
{
folder
:
folderId
}))
.
then
(
(
response
)
=>
{
this
.
folderBreadcrumb
=
response
.
data
;
});
},
handleSizeChange
(
event
)
{
console
.
log
(
'
per page :
'
+
event
);
console
.
log
(
`per page :
${
event
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
per_page
:
event
});
this
.
queryServer
({
per_page
:
event
});
},
handleCurrentChange
(
event
)
{
console
.
log
(
'
current page :
'
+
event
);
console
.
log
(
`current page :
${
event
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
page
:
event
});
this
.
queryServer
({
page
:
event
});
},
handleSortChange
(
event
)
{
console
.
log
(
'
sorting
'
,
event
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
order_by
:
event
.
prop
,
order
:
event
.
order
,
});
this
.
queryServer
({
order_by
:
event
.
prop
,
order
:
event
.
order
});
},
performSearch
(
query
)
{
console
.
log
(
'
searching:
'
+
query
);
performSearch
:
_
.
debounce
(
function
(
query
)
{
console
.
log
(
`searching:
${
query
.
target
.
value
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
search
:
query
});
},
this
.
queryServer
({
search
:
query
.
target
.
value
});
},
300
),
enterFolder
(
scope
)
{
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
folder_id
:
scope
.
row
.
id
});
this
.
queryServer
({
folder_id
:
scope
.
row
.
id
});
this
.
folderId
=
scope
.
row
.
id
;
this
.
$router
.
push
({
query
:
{
folder_id
:
scope
.
row
.
id
}});
this
.
$router
.
push
({
query
:
{
folder_id
:
scope
.
row
.
id
}
});
this
.
fetchFolderBreadcrumb
(
scope
.
row
.
id
);
},
insertMedia
(
scope
)
{
...
...
@@ -245,14 +252,17 @@
showEditFolder
(
scope
)
{
this
.
$events
.
emit
(
'
editFolderWasClicked
'
,
scope
);
},
changeRoot
(
folderId
,
index
)
{
showMoveMedia
()
{
this
.
$events
.
emit
(
'
moveMediaWasClicked
'
,
this
.
selectedMedia
);
},
changeRoot
(
folderId
)
{
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
folder_id
:
folderId
});
this
.
queryServer
({
folder_id
:
folderId
});
this
.
folderId
=
folderId
;
if
(
folderId
===
0
)
{
this
.
$router
.
push
({
query
:
{}});
this
.
$router
.
push
({
query
:
{}
});
}
else
{
this
.
$router
.
push
({
query
:
{
folder_id
:
folderId
}});
this
.
$router
.
push
({
query
:
{
folder_id
:
folderId
}
});
}
this
.
fetchFolderBreadcrumb
(
folderId
);
...
...
@@ -261,17 +271,17 @@
this
.
$confirm
(
this
.
trans
(
'
core.modal.confirmation-message
'
),
this
.
trans
(
'
core.modal.title
'
),
{
confirmButtonText
:
this
.
trans
(
'
core.button.delete
'
),
cancelButtonText
:
this
.
trans
(
'
core.button.cancel
'
),
type
:
'
warning
'
type
:
'
warning
'
,
})
.
then
(()
=>
{
this
.
filesAreDeleting
=
true
;
axios
.
post
(
route
(
'
api.media.media.batch-destroy
'
),
{
files
:
this
.
selectedMedia
files
:
this
.
selectedMedia
,
})
.
then
(
response
=>
{
.
then
(
(
response
)
=>
{
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
data
.
message
message
:
response
.
data
.
message
,
});
this
.
filesAreDeleting
=
false
;
this
.
$refs
.
mediaTable
.
clearSelection
();
...
...
@@ -281,32 +291,36 @@
.
catch
(()
=>
{
this
.
$message
({
type
:
'
info
'
,
message
:
this
.
trans
(
'
core.delete cancelled
'
)
message
:
this
.
trans
(
'
core.delete cancelled
'
)
,
});
});
},
goToEdit
(
scope
)
{
this
.
$router
.
push
({
name
:
'
admin.media.media.edit
'
,
params
:
{
mediaId
:
scope
.
row
.
id
}})
this
.
$router
.
push
({
name
:
'
admin.media.media.edit
'
,
params
:
{
mediaId
:
scope
.
row
.
id
}
});
},
},
mounted
()
{
if
(
window
.
AsgardCMS
.
filesystem
===
'
s3
'
)
{
this
.
canEditFolders
=
false
;
}
this
.
selectedMedia
.
length
=
0
;
this
.
fetchMediaData
();
this
.
$events
.
listen
(
'
fileWasUploaded
'
,
eventData
=>
{
this
.
$events
.
listen
(
'
fileWasUploaded
'
,
(
eventData
)
=>
{
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
folder_id
:
eventData
.
data
.
folder_id
});
this
.
queryServer
({
folder_id
:
eventData
.
data
.
folder_id
});
});
this
.
$events
.
listen
(
'
folderWasCreated
'
,
eventData
=>
{
this
.
$events
.
listen
(
'
folderWasCreated
'
,
(
eventData
)
=>
{
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
folder_id
:
eventData
.
data
.
folder_id
});
this
.
queryServer
({
folder_id
:
eventData
.
data
.
folder_id
});
});
this
.
$events
.
listen
(
'
folderWasUpdated
'
,
eventData
=>
{
this
.
$events
.
listen
(
'
folderWasUpdated
'
,
(
eventData
)
=>
{
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
folder_id
:
eventData
.
data
.
folder_id
});
this
.
queryServer
({
folder_id
:
eventData
.
data
.
folder_id
});
});
}
}
this
.
$events
.
listen
(
'
mediaWasMoved
'
,
(
eventData
)
=>
{
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
folder_id
:
eventData
.
folder_id
});
this
.
fetchFolderBreadcrumb
(
eventData
.
folder_id
);
});
},
};
</
script
>
public/modules/media/js/components/MediaManager.vue
View file @
7de48576
...
...
@@ -7,9 +7,9 @@
<
script
>
export
default
{
data
()
{
return
{}
return
{}
;
},
methods
:
{},
mounted
()
{}
}
mounted
()
{}
,
}
;
</
script
>
public/modules/media/js/components/MoveMediaDialog.vue
0 → 100644
View file @
7de48576
<
template
>
<div>
<el-dialog
title=
"Move Media"
:visible
.
sync=
"dialogFormVisible"
width=
"30%"
class=
"move-media-dialog"
@
open=
"fetchFolders"
>
<el-form
v-loading
.
body=
"loading"
@
submit
.
native
.
prevent=
"onSubmit()"
>
<el-form-item
label=
"To"
:class=
"
{'el-form-item is-error': form.errors.has('destinationFolder') }">
<el-select
v-model=
"destinationFolder"
placeholder=
"Select"
>
<el-option
v-for=
"(item, id) in options"
:key=
"id"
:label=
"item"
:value=
"id"
:loading=
"selectIsLoading"
>
<span
v-html=
"item"
></span>
</el-option>
</el-select>
<div
class=
"el-form-item__error"
v-if=
"form.errors.has('destinationFolder')"
v-text=
"form.errors.first('destinationFolder')"
></div>
</el-form-item>
</el-form>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"closeDialog"
>
{{
trans
(
'
core.button.cancel
'
)
}}
</el-button>
<el-button
type=
"warning"
@
click=
"onSubmit()"
>
{{
trans
(
'
core.move
'
)
}}
</el-button>
</span>
</el-dialog>
</div>
</
template
>
<
script
>
import
axios
from
'
axios
'
;
import
Form
from
'
form-backend-validation
'
;
export
default
{
props
:
{
},
data
()
{
return
{
selectedMedia
:
[],
dialogFormVisible
:
false
,
form
:
new
Form
(),
loading
:
false
,
selectIsLoading
:
false
,
options
:
[],
destinationFolder
:
''
,
};
},
methods
:
{
onSubmit
()
{
this
.
loading
=
true
;
this
.
form
=
new
Form
({
files
:
this
.
selectedMedia
,
destinationFolder
:
this
.
destinationFolder
,
});
this
.
form
.
post
(
route
(
'
api.media.media.move
'
))
.
then
((
response
)
=>
{
this
.
loading
=
false
;
const
type
=
response
.
errors
===
true
?
'
warning
'
:
'
success
'
;
this
.
$message
({
type
,
message
:
response
.
message
,
});
this
.
dialogFormVisible
=
false
;
this
.
$events
.
emit
(
'
mediaWasMoved
'
,
response
);
})
.
catch
(()
=>
{
this
.
loading
=
false
;
this
.
$notify
.
error
({
title
:
'
Error
'
,
message
:
'
There are some errors in the form.
'
,
});
});
},
closeDialog
()
{
this
.
form
.
clear
();
this
.
dialogFormVisible
=
false
;
},
fetchFolders
()
{
this
.
selectIsLoading
=
true
;
axios
.
get
(
route
(
'
api.media.folders.all-nestable
'
))
.
then
((
response
)
=>
{
this
.
options
=
_
.
merge
(
response
.
data
,
{
0
:
'
Root
'
});
this
.
selectIsLoading
=
false
;
});
},
},
mounted
()
{
this
.
$events
.
listen
(
'
moveMediaWasClicked
'
,
(
eventData
)
=>
{
this
.
selectedMedia
=
eventData
;
this
.
dialogFormVisible
=
true
;
});
},
};
</
script
>
<
style
>
.move-media-dialog
.el-select
{
width
:
100%
;
}
</
style
>
public/modules/media/js/components/NewFolder.vue
View file @
7de48576
<
template
>
<div>
<el-button
type=
"success"
class=
"new-folder"
@
click=
"dialogFormVisible = true"
>
<i
class=
"
el-icon-fa-plus"
></i>
New Folder
<i
class=
"
fa fa-plus"
></i>
{{
trans
(
'
folders.create resource
'
)
}}
</el-button>
<el-dialog
title=
"New Folder"
:visible
.
sync=
"dialogFormVisible"
size=
"tiny
"
>
<el-dialog
:title=
"trans('folders.create resource')"
:visible
.
sync=
"dialogFormVisible"
width=
"30%
"
>
<el-form
:model=
"folder"
v-loading
.
body=
"loading"
@
submit
.
native
.
prevent=
"onSubmit()"
>
<el-form-item
label=
"Folder name
"
:class=
"
{'el-form-item is-error': form.errors.has('name') }">
<el-form-item
:label=
"trans('folders.folder name')
"
:class=
"
{'el-form-item is-error': form.errors.has('name') }">
<el-input
v-model=
"folder.name"
auto-complete=
"off"
autofocus
></el-input>
<div
class=
"el-form-item__error"
v-if=
"form.errors.has('name')"
v-text=
"form.errors.first('name')"
></div>
</el-form-item>
</el-form>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"closeDialog"
>
Cancel
</el-button>
<el-button
type=
"primary"
@
click=
"onSubmit()"
>
Confirm
</el-button>
<el-button
@
click=
"closeDialog"
>
{{
trans
(
'
core.button.cancel
'
)
}}
</el-button>
<el-button
type=
"primary"
@
click=
"onSubmit()"
>
{{
trans
(
'
core.confirm
'
)
}}
</el-button>
</span>
</el-dialog>
...
...
@@ -22,11 +22,11 @@
</
template
>
<
script
>
import
Form
from
'
form-backend-validation
'
import
Form
from
'
form-backend-validation
'
;
export
default
{
props
:
{
parentId
:
{
type
:
Number
}
parentId
:
{
type
:
Number
},
},
data
()
{
return
{
...
...
@@ -36,29 +36,29 @@
},
form
:
new
Form
(),
loading
:
false
,
}
}
;
},
methods
:
{
onSubmit
()
{
this
.
form
=
new
Form
(
_
.
merge
(
this
.
folder
,
{
parent_id
:
this
.
parentId
}));
this
.
form
=
new
Form
(
_
.
merge
(
this
.
folder
,
{
parent_id
:
this
.
parentId
}));
this
.
loading
=
true
;
this
.
form
.
post
(
route
(
'
api.media.folders.store
'
))
.
then
(
response
=>
{
.
then
(
(
response
)
=>
{
this
.
loading
=
false
;
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
message
message
:
response
.
message
,
});
this
.
dialogFormVisible
=
false
;
this
.
folder
.
name
=
''
;
this
.
$events
.
emit
(
'
folderWasCreated
'
,
response
);
})
.
catch
(
error
=>
{
.
catch
(
(
error
)
=>
{
console
.
log
(
error
);
this
.
loading
=
false
;
this
.
$notify
.
error
({
title
:
'
Error
'
,
message
:
'
There are some errors in the form.
'
message
:
'
There are some errors in the form.
'
,
});
});
},
...
...
@@ -68,8 +68,8 @@
},
},
mounted
()
{
}
}
}
,
}
;
</
script
>
<
style
>
.new-folder
{
...
...
public/modules/media/js/components/RenameFolder.vue
View file @
7de48576
<
template
>
<div>
<el-dialog
title=
"Rename Folder"
:visible
.
sync=
"dialogFormVisible"
size=
"tiny
"
>
<el-dialog
title=
"Rename Folder"
:visible
.
sync=
"dialogFormVisible"
width=
"30%
"
>
<el-form
:model=
"folder"
v-loading
.
body=
"loading"
@
submit
.
native
.
prevent=
"onSubmit()"
>
<el-form-item
label=
"Folder name"
:class=
"
{'el-form-item is-error': form.errors.has('name') }">
<el-input
v-model=
"folder.name"
auto-complete=
"off"
autofocus
></el-input>
...
...
@@ -9,15 +9,15 @@
</el-form-item>
</el-form>
<span
slot=
"footer"
class=
"dialog-footer"
>
<el-button
@
click=
"closeDialog"
>
Cancel
</el-button>
<el-button
type=
"primary"
@
click=
"onSubmit()"
>
Confirm
</el-button>
<el-button
@
click=
"closeDialog"
>
{{
trans
(
'
core.button.cancel
'
)
}}
</el-button>
<el-button
type=
"primary"
@
click=
"onSubmit()"
>
{{
trans
(
'
core.confirm
'
)
}}
</el-button>
</span>
</el-dialog>
</div>
</
template
>
<
script
>
import
Form
from
'
form-backend-validation
'
import
Form
from
'
form-backend-validation
'
;
export
default
{
// props: {
...
...
@@ -33,28 +33,28 @@
},
form
:
new
Form
(),
loading
:
false
,
}
}
;
},
methods
:
{
onSubmit
()
{
this
.
form
=
new
Form
(
this
.
folder
);
this
.
loading
=
true
;
this
.
form
.
post
(
route
(
'
api.media.folders.update
'
,
{
folder
:
this
.
folder
.
id
}))
.
then
(
response
=>
{
this
.
form
.
post
(
route
(
'
api.media.folders.update
'
,
{
folder
:
this
.
folder
.
id
}))
.
then
(
(
response
)
=>
{
this
.
loading
=
false
;
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
message
message
:
response
.
message
,
});
this
.
dialogFormVisible
=
false
;
this
.
$events
.
emit
(
'
folderWasUpdated
'
,
response
);
})
.
catch
(
error
=>
{
.
catch
(
(
error
)
=>
{
console
.
log
(
error
);
this
.
loading
=
false
;
this
.
$notify
.
error
({
title
:
'
Error
'
,
message
:
'
There are some errors in the form.
'
message
:
'
There are some errors in the form.
'
,
});
});
},
...
...
@@ -64,12 +64,12 @@
},
},
mounted
()
{
this
.
$events
.
listen
(
'
editFolderWasClicked
'
,
eventData
=>
{
this
.
$events
.
listen
(
'
editFolderWasClicked
'
,
(
eventData
)
=>
{
this
.
folder
.
name
=
eventData
.
filename
;
this
.
folder
.
id
=
eventData
.
id
;
this
.
folder
.
parent_id
=
eventData
.
folder_id
;
this
.
dialogFormVisible
=
true
;
});
}
}
}
,
}
;
</
script
>
public/modules/media/js/components/SingleMedia.vue
View file @
7de48576
...
...
@@ -16,7 +16,7 @@
<el-dialog
:visible
.
sync=
"dialogVisible"
size=
"full"
fullscreen
:before-close=
"handleClose"
>
<media-list
single-modal
:event-name=
"this.eventName"
></media-list>
...
...
@@ -29,18 +29,18 @@
</
template
>
<
script
>
import
axios
from
'
axios
'
;
import
UploadZone
from
'
./UploadZone.vue
'
;
import
MediaList
from
'
./MediaList.vue
'
;
import
StringHelpers
from
'
../../../../Core/Assets/js/mixins/StringHelpers
'
import
axios
from
'
axios
'
import
StringHelpers
from
'
../../../../Core/Assets/js/mixins/StringHelpers.vue
'
;
export
default
{
mixins
:
[
StringHelpers
],
props
:
{
zone
:
{
type
:
String
,
required
:
true
},
entity
:
{
type
:
String
,
required
:
true
},
entityId
:
{
type
:
Number
},
label
:
{
type
:
String
},
zone
:
{
type
:
String
,
required
:
true
},
entity
:
{
type
:
String
,
required
:
true
},
entityId
:
{
default
:
null
},
label
:
{
type
:
String
},
},
components
:
{
'
upload-zone
'
:
UploadZone
,
...
...
@@ -58,11 +58,11 @@
dialogVisible
:
false
,
selectedMedia
:
{},
eventName
:
''
,
}
}
;
},
computed
:
{
hasSelectedMedia
()
{
return
!
_
.
isEmpty
(
this
.
selectedMedia
);
return
!
_
.
isEmpty
(
this
.
selectedMedia
);
},
},
methods
:
{
...
...
@@ -71,7 +71,7 @@
},
unSelectMedia
()
{
this
.
selectedMedia
=
{};
this
.
$emit
(
'
singleFileSelected
'
,
_
.
merge
({
id
:
null
},
{
zone
:
this
.
zone
}));
this
.
$emit
(
'
singleFileSelected
'
,
_
.
merge
({
id
:
null
},
{
zone
:
this
.
zone
}));
},
fetchMedia
()
{
axios
.
get
(
route
(
'
api.media.find-first-by-zone-and-entity
'
,
{
...
...
@@ -79,32 +79,34 @@
entity
:
this
.
entity
,
entity_id
:
this
.
entityId
,
}))
.
then
(
response
=>
{
this
.
$emit
(
'
singleFileSelected
'
,
_
.
merge
(
response
.
data
.
data
,
{
zone
:
this
.
zone
}));
.
then
(
(
response
)
=>
{
this
.
$emit
(
'
singleFileSelected
'
,
_
.
merge
(
response
.
data
.
data
,
{
zone
:
this
.
zone
}));
this
.
selectedMedia
=
response
.
data
.
data
;
})
})
;
},
getFieldLabel
()
{
return
this
.
label
||
this
.
ucwords
(
this
.
zone
.
replace
(
'
_
'
,
'
'
));
},
makeId
()
{
let
text
=
""
;
let
possible
=
"
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
"
;
let
text
=
''
;
const
possible
=
'
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
'
;
for
(
let
i
=
0
;
i
<
5
;
i
++
)
text
+=
possible
.
charAt
(
Math
.
floor
(
Math
.
random
()
*
possible
.
length
));
for
(
let
i
=
0
;
i
<
5
;
i
++
)
{
text
+=
possible
.
charAt
(
Math
.
floor
(
Math
.
random
()
*
possible
.
length
));
}
return
text
;
},
},
mounted
()
{
this
.
eventName
=
'
fileWasSelected
'
+
this
.
makeId
()
+
Math
.
floor
(
Math
.
random
()
*
999999
);
if
(
this
.
entityId
)
{
this
.
fetchMedia
();
}
this
.
eventName
=
`fileWasSelected
${
this
.
makeId
()}${
Math
.
floor
(
Math
.
random
()
*
999999
)}
`
;
this
.
$events
.
listen
(
this
.
eventName
,
mediaData
=>
{
this
.
$events
.
listen
(
this
.
eventName
,
(
mediaData
)
=>
{
this
.
dialogVisible
=
false
;
this
.
selectedMedia
=
mediaData
;
this
.
$emit
(
'
singleFileSelected
'
,
_
.
merge
(
mediaData
,
{
zone
:
this
.
zone
}));
this
.
$emit
(
'
singleFileSelected
'
,
_
.
merge
(
mediaData
,
{
zone
:
this
.
zone
}));
});
}
}
}
,
}
;
</
script
>
public/modules/media/js/components/UploadButton.vue
View file @
7de48576
...
...
@@ -8,61 +8,61 @@
:http-request=
"uploadFile"
:multiple=
"true"
style=
"display: inline-block; margin-right: 10px;"
>
<el-button
size=
"small"
type=
"primary"
style=
"padding: 1
1
px 9px;"
:loading=
"fileIsUploading"
>
{{
trans
(
'
media.upload file
'
)
}}
</el-button>
<el-button
size=
"small"
type=
"primary"
style=
"padding: 1
3
px 9px;"
:loading=
"fileIsUploading"
>
{{
trans
(
'
media.upload file
'
)
}}
</el-button>
</el-upload>
</
template
>
<
script
>
import
axios
from
'
axios
'
import
axios
from
'
axios
'
;
export
default
{
props
:
{
parentId
:
{
type
:
Number
}
parentId
:
{
type
:
Number
},
},
data
()
{
return
{
fileIsUploading
:
false
,
}
}
;
},
computed
:
{
uploadUrl
()
{
return
route
(
'
api.media.store
'
).
domain
+
route
(
'
api.media.store
'
).
url
;
},
requestHeaders
()
{
le
t
userApiToken
=
document
.
head
.
querySelector
(
'
meta[name="user-api-token"]
'
);
cons
t
userApiToken
=
document
.
head
.
querySelector
(
'
meta[name="user-api-token"]
'
);
return
{
'
Authorization
'
:
'
Bearer
'
+
userApiToken
.
content
Authorization
:
`Bearer
${
userApiToken
.
content
}
`
,
};
},
},
methods
:
{
handleSuccess
(
response
,
file
,
fileList
)
{
handleSuccess
(
response
)
{
this
.
$events
.
emit
(
'
fileWasUploaded
'
,
response
);
},
uploadFile
(
event
)
{
this
.
fileIsUploading
=
true
;
le
t
data
=
new
FormData
();
cons
t
data
=
new
FormData
();
data
.
append
(
'
parent_id
'
,
this
.
parentId
);
data
.
append
(
'
file
'
,
event
.
file
);
axios
.
post
(
route
(
'
api.media.store
'
),
data
)
.
then
(
response
=>
{
.
then
(
(
response
)
=>
{
this
.
$events
.
emit
(
'
fileWasUploaded
'
,
response
);
this
.
fileIsUploading
=
false
;
})
.
catch
(
error
=>
{
.
catch
(
(
error
)
=>
{
console
.
log
(
error
.
response
.
data
);
this
.
fileIsUploading
=
false
;
this
.
$notify
.
error
({
title
:
'
Error
'
,
message
:
error
.
response
.
data
.
errors
.
file
[
0
]
message
:
error
.
response
.
data
.
errors
.
file
[
0
]
,
});
});
},
handleRemove
()
{},
},
mounted
()
{
}
}
}
,
}
;
</
script
>
<
style
>
.el-upload__input
{
...
...
public/modules/media/js/components/UploadZone.vue
View file @
7de48576
...
...
@@ -23,29 +23,29 @@
data
()
{
return
{
fileList
:
[],
}
}
;
},
computed
:
{
uploadUrl
()
{
return
route
(
'
api.media.store
'
).
domain
+
route
(
'
api.media.store
'
).
url
;
},
requestHeaders
()
{
le
t
userApiToken
=
document
.
head
.
querySelector
(
'
meta[name="user-api-token"]
'
);
cons
t
userApiToken
=
document
.
head
.
querySelector
(
'
meta[name="user-api-token"]
'
);
return
{
'
Authorization
'
:
'
Bearer
'
+
userApiToken
.
content
Authorization
:
`Bearer
${
userApiToken
.
content
}
`
,
};
},
},
methods
:
{
handleSuccess
(
response
,
file
,
fileList
)
{
handleSuccess
(
response
)
{
this
.
$events
.
emit
(
'
fileWasUploaded
'
,
response
);
this
.
fileList
=
[];
},
handlePreview
()
{},
handleRemove
()
{},
},
mounted
()
{}
}
mounted
()
{}
,
}
;
</
script
>
<
style
>
.el-upload__input
{
...
...
public/modules/page/js/PageRoutes.js
View file @
7de48576
import
PageTable
from
'
./components/PageTable.vue
'
import
PageTableServerSide
from
'
./components/PageTableServerSide.vue
'
import
PageForm
from
'
./components/PageForm.vue
'
import
PageTable
from
'
./components/PageTable.vue
'
;
import
PageTableServerSide
from
'
./components/PageTableServerSide.vue
'
;
import
PageForm
from
'
./components/PageForm.vue
'
;
const
locales
=
window
.
AsgardCMS
.
locales
;
...
...
@@ -17,7 +17,7 @@ export default [
props
:
{
locales
,
pageTitle
:
'
create page
'
,
}
}
,
},
{
path
:
'
/page/pages/:pageId/edit
'
,
...
...
@@ -26,6 +26,6 @@ export default [
props
:
{
locales
,
pageTitle
:
'
edit page
'
,
}
}
,
},
];
public/modules/page/js/components/PageForm.vue
View file @
7de48576
...
...
@@ -2,15 +2,15 @@
<div
class=
"div"
>
<div
class=
"content-header"
>
<h1>
{{
trans
(
`page.${pageTitle
}
`
)
}}
{{
trans
(
`page
s
.${pageTitle
}
`
)
}}
<
/h1
>
<
el
-
breadcrumb
separator
=
"
/
"
>
<
el
-
breadcrumb
-
item
>
<
a
href
=
"
/backend
"
>
Home
<
/a
>
<
/el-breadcrumb-item
>
<
el
-
breadcrumb
-
item
:
to
=
"
{name: 'admin.page.page.index'
}
"
>
{{
trans
(
'
page.pages
'
)
}}
<
el
-
breadcrumb
-
item
:
to
=
"
{name: 'admin.page.page.index'
}
"
>
{{
trans
(
'
page
s
.pages
'
)
}}
<
/el-breadcrumb-item
>
<
el
-
breadcrumb
-
item
:
to
=
"
{name: 'admin.page.page.create'
}
"
>
{{
trans
(
`page.${pageTitle
}
`
)
}}
<
el
-
breadcrumb
-
item
:
to
=
"
{name: 'admin.page.page.create'
}
"
>
{{
trans
(
`page
s
.${pageTitle
}
`
)
}}
<
/el-breadcrumb-item
>
<
/el-breadcrumb
>
<
/div
>
...
...
@@ -22,19 +22,19 @@
<
div
class
=
"
col-md-10
"
>
<
div
class
=
"
box box-primary
"
>
<
div
class
=
"
box-body
"
>
<
el
-
tabs
type
=
"
card
"
v
-
model
=
"
activeTab
"
>
<
el
-
tabs
v
-
model
=
"
activeTab
"
>
<
el
-
tab
-
pane
:
label
=
"
localeArray.name
"
v
-
for
=
"
(localeArray, locale) in locales
"
:
key
=
"
localeArray.name
"
:
name
=
"
locale
"
>
<
span
slot
=
"
label
"
:
class
=
"
{'error' : form.errors.has(locale)
}
"
>
{{
localeArray
.
name
}}
<
/span
>
<
el
-
form
-
item
:
label
=
"
trans('page.title')
"
<
el
-
form
-
item
:
label
=
"
trans('page
s
.title')
"
:
class
=
"
{'el-form-item is-error': form.errors.has(locale + '.title')
}
"
>
<
el
-
input
v
-
model
=
"
page[locale].title
"
><
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has(locale + '.title')
"
v
-
text
=
"
form.errors.first(locale + '.title')
"
><
/div
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('page.slug')
"
<
el
-
form
-
item
:
label
=
"
trans('page
s
.slug')
"
:
class
=
"
{'el-form-item is-error': form.errors.has(locale + '.slug')
}
"
>
<
el
-
input
v
-
model
=
"
page[locale].slug
"
>
<
el
-
button
slot
=
"
prepend
"
@
click
=
"
generateSlug($event, locale)
"
>
Generate
<
/el-button
>
...
...
@@ -43,7 +43,7 @@
v
-
text
=
"
form.errors.first(locale + '.slug')
"
><
/div
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('page.body')
"
<
el
-
form
-
item
:
label
=
"
trans('page
s
.body')
"
:
class
=
"
{'el-form-item is-error': form.errors.has(locale + '.body')
}
"
>
<
component
:
is
=
"
getCurrentEditor()
"
v
-
model
=
"
page[locale].body
"
:
value
=
"
page[locale].body
"
>
<
/component
>
...
...
@@ -52,22 +52,29 @@
v
-
text
=
"
form.errors.first(locale + '.body')
"
><
/div
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('pages.status')
"
:
class
=
"
{'el-form-item is-error': form.errors.has(locale + '.status')
}
"
>
<
el
-
checkbox
v
-
model
=
"
page[locale].status
"
>
{{
trans
(
'
pages.status
'
)
}}
<
/el-checkbox
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has(locale + '.status')
"
v
-
text
=
"
form.errors.first(locale + '.status')
"
><
/div
>
<
/el-form-item
>
<
div
class
=
"
panel box box-primary
"
>
<
div
class
=
"
box-header
"
>
<
h4
class
=
"
box-title
"
>
<
a
class
=
"
collapsed
"
data
-
toggle
=
"
collapse
"
data
-
parent
=
"
#accordion
"
:
href
=
"
`#collapseMeta-${locale
}
`
"
>
{{
trans
(
'
page.meta_data
'
)
}}
{{
trans
(
'
page
s
.meta_data
'
)
}}
<
/a
>
<
/h4
>
<
/div
>
<
div
style
=
"
height: 0px;
"
:
id
=
"
`collapseMeta-${locale
}
`
"
class
=
"
panel-collapse collapse
"
>
<
div
class
=
"
box-body
"
>
<
el
-
form
-
item
:
label
=
"
trans('page.meta_title')
"
>
<
el
-
form
-
item
:
label
=
"
trans('page
s
.meta_title')
"
>
<
el
-
input
v
-
model
=
"
page[locale].meta_title
"
><
/el-input
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('page.meta_description')
"
>
<
el
-
form
-
item
:
label
=
"
trans('page
s
.meta_description')
"
>
<
el
-
input
type
=
"
textarea
"
v
-
model
=
"
page[locale].meta_description
"
><
/el-input
>
<
/el-form-item
>
...
...
@@ -80,28 +87,28 @@
<
h4
class
=
"
box-title
"
>
<
a
class
=
"
collapsed
"
data
-
toggle
=
"
collapse
"
data
-
parent
=
"
#accordion
"
:
href
=
"
`#collapseFacebook-${locale
}
`
"
>
{{
trans
(
'
page.facebook_data
'
)
}}
{{
trans
(
'
page
s
.facebook_data
'
)
}}
<
/a
>
<
/h4
>
<
/div
>
<
div
style
=
"
height: 0px;
"
:
id
=
"
`collapseFacebook-${locale
}
`
"
class
=
"
panel-collapse collapse
"
>
<
div
class
=
"
box-body
"
>
<
el
-
form
-
item
:
label
=
"
trans('page.og_title')
"
>
<
el
-
form
-
item
:
label
=
"
trans('page
s
.og_title')
"
>
<
el
-
input
v
-
model
=
"
page[locale].og_title
"
><
/el-input
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('page.og_description')
"
>
<
el
-
form
-
item
:
label
=
"
trans('page
s
.og_description')
"
>
<
el
-
input
type
=
"
textarea
"
v
-
model
=
"
page[locale].og_description
"
><
/el-input
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('page.og_type')
"
>
<
el
-
form
-
item
:
label
=
"
trans('page
s
.og_type')
"
>
<
el
-
select
v
-
model
=
"
page[locale].og_type
"
:
placeholder
=
"
trans('page.og_type')
"
>
<
el
-
option
:
label
=
"
trans('page.facebook-types.website')
"
:
placeholder
=
"
trans('page
s
.og_type')
"
>
<
el
-
option
:
label
=
"
trans('page
s
.facebook-types.website')
"
value
=
"
website
"
><
/el-option
>
<
el
-
option
:
label
=
"
trans('page.facebook-types.product')
"
<
el
-
option
:
label
=
"
trans('page
s
.facebook-types.product')
"
value
=
"
product
"
><
/el-option
>
<
el
-
option
:
label
=
"
trans('page.facebook-types.article')
"
<
el
-
option
:
label
=
"
trans('page
s
.facebook-types.article')
"
value
=
"
article
"
><
/el-option
>
<
/el-select
>
<
/el-form-item
>
...
...
@@ -127,9 +134,9 @@
<
div
class
=
"
box-body
"
>
<
el
-
form
-
item
label
=
""
>
<
el
-
checkbox
v
-
model
=
"
page.is_home
"
:
true
-
label
=
"
1
"
:
false
-
label
=
"
0
"
name
=
"
is_home
"
:
label
=
"
trans('page.is homepage')
"
><
/el-checkbox
>
:
label
=
"
trans('page
s
.is homepage')
"
><
/el-checkbox
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('page.template')
"
<
el
-
form
-
item
:
label
=
"
trans('page
s
.template')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('template')
}
"
>
<
el
-
select
v
-
model
=
"
page.template
"
filterable
>
<
el
-
option
v
-
for
=
"
(template, key) in templates
"
:
key
=
"
template
"
...
...
@@ -138,10 +145,10 @@
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('template')
"
v
-
text
=
"
form.errors.first('template')
"
><
/div
>
<
/el-form-item
>
<
tags
-
input
namespace
=
"
asgardcms/page
"
v
-
model
=
"
tags
"
:
value
=
"
tags
"
:
current
-
tags
=
"
tags
"
><
/tags-input
>
<
tags
-
input
namespace
=
"
asgardcms/page
"
v
-
model
=
"
tags
"
:
current
-
tags
=
"
tags
"
><
/tags-input
>
<
single
-
media
zone
=
"
image
"
@
singleFileSelected
=
"
selectSingleFile($event, 'page')
"
entity
=
"
Modules
\
Page
\
Entities
\
Page
"
:
entity
-
id
=
"
page.i
d
"
><
/single-media
>
entity
=
"
Modules
\
Page
\
Entities
\
Page
"
:
entity
-
id
=
"
$route.params.pageI
d
"
><
/single-media
>
<
/div
>
<
/div
>
<
/div
>
...
...
@@ -152,19 +159,18 @@
<
/template
>
<
script
>
import
axios
from
'
axios
'
import
Slugify
from
'
../../../../Core/Assets/js/mixins/Slugify
'
import
ShortcutHelper
from
'
../../../../Core/Assets/js/mixins/ShortcutHelper
'
import
ActiveEditor
from
'
../../../../Core/Assets/js/mixins/ActiveEditor
'
import
SingleFileSelector
from
'
../../../../Media/Assets/js/mixins/SingleFileSelector
'
import
Form
from
'
form-backend-validation
'
import
axios
from
'
axios
'
;
import
Form
from
'
form-backend-validation
'
;
import
Slugify
from
'
../../../../Core/Assets/js/mixins/Slugify
'
;
import
ShortcutHelper
from
'
../../../../Core/Assets/js/mixins/ShortcutHelper
'
;
import
ActiveEditor
from
'
../../../../Core/Assets/js/mixins/ActiveEditor
'
;
import
SingleFileSelector
from
'
../../../../Media/Assets/js/mixins/SingleFileSelector
'
;
export
default
{
mixins
:
[
Slugify
,
ShortcutHelper
,
ActiveEditor
,
SingleFileSelector
],
props
:
{
locales
:
{
default
:
null
}
,
pageTitle
:
{
default
:
null
,
String
}
,
locales
:
{
default
:
null
}
,
pageTitle
:
{
default
:
null
,
String
}
,
}
,
data
()
{
return
{
...
...
@@ -181,49 +187,49 @@
og_type
:
''
,
}
])
.
fromPairs
()
.
merge
({
template
:
'
default
'
,
is_home
:
0
,
medias_single
:
[]
}
)
.
merge
({
template
:
'
default
'
,
is_home
:
0
,
medias_single
:
[]
}
)
.
value
(),
templates
:
{
'
index
'
:
'
index
'
,
'
home
'
:
'
home
'
,
'
default
'
:
'
default
'
,
index
:
'
index
'
,
home
:
'
home
'
,
default
:
'
default
'
,
}
,
form
:
new
Form
(),
loading
:
false
,
tags
:
{
}
,
activeTab
:
window
.
AsgardCMS
.
currentLocale
||
'
en
'
,
}
}
;
}
,
methods
:
{
onSubmit
()
{
this
.
form
=
new
Form
(
_
.
merge
(
this
.
page
,
{
tags
:
this
.
tags
}
));
this
.
form
=
new
Form
(
_
.
merge
(
this
.
page
,
{
tags
:
this
.
tags
}
));
this
.
loading
=
true
;
this
.
form
.
post
(
this
.
getRoute
())
.
then
(
response
=>
{
.
then
(
(
response
)
=>
{
this
.
loading
=
false
;
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
message
message
:
response
.
message
,
}
);
this
.
$router
.
push
({
name
:
'
admin.page.page.index
'
}
);
this
.
$router
.
push
({
name
:
'
admin.page.page.index
'
}
);
}
)
.
catch
(
error
=>
{
.
catch
(
(
error
)
=>
{
console
.
log
(
error
);
this
.
loading
=
false
;
this
.
$notify
.
error
({
title
:
'
Error
'
,
message
:
'
There are some errors in the form.
'
message
:
'
There are some errors in the form.
'
,
}
);
}
);
}
,
onCancel
()
{
this
.
$router
.
push
({
name
:
'
admin.page.page.index
'
}
);
this
.
$router
.
push
({
name
:
'
admin.page.page.index
'
}
);
}
,
fetchTemplates
()
{
axios
.
get
(
route
(
'
api.page.page-templates.index
'
))
.
then
(
response
=>
{
.
then
(
(
response
)
=>
{
this
.
templates
=
response
.
data
;
}
);
}
,
...
...
@@ -232,19 +238,17 @@
}
,
fetchPage
()
{
this
.
loading
=
true
;
axios
.
post
(
route
(
'
api.page.page.find
'
,
{
page
:
this
.
$route
.
params
.
pageId
}
))
.
then
(
response
=>
{
axios
.
post
(
route
(
'
api.page.page.find
'
,
{
page
:
this
.
$route
.
params
.
pageId
}
))
.
then
(
(
response
)
=>
{
this
.
loading
=
false
;
this
.
page
=
response
.
data
.
data
;
this
.
tags
=
response
.
data
.
data
.
tags
;
$
(
'
.publicUrl
'
).
attr
(
'
href
'
,
this
.
page
.
urls
.
public_url
).
show
();
}
)
.
catch
(
error
=>
{
}
)
}
);
}
,
getRoute
()
{
if
(
this
.
$route
.
params
.
pageId
!==
undefined
)
{
return
route
(
'
api.page.page.update
'
,
{
page
:
this
.
$route
.
params
.
pageId
}
);
return
route
(
'
api.page.page.update
'
,
{
page
:
this
.
$route
.
params
.
pageId
}
);
}
return
route
(
'
api.page.page.store
'
);
}
,
...
...
@@ -258,6 +262,6 @@
}
,
destroyed
()
{
$
(
'
.publicUrl
'
).
hide
();
}
}
}
,
}
;
<
/script
>
public/modules/page/js/components/PageTable.vue
View file @
7de48576
...
...
@@ -6,14 +6,14 @@
<data-tables
:data=
"data"
:actions-def=
"actionsDef"
>
<el-table-column
prop=
"id"
label=
"Id"
width=
"100"
>
</el-table-column>
<el-table-column
prop=
"title"
:label=
"trans('page.title')"
>
<el-table-column
prop=
"title"
:label=
"trans('page
s
.title')"
>
</el-table-column>
<el-table-column
prop=
"slug"
label=
"Slug"
>
</el-table-column>
<el-table-column
prop=
"created_at"
label=
"Created at"
>
</el-table-column>
<el-table-column
fixed=
"right"
prop=
"actions"
label=
"Actions"
>
<template
scope=
"scope"
>
<template
s
lot-s
cope=
"scope"
>
<a
class=
"btn btn-default btn-flat"
@
click
.
prevent=
"goToEdit(scope)"
><i
class=
"fa fa-pencil"
></i></a>
...
...
@@ -29,7 +29,7 @@
</template>
<
script
>
import
axios
from
'
axios
'
import
axios
from
'
axios
'
;
let
data
;
...
...
@@ -42,30 +42,30 @@
links
:
{},
actionsDef
:
{
def
:
[{
name
:
this
.
trans
(
'
page.create-page
'
),
name
:
this
.
trans
(
'
page
s
.create-page
'
),
icon
:
'
edit
'
,
handler
:
()
=>
{
this
.
$router
.
push
({
name
:
'
admin.page.page.create
'
})
}
}]
}
}
this
.
$router
.
push
({
name
:
'
admin.page.page.create
'
});
}
,
}]
,
}
,
}
;
},
methods
:
{
fetchData
()
{
axios
.
get
(
route
(
'
api.page.page.index
'
))
.
then
(
response
=>
{
.
then
(
(
response
)
=>
{
this
.
data
=
response
.
data
.
data
;
this
.
meta
=
response
.
data
.
meta
;
this
.
links
=
response
.
data
.
links
;
});
},
goToEdit
(
scope
)
{
this
.
$router
.
push
({
name
:
'
admin.page.page.edit
'
,
params
:
{
pageId
:
scope
.
row
.
id
}})
this
.
$router
.
push
({
name
:
'
admin.page.page.edit
'
,
params
:
{
pageId
:
scope
.
row
.
id
}
});
},
},
mounted
()
{
this
.
fetchData
();
}
}
}
,
}
;
</
script
>
public/modules/page/js/components/PageTableServerSide.vue
View file @
7de48576
...
...
@@ -2,13 +2,13 @@
<div
class=
"div"
>
<div
class=
"content-header"
>
<h1>
{{
trans
(
'
page.pages
'
)
}}
{{
trans
(
'
page
s
.pages
'
)
}}
</h1>
<el-breadcrumb
separator=
"/"
>
<el-breadcrumb-item>
<a
href=
"/backend"
>
Home
</a>
</el-breadcrumb-item>
<el-breadcrumb-item
:to=
"
{name: 'admin.page.page.index'}">
{{
trans
(
'
page.pages
'
)
}}
</el-breadcrumb-item>
<el-breadcrumb-item
:to=
"
{name: 'admin.page.page.index'}">
{{
trans
(
'
page
s
.pages
'
)
}}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
...
...
@@ -30,12 +30,12 @@
</el-dropdown>
<router-link
:to=
"
{name: 'admin.page.page.create'}">
<el-button
type=
"primary"
><i
class=
"el-icon-edit"
></i>
{{
trans
(
'
page.create page
'
)
}}
{{
trans
(
'
page
s
.create page
'
)
}}
</el-button>
</router-link>
</div>
<div
class=
"search el-col el-col-5"
>
<el-input
icon=
"search"
@
chang
e=
"performSearch"
v-model=
"searchQuery"
>
<el-input
prefix-icon=
"el-icon-search"
@
keyup
.
nativ
e=
"performSearch"
v-model=
"searchQuery"
>
</el-input>
</div>
</div>
...
...
@@ -52,26 +52,35 @@
type=
"selection"
width=
"55"
>
</el-table-column>
<el-table-column
:label=
"trans('page
.status')"
width=
"75
"
>
<template
scope=
"scope"
>
<i
class=
"
el-icon-
fa-circle"
:class=
"(scope.row.translations.status === true) ? 'text-success':'text-danger'"
></i>
<el-table-column
:label=
"trans('page
s.status')"
width=
"100
"
>
<template
s
lot-s
cope=
"scope"
>
<i
class=
"
fa
fa-circle"
:class=
"(scope.row.translations.status === true) ? 'text-success':'text-danger'"
></i>
</
template
>
</el-table-column>
<el-table-column
prop=
"id"
label=
"Id"
width=
"
100
"
sortable=
"custom"
>
<el-table-column
prop=
"id"
label=
"Id"
width=
"
75
"
sortable=
"custom"
>
</el-table-column>
<el-table-column
prop=
"translations.title"
:label=
"trans('page.title')"
>
<el-table-column
prop=
"translations.title"
:label=
"trans('pages.title')"
>
<
template
slot-scope=
"scope"
>
<a
@
click
.
prevent=
"goToEdit(scope)"
href=
"#"
>
{{
scope
.
row
.
translations
.
title
}}
</a>
</
template
>
</el-table-column>
<el-table-column
prop=
"translations.slug"
:label=
"trans('page.slug')"
>
<el-table-column
prop=
"translations.slug"
:label=
"trans('pages.slug')"
>
<
template
slot-scope=
"scope"
>
<a
@
click
.
prevent=
"goToEdit(scope)"
href=
"#"
>
{{
scope
.
row
.
translations
.
slug
}}
</a>
</
template
>
</el-table-column>
<el-table-column
prop=
"created_at"
:label=
"trans('core.table.created at')"
sortable=
"custom"
>
</el-table-column>
<el-table-column
fixed=
"right"
prop=
"actions"
:label=
"trans('core.table.actions')"
>
<
template
scope=
"scope"
>
<a
class=
"btn btn-default btn-flat"
@
click
.
prevent=
"goToEdit(scope)"
><i
class=
"fa fa-pencil"
></i></a>
<delete-button
:scope=
"scope"
:rows=
"data"
>
</delete-button>
<el-table-column
prop=
"actions"
:label=
"trans('core.table.actions')"
>
<
template
slot-scope=
"scope"
>
<el-button-group>
<edit-button
:to=
"
{name: 'admin.page.page.edit', params: {pageId: scope.row.id}}">
</edit-button>
<delete-button
:scope=
"scope"
:rows=
"data"
></delete-button>
</el-button-group>
</
template
>
</el-table-column>
</el-table>
...
...
@@ -96,9 +105,9 @@
</template>
<
script
>
import
axios
from
'
axios
'
import
_
from
"
lodash
"
;
import
ShortcutHelper
from
'
../../../../Core/Assets/js/mixins/ShortcutHelper
'
import
axios
from
'
axios
'
;
import
_
from
'
lodash
'
;
import
ShortcutHelper
from
'
../../../../Core/Assets/js/mixins/ShortcutHelper
'
;
let
data
;
...
...
@@ -120,16 +129,16 @@
tableIsLoading
:
false
,
showExtraButtons
:
false
,
selectedPages
:
{},
}
}
;
},
watch
:
{
selectedPages
()
{
this
.
s
electedPages
.
length
>=
1
?
this
.
showExtraButtons
=
true
:
this
.
showExtraButtons
=
false
;
}
this
.
s
howExtraButtons
=
this
.
selectedPages
.
length
>=
1
;
}
,
},
methods
:
{
queryServer
(
customProperties
)
{
le
t
properties
=
{
cons
t
properties
=
{
page
:
this
.
meta
.
current_page
,
per_page
:
this
.
meta
.
per_page
,
order_by
:
this
.
order_meta
.
order_by
,
...
...
@@ -138,7 +147,7 @@
};
axios
.
get
(
route
(
'
api.page.page.indexServerSide
'
,
_
.
merge
(
properties
,
customProperties
)))
.
then
(
response
=>
{
.
then
(
(
response
)
=>
{
this
.
tableIsLoading
=
false
;
this
.
data
=
response
.
data
.
data
;
this
.
meta
=
response
.
data
.
meta
;
...
...
@@ -152,59 +161,66 @@
this
.
tableIsLoading
=
true
;
this
.
queryServer
();
},
goToEdit
(
scope
)
{
this
.
$router
.
push
({
name
:
'
admin.page.page.edit
'
,
params
:
{
pageId
:
scope
.
row
.
id
}})
},
handleSizeChange
(
event
)
{
console
.
log
(
'
per page :
'
+
event
);
console
.
log
(
`per page :
${
event
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
per_page
:
event
});
this
.
queryServer
({
per_page
:
event
});
},
handleCurrentChange
(
event
)
{
console
.
log
(
'
current page :
'
+
event
);
console
.
log
(
`current page :
${
event
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
page
:
event
});
this
.
queryServer
({
page
:
event
});
},
handleSortChange
(
event
)
{
console
.
log
(
'
sorting
'
,
event
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
order_by
:
event
.
prop
,
order
:
event
.
order
,
});
this
.
queryServer
({
order_by
:
event
.
prop
,
order
:
event
.
order
});
},
performSearch
(
query
)
{
console
.
log
(
'
searching:
'
+
query
);
performSearch
:
_
.
debounce
(
function
(
query
)
{
console
.
log
(
`searching:
${
query
.
target
.
value
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
search
:
query
});
},
this
.
queryServer
({
search
:
query
.
target
.
value
});
},
300
),
handleExtraActions
(
action
)
{
let
pageIds
=
_
.
map
(
this
.
selectedPages
,
function
(
elem
)
{
return
elem
.
id
;
});
axios
.
get
(
route
(
'
api.page.page.mark-status
'
,
{
action
:
action
,
pageIds
:
JSON
.
stringify
(
pageIds
)}))
.
then
(
response
=>
{
const
pageIds
=
_
.
map
(
this
.
selectedPages
,
elem
=>
elem
.
id
);
axios
.
get
(
route
(
'
api.page.page.mark-status
'
,
{
action
,
pageIds
:
JSON
.
stringify
(
pageIds
)
}))
.
then
((
response
)
=>
{
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
data
.
message
message
:
response
.
data
.
message
,
});
this
.
$refs
.
pageTable
.
clearSelection
();
this
.
data
.
find
(
function
(
page
)
{
if
(
pageIds
.
indexOf
(
page
.
id
)
>=
0
)
{
this
.
data
.
filter
(
page
=>
pageIds
.
indexOf
(
page
.
id
)
>=
0
)
.
map
((
p
)
=>
{
const
page
=
p
;
page
.
translations
.
status
=
action
===
'
mark-online
'
;
}
return
page
;
});
})
.
catch
(
error
=>
{
.
catch
(
()
=>
{
this
.
$message
({
type
:
'
error
'
,
message
:
this
.
trans
(
'
core.something went wrong
'
),
});
})
})
;
},
handleSelectionChange
(
selectedPages
)
{
this
.
selectedPages
=
selectedPages
;
},
goToEdit
(
scope
)
{
this
.
$router
.
push
({
name
:
'
admin.page.page.edit
'
,
params
:
{
pageId
:
scope
.
row
.
id
}
});
},
},
mounted
()
{
this
.
fetchData
();
},
};
</
script
>
<
style
>
.text-success
{
color
:
#13ce66
;
}
.text-danger
{
color
:
#ff4949
;
}
</
s
cript
>
</
s
tyle
>
public/modules/user/js/UserRoutes.js
0 → 100644
View file @
7de48576
import
RoleTable
from
'
./components/RoleTable.vue
'
;
import
RoleForm
from
'
./components/RoleForm.vue
'
;
import
UserTable
from
'
./components/UserTable.vue
'
;
import
UserForm
from
'
./components/UserForm.vue
'
;
import
UserProfile
from
'
./components/UserProfile.vue
'
;
import
ApiKeys
from
'
./components/ApiKeys.vue
'
;
const
locales
=
window
.
AsgardCMS
.
locales
;
export
default
[
// Role Routes
{
path
:
'
/user/roles
'
,
name
:
'
admin.user.roles.index
'
,
component
:
RoleTable
,
},
{
path
:
'
/user/roles/create
'
,
name
:
'
admin.user.roles.create
'
,
component
:
RoleForm
,
props
:
{
locales
,
pageTitle
:
'
new-role
'
,
},
},
{
path
:
'
/user/roles/:roleId/edit
'
,
name
:
'
admin.user.roles.edit
'
,
component
:
RoleForm
,
props
:
{
locales
,
pageTitle
:
'
title.edit
'
,
},
},
// User Routes
{
path
:
'
/user/users
'
,
name
:
'
admin.user.users.index
'
,
component
:
UserTable
,
},
{
path
:
'
/user/users/create
'
,
name
:
'
admin.user.users.create
'
,
component
:
UserForm
,
props
:
{
locales
,
pageTitle
:
'
title.new-user
'
,
},
},
{
path
:
'
/user/users/:userId/edit
'
,
name
:
'
admin.user.users.edit
'
,
component
:
UserForm
,
props
:
{
locales
,
pageTitle
:
'
title.edit-user
'
,
},
},
// Account routes
{
path
:
'
/account/profile
'
,
name
:
'
admin.user.users.account
'
,
component
:
UserProfile
,
},
{
path
:
'
/account/api-keys
'
,
name
:
'
admin.user.users.account.api-keys
'
,
component
:
ApiKeys
,
},
];
public/modules/user/js/components/ApiKeys.vue
0 → 100644
View file @
7de48576
<
template
>
<div>
<div
class=
"content-header"
>
<h1>
{{
trans
(
'
users.api-keys
'
)
}}
</h1>
<el-breadcrumb
separator=
"/"
>
<el-breadcrumb-item>
<a
href=
"/backend"
>
{{
trans
(
'
core.breadcrumb.home
'
)
}}
</a>
</el-breadcrumb-item>
<el-breadcrumb-item
:to=
"
{name: 'admin.user.users.account.api-keys'}">
{{
trans
(
'
users.api-keys
'
)
}}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div
class=
"row"
>
<div
class=
"col-md-12"
>
<div
class=
"box box-primary"
>
<div
class=
"box-header with-border"
>
<h3
class=
"box-title"
>
{{
trans
(
'
users.your api keys
'
)
}}
</h3>
<div
class=
"box-tools pull-right"
>
<el-button
type=
"primary"
size=
"small"
icon=
"plus"
@
click=
"generateKey"
>
{{
trans
(
'
users.generate new api key
'
)
}}
</el-button>
</div>
</div>
<div
class=
"box-body"
>
<ul
class=
"list-unstyled"
>
<li
style=
"margin-bottom: 20px;"
v-for=
"key in apiKeys"
:key=
"key.id"
>
<el-input
v-model=
"key.access_token"
disabled
>
<el-button
slot-scope=
"prepend"
@
click=
"destroyApiKey(key)"
>
<i
class=
"fa fa-times"
></i>
</el-button>
</el-input>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
import
axios
from
'
axios
'
;
export
default
{
data
()
{
return
{
loading
:
false
,
apiKeys
:
{},
};
},
methods
:
{
fetchApiKeys
()
{
this
.
loading
=
true
;
axios
.
get
(
route
(
'
api.account.api.index
'
))
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
apiKeys
=
response
.
data
.
data
;
});
},
generateKey
()
{
axios
.
get
(
route
(
'
api.account.api.create
'
))
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
apiKeys
=
response
.
data
.
data
;
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
data
.
message
,
});
});
},
destroyApiKey
(
apiKey
)
{
this
.
$confirm
(
this
.
trans
(
'
users.delete api key confirm
'
),
''
,
{
confirmButtonText
:
this
.
trans
(
'
core.button.delete
'
),
cancelButtonText
:
this
.
trans
(
'
core.button.cancel
'
),
type
:
'
warning
'
,
confirmButtonClass
:
'
el-button--danger
'
,
}).
then
(()
=>
{
axios
.
delete
(
route
(
'
api.account.api.destroy
'
,
{
userTokenId
:
apiKey
.
id
}))
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
apiKeys
=
response
.
data
.
data
;
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
data
.
message
,
});
});
})
.
catch
(()
=>
{
});
},
},
mounted
()
{
this
.
fetchApiKeys
();
},
};
</
script
>
public/modules/user/js/components/AsgardPermissions.vue
0 → 100644
View file @
7de48576
<
template
>
<div>
<p
class=
"pull-right"
>
<el-button
type=
"text"
@
click=
"changeStateForAll(1)"
>
{{
trans
(
'
roles.allow all
'
)
}}
</el-button>
<el-button
type=
"text"
:disabled=
"isRole"
@
click=
"changeStateForAll(0)"
>
{{
trans
(
'
roles.inherit all
'
)
}}
</el-button>
<el-button
type=
"text"
@
click=
"changeStateForAll(-1)"
>
{{
trans
(
'
roles.deny all
'
)
}}
</el-button>
</p>
<div
v-for=
"(value, name) in allPermissions"
:key=
"name"
>
<h3>
{{
name
}}
</h3>
<div
v-for=
"(permissionActions, subPermissionTitle) in value"
:key=
"subPermissionTitle"
>
<div
class=
"row"
>
<div
class=
"col-md-12"
>
<div
class=
"row"
>
<div
class=
"col-md-3"
><h4
class=
"pull-left"
>
{{
ucfirst
(
subPermissionTitle
)
}}
</h4></div>
<div
class=
"col-md-9"
>
<p
style=
"margin-top: 10px;"
>
<el-button
type=
"text"
@
click=
"changeState(subPermissionTitle, permissionActions, 1)"
>
{{
trans
(
'
roles.allow all
'
)
}}
</el-button>
<el-button
type=
"text"
:disabled=
"isRole"
@
click=
"changeState(subPermissionTitle, permissionActions, 0)"
>
{{
trans
(
'
roles.inherit all
'
)
}}
</el-button>
<el-button
type=
"text"
@
click=
"changeState(subPermissionTitle, permissionActions, -1)"
>
{{
trans
(
'
roles.deny all
'
)
}}
</el-button>
</p>
</div>
</div>
</div>
</div>
<div
class=
"row"
>
<div
class=
"col-md-12"
v-for=
"(label, permissionAction) in permissionActions"
:key=
"permissionAction"
>
<div
class=
"row"
>
<div
class=
"col-md-3"
>
<div
class=
"visible-sm-block visible-md-block visible-lg-block"
>
<label
class=
"control-label text-right"
style=
"display: block"
>
{{
parseTranslation
(
label
)
}}
</label>
</div>
<div
class=
"visible-xs-block"
>
<label
class=
"control-label"
>
{{
parseTranslation
(
label
)
}}
</label>
</div>
</div>
<div
class=
"col-md-9"
>
<el-radio-group
v-model=
"permissions[`$
{subPermissionTitle}.${permissionAction}`]">
<el-radio-button
:label=
"1"
@
click=
"triggerEvent"
>
{{
trans
(
'
roles.allow
'
)
}}
</el-radio-button>
<el-radio-button
:label=
"0"
@
click=
"triggerEvent"
:disabled=
"isRole"
>
{{
trans
(
'
roles.inherit
'
)
}}
</el-radio-button>
<el-radio-button
:label=
"-1"
@
click=
"triggerEvent"
>
{{
trans
(
'
roles.deny
'
)
}}
</el-radio-button>
</el-radio-group>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
import
axios
from
'
axios
'
;
import
StringHelpers
from
'
../../../../Core/Assets/js/mixins/StringHelpers.vue
'
;
export
default
{
mixins
:
[
StringHelpers
],
props
:
{
isRole
:
{
type
:
Boolean
},
currentPermissions
:
{
default
:
null
},
},
data
()
{
return
{
permissions
:
{},
allPermissions
:
{},
};
},
methods
:
{
triggerEvent
()
{
this
.
$emit
(
'
input
'
,
this
.
permissions
);
},
parseTranslation
(
label
)
{
return
this
.
trans
(
label
.
split
(
'
::
'
)[
1
]);
},
getPermissionKey
(
subPermissionTitle
,
permissionAction
)
{
return
`
${
subPermissionTitle
}
.
${
permissionAction
}
`
;
},
changeState
(
permissionPart
,
actions
,
state
)
{
_
.
forEach
(
actions
,
(
translationKey
,
key
)
=>
{
this
.
permissions
[
`
${
permissionPart
}
.
${
key
}
`
]
=
state
;
});
},
changeStateForAll
(
state
)
{
_
.
forEach
(
this
.
permissions
,
(
index
,
permission
)
=>
{
this
.
permissions
[
permission
]
=
state
;
});
},
fetchPermissions
()
{
axios
.
get
(
route
(
'
api.user.permissions.index
'
))
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
allPermissions
=
response
.
data
.
permissions
;
});
},
},
watch
:
{
currentPermissions
()
{
if
(
this
.
currentPermissions
!==
null
)
{
this
.
permissions
=
this
.
currentPermissions
;
}
},
},
mounted
()
{
this
.
fetchPermissions
();
},
};
</
script
>
public/modules/user/js/components/RoleForm.vue
0 → 100644
View file @
7de48576
<
template
>
<div>
<div
class=
"content-header"
>
<h1>
{{
trans
(
`roles.${pageTitle
}
`
)
}}
<
small
>
{{
role
.
name
}}
<
/small
>
<
/h1
>
<
el
-
breadcrumb
separator
=
"
/
"
>
<
el
-
breadcrumb
-
item
>
<
a
href
=
"
/backend
"
>
{{
trans
(
'
core.breadcrumb.home
'
)
}}
<
/a
>
<
/el-breadcrumb-item
>
<
el
-
breadcrumb
-
item
:
to
=
"
{name: 'admin.user.roles.index'
}
"
>
{{
trans
(
'
roles.title.roles
'
)
}}
<
/el-breadcrumb-item
>
<
el
-
breadcrumb
-
item
:
to
=
"
{name: 'admin.user.roles.create'
}
"
>
{{
trans
(
`roles.${pageTitle
}
`
)
}}
<
/el-breadcrumb-item
>
<
/el-breadcrumb
>
<
/div
>
<
el
-
form
ref
=
"
form
"
:
model
=
"
role
"
label
-
width
=
"
120px
"
label
-
position
=
"
top
"
v
-
loading
.
body
=
"
loading
"
@
keydown
=
"
form.errors.clear($event.target.name);
"
>
<
div
class
=
"
row
"
>
<
div
class
=
"
col-md-12
"
>
<
div
class
=
"
box box-primary
"
>
<
div
class
=
"
box-body
"
>
<
el
-
tabs
>
<
el
-
tab
-
pane
:
label
=
"
trans('roles.tabs.data')
"
>
<
el
-
form
-
item
:
label
=
"
trans('roles.form.name')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('name')
}
"
>
<
el
-
input
v
-
model
=
"
role.name
"
><
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('name')
"
v
-
text
=
"
form.errors.first('name')
"
><
/div
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('roles.form.slug')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('slug')
}
"
>
<
el
-
input
v
-
model
=
"
role.slug
"
>
<
el
-
button
slot
-
scope
=
"
prepend
"
@
click
=
"
generateSlug
"
>
Generate
<
/el-button
>
<
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('slug')
"
v
-
text
=
"
form.errors.first('slug')
"
><
/div
>
<
/el-form-item
>
<
/el-tab-pane
>
<
el
-
tab
-
pane
:
label
=
"
trans('roles.tabs.permissions')
"
>
<
asgard
-
permissions
v
-
model
=
"
role.permissions
"
is
-
role
:
current
-
permissions
=
"
role.permissions
"
><
/asgard-permissions
>
<
/el-tab-pane
>
<
el
-
tab
-
pane
:
label
=
"
trans('users.title.users')
"
>
<
h3
>
{{
trans
(
'
roles.title.users-with-roles
'
)
}}
<
/h3
>
<
ul
>
<
li
v
-
for
=
"
user in role.users
"
:
key
=
"
user.id
"
>
{{
user
.
fullname
}}
({{
user
.
email
}}
)
<
/li
>
<
/ul
>
<
/el-tab-pane
>
<
/el-tabs
>
<
/div
>
<
div
class
=
"
box-footer
"
>
<
el
-
form
-
item
>
<
el
-
button
type
=
"
primary
"
@
click
=
"
onSubmit()
"
:
loading
=
"
loading
"
>
{{
trans
(
'
core.save
'
)
}}
<
/el-button
>
<
el
-
button
@
click
=
"
onCancel()
"
>
{{
trans
(
'
core.button.cancel
'
)
}}
<
/el-button
>
<
/el-form-item
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/el-form
>
<
button
v
-
shortkey
=
"
['b']
"
@
shortkey
=
"
pushRoute({name: 'admin.user.roles.index'
}
)
"
v
-
show
=
"
false
"
><
/button
>
<
/div
>
<
/template
>
<
script
>
import
axios
from
'
axios
'
;
import
Form
from
'
form-backend-validation
'
;
import
Slugify
from
'
../../../../Core/Assets/js/mixins/Slugify
'
;
import
ShortcutHelper
from
'
../../../../Core/Assets/js/mixins/ShortcutHelper
'
;
import
AsgardPermissions
from
'
./AsgardPermissions.vue
'
;
export
default
{
mixins
:
[
Slugify
,
ShortcutHelper
],
components
:
{
'
asgard-permissions
'
:
AsgardPermissions
,
}
,
props
:
{
locales
:
{
default
:
null
}
,
pageTitle
:
{
default
:
null
,
String
}
,
}
,
data
()
{
return
{
role
:
{
name
:
''
,
slug
:
''
,
permissions
:
{
}
,
users
:
{
}
,
}
,
form
:
new
Form
(),
loading
:
false
,
}
;
}
,
methods
:
{
onSubmit
()
{
this
.
form
=
new
Form
(
this
.
role
);
this
.
loading
=
true
;
this
.
form
.
post
(
this
.
getRoute
())
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
message
,
}
);
this
.
$router
.
push
({
name
:
'
admin.user.roles.index
'
}
);
}
)
.
catch
((
error
)
=>
{
console
.
log
(
error
);
this
.
loading
=
false
;
this
.
$notify
.
error
({
title
:
'
Error
'
,
message
:
'
There are some errors in the form.
'
,
}
);
}
);
}
,
onCancel
()
{
this
.
$router
.
push
({
name
:
'
admin.user.roles.index
'
}
);
}
,
generateSlug
()
{
this
.
role
.
slug
=
this
.
slugify
(
this
.
role
.
name
);
}
,
fetchRole
()
{
this
.
loading
=
true
;
let
routeUri
=
''
;
if
(
this
.
$route
.
params
.
roleId
!==
undefined
)
{
routeUri
=
route
(
'
api.user.role.find
'
,
{
role
:
this
.
$route
.
params
.
roleId
}
);
}
else
{
routeUri
=
route
(
'
api.user.role.find-new
'
);
}
axios
.
post
(
routeUri
)
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
role
=
response
.
data
.
data
;
}
);
}
,
getRoute
()
{
if
(
this
.
$route
.
params
.
roleId
!==
undefined
)
{
return
route
(
'
api.user.role.update
'
,
{
role
:
this
.
$route
.
params
.
roleId
}
);
}
return
route
(
'
api.user.role.store
'
);
}
,
}
,
mounted
()
{
this
.
fetchRole
();
}
,
}
;
<
/script
>
public/modules/user/js/components/RoleTable.vue
0 → 100644
View file @
7de48576
<
template
>
<div>
<div
class=
"content-header"
>
<h1>
{{
trans
(
'
roles.title.roles
'
)
}}
</h1>
<el-breadcrumb
separator=
"/"
>
<el-breadcrumb-item>
<a
href=
"/backend"
>
{{
trans
(
'
core.breadcrumb.home
'
)
}}
</a>
</el-breadcrumb-item>
<el-breadcrumb-item
:to=
"
{name: 'admin.user.roles.index'}">
{{
trans
(
'
roles.title.roles
'
)
}}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div
class=
"row"
>
<div
class=
"col-xs-12"
>
<div
class=
"box box-primary"
>
<div
class=
"box-body"
>
<div
class=
"sc-table"
>
<div
class=
"tool-bar el-row"
style=
"padding-bottom: 20px;"
>
<div
class=
"actions el-col el-col-8"
>
<router-link
:to=
"
{name: 'admin.user.roles.create'}">
<el-button
type=
"primary"
><i
class=
"el-icon-edit"
></i>
{{
trans
(
'
roles.new-role
'
)
}}
</el-button>
</router-link>
</div>
<div
class=
"search el-col el-col-5"
>
<el-input
prefix-icon=
"el-icon-search"
@
keyup
.
native=
"performSearch"
v-model=
"searchQuery"
>
</el-input>
</div>
</div>
<el-table
:data=
"data"
stripe
style=
"width: 100%"
ref=
"pageTable"
v-loading
.
body=
"tableIsLoading"
@
sort-change=
"handleSortChange"
>
<el-table-column
prop=
"id"
label=
"Id"
width=
"75"
sortable=
"custom"
>
</el-table-column>
<el-table-column
prop=
"name"
:label=
"trans('roles.table.name')"
sortable=
"custom"
>
<template
slot-scope=
"scope"
>
<a
@
click
.
prevent=
"goToEdit(scope)"
href=
"#"
>
{{
scope
.
row
.
name
}}
</a>
</
template
>
</el-table-column>
<el-table-column
prop=
"slug"
:label=
"trans('roles.table.slug')"
sortable=
"custom"
>
<
template
slot-scope=
"scope"
>
<a
@
click
.
prevent=
"goToEdit(scope)"
href=
"#"
>
{{
scope
.
row
.
slug
}}
</a>
</
template
>
</el-table-column>
<el-table-column
prop=
"created_at"
:label=
"trans('core.table.created at')"
sortable=
"custom"
>
</el-table-column>
<el-table-column
prop=
"actions"
:label=
"trans('core.table.actions')"
>
<
template
slot-scope=
"scope"
>
<el-button-group>
<edit-button
:to=
"
{name: 'admin.user.roles.edit', params: {roleId: scope.row.id}}">
</edit-button>
<delete-button
:scope=
"scope"
:rows=
"data"
></delete-button>
</el-button-group>
</
template
>
</el-table-column>
</el-table>
<div
class=
"pagination-wrap"
style=
"text-align: center; padding-top: 20px;"
>
<el-pagination
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
:current-page
.
sync=
"meta.current_page"
:page-sizes=
"[10, 20, 50, 100]"
:page-size=
"parseInt(meta.per_page)"
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"meta.total"
>
</el-pagination>
</div>
</div>
</div>
</div>
</div>
</div>
<button
v-shortkey=
"['c']"
@
shortkey=
"pushRoute({name: 'admin.user.roles.create'})"
v-show=
"false"
></button>
</div>
</template>
<
script
>
import
axios
from
'
axios
'
;
import
_
from
'
lodash
'
;
import
ShortcutHelper
from
'
../../../../Core/Assets/js/mixins/ShortcutHelper
'
;
export
default
{
mixins
:
[
ShortcutHelper
],
data
()
{
return
{
data
:
[],
meta
:
{
current_page
:
1
,
per_page
:
10
,
},
order_meta
:
{
order_by
:
''
,
order
:
''
,
},
links
:
{},
searchQuery
:
''
,
tableIsLoading
:
false
,
};
},
methods
:
{
queryServer
(
customProperties
)
{
const
properties
=
{
page
:
this
.
meta
.
current_page
,
per_page
:
this
.
meta
.
per_page
,
order_by
:
this
.
order_meta
.
order_by
,
order
:
this
.
order_meta
.
order
,
search
:
this
.
searchQuery
,
};
axios
.
get
(
route
(
'
api.user.role.index
'
,
_
.
merge
(
properties
,
customProperties
)))
.
then
((
response
)
=>
{
this
.
tableIsLoading
=
false
;
this
.
data
=
response
.
data
.
data
;
this
.
meta
=
response
.
data
.
meta
;
this
.
links
=
response
.
data
.
links
;
this
.
order_meta
.
order_by
=
properties
.
order_by
;
this
.
order_meta
.
order
=
properties
.
order
;
});
},
fetchData
()
{
this
.
tableIsLoading
=
true
;
this
.
queryServer
();
},
handleSizeChange
(
event
)
{
console
.
log
(
`per page :
${
event
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
per_page
:
event
});
},
handleCurrentChange
(
event
)
{
console
.
log
(
`current page :
${
event
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
page
:
event
});
},
handleSortChange
(
event
)
{
console
.
log
(
'
sorting
'
,
event
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
order_by
:
event
.
prop
,
order
:
event
.
order
});
},
performSearch
:
_
.
debounce
(
function
(
query
)
{
console
.
log
(
`searching:
${
query
.
target
.
value
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
search
:
query
.
target
.
value
});
},
300
),
goToEdit
(
scope
)
{
this
.
$router
.
push
({
name
:
'
admin.user.roles.edit
'
,
params
:
{
roleId
:
scope
.
row
.
id
}
});
},
},
mounted
()
{
this
.
fetchData
();
},
};
</
script
>
public/modules/user/js/components/UserForm.vue
0 → 100644
View file @
7de48576
<
template
>
<div>
<div
class=
"content-header"
>
<h1>
{{
trans
(
`users.${pageTitle
}
`
)
}}
<
small
>
{{
user
.
first_name
}}
{{
user
.
last_name
}}
<
/small
>
<
/h1
>
<
el
-
breadcrumb
separator
=
"
/
"
>
<
el
-
breadcrumb
-
item
>
<
a
href
=
"
/backend
"
>
{{
trans
(
'
core.breadcrumb.home
'
)
}}
<
/a
>
<
/el-breadcrumb-item
>
<
el
-
breadcrumb
-
item
:
to
=
"
{name: 'admin.user.users.index'
}
"
>
{{
trans
(
'
users.title.users
'
)
}}
<
/el-breadcrumb-item
>
<
el
-
breadcrumb
-
item
:
to
=
"
{name: 'admin.user.users.create'
}
"
>
{{
trans
(
`users.${pageTitle
}
`
)
}}
<
/el-breadcrumb-item
>
<
/el-breadcrumb
>
<
/div
>
<
el
-
form
ref
=
"
form
"
:
model
=
"
user
"
label
-
width
=
"
120px
"
label
-
position
=
"
top
"
v
-
loading
.
body
=
"
loading
"
@
keydown
=
"
form.errors.clear($event.target.name);
"
>
<
div
class
=
"
row
"
>
<
div
class
=
"
col-md-12
"
>
<
div
class
=
"
box box-primary
"
>
<
div
class
=
"
box-body
"
>
<
el
-
tabs
>
<
el
-
tab
-
pane
:
label
=
"
trans('users.tabs.data')
"
>
<
span
slot
=
"
label
"
:
class
=
"
{'error' : form.errors.any()
}
"
>
{{
trans
(
'
users.tabs.data
'
)
}}
<
/span
>
<
el
-
form
-
item
:
label
=
"
trans('users.form.first-name')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('first_name')
}
"
>
<
el
-
input
v
-
model
=
"
user.first_name
"
><
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('first_name')
"
v
-
text
=
"
form.errors.first('first_name')
"
><
/div
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('users.form.last-name')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('last_name')
}
"
>
<
el
-
input
v
-
model
=
"
user.last_name
"
><
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('last_name')
"
v
-
text
=
"
form.errors.first('last_name')
"
><
/div
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('users.form.email')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('email')
}
"
>
<
el
-
input
v
-
model
=
"
user.email
"
><
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('email')
"
v
-
text
=
"
form.errors.first('email')
"
><
/div
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('users.form.is activated')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('activated')
}
"
>
<
el
-
checkbox
v
-
model
=
"
user.activated
"
>
Activated
<
/el-checkbox
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('activated')
"
v
-
text
=
"
form.errors.first('activated')
"
><
/div
>
<
/el-form-item
>
<
div
v
-
if
=
"
user.is_new
"
>
<
el
-
form
-
item
:
label
=
"
trans('users.form.password')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('password')
}
"
>
<
el
-
input
v
-
model
=
"
user.password
"
type
=
"
password
"
><
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('password')
"
v
-
text
=
"
form.errors.first('password')
"
><
/div
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('users.form.password-confirmation')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('password_confirmation')
}
"
>
<
el
-
input
v
-
model
=
"
user.password_confirmation
"
type
=
"
password
"
><
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('password_confirmation')
"
v
-
text
=
"
form.errors.first('password_confirmation')
"
><
/div
>
<
/el-form-item
>
<
/div
>
<
/el-tab-pane
>
<
el
-
tab
-
pane
:
label
=
"
trans('users.tabs.roles')
"
>
<
el
-
form
-
item
:
label
=
"
trans('users.form.password')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('password')
}
"
>
<
el
-
select
v
-
model
=
"
user.roles
"
multiple
placeholder
=
"
Select
"
>
<
el
-
option
v
-
for
=
"
role in roles
"
:
key
=
"
role.id
"
:
label
=
"
role.name
"
:
value
=
"
role.id
"
>
<
/el-option
>
<
/el-select
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('password')
"
v
-
text
=
"
form.errors.first('password')
"
><
/div
>
<
/el-form-item
>
<
/el-tab-pane
>
<
el
-
tab
-
pane
:
label
=
"
trans('users.tabs.permissions')
"
>
<
asgard
-
permissions
v
-
model
=
"
user.permissions
"
:
current
-
permissions
=
"
user.permissions
"
><
/asgard-permissions
>
<
/el-tab-pane
>
<
el
-
tab
-
pane
:
label
=
"
trans('users.tabs.new password')
"
v
-
if
=
"
! user.is_new
"
>
<
div
v
-
if
=
"
! user.is_new
"
>
<
div
class
=
"
col-md-6
"
>
<
el
-
form
-
item
:
label
=
"
trans('users.form.password')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('password')
}
"
>
<
el
-
input
v
-
model
=
"
user.password
"
type
=
"
password
"
><
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('password')
"
v
-
text
=
"
form.errors.first('password')
"
><
/div
>
<
/el-form-item
>
<
el
-
form
-
item
:
label
=
"
trans('users.form.password-confirmation')
"
:
class
=
"
{'el-form-item is-error': form.errors.has('password_confirmation')
}
"
>
<
el
-
input
v
-
model
=
"
user.password_confirmation
"
type
=
"
password
"
><
/el-input
>
<
div
class
=
"
el-form-item__error
"
v
-
if
=
"
form.errors.has('password_confirmation')
"
v
-
text
=
"
form.errors.first('password_confirmation')
"
><
/div
>
<
/el-form-item
>
<
/div
>
<
div
class
=
"
col-md-6
"
>
<
h4
>
{{
trans
(
'
users.tabs.or send reset password mail
'
)
}}
<
/h4
>
<
el
-
button
type
=
"
info
"
:
loading
=
"
resetEmailIsLoading
"
@
click
=
"
sendResetEmail
"
>
{{
trans
(
'
users.send reset password email
'
)
}}
<
/el-button
>
<
/div
>
<
/div
>
<
/el-tab-pane
>
<
/el-tabs
>
<
/div
>
<
div
class
=
"
box-footer
"
>
<
el
-
form
-
item
>
<
el
-
button
type
=
"
primary
"
@
click
=
"
onSubmit()
"
:
loading
=
"
loading
"
>
{{
trans
(
'
core.save
'
)
}}
<
/el-button
>
<
el
-
button
@
click
=
"
onCancel()
"
>
{{
trans
(
'
core.button.cancel
'
)
}}
<
/el-button
>
<
/el-form-item
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/el-form
>
<
button
v
-
shortkey
=
"
['b']
"
@
shortkey
=
"
pushRoute({name: 'admin.user.users.index'
}
)
"
v
-
show
=
"
false
"
><
/button
>
<
/div
>
<
/template
>
<
script
>
import
axios
from
'
axios
'
;
import
Form
from
'
form-backend-validation
'
;
import
ShortcutHelper
from
'
../../../../Core/Assets/js/mixins/ShortcutHelper
'
;
import
AsgardPermissions
from
'
./AsgardPermissions.vue
'
;
export
default
{
mixins
:
[
ShortcutHelper
],
components
:
{
'
asgard-permissions
'
:
AsgardPermissions
,
}
,
props
:
{
locales
:
{
default
:
null
}
,
pageTitle
:
{
default
:
null
,
String
}
,
}
,
data
()
{
return
{
user
:
{
first_name
:
''
,
last_name
:
''
,
permissions
:
{
}
,
roles
:
{
}
,
is_new
:
false
,
}
,
roles
:
{
}
,
form
:
new
Form
(),
loading
:
false
,
resetEmailIsLoading
:
false
,
}
;
}
,
methods
:
{
onSubmit
()
{
this
.
form
=
new
Form
(
this
.
user
);
this
.
loading
=
true
;
this
.
form
.
post
(
this
.
getRoute
())
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
message
,
}
);
this
.
$router
.
push
({
name
:
'
admin.user.users.index
'
}
);
}
)
.
catch
((
error
)
=>
{
console
.
log
(
error
);
this
.
loading
=
false
;
this
.
$notify
.
error
({
title
:
'
Error
'
,
message
:
'
There are some errors in the form.
'
,
}
);
}
);
}
,
onCancel
()
{
this
.
$router
.
push
({
name
:
'
admin.user.users.index
'
}
);
}
,
fetchUser
()
{
this
.
loading
=
true
;
let
routeUri
=
''
;
if
(
this
.
$route
.
params
.
userId
!==
undefined
)
{
routeUri
=
route
(
'
api.user.user.find
'
,
{
user
:
this
.
$route
.
params
.
userId
}
);
}
else
{
routeUri
=
route
(
'
api.user.user.find-new
'
);
}
axios
.
post
(
routeUri
)
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
user
=
response
.
data
.
data
;
}
);
}
,
getRoute
()
{
if
(
this
.
$route
.
params
.
userId
!==
undefined
)
{
return
route
(
'
api.user.user.update
'
,
{
user
:
this
.
$route
.
params
.
userId
}
);
}
return
route
(
'
api.user.user.store
'
);
}
,
fetchRoles
()
{
axios
.
get
(
route
(
'
api.user.role.all
'
))
.
then
((
response
)
=>
{
this
.
roles
=
response
.
data
.
data
;
}
);
}
,
sendResetEmail
()
{
this
.
resetEmailIsLoading
=
true
;
axios
.
get
(
route
(
'
api.user.user.sendResetPassword
'
,
{
user
:
this
.
$route
.
params
.
userId
}
))
.
then
((
response
)
=>
{
this
.
resetEmailIsLoading
=
false
;
this
.
$notify
.
success
({
title
:
'
Success
'
,
message
:
response
.
data
.
message
,
}
);
}
);
}
,
}
,
mounted
()
{
this
.
fetchUser
();
this
.
fetchRoles
();
}
,
}
;
<
/script
>
public/modules/user/js/components/UserProfile.vue
0 → 100644
View file @
7de48576
<
template
>
<div>
<div
class=
"content-header"
>
<h1>
{{
trans
(
'
users.title.edit-profile
'
)
}}
</h1>
<el-breadcrumb
separator=
"/"
>
<el-breadcrumb-item>
<a
href=
"/backend"
>
{{
trans
(
'
core.breadcrumb.home
'
)
}}
</a>
</el-breadcrumb-item>
<el-breadcrumb-item
:to=
"
{name: 'admin.user.users.account'}">
{{
trans
(
'
users.breadcrumb.edit-profile
'
)
}}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<el-form
ref=
"form"
:model=
"user"
label-width=
"120px"
label-position=
"top"
v-loading
.
body=
"loading"
@
keydown=
"form.errors.clear($event.target.name);"
>
<div
class=
"row"
>
<div
class=
"col-md-12"
>
<div
class=
"box box-primary"
>
<div
class=
"box-body"
>
<el-tabs>
<el-tab-pane
:label=
"trans('users.tabs.data')"
>
<span
slot-scope=
"label"
:class=
"
{'error' : form.errors.any()}">
{{
trans
(
'
users.tabs.data
'
)
}}
</span>
<el-form-item
:label=
"trans('users.form.first-name')"
:class=
"
{'el-form-item is-error': form.errors.has('first_name') }">
<el-input
v-model=
"user.first_name"
></el-input>
<div
class=
"el-form-item__error"
v-if=
"form.errors.has('first_name')"
v-text=
"form.errors.first('first_name')"
></div>
</el-form-item>
<el-form-item
:label=
"trans('users.form.last-name')"
:class=
"
{'el-form-item is-error': form.errors.has('last_name') }">
<el-input
v-model=
"user.last_name"
></el-input>
<div
class=
"el-form-item__error"
v-if=
"form.errors.has('last_name')"
v-text=
"form.errors.first('last_name')"
></div>
</el-form-item>
<el-form-item
:label=
"trans('users.form.email')"
:class=
"
{'el-form-item is-error': form.errors.has('email') }">
<el-input
v-model=
"user.email"
></el-input>
<div
class=
"el-form-item__error"
v-if=
"form.errors.has('email')"
v-text=
"form.errors.first('email')"
></div>
</el-form-item>
</el-tab-pane>
<el-tab-pane
:label=
"trans('users.tabs.new password')"
v-if=
"! user.is_new"
>
<h4>
{{
trans
(
'
users.new password setup
'
)
}}
</h4>
<el-form-item
:label=
"trans('users.form.password')"
:class=
"
{'el-form-item is-error': form.errors.has('password') }">
<el-input
v-model=
"user.password"
type=
"password"
></el-input>
<div
class=
"el-form-item__error"
v-if=
"form.errors.has('password')"
v-text=
"form.errors.first('password')"
></div>
</el-form-item>
<el-form-item
:label=
"trans('users.form.password-confirmation')"
:class=
"
{'el-form-item is-error': form.errors.has('password_confirmation') }">
<el-input
v-model=
"user.password_confirmation"
type=
"password"
></el-input>
<div
class=
"el-form-item__error"
v-if=
"form.errors.has('password_confirmation')"
v-text=
"form.errors.first('password_confirmation')"
></div>
</el-form-item>
</el-tab-pane>
</el-tabs>
</div>
<div
class=
"box-footer"
>
<el-form-item>
<el-button
type=
"primary"
@
click=
"onSubmit()"
:loading=
"loading"
>
{{
trans
(
'
core.save
'
)
}}
</el-button>
</el-form-item>
</div>
</div>
</div>
</div>
</el-form>
</div>
</
template
>
<
script
>
import
axios
from
'
axios
'
;
import
Form
from
'
form-backend-validation
'
;
export
default
{
props
:
{
locales
:
{
default
:
null
},
},
data
()
{
return
{
user
:
{
first_name
:
''
,
last_name
:
''
,
permissions
:
{},
roles
:
{},
is_new
:
false
,
},
roles
:
{},
form
:
new
Form
(),
loading
:
false
,
};
},
methods
:
{
onSubmit
()
{
this
.
form
=
new
Form
(
this
.
user
);
this
.
loading
=
true
;
this
.
form
.
post
(
route
(
'
api.account.profile.update
'
))
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
$message
({
type
:
'
success
'
,
message
:
response
.
message
,
});
})
.
catch
((
error
)
=>
{
console
.
log
(
error
);
this
.
loading
=
false
;
this
.
$notify
.
error
({
title
:
'
Error
'
,
message
:
'
There are some errors in the form.
'
,
});
});
},
fetchUser
()
{
this
.
loading
=
true
;
axios
.
get
(
route
(
'
api.account.profile.find-current-user
'
))
.
then
((
response
)
=>
{
this
.
loading
=
false
;
this
.
user
=
response
.
data
.
data
;
});
},
},
mounted
()
{
this
.
fetchUser
();
},
};
</
script
>
public/modules/user/js/components/UserTable.vue
0 → 100644
View file @
7de48576
<
template
>
<div>
<div
class=
"content-header"
>
<h1>
{{
trans
(
'
users.title.users
'
)
}}
</h1>
<el-breadcrumb
separator=
"/"
>
<el-breadcrumb-item>
<a
href=
"/backend"
>
{{
trans
(
'
core.breadcrumb.home
'
)
}}
</a>
</el-breadcrumb-item>
<el-breadcrumb-item
:to=
"
{name: 'admin.user.users.index'}">
{{
trans
(
'
users.title.users
'
)
}}
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div
class=
"row"
>
<div
class=
"col-xs-12"
>
<div
class=
"box box-primary"
>
<div
class=
"box-body"
>
<div
class=
"sc-table"
>
<div
class=
"tool-bar el-row"
style=
"padding-bottom: 20px;"
>
<div
class=
"actions el-col el-col-8"
>
<router-link
:to=
"
{name: 'admin.user.users.create'}">
<el-button
type=
"primary"
><i
class=
"el-icon-edit"
></i>
{{
trans
(
'
users.button.new-user
'
)
}}
</el-button>
</router-link>
</div>
<div
class=
"search el-col el-col-5"
>
<el-input
prefix-icon=
"el-icon-search"
@
keyup
.
native=
"performSearch"
v-model=
"searchQuery"
>
</el-input>
</div>
</div>
<el-table
:data=
"data"
stripe
style=
"width: 100%"
ref=
"pageTable"
v-loading
.
body=
"tableIsLoading"
@
sort-change=
"handleSortChange"
>
<el-table-column
prop=
"id"
label=
"Id"
width=
"75"
sortable=
"custom"
>
</el-table-column>
<el-table-column
prop=
"first_name"
:label=
"trans('users.table.first-name')"
sortable=
"custom"
>
<template
slot-scope=
"scope"
>
<a
@
click
.
prevent=
"goToEdit(scope)"
href=
"#"
>
{{
scope
.
row
.
first_name
}}
</a>
</
template
>
</el-table-column>
<el-table-column
prop=
"last_name"
:label=
"trans('users.table.last-name')"
sortable=
"custom"
>
<
template
slot-scope=
"scope"
>
<a
@
click
.
prevent=
"goToEdit(scope)"
href=
"#"
>
{{
scope
.
row
.
last_name
}}
</a>
</
template
>
</el-table-column>
<el-table-column
prop=
"email"
:label=
"trans('users.table.email')"
sortable=
"custom"
>
<
template
slot-scope=
"scope"
>
<a
@
click
.
prevent=
"goToEdit(scope)"
href=
"#"
>
{{
scope
.
row
.
email
}}
</a>
</
template
>
</el-table-column>
<el-table-column
prop=
"created_at"
:label=
"trans('core.table.created at')"
sortable=
"custom"
>
</el-table-column>
<el-table-column
prop=
"actions"
:label=
"trans('core.table.actions')"
>
<
template
slot-scope=
"scope"
>
<el-button-group>
<edit-button
:to=
"
{name: 'admin.user.users.edit', params: {userId: scope.row.id}}">
</edit-button>
<delete-button
:scope=
"scope"
:rows=
"data"
></delete-button>
</el-button-group>
</
template
>
</el-table-column>
</el-table>
<div
class=
"pagination-wrap"
style=
"text-align: center; padding-top: 20px;"
>
<el-pagination
@
size-change=
"handleSizeChange"
@
current-change=
"handleCurrentChange"
:current-page
.
sync=
"meta.current_page"
:page-sizes=
"[10, 20, 50, 100]"
:page-size=
"parseInt(meta.per_page)"
layout=
"total, sizes, prev, pager, next, jumper"
:total=
"meta.total"
>
</el-pagination>
</div>
</div>
</div>
</div>
</div>
</div>
<button
v-shortkey=
"['c']"
@
shortkey=
"pushRoute({name: 'admin.user.users.create'})"
v-show=
"false"
></button>
</div>
</template>
<
script
>
import
axios
from
'
axios
'
;
import
_
from
'
lodash
'
;
import
ShortcutHelper
from
'
../../../../Core/Assets/js/mixins/ShortcutHelper
'
;
export
default
{
mixins
:
[
ShortcutHelper
],
data
()
{
return
{
data
:
[],
meta
:
{
current_page
:
1
,
per_page
:
10
,
},
order_meta
:
{
order_by
:
''
,
order
:
''
,
},
links
:
{},
searchQuery
:
''
,
tableIsLoading
:
false
,
};
},
methods
:
{
queryServer
(
customProperties
)
{
const
properties
=
{
page
:
this
.
meta
.
current_page
,
per_page
:
this
.
meta
.
per_page
,
order_by
:
this
.
order_meta
.
order_by
,
order
:
this
.
order_meta
.
order
,
search
:
this
.
searchQuery
,
};
axios
.
get
(
route
(
'
api.user.user.index
'
,
_
.
merge
(
properties
,
customProperties
)))
.
then
((
response
)
=>
{
this
.
tableIsLoading
=
false
;
this
.
data
=
response
.
data
.
data
;
this
.
meta
=
response
.
data
.
meta
;
this
.
links
=
response
.
data
.
links
;
this
.
order_meta
.
order_by
=
properties
.
order_by
;
this
.
order_meta
.
order
=
properties
.
order
;
});
},
fetchData
()
{
this
.
tableIsLoading
=
true
;
this
.
queryServer
();
},
handleSizeChange
(
event
)
{
console
.
log
(
`per page :
${
event
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
per_page
:
event
});
},
handleCurrentChange
(
event
)
{
console
.
log
(
`current page :
${
event
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
page
:
event
});
},
handleSortChange
(
event
)
{
console
.
log
(
'
sorting
'
,
event
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
order_by
:
event
.
prop
,
order
:
event
.
order
});
},
performSearch
:
_
.
debounce
(
function
(
query
)
{
console
.
log
(
`searching:
${
query
.
target
.
value
}
`
);
this
.
tableIsLoading
=
true
;
this
.
queryServer
({
search
:
query
.
target
.
value
});
},
300
),
goToEdit
(
scope
)
{
this
.
$router
.
push
({
name
:
'
admin.user.users.edit
'
,
params
:
{
userId
:
scope
.
row
.
id
}
});
},
},
mounted
()
{
this
.
fetchData
();
},
};
</
script
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment