11@page
2- @model App .Pages .Admin .Posts .IndexModel
32@inject IViewLocalizer Localizer
43@{
5- ViewData [" Title" ] = " Index" ;
4+ ViewData [" Title" ] = Localizer [" posts" ];
5+ var user = User .Identity .Name ;
66}
7- @{
8- var ftr = new PostListFilter (HttpContext .Request );
9-
10- var pgr = Model .Pager ;
11- var cntFrom = pgr .CurrentPage == 1 ? 1 : (pgr .CurrentPage - 1 ) * pgr .ItemsPerPage + 1 ;
12- var cntTo = pgr .CurrentPage * pgr .ItemsPerPage < pgr .Total ? pgr .CurrentPage * pgr .ItemsPerPage : pgr .Total ;
13- }
14- <div class =" bf-main" >
7+ <div id =" app" class =" bf-main" style =" display :none " >
158 <div class =" bf-sidebar d-lg-block" >
16- <form class =" bf-posts-form-search" method =" post" >
17- <input type =" hidden" name =" page" value =" 1" />
18- <input type =" hidden" name =" status" value =" @ftr.Status" />
19- <input class =" form-control form-control-sm form-control-rounded" type =" search" name =" search" placeholder =" @Localizer[" search " ]..." autocomplete =" off" />
20- </form >
9+ <div class =" bf-posts-form-search" >
10+ <input id =" txtSearch" name =" txtSearch" v-on:keyup.13 =" search" class =" form-control form-control-sm form-control-rounded" placeholder =" @Localizer[" search " ]..." >
11+ </div >
2112 <form id =" frmPostFilter" class =" bf-posts-filters" >
2213 <div class =" filter-group" >
2314 <div class =" filter-group-title" ><span >@Localizer ["status"]</span > <i class =" fa fa-chevron-down d-block d-lg-none" ></i ></div >
2415 <ul class =" filter-group-list" >
2516 <li >
2617 <label class =" custom-control custom-radio filters-label" >
27- <input class =" custom-control-input" type =" radio" @ftr.IsChecked( " A " ) name =" status-filter" id =" status-filter" value =" A" onclick = " postsController. filter()" >
18+ <input class =" custom-control-input" type =" radio" name =" status-filter" id =" status-filter" value =" A" v-model = " status " v-on:click = " filter('A' )" >
2819 <span class =" custom-control-label" >@Localizer ["all"]</span >
2920 </label >
3021 <label class =" custom-control custom-radio filters-label" >
31- <input class =" custom-control-input" type =" radio" @ftr.IsChecked( " P " ) name =" status-filter" id =" status-filter" value =" P" onclick = " postsController. filter()" >
22+ <input class =" custom-control-input" type =" radio" name =" status-filter" id =" status-filter" value =" P" v-model = " status " v-on:click = " filter('P' )" >
3223 <span class =" custom-control-label" >@Localizer ["published"]</span >
3324 </label >
3425 <label class =" custom-control custom-radio filters-label" >
35- <input class =" custom-control-input" type =" radio" @ftr.IsChecked( " D " ) name =" status-filter" id =" status-filter" value =" D" onclick = " postsController. filter()" >
26+ <input class =" custom-control-input" type =" radio" name =" status-filter" id =" status-filter" value =" D" v-model = " status " v-on:click = " filter('D' )" >
3627 <span class =" custom-control-label" >@Localizer ["draft"]</span >
3728 </label >
3829 </li >
3930 </ul >
4031 </div >
41- </form >
32+ </form >
4233 </div >
4334 <div class =" bf-body" >
4435 <!-- Grid -->
4536 <div class =" bf-posts-grid d-flex" aria-label =" posts" >
46- @foreach ( var post in Model .Posts )
47- {
48- var dt = post .Published == DateTime .MinValue ? " DRAFT" : post .Published .ToFriendlyShortDateString ();
49- var img = string .IsNullOrEmpty (post .Cover ) ? Model .Blog .Cover : post .Cover ;
50- img = $" {Url .Content (" ~/" )}{img }" ;
51- <div class =" post-grid-col" >
52- <div class =" post-grid-item" >
53- <a class =" item-link" href =" ~/admin/posts/edit?id=@post.Id" style =" background-image :url (@img );" ><div class =" item-title mt-auto" >@post.Title </div ></a >
54- <div class =" item-info d-flex align-items-center" >
55- <span class =" item-date mr-auto" >@dt </span >
37+ <div v-for =" post in pageList.posts" :key =" post.id" class =" post-grid-col" >
38+ <div class =" post-grid-item" >
39+ <a class =" item-link" :href =" 'posts/edit?id=' + post.id" v-bind:style =" { backgroundImage: 'url(' + webRoot + post.cover + ')' }" >
40+ <div class =" item-title mt-auto" >{{ post .title }} </div >
41+ </a >
42+ <div class =" item-info d-flex align-items-center" >
43+ <span class =" item-date mr-auto" >{{ toDate (post .published )}} </span >
44+
45+ <a v-if =" post.isPublished" href =" #" v-on:click =" return publish(post.id, 'U')" class =" item-show" >
46+ <span class =" item-status item-status-published ml-auto" data-tooltip title =" @Localizer[" published " ]" ><i class =" fas fa-circle" ></i ></span >
47+ </a >
48+ <a v-if =" post.isPublished === false" href =" #" v-on:click =" return publish(post.id, 'P')" class =" item-show ml-5" >
49+ <span class =" item-status item-status-draft ml-auto" data-tooltip title =" @Localizer[" draft " ]" ><i class =" fas fa-circle" ></i ></span >
50+ </a >
5651
57- @if (post .Published > DateTime .MinValue )
58- {
59- <a href =" #" onclick =" postsController.unpublish(@post.Id); return false;" class =" item-show" >
60- <span class =" item-status item-status-published ml-auto" data-tooltip title =" @Localizer[" published " ]" ><i class =" fas fa-circle" ></i ></span >
61- </a >
62- }
63- else
64- {
65- <a href =" #" onclick =" postsController.publish(@post.Id); return false;" class =" item-show ml-5" >
66- <span class =" item-status item-status-draft ml-auto" data-tooltip title =" @Localizer[" draft " ]" ><i class =" fas fa-circle" ></i ></span >
67- </a >
68- }
52+ <button v-if =" isAdmin && post.featured" class =" btn-unstyled item-favorite ml-3" data-tooltip =" " title =" " v-on:click =" return feature(post.id, 'U')" data-original-title =" @Localizer[" featured " ]" >
53+ <i class =" fas fa-star" ></i >
54+ </button >
55+ <button v-if =" isAdmin && !post.featured" class =" btn-unstyled item-favorite ml-3" data-tooltip =" " title =" " v-on:click =" return feature(post.id, 'F')" data-original-title =" @Localizer[" add-to-featured " ]" >
56+ <i class =" far fa-star" ></i >
57+ </button >
6958
70- @if (Model .IsAdmin )
71- {
72- if (post .Featured )
73- {
74- < button class = " btn-unstyled item-favorite ml-3" data - tooltip = " " title = " " onclick = " postsController.unfeature('@post.Id')" data - original - title = " @Localizer[" featured " ]" >
75- < i class = " fas fa-star" >< / i >
76- < / button >
77- }
78- else
79- {
80- <button class =" btn-unstyled item-favorite ml-3" data-tooltip =" " title =" " onclick =" postsController.feature('@post.Id')" data-original-title =" @Localizer[" add-to-featured " ]" >
81- <i class =" far fa-star" ></i >
82- </button >
83- }
84- }
85- <a class =" item-show ml-3" href =" ~/posts/@post.Slug" target =" _blank" data-tooltip =" " title =" " data-original-title =" @Localizer[" view " ]" ><i class =" fas fa-external-link-square-alt" ></i ></a >
86- <a class =" item-show ml-4" href =" #" onclick =" postsController.remove(@post.Id); return false;" data-tooltip =" " title =" " data-original-title =" @Localizer[" delete " ]" ><i class =" fas fa-trash" style =" color : #ff6666 " ></i ></a >
87- </div >
59+ <a class =" item-show ml-3" :href =" webRoot + 'posts/' + post.slug" target =" _blank" data-tooltip =" " title =" " data-original-title =" @Localizer[" view " ]" ><i class =" fas fa-external-link-square-alt" ></i ></a >
60+ <a class =" item-show ml-4" href =" #" v-on:click =" return remove(post.id)" data-tooltip =" " title =" " data-original-title =" @Localizer[" delete " ]" ><i class =" fas fa-trash" style =" color : #ff6666 " ></i ></a >
8861 </div >
8962 </div >
90- }
63+ </ div >
9164 </div >
9265 <!-- /Grid -->
66+
9367 <!-- Empty -->
94- @if (Model .Posts .Count () == 0 )
95- {
96- <div class =" bf-list-empty" >
68+ <div v-if =" pageList.posts && pageList.posts.length === 0" class =" bf-list-empty" >
9769 @Localizer ["not-found"]!
9870 </div >
99- }
10071 <!-- /Empty -->
72+
10173 <!-- Pagination -->
102- @if (pgr .ShowNewer || pgr .ShowOlder )
103- {
104- <ul class =" bf-pagination d-flex" >
105- @if (pgr .ShowOlder )
106- {
107- <li class =" bf-pagination-item" ><a class =" bf-pagination-link" href =" ~/admin/posts?pg=@pgr.Older@ftr.Qstring" ><i class =" bf-pagination-icon fa fa-chevron-left" ></i ></a ></li >
108- }
109- @if (pgr .ShowNewer )
110- {
111- <li class =" bf-pagination-item" ><a class =" bf-pagination-link" href =" ~/admin/posts?pg=@pgr.Newer@ftr.Qstring" ><i class =" bf-pagination-icon fa fa-chevron-right" ></i ></a ></li >
112- }
113- <li class =" bf-pagination-item" ><span class =" bf-pagination-count" >@cntFrom - @cntTo out of @pgr.Total </span ></li >
114- </ul >
115- }
74+ <ul v-if =" pageList && pageList.pager && pageList.pager.total > 0" class =" bf-pagination d-flex" >
75+ <li v-if =" pageList.pager.showOlder" class =" bf-pagination-item" >
76+ <a class =" bf-pagination-link" :href =" 'posts?page=' + pageList.pager.older" >
77+ <i class =" bf-pagination-icon fa fa-chevron-left" ></i >
78+ </a >
79+ </li >
80+ <li v-if =" pageList.pager.showNewer" class =" bf-pagination-item" >
81+ <a class =" bf-pagination-link" :href =" 'posts?page=' + pageList.pager.newer" >
82+ <i class =" bf-pagination-icon fa fa-chevron-right" ></i >
83+ </a >
84+ </li >
85+ <li class =" bf-pagination-item" >
86+ <span class =" bf-pagination-count" >
87+ {{ cntFrom }} -{{ cntTo }} out of {{ pageList .pager .total }}
88+ </span >
89+ </li >
90+ </ul >
11691 <!-- /Pagination -->
11792 </div >
11893</div >
11994
12095@section Scripts{
121- <script src =" ~/admin/js/app/postsController.js" ></script >
122- }
96+ <script >
97+ var vm = new Vue ({
98+ el: " #app" ,
99+ data: {
100+ isAdmin: isAdmin (),
101+ term: " " ,
102+ status: " A" ,
103+ page: 1 ,
104+ cntFrom: 0 ,
105+ cntTo: 0 ,
106+ pageList: {}
107+ },
108+ methods: {
109+ load : function () {
110+ var url = getUrl (' api/posts?page=' + this .page );
111+ if (this .term ){ url += ' &term=' + this .term ; }
112+ if (this .status !== " A" ){ url += ' &status=' + this .status ; }
113+
114+ axios .get (url)
115+ .then (response => {
116+ this .pageList = response .data ;
117+ if (this .pageList && this .pageList .pager ){
118+ var pgr = this .pageList .pager ;
119+ this .cntFrom = pgr .currentPage == 1 ? 1 : (pgr .currentPage - 1 ) * pgr .itemsPerPage + 1 ;
120+ this .cntTo = pgr .currentPage * pgr .itemsPerPage < pgr .total ? pgr .currentPage * pgr .itemsPerPage : pgr .total ;
121+ }
122+ $ (' #app' ).fadeIn ();
123+ })
124+ .catch (function (error ) { toastr .error (error); });
125+ },
126+ publish : function (id , flag ){
127+ axios .put (webRoot + ' api/posts/publish?flag=' + flag + ' &id=' + id)
128+ .then (function (response ) {
129+ toastr .success (response .data );
130+ setTimeout (function (){ location .reload (); }, 1000 );
131+ })
132+ .catch (function (error ) {
133+ toastr .error (error);
134+ });
135+ },
136+ feature : function (id , flag ){
137+ axios .put (webRoot + ' api/posts/feature?flag=' + flag + ' &id=' + id)
138+ .then (function (response ) {
139+ toastr .success (response .data );
140+ setTimeout (function (){ location .reload (); }, 1000 );
141+ })
142+ .catch (function (error ) {
143+ toastr .error (error);
144+ });
145+ },
146+ search : function (){
147+ var term = $ (' #txtSearch' ).val ();
148+ if (! term)
149+ return false ;
150+
151+ window .location .href = getUrl (' admin/posts?term=' + term);
152+ },
153+ filter : function (status ){
154+ var url = getUrl (' admin/posts?status=' + status);
155+ if (this .term && this .term .length > 0 ){
156+ url += " &term=" + this .term ;
157+ }
158+ window .location .href = url;
159+ },
160+ toDate : function (dt ){
161+ return dt .startsWith (' 0001-01-01' ) || dt .startsWith (' 01-01-01' ) ? ' DRAFT' : getDate (dt);
162+ },
163+ remove : function (id ){
164+ var result = confirm (" Please confirm removing this post" );
165+ if (result) {
166+ axios .delete (webRoot + ' api/posts/remove/' + id)
167+ .then (response => {
168+ toastr .success (response .data );
169+ setTimeout (function (){ location .reload (); }, 1000 );
170+ })
171+ .catch (function (error ) { toastr .error (error); });
172+ }
173+ return false ;
174+ }
175+ },
176+ beforeMount () {
177+ if (fromQueryString (' page' )){ this .page = fromQueryString (' page' ); }
178+ if (fromQueryString (' term' )){ this .term = fromQueryString (' term' ); }
179+ if (fromQueryString (' status' )){ this .status = fromQueryString (' status' ); }
180+ this .load ();
181+ }
182+ })
183+ </script >
184+ }
0 commit comments