diff --git a/Database/Migrations/2021_02_19_151111_vh_cms_blocks_table.php b/Database/Migrations/2021_02_19_151111_vh_cms_blocks_table.php new file mode 100644 index 0000000..b20ebf6 --- /dev/null +++ b/Database/Migrations/2021_02_19_151111_vh_cms_blocks_table.php @@ -0,0 +1,50 @@ +increments('id'); + $table->uuid('uuid')->nullable()->index(); + + $table->integer('vh_theme_id')->nullable()->index(); + $table->integer('vh_theme_location_id')->nullable()->index(); + $table->string('name')->nullable()->index(); + $table->string('slug')->nullable()->index(); + $table->text('content')->nullable(); + $table->integer('sort')->nullable()->index(); + $table->boolean('is_published')->nullable()->index(); + + $table->text('meta')->nullable(); + + $table->integer('created_by')->nullable()->index(); + $table->integer('updated_by')->nullable()->index(); + $table->integer('deleted_by')->nullable()->index(); + $table->timestamps(); + $table->softDeletes(); + $table->index(['created_at', 'updated_at', 'deleted_at']); + + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('vh_cms_blocks'); + } +} diff --git a/Entities/Block.php b/Entities/Block.php new file mode 100644 index 0000000..9a53110 --- /dev/null +++ b/Entities/Block.php @@ -0,0 +1,578 @@ +attributes['name'] = ucwords($value); + } else{ + $this->attributes['name'] = null; + } + + } + //------------------------------------------------- + public function getNameAttribute($value) + { + if($value) + { + return ucwords($value); + } + return null; + } + //------------------------------------------------- + public function setMetaAttribute($value) + { + if($value) + { + $this->attributes['meta'] = json_encode($value); + } else{ + $this->attributes['meta'] = null; + } + } + //------------------------------------------------- + public function getMetaAttribute($value) + { + if($value) + { + return json_decode($value); + } + return null; + } + //------------------------------------------------- + public function getTableColumns() { + return $this->getConnection()->getSchemaBuilder() + ->getColumnListing($this->getTable()); + } + //------------------------------------------------- + public function scopeExclude($query, $columns) + { + return $query->select( array_diff( $this->getTableColumns(),$columns) ); + } + //------------------------------------------------- + public function scopeIsPublished($query) + { + return $query->where( 'is_published', 1 ); + } + //------------------------------------------------- + public function createdByUser() + { + return $this->belongsTo(User::class, + 'created_by', 'id' + )->select('id', 'uuid', 'first_name', 'last_name', 'email'); + } + + //------------------------------------------------- + public function updatedByUser() + { + return $this->belongsTo(User::class, + 'updated_by', 'id' + )->select('id', 'uuid', 'first_name', 'last_name', 'email'); + } + //------------------------------------------------- + public function deletedByUser() + { + return $this->belongsTo(User::class, + 'deleted_by', 'id' + )->select('id', 'uuid', 'first_name', 'last_name', 'email'); + } + //------------------------------------------------- + public function theme() + { + return $this->belongsTo(Theme::class, + 'vh_theme_id', 'id' + ); + } + //------------------------------------------------- + public function themeLocation() + { + return $this->belongsTo(ThemeLocation::class, + 'vh_theme_location_id', 'id' + ); + } + //------------------------------------------------- + public static function postCreate($request) + { + + $validation = static::validation($request); + if(isset($validation['status']) && $validation['status'] == 'failed') + { + return $validation; + } + + // check if sort number exist + $sort_number_exist = static::where('vh_theme_id',$request['vh_theme_id']) + ->where('vh_theme_location_id',$request['vh_theme_location_id']) + ->where('sort',$request['sort']) + ->first(); + + if($sort_number_exist) + { + $response['status'] = 'failed'; + $response['errors'][] = "Select different sort number."; + return $response; + } + + $item = new static(); + $item->fill($request->all()); + $item->save(); + + $response['status'] = 'success'; + $response['data']['item'] =$item; + $response['messages'][] = 'Saved'; + + return $response; + + } + //------------------------------------------------- + public static function getList($request) + { + if($request->has('sort_by') && $request['sort_by']) + { + $list = static::orderBy($request['sort_by'], $request['sort_order']); + }else{ + $list = static::orderBy('id', $request['sort_order']); + } + + $list->with([ 'themeLocation','theme']); + + if($request->has('trashed') && $request['trashed'] == 'true') + { + + $list->withTrashed(); + } + + if($request->has('from') && $request->from + && $request->has('to') && $request->to) + { + $list->whereBetween('updated_at',[$request->from." 00:00:00",$request->to." 23:59:59"]); + } + + if($request->has('filter') && $request['filter']) + { + if($request['filter'] == '1') + { + $list->where('is_published',$request['filter']); + }elseif($request['filter'] == '10'){ + $list->whereNull('is_published')->orWhere('is_published',0); + }else{ + $list->with(['themeLocation']) + ->whereHas('themeLocation', function ($q) use ($request){ + $q->where('slug', $request['filter']); + }); + + } + } + + if($request->has('q') && $request->q) + { + $search_array = explode(" ",$request->q); + + foreach ($search_array as $item){ + $list->where(function ($q) use ($item){ + $q->where('name', 'LIKE', '%'.$item.'%') + ->orWhere('id', 'LIKE', $item.'%') + ->orWhere('slug', 'LIKE', '%'.$item.'%'); + }); + } + } + + + $data['list'] = $list->paginate(config('vaahcms.per_page')); + + + + $response['status'] = 'success'; + $response['data'] = $data; + + return $response; + + + } + //------------------------------------------------- + public static function validation($request) + { + $rules = array( + 'name' => 'required|unique:vh_cms_blocks|max:60', + 'slug' => 'required|unique:vh_cms_blocks|max:60', + 'content' => 'required', + 'vh_theme_id' => 'required', + 'vh_theme_location_id' => 'required', + 'sort' => 'required|numeric|min:0|regex:/^\d{1,13}?$/', + ); + $messages = array( + 'vh_theme_id.required' => 'Select a theme.', + 'vh_theme_location_id.required' => 'Select a theme location.', + ); + + $validator = \Validator::make( $request->all(), $rules, $messages); + if ( $validator->fails() ) { + + $errors = errorsToArray($validator->errors()); + $response['status'] = 'failed'; + $response['errors'] = $errors; + return $response; + } + + $response['status'] = 'success'; + + return $response; + + } + //------------------------------------------------- + public static function storeValidation($request) + { + $rules = array( + 'name' => 'required|max:60', + 'slug' => 'required|max:60', + 'content' => 'required', + 'vh_theme_id' => 'required', + 'vh_theme_location_id' => 'required', + 'sort' => 'required|numeric|min:0|regex:/^\d{1,13}?$/', + ); + $messages = array( + 'vh_theme_id.required' => 'Select a theme.', + 'vh_theme_location_id.required' => 'Select a theme location.', + ); + + $validator = \Validator::make( $request->all(), $rules, $messages); + if ( $validator->fails() ) { + + $errors = errorsToArray($validator->errors()); + $response['status'] = 'failed'; + $response['errors'] = $errors; + return $response; + } + + $response['status'] = 'success'; + + return $response; + + } + //------------------------------------------------- + + //------------------------------------------------- + public static function getItem($id) + { + + $item = static::where('id', $id) + ->with([ + 'theme', 'themeLocation', + 'createdByUser', 'updatedByUser', + 'deletedByUser', + ]) + ->withTrashed() + ->first(); + + $response['status'] = 'success'; + $response['data'] = $item; + + return $response; + + } + //------------------------------------------------- + public static function postStore($request,$id) + { + + $validation = static::storeValidation($request); + if(isset($validation['status']) && $validation['status'] == 'failed') + { + return $validation; + } + + // check if name exist + $name_exist = static::where('id','!=',$request['id']) + ->where('name',$request['name']) + ->first(); + + if($name_exist) + { + $response['status'] = 'failed'; + $response['errors'][] = "This name is already exist."; + return $response; + } + + + // check if slug exist + $slug_exist = static::where('id','!=',$request['id']) + ->where('slug',$request['slug']) + ->first(); + + if($slug_exist) + { + $response['status'] = 'failed'; + $response['errors'][] = "This slug is already exist."; + return $response; + } + + + // check if sort number exist + $sort_number_exist = static::where('id','!=',$request['id']) + ->where('vh_theme_id',$request['vh_theme_id']) + ->where('vh_theme_location_id',$request['vh_theme_location_id']) + ->where('sort',$request['sort']) + ->first(); + + if($sort_number_exist) + { + $response['status'] = 'failed'; + $response['errors'][] = "Select different sort number."; + return $response; + } + + $update = static::where('id',$id)->withTrashed()->first(); + + $update->fill($request->all()); + $update->save(); + + + $response['status'] = 'success'; + $response['data'] = []; + $response['messages'][] = 'Data updated.'; + + return $response; + + } + //------------------------------------------------- + public static function bulkStatusChange($request) + { + if(!$request->has('inputs')) + { + $response['status'] = 'failed'; + $response['errors'][] = 'Select IDs'; + return $response; + } + + if(!$request->has('data')) + { + $response['status'] = 'failed'; + $response['errors'][] = 'Select Status'; + return $response; + } + + foreach($request->inputs as $id) + { + $role = static::where('id',$id)->withTrashed()->first(); + + if($role->deleted_at){ + continue ; + } + + if($request['data']){ + $role->is_published = $request['data']['status']; + }else{ + if($role->is_published == 1){ + $role->is_published = 0; + }else{ + $role->is_published = 1; + } + } + $role->save(); + } + + $response['status'] = 'success'; + $response['data'] = []; + $response['messages'][] = 'Action was successful'; + + return $response; + + + } + //------------------------------------------------- + public static function bulkTrash($request) + { + + if(!$request->has('inputs')) + { + $response['status'] = 'failed'; + $response['errors'][] = 'Select IDs'; + return $response; + } + + + foreach($request->inputs as $id) + { + $item = static::withTrashed()->where('id', $id)->first(); + if($item) + { + $item->is_published = 0; + $item->save(); + $item->delete(); + } + } + + $response['status'] = 'success'; + $response['data'] = []; + $response['messages'][] = 'Action was successful'; + + return $response; + + + } + //------------------------------------------------- + public static function bulkRestore($request) + { + + + if(!$request->has('inputs')) + { + $response['status'] = 'failed'; + $response['errors'][] = 'Select IDs'; + return $response; + } + + if(!$request->has('data')) + { + $response['status'] = 'failed'; + $response['errors'][] = 'Select Status'; + return $response; + } + + foreach($request->inputs as $id) + { + $item = static::withTrashed()->where('id', $id)->first(); + if(isset($item) && isset($item->deleted_at)) + { + $item->restore(); + } + } + + $response['status'] = 'success'; + $response['data'] = []; + $response['messages'][] = 'Action was successful'; + + return $response; + + } + //------------------------------------------------- + public static function bulkDelete($request) + { + + if(!$request->has('inputs')) + { + $response['status'] = 'failed'; + $response['errors'][] = 'Select IDs'; + return $response; + } + + + foreach($request->inputs as $id) + { + $item = static::where('id', $id)->withTrashed()->first(); + if($item) + { + $item->forceDelete(); + } + } + + $response['status'] = 'success'; + $response['data'] = []; + $response['messages'][] = 'Action was successful'; + + return $response; + } + + //--------------------------------------------------------------------------- + public static function getBlock($block_slug) + { + + if(!$block_slug){ + return false; + } + + + $block = self::where('is_published',1) + ->where('slug',$block_slug) + ->where('vh_theme_id',vh_get_theme_id()) + ->first(); + + if(!$block) + { + return false; + } + + return $block->content; + } + + //--------------------------------------------------------------------------- + public static function getBlocksByLocation($location) + { + + + if(!$location) + { + return false; + } + + $blocks = self::where('vh_theme_location_id', $location->id) + ->where('is_published',1) + ->orderBy('sort','asc') + ->get(); + + if(count($blocks) < 1) + { + return false; + } + + $data = ""; + + foreach ($blocks as $block){ + $data .= $block->content; + } + + + return $data; + } + //------------------------------------------------- + //------------------------------------------------- + //------------------------------------------------- + //------------------------------------------------- + //------------------------------------------------- + //------------------------------------------------- + //------------------------------------------------- + //------------------------------------------------- + +} diff --git a/Entities/FormGroup.php b/Entities/FormGroup.php index 64cbc53..d48eb32 100644 --- a/Entities/FormGroup.php +++ b/Entities/FormGroup.php @@ -173,6 +173,11 @@ public static function syncWithFormFields(FormGroup $group, $fields_array) foreach ($fields_array as $f_index => $field) { + if(!isset($field['slug']) || !$field['slug']){ + $field['slug'] = Str::slug($field['name']); + } + + $stored_field = FormField::where('vh_cms_form_group_id', $group->id) ->where('slug', $field['slug']) ->first(); diff --git a/Http/Controllers/Backend/BlocksController.php b/Http/Controllers/Backend/BlocksController.php new file mode 100644 index 0000000..111e8ce --- /dev/null +++ b/Http/Controllers/Backend/BlocksController.php @@ -0,0 +1,127 @@ +theme = vh_get_backend_theme(); + } + + public function getAssets(Request $request) + { + + $data['field_types'] = FieldType::select('id', 'name', 'slug', 'meta') + ->get(); + + $data['bulk_actions'] = vh_general_bulk_actions(); + $data['themes'] = Theme::getActiveThemesWithBlockLocations(); + + + $response['status'] = 'success'; + $response['data'] = $data; + + return response()->json($response); + } + //---------------------------------------------------------- + public function postCreate(Request $request) + { + $response = Block::postCreate($request); + return response()->json($response); + } + //---------------------------------------------------------- + public function getList(Request $request) + { + $response = Block::getList($request); + return response()->json($response); + } + //---------------------------------------------------------- + public function getItem(Request $request, $id) + { + + $response = Block::getItem($id); + return response()->json($response); + + } + //---------------------------------------------------------- + public function postStore(Request $request,$id) + { + $response = Block::postStore($request,$id); + return response()->json($response); + } + + //---------------------------------------------------------- + //---------------------------------------------------------- + public function postActions(Request $request, $action) + { + $rules = array( + 'inputs' => 'required', + ); + + $validator = \Validator::make( $request->all(), $rules); + if ( $validator->fails() ) { + + $errors = errorsToArray($validator->errors()); + $response['status'] = 'failed'; + $response['errors'] = $errors; + return response()->json($response); + } + + $response = []; + + $response['status'] = 'success'; + + $inputs = $request->all(); + + switch ($action) + { + + //------------------------------------ + case 'bulk-change-status': + $response = Block::bulkStatusChange($request); + break; + //------------------------------------ + case 'bulk-trash': + + $response = Block::bulkTrash($request); + + break; + //------------------------------------ + case 'bulk-restore': + + $response = Block::bulkRestore($request); + + break; + + //------------------------------------ + case 'bulk-delete': + + $response = Block::bulkDelete($request); + + break; + + //------------------------------------ + } + + return response()->json($response); + + } + + //---------------------------------------------------------- + //---------------------------------------------------------- + //---------------------------------------------------------- + + +} diff --git a/Http/Controllers/Backend/JsonController.php b/Http/Controllers/Backend/JsonController.php index c16838a..dd33945 100644 --- a/Http/Controllers/Backend/JsonController.php +++ b/Http/Controllers/Backend/JsonController.php @@ -52,6 +52,13 @@ public function getAssets(Request $request) 'path' => "/menus", ], + [ + "label"=>'Blocks', + "icon"=>'cubes', + "link"=> self::$link."blocks", + 'path' => "/blocks", + ], + ], ]; diff --git a/Http/Controllers/Backend/MenusController.php b/Http/Controllers/Backend/MenusController.php index 13da087..5e4c4de 100644 --- a/Http/Controllers/Backend/MenusController.php +++ b/Http/Controllers/Backend/MenusController.php @@ -26,7 +26,7 @@ public function __construct() public function getAssets(Request $request) { - $data['themes'] = Theme::getActiveThemesWithLocations(); + $data['themes'] = Theme::getActiveThemesWithMenuLocations(); $response['status'] = 'success'; $response['data'] = $data; diff --git a/Libraries/CmsSeeder.php b/Libraries/CmsSeeder.php index 611c14c..5f22b97 100644 --- a/Libraries/CmsSeeder.php +++ b/Libraries/CmsSeeder.php @@ -163,6 +163,8 @@ public static function templates($theme_slug, $file_path) ->where('slug', $template['template']['slug']) ->first(); + $stored_template = ThemeTemplate::find($stored_template->id); + //template groups ThemeTemplate::syncWithFormGroups($stored_template, $template['groups']); @@ -187,9 +189,9 @@ public static function contentTypes($file_path) if(!$exist) { - $stored = DB::table('vh_cms_content_types')->insert($content_type['content']); + DB::table('vh_cms_content_types')->insert($content_type['content']); } else{ - $stored = DB::table('vh_cms_content_types') + DB::table('vh_cms_content_types') ->where('slug', $content_type['content']['slug']) ->update($content_type['content']); } diff --git a/Routes/backend.php b/Routes/backend.php index ae06032..b192dea 100644 --- a/Routes/backend.php +++ b/Routes/backend.php @@ -43,5 +43,6 @@ function () { ->name( 'vh.backend.cms.getUserById' ); include('backend/content-types.php'); +include('backend/blocks.php'); include('backend/contents.php'); include('backend/menus.php'); diff --git a/Routes/backend/blocks.php b/Routes/backend/blocks.php new file mode 100644 index 0000000..445dd48 --- /dev/null +++ b/Routes/backend/blocks.php @@ -0,0 +1,40 @@ + 'backend/cms/blocks', + 'namespace' => 'Backend', + 'middleware' => ['web', 'has.backend.access'], + ], + function () { + //--------------------------------------------------------- + Route::get('/assets', 'BlocksController@getAssets') + ->name('backend.cms.blocks.assets'); + //--------------------------------------------------------- + Route::post('/create', 'BlocksController@postCreate') + ->name('backend.cms.blocks.create'); + //--------------------------------------------------------- + Route::get('/list', 'BlocksController@getList') + ->name('backend.cms.blocks.list'); + //--------------------------------------------------------- + Route::get('/item/{id}', 'BlocksController@getItem') + ->name('backend.cms.blocks.item'); + //--------------------------------------------------------- + Route::post('/item/{id}/relations', 'BlocksController@getItemRelations') + ->name('backend.cms.blocks.item.relations'); + //--------------------------------------------------------- + Route::post('/store/{id}', 'BlocksController@postStore') + ->name('backend.cms.blocks.store'); + //--------------------------------------------------------- + Route::post('/store/{id}/groups', 'BlocksController@postStoreGroups') + ->name('backend.cms.blocks.store.groups'); + //--------------------------------------------------------- + Route::post('/actions/{action_name}', 'BlocksController@postActions') + ->name('backend.cms.blocks.actions'); + //--------------------------------------------------------- + Route::get('/getModuleSections', 'BlocksController@getModuleSections') + ->name('backend.cms.blocks.module-section'); + //--------------------------------------------------------- + }); diff --git a/Vue/pages/blocks/Create.vue b/Vue/pages/blocks/Create.vue new file mode 100644 index 0000000..fccfcfc --- /dev/null +++ b/Vue/pages/blocks/Create.vue @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + Content + + + + + + + Editor + + + + + Code Editor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create New Block + + + + + + + + + + Save + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Select a Theme + {{theme.name}} + + + + + + Select a Location + {{location.name}} + + + + + + + + + + Yes + + + + No + + + + + + + + + + + + + + + + + + + + + diff --git a/Vue/pages/blocks/CreateJs.js b/Vue/pages/blocks/CreateJs.js new file mode 100644 index 0000000..85f22ff --- /dev/null +++ b/Vue/pages/blocks/CreateJs.js @@ -0,0 +1,266 @@ +import GlobalComponents from '../../vaahvue/helpers/GlobalComponents' +import ContentFieldAll from '../../vaahvue/reusable/content-fields/All' +import draggable from 'vuedraggable'; +import { codemirror } from 'vue-codemirror' + +// language +import 'codemirror/mode/xml/xml.js' +// theme css +import 'codemirror/lib/codemirror.css' +import 'codemirror/theme/monokai.css' +// require active-line.js +import'codemirror/addon/selection/active-line.js' +// autoCloseTags +import'codemirror/addon/edit/closetag.js' + +let namespace = 'blocks'; + +export default { + computed:{ + root() {return this.$store.getters['root/state']}, + page() {return this.$store.getters[namespace+'/state']}, + assets() {return this.$store.getters[namespace+'/state'].assets}, + ajax_url() {return this.$store.getters[namespace+'/state'].ajax_url}, + new_item() {return this.$store.getters[namespace+'/state'].new_item}, + }, + components:{ + ...GlobalComponents, + ContentFieldAll, + draggable, + codemirror + }, + data() + { + return { + namespace: namespace, + is_content_loading: false, + is_textarea_disable: false, + is_btn_loading: null, + labelPosition: 'on-border', + params: {}, + local_action: null, + title: null, + new_status: null, + disable_status_editing: true, + edit_status_index: null, + cm_options: { + tabSize: 4, + styleActiveLine: true, + lineNumbers: true, + lineWrapping: true, + autoCloseTags: true, + line: true, + mode: 'text/html', + theme: 'monokai' + // more CodeMirror options... + } + } + }, + watch: { + $route(to, from) { + this.updateView() + }, + + 'new_item.name': { + deep: true, + handler(new_val, old_val) { + + if(new_val) + { + this.new_item.slug = this.$vaah.strToSlug(new_val); + this.updateNewItem(); + } + + } + }, + + 'new_item.plural': { + deep: true, + handler(new_val, old_val) { + + if(new_val) + { + this.new_item.plural_slug = this.$vaah.strToSlug(new_val); + this.updateNewItem(); + } + + } + }, + + 'new_item.singular': { + deep: true, + handler(new_val, old_val) { + + if(new_val) + { + this.new_item.singular_slug = this.$vaah.strToSlug(new_val); + this.updateNewItem(); + } + + } + }, + + }, + mounted() { + //---------------------------------------------------- + + //---------------------------------------------------- + this.onLoad(); + //---------------------------------------------------- + + //---------------------------------------------------- + }, + methods: { + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + update: function(name, value) + { + let update = { + state_name: name, + state_value: value, + namespace: this.namespace, + }; + this.$vaah.updateState(update); + }, + //--------------------------------------------------------------------- + updateNewItem: function() + { + let update = { + state_name: 'new_item', + state_value: this.new_item, + namespace: this.namespace, + }; + this.$vaah.updateState(update); + }, + //--------------------------------------------------------------------- + updateView: function() + { + this.$store.dispatch(this.namespace+'/updateView', this.$route); + }, + //--------------------------------------------------------------------- + onLoad: function() + { + this.is_content_loading = true; + this.updateView(); + this.getAssets(); + }, + //--------------------------------------------------------------------- + async reloadRootAssets() { + await this.$store.dispatch('root/reloadAssets'); + }, + //--------------------------------------------------------------------- + async getAssets() { + await this.$store.dispatch(namespace+'/getAssets'); + }, + + //--------------------------------------------------------------------- + addStatus: function() + { + this.new_item.content_statuses.push(this.new_status); + this.new_status = null; + this.update('new_item', this.new_item); + }, + //--------------------------------------------------------------------- + toggleEditStatus: function(status_index) + { + this.edit_status_index = status_index; + if(this.disable_status_editing) + { + this.disable_status_editing = false; + } else + { + this.disable_status_editing = true; + } + }, + //--------------------------------------------------------------------- + create: function () { + this.$Progress.start(); + let params = this.new_item; + + console.log('--->', params); + + let url = this.ajax_url+'/create'; + this.$vaah.ajax(url, params, this.createAfter); + }, + //--------------------------------------------------------------------- + createAfter: function (data, res) { + + this.$Progress.finish(); + + if(data) + { + this.$emit('eReloadList'); + + if(this.local_action === 'save-and-close') + { + this.saveAndClose(); + }else{ + //this.$router.push({name: 'blocks.list'}); + this.saveAndNew(); + + // this.$root.$emit('eReloadItem'); + } + + this.reloadRootAssets(); + + } + + }, + //--------------------------------------------------------------------- + setLocalAction: function (action) { + this.local_action = action; + this.store(); + }, + //--------------------------------------------------------------------- + saveAndClose: function () { + this.update('active_item', null); + this.$router.push({name:'blocks.list'}); + }, + //--------------------------------------------------------------------- + saveAndNew: function () { + this.update('active_item', null); + this.resetNewItem(); + }, + //--------------------------------------------------------------------- + resetNewItem: function() + { + let new_item = this.getNewItem(); + this.update('new_item', new_item); + }, + //--------------------------------------------------------------------- + getNewItem: function() + { + let new_item = { + name: null, + slug: null, + vh_theme_id: "", + vh_theme_location_id: "", + content: "", + is_published: null, + }; + return new_item; + }, + //--------------------------------------------------------------------- + setActiveTheme: function () { + + this.new_item.vh_theme_location_id = ''; + this.update('new_item', this.new_item); + + this.page.active_theme = { + 'locations':[] + }; + + this.update('active_theme', this.page.active_theme); + + if(this.new_item.vh_theme_id){ + let theme = this.$vaah.findInArrayByKey(this.assets.themes, + 'id', this.new_item.vh_theme_id); + + this.update('active_theme', theme); + } + + + }, + //--------------------------------------------------------------------- + } +} diff --git a/Vue/pages/blocks/Edit.vue b/Vue/pages/blocks/Edit.vue new file mode 100644 index 0000000..696deea --- /dev/null +++ b/Vue/pages/blocks/Edit.vue @@ -0,0 +1,206 @@ + + + + + + + + + + + + + + + + + Content + + + + + + + + Editor + + + + + Code Editor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{$vaah.limitString(title, 15)}} + + + + + + + + + #{{item.id}} + + + + + + Save + + + + + + + + + + + + + + Save & Close + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Select a Theme + {{theme.name}} + + + + + + + + Select a Location + {{location.name}} + + + + + + + + + + Yes + + + + No + + + + + + + + + + + + + + + + + + + + diff --git a/Vue/pages/blocks/EditJs.js b/Vue/pages/blocks/EditJs.js new file mode 100644 index 0000000..c51cbad --- /dev/null +++ b/Vue/pages/blocks/EditJs.js @@ -0,0 +1,275 @@ +import GlobalComponents from '../../vaahvue/helpers/GlobalComponents' +import ContentFieldAll from '../../vaahvue/reusable/content-fields/All' +import draggable from 'vuedraggable'; +import { codemirror } from 'vue-codemirror' + +// language +import 'codemirror/mode/xml/xml.js' +// theme css +import 'codemirror/lib/codemirror.css' +import 'codemirror/theme/monokai.css' +// require active-line.js +import'codemirror/addon/selection/active-line.js' +// autoCloseTags +import'codemirror/addon/edit/closetag.js' + +let namespace = 'blocks'; + +export default { + props: ['id'], + computed:{ + root() {return this.$store.getters['root/state']}, + page() {return this.$store.getters[namespace+'/state']}, + assets() {return this.$store.getters[namespace+'/state'].assets}, + ajax_url() {return this.$store.getters[namespace+'/state'].ajax_url}, + item() {return this.$store.getters[namespace+'/state'].active_item}, + }, + components:{ + ...GlobalComponents, + ContentFieldAll, + draggable, + codemirror + + }, + data() + { + return { + namespace: namespace, + is_content_loading: false, + is_textarea_disable: false, + is_btn_loading: null, + labelPosition: 'on-border', + params: {}, + local_action: null, + title: null, + edit_status_index: null, + status: null, + disable_status_editing: true, + cm_options: { + tabSize: 4, + styleActiveLine: true, + lineNumbers: true, + lineWrapping: true, + autoCloseTags: true, + line: true, + mode: 'text/html', + theme: 'monokai' + // more CodeMirror options... + } + } + }, + watch: { + $route(to, from) { + this.updateView() + }, + + 'item.name': { + deep: true, + handler(new_val, old_val) { + + if(new_val) + { + this.item.slug = this.$vaah.strToSlug(new_val); + this.updateNewItem(); + } + + } + }, + + 'item.plural': { + deep: true, + handler(new_val, old_val) { + + if(new_val) + { + this.item.plural_slug = this.$vaah.strToSlug(new_val); + this.updateNewItem(); + } + + } + }, + + 'item.singular': { + deep: true, + handler(new_val, old_val) { + + if(new_val) + { + this.item.singular_slug = this.$vaah.strToSlug(new_val); + this.updateNewItem(); + } + + } + }, + + }, + mounted() { + //---------------------------------------------------- + this.onLoad(); + //---------------------------------------------------- + + //---------------------------------------------------- + }, + methods: { + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + update: function(name, value) + { + let update = { + state_name: name, + state_value: value, + namespace: this.namespace, + }; + this.$vaah.updateState(update); + }, + //--------------------------------------------------------------------- + updateView: function() + { + this.$store.dispatch(this.namespace+'/updateView', this.$route); + }, + //--------------------------------------------------------------------- + updateNewItem: function() + { + let update = { + state_name: 'item', + state_value: this.item, + namespace: this.namespace, + }; + this.$vaah.updateState(update); + }, + //--------------------------------------------------------------------- + onLoad: function() + { + this.is_content_loading = true; + + this.updateView(); + this.getAssets(); + this.getItem(); + }, + //--------------------------------------------------------------------- + async getAssets() { + await this.$store.dispatch(namespace+'/getAssets'); + }, + //--------------------------------------------------------------------- + getItem: function () { + this.$Progress.start(); + this.params = {}; + let url = this.ajax_url+'/item/'+this.$route.params.id; + this.$vaah.ajaxGet(url, this.params, this.getItemAfter); + }, + //--------------------------------------------------------------------- + getItemAfter: function (data, res) { + this.$Progress.finish(); + this.is_content_loading = false; + + if(data) + { + this.title = data.name; + this.update('active_item', data); + this.setActiveTheme(false); + + } else + { + //if item does not exist or delete then redirect to list + this.update('active_item', null); + this.$router.push({name: 'blocks.list'}); + } + }, + //--------------------------------------------------------------------- + store: function () { + this.$Progress.start(); + + let params = this.item; + + let url = this.ajax_url+'/store/'+this.item.id; + this.$vaah.ajax(url, params, this.storeAfter); + }, + //--------------------------------------------------------------------- + storeAfter: function (data, res) { + + this.$Progress.finish(); + + if(data) + { + this.$emit('eReloadList'); + + if(this.local_action === 'save-and-close') + { + this.saveAndClose() + }else{ + this.$router.push({name: 'blocks.view', params:{id:this.id}}); + this.$root.$emit('eReloadItem'); + } + + this.reloadRootAssets(); + + } + + }, + //--------------------------------------------------------------------- + async reloadRootAssets() { + await this.$store.dispatch('root/reloadAssets'); + }, + //--------------------------------------------------------------------- + setLocalAction: function (action) { + this.local_action = action; + this.store(); + }, + //--------------------------------------------------------------------- + saveAndClose: function () { + this.update('active_item', null); + this.$router.push({name:'blocks.list'}); + }, + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + toggleEditStatus: function(status_index) + { + this.edit_status_index = status_index; + if(this.disable_status_editing) + { + this.disable_status_editing = false; + } else + { + this.disable_status_editing = true; + } + }, + //--------------------------------------------------------------------- + + addStatus: function() + { + this.item.content_statuses.push(this.status); + this.status = null; + this.update('item', this.item); + }, + //--------------------------------------------------------------------- + setActiveTheme: function (set_null = true) { + + if(set_null){ + this.item.vh_theme_location_id = ''; + } + + this.update('item', this.item); + + this.page.active_theme = { + 'locations':[] + }; + + this.update('active_theme', this.page.active_theme); + + if(this.item.vh_theme_id && this.assets && this.assets.themes){ + let theme = this.$vaah.findInArrayByKey(this.assets.themes, + 'id', this.item.vh_theme_id); + + this.update('active_theme', theme); + } + + + }, + //--------------------------------------------------------------------- + resetActiveItem: function () { + this.update('active_item', null); + this.$router.push({name:'blocks.list'}); + }, + } +} diff --git a/Vue/pages/blocks/List.vue b/Vue/pages/blocks/List.vue new file mode 100644 index 0000000..58247b6 --- /dev/null +++ b/Vue/pages/blocks/List.vue @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + Blocks + + + + + + + + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - Bulk Actions - + + + {{ option.name }} + + + + + + - Select Status - + + + Published + + + Unpublished + + + + + + Apply + + + + + + + + + + + + + + + + + + + + + + Filter + + + + + Reset + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Select a filter + + + + Published + + + Unpublished + + + + + {{location.name}} + + + + + + + + + + + + + + + - Sort by - + + + Id + + + Name + + + Is Published + + + Updated At + + + + + + + + + + + + + Descending + Ascending + + + + Descending + + + Ascending + + + + + + + + + + + Include Trashed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Vue/pages/blocks/ListJs.js b/Vue/pages/blocks/ListJs.js new file mode 100644 index 0000000..45d1f28 --- /dev/null +++ b/Vue/pages/blocks/ListJs.js @@ -0,0 +1,337 @@ +import GlobalComponents from '../../vaahvue/helpers/GlobalComponents'; +import ListLargeView from './partials/ListLargeView'; +import ListSmallView from './partials/ListSmallView'; + +let namespace = 'blocks'; + +export default { + computed:{ + root() {return this.$store.getters['root/state']}, + page() {return this.$store.getters[namespace+'/state']}, + ajax_url() {return this.$store.getters[namespace+'/state'].ajax_url}, + query_string() {return this.$store.getters[namespace+'/state'].query_string}, + }, + components:{ + ...GlobalComponents, + ListLargeView, + ListSmallView, + + }, + data() + { + return { + namespace: namespace, + is_content_loading: false, + is_btn_loading: false, + assets: null, + selected_date: null, + search_delay: null, + search_delay_time: 800, + ids: [], + moduleSection: null, + } + }, + watch: { + $route(to, from) { + this.updateView(); + this.updateQueryString(); + } + }, + mounted() { + //---------------------------------------------------- + this.onLoad(); + //---------------------------------------------------- + //---------------------------------------------------- + }, + methods: { + //--------------------------------------------------------------------- + update: function(name, value) + { + let update = { + state_name: name, + state_value: value, + namespace: this.namespace, + }; + this.$vaah.updateState(update); + }, + //--------------------------------------------------------------------- + updateView: function() + { + this.$store.dispatch(this.namespace+'/updateView', this.$route); + }, + //--------------------------------------------------------------------- + onLoad: function() + { + this.updateView(); + this.updateQueryString(); + this.getAssets(); + this.setDateFilter(); + }, + //--------------------------------------------------------------------- + toCreate: function() + { + this.update('active_item', null); + this.$router.push({name:'blocks.create'}); + }, + //--------------------------------------------------------------------- + updateQueryString: function() + { + let query = this.$vaah.removeEmpty(this.$route.query); + if(Object.keys(query).length) + { + for(let key in query) + { + this.query_string[key] = query[key]; + } + } + this.update('query_string', this.query_string); + this.$vaah.updateCurrentURL(this.query_string, this.$router); + }, + //--------------------------------------------------------------------- + async getAssets() { + await this.$store.dispatch(this.namespace+'/getAssets'); + this.getList(); + }, + //--------------------------------------------------------------------- + toggleFilters: function() + { + if(this.page.show_filters == false) + { + this.page.show_filters = true; + } else + { + this.page.show_filters = false; + } + + this.update('show_filters', this.page.show_filters); + + }, + //--------------------------------------------------------------------- + clearSearch: function () { + this.query_string.q = null; + this.update('query_string', this.query_string); + this.getList(); + }, + //--------------------------------------------------------------------- + setDateFilter: function() + { + if(this.query_string.from){ + let from = new Date(this.query_string.from); + + this.selected_date=[ + from + ]; + } + + if(this.query_string.to){ + let to = new Date(this.query_string.to); + + this.selected_date[1] = to; + } + }, + //--------------------------------------------------------------------- + resetPage: function() + { + + //reset query strings + this.resetQueryString(); + + //reset bulk actions + this.resetBulkAction(); + + this.resetSelectedDate(); + + //reload page list + this.getList(); + + }, + //--------------------------------------------------------------------- + resetSelectedDate: function() + { + this.selected_date = null; + }, + //--------------------------------------------------------------------- + resetQueryString: function() + { + for(let key in this.query_string) + { + if(key == 'page') + { + this.query_string[key] = 1; + } else if(key == 'sort_order') + { + this.query_string[key] = 'desc'; + } else + { + this.query_string[key] = null; + } + } + + this.update('query_string', this.query_string); + }, + //--------------------------------------------------------------------- + resetBulkAction: function() + { + this.page.bulk_action = { + selected_items: [], + data: {}, + action: null, + }; + this.update('bulk_action', this.page.bulk_action); + }, + //--------------------------------------------------------------------- + paginate: function(page=1) + { + this.query_string.page = page; + this.update('query_string', this.query_string); + this.getList(); + }, + //--------------------------------------------------------------------- + delayedSearch: function() + { + let self = this; + clearTimeout(this.search_delay); + this.search_delay = setTimeout(function() { + self.getList(); + }, this.search_delay_time); + + this.query_string.page = 1; + this.update('query_string', this.query_string); + + }, + //--------------------------------------------------------------------- + getList: function () { + this.$Progress.start(); + this.$vaah.updateCurrentURL(this.query_string, this.$router); + let url = this.ajax_url+'/list'; + this.$vaah.ajaxGet(url, this.query_string, this.getListAfter); + }, + //--------------------------------------------------------------------- + getListAfter: function (data, res) { + + this.update('is_list_loading', false); + + if(data){ + + console.log('--->data.list', data.list); + + this.update('list', data.list); + + + this.update('total_roles', data.totalRole); + this.update('total_users', data.totalUser); + + if(data.list.total === 0) + { + this.update('list_is_empty', true); + }else{ + this.update('list_is_empty', false); + } + + this.page.query_string.recount = null; + + this.update('query_string', this.page.query_string); + this.$vaah.updateCurrentURL(this.page.query_string, this.$router); + + this.is_btn_loading = false; + + } + + this.$Progress.finish(); + + }, + //--------------------------------------------------------------------- + actions: function () { + + if(!this.page.bulk_action.action) + { + this.$vaah.toastErrors(['Select an action']); + return false; + } + + if(this.page.bulk_action.action == 'bulk-change-status'){ + if(!this.page.bulk_action.data.status){ + this.$vaah.toastErrors(['Select a status']); + return false; + } + } + + if(this.page.bulk_action.selected_items.length < 1) + { + this.$vaah.toastErrors(['Select a record']); + return false; + } + + this.$Progress.start(); + this.update('bulk_action', this.page.bulk_action); + let ids = this.$vaah.pluckFromObject(this.page.bulk_action.selected_items, 'id'); + + let params = { + inputs: ids, + data: this.page.bulk_action.data + }; + + let url = this.ajax_url+'/actions/'+this.page.bulk_action.action; + this.$vaah.ajax(url, params, this.actionsAfter); + }, + //--------------------------------------------------------------------- + actionsAfter: function (data, res) { + if(data) + { + this.$root.$emit('eReloadItem'); + this.resetBulkAction(); + this.getList(); + } else + { + this.$Progress.finish(); + } + this.reloadRootAssets(); + }, + //--------------------------------------------------------------------- + async reloadRootAssets() { + await this.$store.dispatch('root/reloadAssets'); + }, + //--------------------------------------------------------------------- + sync: function () { + + this.page.query_string.recount = true; + + this.is_btn_loading = true; + + this.update('query_string', this.page.query_string); + this.getList(); + }, + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + setFilter: function (data) { + + if(!isNaN(this.query_string.filter)){ + this.query_string.location = null; + } + + this.query_string.page = 1; + this.update('query_string', this.query_string); + + this.getList(); + + }, + //--------------------------------------------------------------------- + setDateRange: function() + { + + if(this.selected_date.length > 0){ + let current_datetime = new Date(this.selected_date[0]); + this.query_string.from = current_datetime.getFullYear() + "-" + (current_datetime.getMonth() + 1) + "-" + current_datetime.getDate(); + + current_datetime = new Date(this.selected_date[1]); + this.query_string.to = current_datetime.getFullYear() + "-" + (current_datetime.getMonth() + 1) + "-" + current_datetime.getDate(); + + this.getList(); + } + + }, + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + } +} diff --git a/Vue/pages/blocks/View.vue b/Vue/pages/blocks/View.vue new file mode 100644 index 0000000..1f2ec37 --- /dev/null +++ b/Vue/pages/blocks/View.vue @@ -0,0 +1,210 @@ + + + + + + + + + + + + + + + + + + Content + + + + + + + + + + + + + + + + + + + + + + + + + + + {{$vaah.limitString(item.name, 15)}} + + + + + + + + #{{item.id}} + + + + + Edit + + + + + + + + + + + + + Trash + + + + + Restore + + + + Delete + + + + + + + + + + + + + + + + + + + + + + Deleted {{$vaah.fromNow(item.deleted_at)}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Vue/pages/blocks/ViewJs.js b/Vue/pages/blocks/ViewJs.js new file mode 100644 index 0000000..7bdf25f --- /dev/null +++ b/Vue/pages/blocks/ViewJs.js @@ -0,0 +1,204 @@ +import GlobalComponents from '../../vaahvue/helpers/GlobalComponents' +import TableTrView from '../../vaahvue/reusable/TableTrView' +import TableTrActedBy from '../../vaahvue/reusable/TableTrActedBy' +import TableTrStatus from '../../vaahvue/reusable/TableTrStatus' + +let namespace = 'blocks'; + +export default { + computed:{ + root() {return this.$store.getters['root/state']}, + page() {return this.$store.getters[namespace+'/state']}, + ajax_url() {return this.$store.getters[namespace+'/state'].ajax_url}, + item() {return this.$store.getters[namespace+'/state'].active_item}, + }, + components:{ + ...GlobalComponents, + TableTrView, + TableTrStatus, + TableTrActedBy, + }, + data() + { + return { + namespace: namespace, + is_btn_loading: false, + is_content_loading: false, + } + }, + watch: { + $route(to, from) { + this.updateView(); + this.getItem(); + } + }, + mounted() { + //---------------------------------------------------- + this.onLoad(); + //---------------------------------------------------- + this.$root.$on('eReloadItem', this.getItem); + //---------------------------------------------------- + this.$root.$on('eResetBulkActions', this.resetBulkAction); + //---------------------------------------------------- + //---------------------------------------------------- + }, + methods: { + //--------------------------------------------------------------------- + update: function(name, value) + { + let update = { + state_name: name, + state_value: value, + namespace: this.namespace, + }; + this.$vaah.updateState(update); + }, + //--------------------------------------------------------------------- + updateView: function() + { + this.$store.dispatch(this.namespace+'/updateView', this.$route); + }, + //--------------------------------------------------------------------- + onLoad: function() + { + this.is_content_loading = true; + + this.updateView(); + this.getAssets(); + this.getItem(); + }, + //--------------------------------------------------------------------- + async getAssets() { + await this.$store.dispatch(namespace+'/getAssets'); + }, + //--------------------------------------------------------------------- + getItem: function () { + this.$Progress.start(); + this.params = {}; + let url = this.ajax_url+'/item/'+this.$route.params.id; + this.$vaah.ajaxGet(url, this.params, this.getItemAfter); + }, + //--------------------------------------------------------------------- + getItemAfter: function (data, res) { + this.$Progress.finish(); + this.is_content_loading = false; + + if(data && data) + { + if(data.is_active == 1){ + data.is_active = 'Yes'; + }else{ + data.is_active = 'No'; + } + this.update('active_item', data); + } else + { + //if item does not exist or delete then redirect to list + this.update('active_item', null); + this.$router.push({name: 'perm.list'}); + } + }, + //--------------------------------------------------------------------- + actions: function (action) { + + this.$Progress.start(); + this.page.bulk_action.action = action; + this.update('bulk_action', this.page.bulk_action); + let params = { + inputs: [this.item.id], + data: null + }; + + let url = this.ajax_url+'/actions/'+this.page.bulk_action.action; + this.$vaah.ajax(url, params, this.actionsAfter); + + }, + //--------------------------------------------------------------------- + actionsAfter: function (data, res) { + let action = this.page.bulk_action.action; + if(data) + { + this.resetBulkAction(); + this.$emit('eReloadList'); + + if(action == 'bulk-delete') + { + this.$router.push({name: 'blocks.list'}); + } else + { + this.getItem(); + } + + } else + { + this.$Progress.finish(); + } + + this.reloadRootAssets(); + }, + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + resetBulkAction: function() + { + this.page.bulk_action = { + selected_items: [], + data: {}, + action: "", + }; + this.update('bulk_action', this.page.bulk_action); + }, + //--------------------------------------------------------------------- + confirmDelete: function() + { + let self = this; + this.$buefy.dialog.confirm({ + title: 'Deleting record', + message: 'Are you sure you want to delete the record? This action cannot be undone.', + confirmText: 'Delete', + type: 'is-danger', + hasIcon: true, + onConfirm: function () { + self.actions('bulk-delete'); + } + }) + }, + //--------------------------------------------------------------------- + isCopiable: function (label) { + + if( + label == 'id' || label == 'uuid' || label == 'slug' || label == 'plural_slug' || label == 'singular_slug' + ) + { + return true; + } + + return false; + + }, + //--------------------------------------------------------------------- + isUpperCase: function (label) { + + if( + label == 'id' || label == 'uuid' + ) + { + return true; + } + + return false; + + }, + //--------------------------------------------------------------------- + resetActiveItem: function () { + this.update('active_item', null); + this.$router.push({name:'blocks.list'}); + }, + //--------------------------------------------------------------------- + async reloadRootAssets() { + await this.$store.dispatch('root/reloadAssets'); + }, + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + } +} diff --git a/Vue/pages/blocks/partials/ListLargeView.vue b/Vue/pages/blocks/partials/ListLargeView.vue new file mode 100644 index 0000000..833c562 --- /dev/null +++ b/Vue/pages/blocks/partials/ListLargeView.vue @@ -0,0 +1,127 @@ + + + + + + + + {{ props.row.id }} + + + + + + + + + + + + + + + + + + + {{props.row.theme.name}} + + + {{props.row.theme_location.name}} + + + + + + + + + + + + + + + + + + + Yes + + + No + + + + + + + + Yes + + + No + + + + + + + + + + + {{$vaah.fromNow(props.row.updated_at)}} + + + + + + + + + + + + + + + + + + + + + + + + Nothing here. + + + + + + + + diff --git a/Vue/pages/blocks/partials/ListLargeViewJs.js b/Vue/pages/blocks/partials/ListLargeViewJs.js new file mode 100644 index 0000000..646c0f6 --- /dev/null +++ b/Vue/pages/blocks/partials/ListLargeViewJs.js @@ -0,0 +1,134 @@ +import copy from "copy-to-clipboard"; + +let namespace = 'blocks'; +export default { + computed: { + root() {return this.$store.getters['root/state']}, + page() {return this.$store.getters[namespace+'/state']}, + ajax_url() {return this.$store.getters[namespace+'/state'].ajax_url}, + query_string() {return this.$store.getters[namespace+'/state'].query_string}, + }, + components:{ + + }, + + data() + { + let obj = { + namespace: namespace, + icon_copy: "" + }; + + return obj; + }, + created() { + }, + mounted(){ + + }, + + watch: { + + }, + methods: { + //--------------------------------------------------------------------- + update: function(name, value) + { + let update = { + state_name: name, + state_value: value, + namespace: this.namespace, + }; + this.$vaah.updateState(update); + }, + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + setRowClass: function(row, index) + { + + if(this.page.active_item && row.id == this.page.active_item.id) + { + return 'is-selected'; + } + + if(row.deleted_at != null) + { + return 'is-danger'; + } + + }, + //--------------------------------------------------------------------- + setActiveItem: function (item) { + this.update('active_item', item); + this.$router.push({name: 'blocks.view', params:{id:item.id}}) + }, + //--------------------------------------------------------------------- + changeStatus: function (id) { + this.$Progress.start(); + let url = this.ajax_url+'/actions/bulk-change-status'; + let params = { + inputs: [id], + data: null + }; + this.$vaah.ajax(url, params, this.changeStatusAfter); + }, + //--------------------------------------------------------------------- + changeStatusAfter: function (data,res) { + this.$emit('eReloadList'); + this.reloadRootAssets(); + this.update('is_list_loading', false); + + }, + //--------------------------------------------------------------------- + async reloadRootAssets() { + await this.$store.dispatch('root/reloadAssets'); + }, + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + copiedData: function (data) { + + this.$vaah.toastSuccess(['copied']); + + // alertify.success('copied'); + + this.$vaah.console(data, 'copied data'); + + }, + //--------------------------------------------------------------------- + copyCode: function (item,has_location = false) + { + let code = ""; + + + + if(has_location){ + if(item && item.theme_location && item.theme_location.slug){ + code = "{!! vh_location_blocks('"+item.theme_location.slug+"') !!}"; + } + }else{ + if(item && item.slug){ + code = "{!! vh_block('"+item.slug+"') !!}"; + } + } + + + + copy(code); + + this.$buefy.toast.open({ + message: 'Copied!', + type: 'is-success' + }); + }, + //--------------------------------------------------------------------- + toEdit: function (item) { + this.update('active_item', item); + this.$router.push({name:'blocks.edit', params:{id:item.id}}); + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + } +} diff --git a/Vue/pages/blocks/partials/ListSmallView.vue b/Vue/pages/blocks/partials/ListSmallView.vue new file mode 100644 index 0000000..ed9088e --- /dev/null +++ b/Vue/pages/blocks/partials/ListSmallView.vue @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Nothing here. + + + + + + + + diff --git a/Vue/pages/blocks/partials/ListSmallViewJs.js b/Vue/pages/blocks/partials/ListSmallViewJs.js new file mode 100644 index 0000000..b129f04 --- /dev/null +++ b/Vue/pages/blocks/partials/ListSmallViewJs.js @@ -0,0 +1,126 @@ +import copy from "copy-to-clipboard"; + +let namespace = 'blocks'; +export default { + computed: { + root() {return this.$store.getters['root/state']}, + page() {return this.$store.getters[namespace+'/state']}, + ajax_url() {return this.$store.getters[namespace+'/state'].ajax_url}, + query_string() {return this.$store.getters[namespace+'/state'].query_string}, + }, + components:{ + + }, + + data() + { + let obj = { + namespace: namespace, + icon_copy: "" + }; + + return obj; + }, + created() { + }, + mounted(){ + + }, + + watch: { + + }, + methods: { + //--------------------------------------------------------------------- + update: function(name, value) + { + let update = { + state_name: name, + state_value: value, + namespace: this.namespace, + }; + this.$vaah.updateState(update); + }, + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + setRowClass: function(row, index) + { + + if(this.page.active_item && row.id == this.page.active_item.id) + { + return 'is-selected'; + } + + if(row.deleted_at != null) + { + return 'is-danger'; + } + + }, + //--------------------------------------------------------------------- + setActiveItem: function (item) { + this.update('active_item', item); + this.$router.push({name: 'blocks.view', params:{id:item.id}}) + }, + //--------------------------------------------------------------------- + changeStatus: function (id) { + this.$Progress.start(); + let url = this.ajax_url+'/actions/bulk-change-status'; + let params = { + inputs: [id], + data: null + }; + this.$vaah.ajax(url, params, this.changeStatusAfter); + }, + //--------------------------------------------------------------------- + changeStatusAfter: function (data,res) { + this.$emit('eReloadList'); + this.reloadRootAssets(); + this.update('is_list_loading', false); + + }, + //--------------------------------------------------------------------- + async reloadRootAssets() { + await this.$store.dispatch('root/reloadAssets'); + }, + //--------------------------------------------------------------------- + + //--------------------------------------------------------------------- + copiedData: function (data) { + + this.$vaah.toastSuccess(['copied']); + + // alertify.success('copied'); + + this.$vaah.console(data, 'copied data'); + + }, + //--------------------------------------------------------------------- + copyCode: function (item) + { + let code = ""; + + if(item && item.slug && item.theme_location && item.theme_location.slug){ + code = "{!! vh_block('"+item.slug+"') !!}"; + } + + copy(code); + + this.$buefy.toast.open({ + message: 'Copied!', + type: 'is-success' + }); + }, + + //--------------------------------------------------------------------- + toEdit: function (item) { + this.update('active_item', item); + this.$router.push({name:'blocks.edit', params:{id:item.id}}); + + } + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + } +} diff --git a/Vue/pages/contents/Edit.vue b/Vue/pages/contents/Edit.vue index f54c42f..dffca1e 100644 --- a/Vue/pages/contents/Edit.vue +++ b/Vue/pages/contents/Edit.vue @@ -1,8 +1,12 @@ - + - + + + + + @@ -203,7 +207,7 @@ :label-position="labelPosition"> - + Select a Template assets url', url); + + let params = {}; + let data = await Vaah.ajaxGet(url, params); + payload = { + key: 'assets', + value: data.data.data + }; + + commit('updateState', payload); + } + + }, + //----------------------------------------------------------------- + updateView({ state, commit, dispatch, getters }, payload) { + let list_view; + let update; + + if(payload && payload.name && payload.name == 'blocks.list') + { + list_view = 'large'; + + update = { + key: 'active_item', + value: null + }; + + commit('updateState', update); + + } + + if(payload.name == 'blocks.create' || payload.name == 'blocks.view' || payload.name == 'blocks.edit') + { + list_view = 'small'; + }; + + let view = { + key: 'list_view', + value: list_view + }; + + commit('updateState', view); + + }, + //----------------------------------------------------------------- + }, + //========================================================================= + getters:{ + state(state) {return state;}, + assets(state) {return state.assets;}, + is_logged_in(state) {return state.is_logged_in;}, + } + +} diff --git a/Vue/store/store.js b/Vue/store/store.js index 49c446c..1c90c24 100644 --- a/Vue/store/store.js +++ b/Vue/store/store.js @@ -5,6 +5,7 @@ Vue.use(Vuex); import root from './modules/root'; import content_types from './modules/content_types'; +import blocks from './modules/blocks'; import contents from './modules/contents'; import menus from './modules/menus'; @@ -12,6 +13,7 @@ export const store = new Vuex.Store({ modules: { root: root, content_types: content_types, + blocks: blocks, contents: contents, menus: menus, } diff --git a/Vue/vaahvue b/Vue/vaahvue index 5d77880..70a2068 160000 --- a/Vue/vaahvue +++ b/Vue/vaahvue @@ -1 +1 @@ -Subproject commit 5d77880a904e694a6c272eb234fdcd6f01c50c7c +Subproject commit 70a206801477d723a17b1f77eeac81f567244918
+ + Editor + +
+ + Code Editor + +
+ + Save + +
+ + +
+ + #{{item.id}} + +
+ + + + + + + + + + Save & Close + + + + + +
+ + Create + +
+ + Apply + +
+ + Filter + +
+ + Reset + +
+ + + +
+ + Edit + +
+ + + + + + + + + + Trash + + + + + Restore + + + + Delete + + + + + +
Nothing here.