From 34c14102259dda2df0f3535902994e492dc64fad Mon Sep 17 00:00:00 2001 From: SintezCode Date: Thu, 11 May 2017 16:01:37 +0300 Subject: [PATCH 01/16] Refactor Refactor code and add events for file notes --- .../elements/plugins/plugin.elementnotes.php | 122 ++++++++++++------ 1 file changed, 83 insertions(+), 39 deletions(-) diff --git a/core/components/elementnotes/elements/plugins/plugin.elementnotes.php b/core/components/elementnotes/elements/plugins/plugin.elementnotes.php index 71535e8..c4e7950 100644 --- a/core/components/elementnotes/elements/plugins/plugin.elementnotes.php +++ b/core/components/elementnotes/elements/plugins/plugin.elementnotes.php @@ -1,56 +1,100 @@ event->name) { - // add the "Note" tab +$elementNotes = $modx->getService('elementnotes', 'elementNotes', $modx->getOption('core_path') . 'components/elementnotes/model/elementnotes/'); +$prerenderData=array( + 'OnTempFormPrerender'=>['type'=>'template','id'=>function($scriptProperties){return $scriptProperties['id'];}] + ,'OnChunkFormPrerender'=>['type'=>'chunk','id'=>function($scriptProperties){return $scriptProperties['id'];}] + ,'OnSnipFormPrerender'=>['type'=>'snippet','id'=>function($scriptProperties){return $scriptProperties['id'];}] + ,'OnPluginFormPrerender'=>['type'=>'plugin','id'=>function($scriptProperties){return $scriptProperties['id'];}] + ,'OnFileEditFormPrerender'=>['type'=>'file','id'=>function($scriptProperties){return $scriptProperties['fa']['path'];}] +); +$removeData=array( + 'OnTemplateRemove'=>['type'=>'template','criteria'=>function($scriptProperties){return array('id'=>$scriptProperties['template']->id);}] + ,'OnChunkRemove'=>['type'=>'chunk','criteria'=>function($scriptProperties){return array('id'=>$scriptProperties['chunk']->id);}] + ,'OnSnippetRemove'=>['type'=>'snippet','criteria'=>function($scriptProperties){return array('id'=>$scriptProperties['snippet']->id);}] + ,'OnPluginRemove'=>['type'=>'plugin','criteria'=>function($scriptProperties){return array('id'=>$scriptProperties['plugin']->id);}] + ,'OnFileManagerFileRemove'=>['type'=>'file','criteria'=>function($scriptProperties){return array('id'=>$scriptProperties['path']);}] + ,'OnFileManagerDirRemove'=>['type'=>'file','criteria'=>function($scriptProperties){return array('id:LIKE'=>$scriptProperties['directory'].'%');}] +); +switch ($modx->event->name){ + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////// add the "Note" tab + /////////////////////////////////////////////////////////////////////////////////////////// case 'OnTempFormPrerender': - $enTabs = 'modx-template-tabs'; case 'OnChunkFormPrerender': - if (!isset($enTabs)) $enTabs = 'modx-chunk-tabs'; case 'OnSnipFormPrerender': - if (!isset($enTabs)) $enTabs = 'modx-snippet-tabs'; case 'OnPluginFormPrerender': - if (!isset($enTabs)) $enTabs = 'modx-plugin-tabs'; + case 'OnFileEditFormPrerender': if ($mode == modSystemEvent::MODE_UPD) { $modx->controller->addLexiconTopic('elementnotes:default'); - $modx->controller->addJavascript($modx->getOption('assets_url') . 'components/elementnotes/js/mgr/elementnotes.js'); - $modx->controller->addLastJavascript($modx->getOption('assets_url') . 'components/elementnotes/js/mgr/widgets/elementnotes.panel.js'); + $modx->controller->addJavascript($elementNotes->config['jsUrl'].'mgr/elementnotes.js'); + $modx->controller->addLastJavascript($elementNotes->config['jsUrl'].'mgr/widgets/elementnotes.panel.js'); $_html = ''; + elementNotes.config = ' . $modx->toJSON($elementNotes->config) . '; + elementNotes.getPageStructure=MODx.getPageStructure; + MODx.getPageStructure=function(v,c) { + v.push({ + id: "elementnotes-tab", + title: _("Notes"), + items: [{ + xtype: "elementnotes-panel" + ,width: "100%" + ,note:{ + type: "'.$prerenderData[$modx->event->name]['type'].'" + ,id: "'.$prerenderData[$modx->event->name]['id']($scriptProperties).'" + } + }] + }); + return elementNotes.getPageStructure(v,c); + }; + '; $modx->controller->addHtml($_html); } break; - // Remove the element note + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////// remove Note + /////////////////////////////////////////////////////////////////////////////////////////// case 'OnChunkRemove': - $type = 'chunk'; - $id = $chunk->id; case 'OnPluginRemove': - if (!isset($type)) { - $type = 'plugin'; - $id = $plugin->id; - } case 'OnSnippetRemove': - if (!isset($type)) { - $type = 'snippet'; - $id = $snippet->id; - } case 'OnTemplateRemove': - if (!isset($type)) { - $type = 'template'; - $id = $template->id; + case 'OnFileManagerFileRemove': + case 'OnFileManagerDirRemove': + $notes = $modx->getCollection('elementNote',array_merge(array('type'=>$removeData[$modx->event->name]['type']),$removeData[$modx->event->name]['criteria']($scriptProperties))); + foreach($notes as $note)$note->remove(); + break; + case 'OnFileManagerFileRename': + case 'OnFileManagerDirRename': + //Need oldpath to work, create pullrequest for modx or set oldpath youself in model/modx/sources/modfilemediasource.class.php + $oldPath = $scriptProperties['oldPath']; + $newPath = $scriptProperties['path']?:$scriptProperties['directory']; + if(!$oldPath)break; + $notes = $modx->getCollection('elementNote',array('type'=>'file','id:LIKE'=>$oldPath.'%')); + foreach($notes as $note) + { + //create new note, because id is PRIMARY and we dont change it + $newnote = $modx->newObject('elementNote'); + $newnote->set('type','file'); + $newnote->set('id',str_replace($oldPath,$newPath,$note->id)); + $newnote->set('createdon',$note->createdon); + $newnote->set('text',$note->text); + $newnote->save(); + $note->remove(); + } + break; + case 'OnFileManagerMoveObject': + $newPath = rtrim($to,'/').'/'.basename($from); + if(substr($from,-1)=='/')$newPath.='/'; + $notes = $modx->getCollection('elementNote',array('type'=>'file','id:LIKE'=>$from.'%')); + foreach($notes as $note) + { + //create new note, because id is PRIMARY and we dont change it + $newnote = $modx->newObject('elementNote'); + $newnote->set('type','file'); + $newnote->set('id',str_replace($from,$newPath,$note->id)); + $newnote->set('createdon',$note->createdon); + $newnote->set('text',$note->text); + $newnote->save(); + $note->remove(); } - - /** @var elementNotes $elementNotes */ - $elementNotes = $modx->getService('elementnotes', 'elementNotes', $modx->getOption('core_path') . 'components/elementnotes/model/elementnotes/'); - if (isset($type) && isset($id)) $elementNotes->removeNote($type,$id); break; -} \ No newline at end of file +} From 470a2dd801a8d8f6c5852fd62a93ef850f1498a0 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Thu, 11 May 2017 16:10:17 +0300 Subject: [PATCH 02/16] Refactor Refactor, and remove dependence from type --- .../js/mgr/widgets/elementnotes.panel.js | 89 +++++++------------ 1 file changed, 32 insertions(+), 57 deletions(-) diff --git a/assets/components/elementnotes/js/mgr/widgets/elementnotes.panel.js b/assets/components/elementnotes/js/mgr/widgets/elementnotes.panel.js index 87bc531..9c14f8a 100644 --- a/assets/components/elementnotes/js/mgr/widgets/elementnotes.panel.js +++ b/assets/components/elementnotes/js/mgr/widgets/elementnotes.panel.js @@ -2,12 +2,8 @@ elementNotes.panel.Notes = function(config) { config = config || {}; Ext.apply(config,{ - listeners: { - render: {fn: function(a) { - this.getElementNote(); - }, scope: this} - }, - id: 'elementnotes-page', + listeners:{render: {fn:function(a){this.getElementNote();},scope:this}}, + id:'elementnotes-panel', items: [{ border: false, baseCls: 'panel-desc', @@ -49,67 +45,31 @@ elementNotes.panel.Notes = function(config) { cls: 'primary-button', style: {marginTop: '10px'}, disabled: true, - /*keys: [{ - key: MODx.config.keymap_save || 's' - ,ctrl: true - }],*/ listeners: { - click: {fn:function() { - if (this.disabled) return false; - var type = ''; - if (MODx.request.a.indexOf('snippet') > 0) - type = 'snippet'; - else if (MODx.request.a.indexOf('chunk') > 0) - type = 'chunk'; - else if (MODx.request.a.indexOf('plugin') > 0) - type = 'plugin'; - else if (MODx.request.a.indexOf('template') > 0) - type = 'template'; - var text = Ext.getCmp('elementnotes-text').getValue(); - - this.setText(_('saving')); - MODx.Ajax.request({ - url: elemNotes.config.connector_url, - params: { - action: 'mgr/note/save', - id: MODx.request.id, - type: type, - text: text - }, - listeners: { - 'success': {fn:function(r) { - if (r.success) { - this.setDisabled(true); - this.setText(_('save')); - } - },scope:this} - } - }); - }} + click: {fn:function(btn) { + if(btn.disabled)return false; + btn.setText(_('saving')); + this.saveElementNote(); + },scope:this} } }] }] }); elementNotes.panel.Notes.superclass.constructor.call(this,config); + this.on('afterSave',function(){ + btn = Ext.getCmp('elementnotes-save-btn'); + btn.setDisabled(true); + btn.setText(_('save')); + },this); }; Ext.extend(elementNotes.panel.Notes,MODx.Panel, { - getElementNote: function() { - var type = ''; - if (MODx.request.a.indexOf('snippet') > 0) - type = 'snippet'; - else if (MODx.request.a.indexOf('chunk') > 0) - type = 'chunk'; - else if (MODx.request.a.indexOf('plugin') > 0) - type = 'plugin'; - else if (MODx.request.a.indexOf('template') > 0) - type = 'template'; MODx.Ajax.request({ - url: elemNotes.config.connector_url, + url: elementNotes.config.connectorUrl, params: { action: 'mgr/note/get', - id: MODx.request.id, - type: type + id: this.note.id, + type: this.note.type }, listeners: { 'success': {fn:function(r) { @@ -120,6 +80,21 @@ Ext.extend(elementNotes.panel.Notes,MODx.Panel, { } }); } - + ,saveElementNote:function() { + MODx.Ajax.request({ + url: elementNotes.config.connectorUrl, + params: { + action: 'mgr/note/save', + id: this.note.id, + type: this.note.type, + text: Ext.getCmp('elementnotes-text').getValue() + }, + listeners: { + 'success': {fn:function(r) { + if(r.success){this.fireEvent('afterSave',{response:r});} + },scope:this} + } + }); + } }); -Ext.reg('elementnotes-page',elementNotes.panel.Notes); \ No newline at end of file +Ext.reg('elementnotes-panel',elementNotes.panel.Notes); From e199fd31927f1bee5023469b3f661a04195f3941 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Thu, 11 May 2017 16:15:50 +0300 Subject: [PATCH 03/16] Add createdon column --- .../elementnotes/model/elementnotes/elementnote.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/components/elementnotes/model/elementnotes/elementnote.class.php b/core/components/elementnotes/model/elementnotes/elementnote.class.php index 6231b2f..80ae8bd 100644 --- a/core/components/elementnotes/model/elementnotes/elementnote.class.php +++ b/core/components/elementnotes/model/elementnotes/elementnote.class.php @@ -1,2 +1,8 @@ isNew()&&empty($this->createdon))$this->set('createdon',time()); + return parent::save($cacheFlag); + } +} From b7dfd95bd23e21ae106f8328f50ac79aa4a6c228 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Thu, 11 May 2017 16:17:56 +0300 Subject: [PATCH 04/16] Change model Add createdon column, and set id to mediumtext for files --- .../mysql/elementnote.map.inc.php | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/core/components/elementnotes/model/elementnotes/mysql/elementnote.map.inc.php b/core/components/elementnotes/model/elementnotes/mysql/elementnote.map.inc.php index 4b8f0e8..327d202 100644 --- a/core/components/elementnotes/model/elementnotes/mysql/elementnote.map.inc.php +++ b/core/components/elementnotes/model/elementnotes/mysql/elementnote.map.inc.php @@ -9,15 +9,14 @@ 'id' => NULL, 'type' => NULL, 'text' => NULL, + 'createdon' => NULL, ), 'fieldMeta' => array ( 'id' => array ( - 'dbtype' => 'int', - 'precision' => '10', - 'attributes' => 'unsigned', - 'phptype' => 'integer', + 'dbtype' => 'mediumtext', + 'phptype' => 'string', 'null' => false, 'index' => 'pk', ), @@ -35,6 +34,15 @@ 'phptype' => 'string', 'null' => false, ), + 'createdon' => + array ( + 'dbtype' => 'int', + 'precision' => '20', + 'phptype' => 'integer', + 'attributes' => 'unsigned', + 'null' => false, + 'index' => 'pk', + ), ), 'indexes' => array ( @@ -48,7 +56,7 @@ array ( 'id' => array ( - 'length' => '', + 'length' => '255', 'collation' => 'A', 'null' => false, ), @@ -58,6 +66,12 @@ 'collation' => 'A', 'null' => false, ), + 'createdon' => + array ( + 'length' => '', + 'collation' => 'A', + 'null' => false, + ), ), ), ), From 5f480c39be38487ed8cca3de92f07a8df6d96c2d Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:40:50 +0300 Subject: [PATCH 05/16] Add notes tv --- .../elements/plugins/plugin.elementnotes.php | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/core/components/elementnotes/elements/plugins/plugin.elementnotes.php b/core/components/elementnotes/elements/plugins/plugin.elementnotes.php index c4e7950..7ea84ce 100644 --- a/core/components/elementnotes/elements/plugins/plugin.elementnotes.php +++ b/core/components/elementnotes/elements/plugins/plugin.elementnotes.php @@ -62,6 +62,9 @@ $notes = $modx->getCollection('elementNote',array_merge(array('type'=>$removeData[$modx->event->name]['type']),$removeData[$modx->event->name]['criteria']($scriptProperties))); foreach($notes as $note)$note->remove(); break; + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////// file events + /////////////////////////////////////////////////////////////////////////////////////////// case 'OnFileManagerFileRename': case 'OnFileManagerDirRename': //Need oldpath to work, create pullrequest for modx or set oldpath youself in model/modx/sources/modfilemediasource.class.php @@ -97,4 +100,78 @@ $note->remove(); } break; + /////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////// Notes-TV + /////////////////////////////////////////////////////////////////////////////////////////// + case 'OnTVInputRenderList': + { + $modx->getService('elementnotes', 'elementNotes', $modx->getOption('core_path') . 'components/elementnotes/model/elementnotes/'); + $modx->event->output($modx->elementnotes->config['corePath'].'elements/tv/input/'); + break; + } + case 'OnTVInputPropertiesList': + { + $modx->getService('elementnotes', 'elementNotes', $modx->getOption('core_path') . 'components/elementnotes/model/elementnotes/'); + $modx->event->output($modx->elementnotes->config['corePath'].'elements/tv/inputoptions/'); + break; + } + case 'OnTVFormPrerender': + case 'OnDocFormPrerender': + { + $modx->getService('elementnotes', 'elementNotes', $modx->getOption('core_path') . 'components/elementnotes/model/elementnotes/'); + $modx->controller->addLexiconTopic('elementnotes:default'); + $modx->controller->addJavascript($modx->elementnotes->config['jsUrl'] . 'mgr/elementnotes.js'); + $modx->controller->addHtml(''); + break; + } + case 'OnTemplateVarRemove': + { + $modx->getService('elementnotes', 'elementNotes', $modx->getOption('core_path') . 'components/elementnotes/model/elementnotes/'); + switch($templateVar->type) + { + case 'notes':{$modx->removeCollection('elementNote', array('id:LIKE'=>'%_'.$templateVar->id,'type'=>'resource'));break;} + } + break; + } + case 'OnEmptyTrash': + { + $ids_where=array(); + foreach($ids as $i=>$id) + { + $ids_where[]=array(($i>0?'OR:id:LIKE':'id:LIKE')=>$id.'_%'); + } + $modx->removeCollection('elementNote', array($ids_where,'type'=>'resource')); + break; + } + case 'OnDocFormSave': + { + if($mode == modSystemEvent::MODE_NEW) + { + $modx->getService('elementnotes', 'elementNotes', $modx->getOption('core_path') . 'components/elementnotes/model/elementnotes/'); + $n_query = $modx->newQuery('modTemplateVarTemplate'); + $n_query->leftJoin('modTemplateVar','TemplateVar'); + $n_query->where(array('TemplateVar.type'=>'notes','modTemplateVarTemplate.templateid'=>$resource->template)); + $n_query->select(array('modTemplateVarTemplate'=>"GROUP_CONCAT(tmplvarid SEPARATOR ',')")); + $n_query->prepare(); + $n_query->stmt->execute(); + $n_tvs = explode(',',$modx->getValue($n_query->stmt)); + foreach($n_tvs as $n_tv_id) + { + $n_data = json_decode($processor->getProperty('tv'.$n_tv_id.'_local'),true); + if(!$n_data||count($n_data)===0)continue; + foreach($n_data as $ar_note) + { + $note=$modx->newObject('elementNote'); + $note->set('id',$resource->id.'_'.$n_tv_id); + $note->set('type','resource'); + $note->set('text',$ar_note['text']); + $note->set('createdon',$ar_note['createdon']); + $note->save(false); + } + } + } + break; + } } From 482182da74d7aa7e7ff8eabc7f9de87d7c5838d3 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:49:06 +0300 Subject: [PATCH 06/16] Add notes-tv-grid --- .../elementnotes/js/mgr/widgets/notes.tv.js | 233 ++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 assets/components/elementnotes/js/mgr/widgets/notes.tv.js diff --git a/assets/components/elementnotes/js/mgr/widgets/notes.tv.js b/assets/components/elementnotes/js/mgr/widgets/notes.tv.js new file mode 100644 index 0000000..917aacd --- /dev/null +++ b/assets/components/elementnotes/js/mgr/widgets/notes.tv.js @@ -0,0 +1,233 @@ +elementNotes.grid.notes = function(config) { + config = config || {}; + + this.sm = this.setSelectionModel(this.rememberRow,this.forgotRow); + var grid = this; + if(config.resource===0) + { + this.localmode=true; + this.inputEl = Ext.get(config.localID); + } + + Ext.applyIf(config,{ + url: elementNotes.config.connectorUrl + ,baseParams: { + action: 'mgr/tv/notes/getlist' + ,mode: 'grid' + ,tv : config.tv + ,resource : config.resource + ,'HTTP_MODAUTH': config.auth + } + ,save_action: 'mgr/tv/notes/save' + ,saveParams:{tv : config.tv,resource : config.resource} + ,autosave: true + ,preventSaveRefresh: false + ,fields: ['id','type','text','createdon'] + ,paging: false + ,remoteSort: true + ,autoHeight: true + ,autoWidth: true + ,collapsible: true + ,resizable: true + ,viewConfig: { + forceFit: true + ,autoFill: true + ,getRowClass: function(record, index){} + } + ,enableDragDrop: false + ,sm: this.sm + ,columns: [this.sm,{ + header: _('id') + ,dataIndex: 'id' + ,sortable: false + ,hidden: true + },{ + header: _('notes.grid.columns.createdon.title') + ,dataIndex: 'createdon' + ,sortable: false + ,resizable: false + ,width: 150 + ,fixed:true + ,renderer: {fn:function(value, metaData, record, rowIndex, colIndex, store) + { + if(!value||value==='')return ''; + if(!isNaN(parseInt(value)))value = new Date(value*1000); + else{value = Date.parseDate(value, 'Y-m-d H:i:s');} + if(!value)return ''; + return String.format('{0}', value.format(MODx.config.manager_date_format+' '+MODx.config.manager_time_format)); + },scope:this} + },{ + header: _('notes.grid.columns.text.title') + ,dataIndex: 'text' + ,sortable: false + ,resizable: true + ,minWidth: 200 + ,autoSizeColumn: true + ,renderer: {fn:function(value, metaData, record, rowIndex, colIndex, store) + { + return value.replace(/\n/g,'
'); + },scope:this} + ,editor: new Ext.grid.GridEditor(new Ext.form.TextArea({}),{grid:grid + ,listeners: { + complete: {fn:function (editor, value, startValue){grid.local__addSaveParams();}} + } + }) + }] + ,tbar: [{ + xtype: 'textarea' + ,width: 400 + ,name: 'note_text' + ,key: 'note_text' + },' ',{ + text: _('notes.grid.add.text') + ,height: 70 + ,style:{lineHeight:'45px'} + ,handler: this.addRecord + ,scope: this + }] + ,listeners:{'render':{fn:this.registerGridDropTarget,scope:this}} + }); + config.baseParams.localData = this.local__getValue(); + elementNotes.grid.notes.superclass.constructor.call(this,config); + + this.getView().on('refresh', this.refreshSelection, this); + if(this.topToolbar){this.topToolbar.container.setSize("auto");this.topToolbar.setSize("auto");} + if(this.bottomToolbar){this.bottomToolbar.container.setSize("auto");this.bottomToolbar.setSize("auto");} + if(this.footerToolbar){this.footerToolbar.container.setSize("auto");this.footerToolbar.setSize("auto");} + if(this.localmode) + { + this.getStore().on('beforeload', this.local__beforeLoad, this); + this.config.save_callback=this.local__saveFromResponse; + } +}; + +Ext.extend(elementNotes.grid.notes,MODx.grid.Grid,{ + local__getValue:function(decode) + { + if(!this.localmode)return ''; + return decode?Ext.util.JSON.decode(this.inputEl.dom.value||'[]'):this.inputEl.dom.value||'[]'; + } + ,local__setValue:function(v) + { + if(!this.localmode)return; + if(typeof(v)==='object')v=Ext.util.JSON.encode(v); + this.inputEl.dom.value = v; + } + ,local__addSaveParams:function() + { + if(!this.localmode)return; + this.config.saveParams.localData = this.local__getValue(); + } + ,local__beforeLoad:function(that,options) + { + if(this.localmode)options.params.localData = this.local__getValue(); + return true; + } + ,local__saveFromResponse:function(response) + { + if(this.localmode&&response.object)this.local__setValue(response.object); + } + ///////////////////////////////////////////////////////////////// + //////////////////// SELCTION + ,selectedRecords: [] + ,setSelectionModel: function(rowselect,rowdeselect) + { + return new Ext.grid.CheckboxSelectionModel({ + listeners: { + rowselect:{fn:function(sm,rowIndex,record){rowselect(record,this);},scope:this}, + rowdeselect:{fn:function(sm,rowIndex,record){rowdeselect(record,this);},scope: this} + } + }); + } + ,rememberRow: function(record,that){if(that.selectedRecords.indexOf(record.id)==-1){that.selectedRecords.push(record.id);}} + ,forgotRow: function(record,that){that.selectedRecords.remove(record.id);} + ,refreshSelection: function() + { + var rowsToSelect = []; + var rowsToDeselect = []; + Ext.each(this.selectedRecords, function(item,index){ + idx = this.store.indexOfId(item); + (idx===-1)?rowsToDeselect.push(item):rowsToSelect.push(idx); + },this); + this.selectedRecords = this.selectedRecords.filter(function(item){return rowsToDeselect.indexOf(item) === -1;}); + this.getSelectionModel().selectRows(rowsToSelect); + } + ,getSelectedAsList: function(){return this.selectedRecords.join();} + + //////////////////////////////////////////////////////////////// + //////////////////// DRAG + ,registerGridDropTarget: function() { + + } + + //////////////////////////////////////////////////////////////// + //////////////////// MENU + ,getMenu: function() { + var m = []; + + m.push({ + text: _('notes.grid.menu.remove.title') + ,handler: this.removeRecord + }); + + if(this.selectedRecords.length > 1) + { + m.push('-',{ + text: _('notes.grid.menu.removeselected.title') + ,handler: this.removeSelectedRecords + }); + } + + return m; + } + //////////////////////////////////////////////////////////////// + //////////////////// ACTIONS + ,addRecord:function() + { + field = this.getTopToolbar().items.find(function(el){if(el.name=='note_text');return true;}); + + MODx.Ajax.request({ + url: this.config.url + ,params: + { + action: this.config.save_action + ,resource: this.config.resource + ,tv: this.config.tv + ,text: field.getValue() + ,localData: this.local__getValue() + } + ,listeners:{ + success:{fn: function(response){this.local__saveFromResponse(response);this.refresh();}, scope: this} + ,failure: {fn: function (r){MODx.msg.alert(_('error'), r.message);}, scope: this} + } + }); + } + ,removeRecord:function(btn,e) + { + if (!this.menu.record) return false; + this.removeRecordById([this.menu.record.id]); + } + ,removeSelectedRecords:function(btn,e) + { + this.removeRecordById(this.selectedRecords); + } + ,removeRecordById:function(ids) + { + MODx.msg.confirm({ + title: _('notes.grid.msg.remove.title') + ,text: _('notes.grid.msg.remove.text') + ,url: this.config.url + ,params: { + action: 'mgr/tv/notes/remove' + ,resource: this.config.resource + ,tv: this.config.tv + ,'ids[]': ids + ,localData:this.local__getValue() + } + ,listeners: { + 'success': {fn:function(r) {this.local__saveFromResponse(r);this.refresh();},scope:this} + } + }); + } +}); +Ext.reg('notes-tv-grid',elementNotes.grid.notes); From 2c7ec5c3268374de13f6c39a192f26fd88a56457 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:50:49 +0300 Subject: [PATCH 07/16] Add notes tv inputprops panel --- .../elementnotes/js/mgr/elementnotes.js | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/assets/components/elementnotes/js/mgr/elementnotes.js b/assets/components/elementnotes/js/mgr/elementnotes.js index 34aae2f..965f448 100644 --- a/assets/components/elementnotes/js/mgr/elementnotes.js +++ b/assets/components/elementnotes/js/mgr/elementnotes.js @@ -8,4 +8,44 @@ Ext.extend(elementNotes,Ext.Component,{ }); Ext.reg('elementnotes', elementNotes); -elementNotes = new elementNotes(); \ No newline at end of file +elementNotes = new elementNotes(); + +elementNotes.panel.notesIP = function(config) { + config = config || {}; + Ext.applyIf(config,{ + layout: 'form' + ,cls: 'form-with-labels' + ,autoHeight: true + ,border: false + ,labelAlign: 'top' + ,labelSeparator: '' + ,items:this.getItems(config) + }); + elementNotes.panel.notesIP.superclass.constructor.call(this,config); +}; +Ext.extend(elementNotes.panel.notesIP,MODx.Panel,{ + + getItems:function(config) + { + var items = []; + items.push({ + xtype: 'combo-boolean' + ,fieldLabel: _('required') + ,description: MODx.expandHelp ? '' : _('required_desc') + ,name: 'inopt_allowBlank' + ,hiddenName: 'inopt_allowBlank' + ,id: 'inopt_allowBlank'+config.tv + ,value: config.properties['allowBlank'] == 0 || config.properties['allowBlank'] == 'false' ? false : true + ,width: 200 + ,listeners: config.oc + },{ + xtype: MODx.expandHelp ? 'label' : 'hidden' + ,forId: 'inopt_allowBlank'+config.tv + ,html: _('required_desc') + ,cls: 'desc-under' + }); + return items; + } + +}); +Ext.reg('notes-ip-panel',elementNotes.panel.notesIP); From 30d3024df2e201f59463067128af67913f04b491 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:53:01 +0300 Subject: [PATCH 08/16] Create notes.class.php --- .../elements/tv/input/notes.class.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 core/components/elementnotes/elements/tv/input/notes.class.php diff --git a/core/components/elementnotes/elements/tv/input/notes.class.php b/core/components/elementnotes/elements/tv/input/notes.class.php new file mode 100644 index 0000000..764f4cb --- /dev/null +++ b/core/components/elementnotes/elements/tv/input/notes.class.php @@ -0,0 +1,15 @@ +modx->elementnotes->config['corePath'].'elements/tv/templates/notes.tpl';} + public function process($value,array $params = array()) + { + $this->modx->controller->addLastJavascript($this->modx->elementnotes->config['jsUrl'].'mgr/widgets/notes.tv.js'); + $this->setPlaceholder('auth',$_SESSION["modx.{$this->modx->context->get('key')}.user.token"]); + } + } +} +return 'NotesInputRender'; From 59fb006a46f6bc5ee8360008acd0b9efb4c7d3d3 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:53:29 +0300 Subject: [PATCH 09/16] Create notes.php --- core/components/elementnotes/elements/tv/inputoptions/notes.php | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 core/components/elementnotes/elements/tv/inputoptions/notes.php diff --git a/core/components/elementnotes/elements/tv/inputoptions/notes.php b/core/components/elementnotes/elements/tv/inputoptions/notes.php new file mode 100644 index 0000000..6c3d348 --- /dev/null +++ b/core/components/elementnotes/elements/tv/inputoptions/notes.php @@ -0,0 +1,2 @@ +smarty->fetch($modx->elementnotes->config['corePath'].'elements/tv/templates/notes.ip.tpl'); From c14ed8acb03046e57879bb57e61e714c95e0c47e Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:54:03 +0300 Subject: [PATCH 10/16] Create notes.ip.tpl --- .../elements/tv/templates/notes.ip.tpl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 core/components/elementnotes/elements/tv/templates/notes.ip.tpl diff --git a/core/components/elementnotes/elements/tv/templates/notes.ip.tpl b/core/components/elementnotes/elements/tv/templates/notes.ip.tpl new file mode 100644 index 0000000..6a15816 --- /dev/null +++ b/core/components/elementnotes/elements/tv/templates/notes.ip.tpl @@ -0,0 +1,15 @@ +
+ +{literal} + +{/literal} From b5e9aaf1b9f177ef05f70b5f2c50c1445c9b26f4 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:55:00 +0300 Subject: [PATCH 11/16] Create notes.tpl --- .../elements/tv/templates/notes.tpl | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 core/components/elementnotes/elements/tv/templates/notes.tpl diff --git a/core/components/elementnotes/elements/tv/templates/notes.tpl b/core/components/elementnotes/elements/tv/templates/notes.tpl new file mode 100644 index 0000000..e44047a --- /dev/null +++ b/core/components/elementnotes/elements/tv/templates/notes.tpl @@ -0,0 +1,26 @@ +
+ +
+ +{literal} + +{/literal} From 664ceddf403854725ab7f0c52bd2cc83e304727d Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:56:52 +0300 Subject: [PATCH 12/16] Create getlist.class.php --- .../processors/mgr/tv/notes/getlist.class.php | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 core/components/elementnotes/processors/mgr/tv/notes/getlist.class.php diff --git a/core/components/elementnotes/processors/mgr/tv/notes/getlist.class.php b/core/components/elementnotes/processors/mgr/tv/notes/getlist.class.php new file mode 100644 index 0000000..22c1a90 --- /dev/null +++ b/core/components/elementnotes/processors/mgr/tv/notes/getlist.class.php @@ -0,0 +1,46 @@ +cmp=&$this->modx->elementnotes; + $this->properties = $this->getProperties(); + return parent::initialize($this); + } + + public function process() + { + $localmode = empty($this->properties['resource']); + if(!$localmode)return parent::process(); + $data = json_decode($this->properties['localData'],true); + uasort($data,function($a,$b){ + if($a['createdon']==$b['createdon'])return 0; + return ($a['createdon'] < $b['createdon'])?1:-1; + }); + return $this->outputArray(array_values($data)); + } + + public function prepareQueryBeforeCount(xPDOQuery $c) + { + $c->where(array('type'=>'resource')); + $c->where(array('id'=>$this->properties['resource'].'_'.$this->properties['tv'])); + return parent::prepareQueryBeforeCount($c); + } + + public function prepareRow(xPDOObject $object) { + $objectArray = parent::prepareRow($object); + $objectArray['id'] = $objectArray['createdon']; + return $objectArray; + } +} + +return 'NotesGetList'; From 4a837ac2590b082e5b21131621d4f21522eba6d5 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:57:25 +0300 Subject: [PATCH 13/16] Create remove.class.php --- .../processors/mgr/tv/notes/remove.class.php | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 core/components/elementnotes/processors/mgr/tv/notes/remove.class.php diff --git a/core/components/elementnotes/processors/mgr/tv/notes/remove.class.php b/core/components/elementnotes/processors/mgr/tv/notes/remove.class.php new file mode 100644 index 0000000..be3ef58 --- /dev/null +++ b/core/components/elementnotes/processors/mgr/tv/notes/remove.class.php @@ -0,0 +1,37 @@ +cmp=&$this->modx->filials; + $this->properties = $this->getProperties(); + if(isset($this->properties['localData']))$this->properties['localData']=$this->modx->fromJSON($this->properties['localData']); + return parent::initialize($this); + } + + public function process() + { + $localmode = !$this->properties['resource']; + + if(!$localmode) + { + $notes = $this->modx->getCollection('elementNote',array( + 'id'=>$this->properties['resource'].'_'.$this->properties['tv'], + 'type'=>'resource', + 'createdon:IN'=>$this->properties['ids'] + ),false); + foreach($notes as $note){$note->remove();} + } + else + { + foreach($this->properties['ids'] as $id){unset($this->properties['localData'][$id]);} + } + + $result = array('success'=>true); + if($localmode)$result['object']=$this->properties['localData']; + return $result; + } +} + +return 'NotesRemove'; From d11d8a005a52ebb8bc4d7ad6450bfc66bb855edd Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 16:59:38 +0300 Subject: [PATCH 14/16] Create save.class.php --- .../processors/mgr/tv/notes/save.class.php | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 core/components/elementnotes/processors/mgr/tv/notes/save.class.php diff --git a/core/components/elementnotes/processors/mgr/tv/notes/save.class.php b/core/components/elementnotes/processors/mgr/tv/notes/save.class.php new file mode 100644 index 0000000..35e28a9 --- /dev/null +++ b/core/components/elementnotes/processors/mgr/tv/notes/save.class.php @@ -0,0 +1,46 @@ +cmp=&$this->modx->filials; + $this->properties = $this->getProperties(); + if(isset($this->properties['data']))$this->properties=array_merge($this->properties,$this->modx->fromJSON($this->properties['data'])); + if(isset($this->properties['localData']))$this->properties['localData']=$this->modx->fromJSON($this->properties['localData']); + return parent::initialize($this); + } + + public function process() + { + $localmode = !$this->properties['resource']; + $isnew = empty($this->properties['id']); + if($isnew||$localmode) + { + $note = $this->modx->newObject('elementNote'); + $note->set('id',$this->properties['resource'].'_'.$this->properties['tv']); + $note->set('type','resource'); + } + else + { + $note = $this->modx->getObject('elementNote',array( + 'id'=>$this->properties['resource'].'_'.$this->properties['tv'], + 'type'=>'resource', + 'createdon'=>intval($this->properties['createdon']) + ),false); + } + $note->set('text',$this->properties['text']); + + if(!$localmode){$note->save(false);return array('success'=>true);} + else + { + if($isnew)$this->properties['createdon']=time(); + $note->set('createdon',$this->properties['createdon']); + $this->properties['localData'][$note->get('createdon')]=$note->toArray(); + $this->properties['localData'][$note->get('createdon')]['id']=$note->get('createdon'); + return array('success'=>true,'object'=>$this->properties['localData']); + } + } +} + +return 'NoteSave'; From 9a7cddcea6a6c69bae2a2c642d39f16b23092151 Mon Sep 17 00:00:00 2001 From: SintezCode Date: Tue, 16 May 2017 17:01:22 +0300 Subject: [PATCH 15/16] Update default.inc.php --- .../elementnotes/lexicon/ru/default.inc.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/components/elementnotes/lexicon/ru/default.inc.php b/core/components/elementnotes/lexicon/ru/default.inc.php index fe488e7..4521268 100644 --- a/core/components/elementnotes/lexicon/ru/default.inc.php +++ b/core/components/elementnotes/lexicon/ru/default.inc.php @@ -1,5 +1,13 @@ Date: Tue, 16 May 2017 17:04:12 +0300 Subject: [PATCH 16/16] Update default.inc.php --- .../elementnotes/lexicon/en/default.inc.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/components/elementnotes/lexicon/en/default.inc.php b/core/components/elementnotes/lexicon/en/default.inc.php index b8a7799..81f78f5 100644 --- a/core/components/elementnotes/lexicon/en/default.inc.php +++ b/core/components/elementnotes/lexicon/en/default.inc.php @@ -1,5 +1,13 @@