Plugin Directory

Changeset 2160754


Ignore:
Timestamp:
09/21/2019 09:54:36 PM (7 years ago)
Author:
gtekelis
Message:

draft pages supported

Location:
interactive-page-hierarchy/trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • interactive-page-hierarchy/trunk/css/gtek_iph_style.css

    r1995050 r2160754  
    1 /*THEME*/
    2 #wpcontent {
    3     background-color: #424250;
    4 }
    5 
    6 #pageRect {
    7     fill: #545469;
    8     /*stroke:#ff4181;*/
    9     stroke: #34343d;
    10     stroke-width: 1;
    11     opacity: 1;
    12 }
    13 
    14 .label {
    15     font-size: 1em;
    16     color: #3c3c44;
    17 }
    18 
    19 #vch-toolbar {
    20     margin-bottom: 20px;
    21 }
    22 
    23 #graphContainer {
    24     margin-top: 20px;
    25 }
    26 
    27 /*context menu*/
    28 .iph-context-menu {
    29     display: none;
    30     z-index: 1000;
    31     position: absolute;
    32     overflow: hidden;
    33     border: 1px solid #CCC;
    34     white-space: nowrap;
    35     font-family: sans-serif;
    36     background: #FFF;
    37     color: #333;
    38     list-style: none;
    39     padding: 0;
    40     margin: 0;
    41 }
    42 
    43 .iph-context-menu li {
    44     padding: 8px 12px;
    45     cursor: pointer;
    46 }
    47 
    48 .iph-context-menu li:hover {
    49     background-color: #DEF;
    50 }
     1#wpcontent{background-color:#424250}#pageRect{fill:#545469;stroke:#34343d;stroke-width:1;opacity:1}.label{font-size:1em;color:#3c3c44}#vch-toolbar{margin-bottom:20px}#graphContainer{margin-top:20px}.iph-context-menu{display:none;z-index:1000;position:absolute;overflow:hidden;border:1px solid #ccc;white-space:nowrap;font-family:sans-serif;background:#fff;color:#333;list-style:none;padding:0;margin:0}.iph-context-menu li{padding:8px 12px;cursor:pointer}.iph-context-menu li:hover{background-color:#def}#pageRectDraft{fill:#6138a1;stroke:#34343d;stroke-width:1;opacity:1}.wp-admin select{padding-left:11px;line-height:28px;height:40px;vertical-align:middle}
  • interactive-page-hierarchy/trunk/gtek_iph_main.php

    r2061847 r2160754  
    77Plugin URI: https://interactivepagehierarchy.georgetekelis.com
    88Description: Interactive Page Hierarchy lets you edit or create page hierarchies in a powerful, visual drag & drop interface.
    9 Version: 0.1.1
     9Version: 1.0.1
    1010Author: George Tekelis
    1111Author URI: https://www.georgetekelis.com
     
    100100                <div class="form-group">
    101101                    <label for="pageTitle">Page title</label>
    102                     <input type="text" class="form-control" id="pageTitle" aria-describedby="pageTitle" placeholder="page title">                   
     102                    <input type="text" class="form-control" id="pageTitle" aria-describedby="pageTitle" placeholder="page title"> 
    103103                </div>               
     104
     105                <div class="form-group">
     106                <label for="pageStatus">Page status</label>
     107                    <select id="pageStatus" class="form-control">
     108                    <option value="draft">draft</option>
     109                    <option value="publish">publish</option>                   
     110                    </select>
     111                </div>
    104112
    105113                </div>
     
    136144            </div>
    137145            </div>';
    138     echo '<input id="hdn_PageTitles" type="text" hidden value="' . json_encode($pageTitlesList) . '">';
     146    echo '<input id="hdn_PageTitles" type="text" hidden value="' . json_encode($pageTitlesList) . '">';   
    139147
    140148    echo '<div id="graphContainer" style="height:700px; overflow:auto; position: relative;" >';   
     
    152160
    153161function gtek_iph_load_wp_pages() {
    154     $pages = get_pages();
     162    $pages = get_pages(
     163        array(
     164            'post_status' => ['draft', 'publish']
     165        )
     166    );
    155167    $pageTitlesList = array();
    156168
     
    177189            'post_title'    => strlen ( $_POST['postTitle'] ) > 0 ? gtek_iph_sanitize_text_field($_POST['postTitle']) : '--NO TITLE--',
    178190            'post_name'     => strlen ( $_POST['postTitle'] ) > 0 ? sanitize_title_with_dashes($_POST['postTitle'],'','save') : '--NO TITLE--',
    179             'post_status'   => 'publish',
     191            'post_status'   => strlen ($_POST['postStatus'] ) > 0 ? gtek_iph_sanitize_text_field($_POST['postStatus']) : 'publish',
    180192            'post_author'   => get_current_user_id()           
    181193        );
     
    192204            'post_title'    => strlen ( $_POST['postTitle'] ) > 0 ? gtek_iph_sanitize_text_field($_POST['postTitle']) : '--NO TITLE--',
    193205            'post_name'     => strlen ( $_POST['postTitle'] ) > 0 ? sanitize_title_with_dashes($_POST['postTitle'],'','save') : '--NO TITLE--',
    194             'post_status'   => 'publish',
     206            'post_status'   => strlen ($_POST['postStatus'] ) > 0 ? gtek_iph_sanitize_text_field($_POST['postStatus']) : 'publish',
    195207            'post_author'   => get_current_user_id(),
    196208            'post_parent'   => absint(intval( $_POST['postParent'] )),
  • interactive-page-hierarchy/trunk/js/gtek_iph_manager.js

    r2061847 r2160754  
    1 jQuery(document).ready(function () {
    2     toastr.options = {
    3         "closeButton": !1,
    4         "debug": !1,
    5         "newestOnTop": !1,
    6         "progressBar": !1,
    7         "positionClass": "toast-top-right",
    8         "preventDuplicates": !0,
    9         "onclick": null,
    10         "showDuration": "300",
    11         "hideDuration": "1000",
    12         "timeOut": "3000",
    13         "extendedTimeOut": "1000",
    14         "showEasing": "swing",
    15         "hideEasing": "linear",
    16         "showMethod": "fadeIn",
    17         "hideMethod": "fadeOut"
    18     }
    19     let graph = null;
    20     let paper = null;
    21 
    22     function setUp() {
    23         graph = new joint.dia.Graph;
    24         joint.shapes.devs.Model = joint.shapes.devs.Model.extend({
    25             markup: '<g class="element-node">' + '<rect id="pageRect" class="body" rx="5px" ry="5px"></rect>' + '<g transform="translate(60, -5)">' + '<a class="Action_Remove_Link" href="#">' + '<rect x="71" y="11" width="20" height="20" style="fill:#e16b5d;" />' + '<path transform="translate(71,11) scale(1.3)" fill="#fefefe" d="M4 7h8v2h-8v-2z"></path>' + '<rect class="Action_DeletePage" x="71" y="11" width="20" height="20" style="fill:rgba(242,0,40,0);" />' + '</a>' + '<a class="Action_View_Link" href="#" target="_blank">' + '<rect x="71" y="34" width="20" height="20" style="fill:rgba(116,115,116,1);" />' + '<path transform="translate(74,36) scale(.9)" fill="#fefefe" d="M8 3.9c-6.7 0-8 5.1-8 5.1s2.2 4.1 7.9 4.1 8.1-4 8.1-4-1.3-5.2-8-5.2zM5.3 5.4c0.5-0.3 1.3-0.3 1.3-0.3s-0.5 0.9-0.5 1.6c0 0.7 0.2 1.1 0.2 1.1l-1.1 0.2c0 0-0.3-0.5-0.3-1.2 0-0.8 0.4-1.4 0.4-1.4zM7.9 12.1c-4.1 0-6.2-2.3-6.8-3.2 0.3-0.7 1.1-2.2 3.1-3.2-0.1 0.4-0.2 0.8-0.2 1.3 0 2.2 1.8 4 4 4s4-1.8 4-4c0-0.5-0.1-0.9-0.2-1.3 2 0.9 2.8 2.5 3.1 3.2-0.7 0.9-2.8 3.2-7 3.2z"></path>' + '<rect class="Action_Eye" x="71" y="34" width="20" height="20" style="fill:rgba(242,0,40,0);" />' + '</a>' + '<a class="Action_Edit_Link" href="#">' + '<rect x="71" y="57" width="20" height="20" style="fill:rgba(116,115,116,1);" />' + '<g transform="translate(75,60) scale(.8)">' + '<path fill="#FFFFFF" d="M1 11.9l-1 4.1 4.1-1 9.2-9.2-3.1-3.1-9.2 9.2zM1.5 15l-0.4-0.5 0.4-2 2 2-2 0.5zM10.9 4.4l-8.1 8-0.6-0.6 8.1-8 0.6 0.6z"/>' + '<path fill="#FFFFFF" d="M15.3 0.7c-1.1-1.1-2.6-0.5-2.6-0.5l-1.5 1.5 3.1 3.1 1.5-1.5c0-0.1 0.6-1.5-0.5-2.6zM13.4 1.6l-0.5-0.5c0.6-0.6 1.1-0.1 1.1-0.1l-0.6 0.6z"/>' + '</g>' + '<rect class="Action_Edit" x="71" y="57" width="20" height="20" style="fill:rgba(242,0,40,0);" />' + '</a>' + '<a href="#">' + '<rect x="71" y="80" width="20" height="20" style="fill:rgba(116,115,116,1);" />' + '<g transform="translate(75,83) scale(.8)">' + '<path fill="#FFFFFF" d="M16 9v-2l-1.7-0.6c-0.2-0.6-0.4-1.2-0.7-1.8l0.8-1.6-1.4-1.4-1.6 0.8c-0.5-0.3-1.1-0.6-1.8-0.7l-0.6-1.7h-2l-0.6 1.7c-0.6 0.2-1.2 0.4-1.7 0.7l-1.6-0.8-1.5 1.5 0.8 1.6c-0.3 0.5-0.5 1.1-0.7 1.7l-1.7 0.6v2l1.7 0.6c0.2 0.6 0.4 1.2 0.7 1.8l-0.8 1.6 1.4 1.4 1.6-0.8c0.5 0.3 1.1 0.6 1.8 0.7l0.6 1.7h2l0.6-1.7c0.6-0.2 1.2-0.4 1.8-0.7l1.6 0.8 1.4-1.4-0.8-1.6c0.3-0.5 0.6-1.1 0.7-1.8l1.7-0.6zM8 12c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/>' + '<path fill="#FFFFFF" d="M10.6 7.9c0 1.381-1.119 2.5-2.5 2.5s-2.5-1.119-2.5-2.5c0-1.381 1.119-2.5 2.5-2.5s2.5 1.119 2.5 2.5z"/>' + '</g>' + '<rect class="Action_Modal" x="71" y="80" width="20" height="20" style="fill:rgba(242,0,40,0);" />' + '</a>' + '</g>' + '<text style="fill:#dddddd" id="myText" class="label" y="0.8em" xml:space="preserve" font-size="14" text-anchor="middle" font-family="Arial, helvetica, sans-serif">' + '<tspan  id="v-18" dy="0em" x="0" class="v-line"></tspan>' + '</text>' + '<g class="inPorts"/>' + '<g class="outPorts"/>' + '</g>',
    26         });
    27         paper = new joint.dia.Paper({
    28             el: jQuery('#myholder'),
    29             width: 16000,
    30             height: 16000,
    31             model: graph,
    32             gridSize: 10,
    33             preventDefaultBlankAction: !1,
    34             background: {
    35                 color: '#424250'
    36             },
    37             snapLinks: !0,
    38             linkPinning: !1,
    39             defaultLink: new joint.dia.Link({
    40                 attrs: {
    41                     '.marker-target': {
    42                         d: 'M 10 0 L 0 5 L 10 10 z',
    43                         fill: '#ffffff',
    44                         stroke: '#ffffff'
    45                     },
    46                     '.connection': {
    47                         'stroke-width': 2,
    48                         stroke: '#a8a8a8'
    49                     }
    50                 }
    51             }),
    52             validateConnection: function (cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
    53                 if (magnetS && magnetS.getAttribute('port-group') === 'in') return !1;
    54                 if (cellViewS === cellViewT) return !1;
    55                 return magnetT && magnetT.getAttribute('port-group') === 'in'
    56             },
    57             validateMagnet: function (cellView, magnet) {
    58                 return magnet.getAttribute('magnet') !== 'passive'
    59             }
    60         });
    61         paper.setGrid('mesh');
    62         paper.drawGrid({
    63             'color': '#3c3c44',
    64             'thickness': 1
    65         });
    66         paper.scale(.9, .9);
    67 
    68         function resizeCanvas() {
    69             jQuery("#graphContainer").css({
    70                 'height': jQuery(window).height() - 170
    71             })
    72         }
    73         resizeCanvas();
    74         jQuery(window).resize(function () {
    75             resizeCanvas()
    76         })
    77     }
    78     setUp();
    79     let sentenceWrapped = function (sentence, lineSize, maxSize) {
    80         let descriptionTrim = "";
    81         if (sentence.length + 3 > maxSize) {
    82             descriptionTrim = sentence.substring(0, maxSize - 3);
    83             descriptionTrim = descriptionTrim + '...'
    84         } else {
    85             descriptionTrim = sentence
    86         }
    87         let splitSentence = descriptionTrim.match(new RegExp('.{1,' + lineSize + '}', 'g'));
    88         let sentenceWrapped = "";
    89         let splitArray = [];
    90         for (i = 0; i < splitSentence.length; i++) {
    91             splitArray.push(splitSentence[i]);
    92             sentenceWrapped = sentenceWrapped + splitSentence[i] + '\n'
    93         }
    94         return splitArray
    95     }
    96 
    97 
    98 
    99     let hierarchyData = [];
    100 
    101 
    102     function LoadPages() {
    103         let data = null;
    104 
    105         jQuery.post(ajaxurl, {
    106             'action': 'gtek_iph_load_wp_pages'
    107         }, function (response) {
    108             data = JSON.parse(response.substring(0, response.length - 1));
    109 
    110             console.log(data);
    111 
    112             for (let i = 0; i < data.length; i++) {
    113                 let item = data[i];
    114                 let sentenceWrappedTextArray = '';
    115                 let finalWrappedText = '';
    116                 if (item.post_title != undefined) {
    117                     sentenceWrappedTextArray = sentenceWrapped(item.post_title, 15, 45);
    118                     for (let i = 0; i < sentenceWrappedTextArray.length; i++) {
    119                         let element = sentenceWrappedTextArray[i];
    120                         finalWrappedText += element + '\n'
    121                     }
    122                 }
    123 
    124                 jQuery.post(ajaxurl, {
    125                     'action': 'iph_get_page_links',
    126                     'id': item.ID
    127                 }, function (response) {
    128                     let responseArray = JSON.parse(response.substring(0, response.length - 1));
    129                     let page = new joint.shapes.devs.Model({
    130                         position: {
    131                             x: -1160,
    132                             y: -1160 * i + 60
    133                         },
    134                         size: {
    135                             width: 140,
    136                             height: 100
    137                         },
    138                         inPorts: ['in'],
    139                         outPorts: ['out'],
    140                         ports: {
    141                             groups: {
    142                                 'in': {
    143                                     attrs: {
    144                                         '.port-body': {
    145                                             fill: '#88e9ad',
    146                                             stroke: '#34343d'
    147                                         }
    148                                     },
    149                                     position: 'top',
    150                                     label: {
    151                                         position: 'outside'
    152                                     }
    153                                 },
    154                                 'out': {
    155                                     attrs: {
    156                                         '.port-body': {
    157                                             fill: '#88cae9',
    158                                             stroke: '#34343d'
    159                                         }
    160                                     },
    161                                     position: 'bottom',
    162                                     label: {
    163                                         position: 'outside'
    164                                     }
    165                                 }
    166                             }
    167                         },
    168                         attrs: {
    169                             '.label': {
    170                                 text: finalWrappedText,
    171                                 'ref-x': .5,
    172                                 'ref-y': .2
    173                             },
    174                             '.Action_Edit_Link': {
    175                                 href: responseArray.edit_link
    176                             },
    177                             '.Action_View_Link': {
    178                                 href: responseArray.view_link
    179                             },
    180                             rect: {
    181                                 fill: '#d4edda'
    182                             }
    183                         }
    184                     });
    185                     page.pageTitle = item.post_title;
    186                     page.children = [];
    187                     page.wpPageId = parseInt(item.ID);
    188                     page.parentWpPageId = item.post_parent;
    189                     page.isChild = item.post_parent == 0 ? !1 : !0;
    190                     page.parentNodeId = null;
    191                     page.content = item.post_content;
    192                     hierarchyData.push(page);
    193 
    194                     page.addTo(graph);
    195 
    196                     if (hierarchyData.length == data.length) {
    197                         CreatePagesHierarchy();
    198                     }
    199 
    200                 })//end second ajax               
    201             }//end for loop           
    202 
    203         })//end first ajax
    204        
    205     }
    206     LoadPages();
    207 
    208     function CreatePagesHierarchy() {
    209 
    210         for (let i = 0; i < hierarchyData.length; i++) {
    211             let element = hierarchyData[i];
    212             if (element.parentWpPageId > 0) {
    213                 let parentNodeObject = hierarchyData.find(function (item) {
    214                     return item.wpPageId == element.parentWpPageId
    215                 });
    216                 let parentNodeId = parentNodeObject.id;
    217                 element.parentNodeId = parentNodeObject.id;
    218                 parentNodeObject.children.push(parseInt(element.wpPageId));
    219                 let link = new joint.dia.Link({
    220                     source: {
    221                         id: parentNodeId,
    222                         port: 'out'
    223                     },
    224                     target: {
    225                         id: element.id,
    226                         port: 'in'
    227                     },
    228                     attrs: {
    229                         '.connection': {
    230                             'stroke-width': 2,
    231                             stroke: '#a8a8a8'
    232                         }
    233                     }
    234                 });
    235                 graph.addCells([link])
    236             }
    237         }
    238         joint.layout.DirectedGraph.layout(graph, {
    239             setLinkVertices: !1
    240         })
    241     }
    242 
    243     let data = null;
    244 
    245     jQuery("body").bind("click", function () {
    246         data = null;
    247         jQuery.post(ajaxurl, {
    248             'action': 'gtek_iph_load_wp_pages'
    249         }, function (response) {
    250             data = JSON.parse(response.substring(0, response.length - 1))
    251         })
    252     });
    253     jQuery('#iph-newPage').on('click', function () {
    254         let page = new joint.shapes.devs.Model({
    255             position: {
    256                 x: contextMenuX,
    257                 y: contextMenuY
    258             },
    259             size: {
    260                 width: 140,
    261                 height: 100
    262             },
    263             inPorts: ['in'],
    264             outPorts: ['out'],
    265             ports: {
    266                 groups: {
    267                     'in': {
    268                         attrs: {
    269                             '.port-body': {
    270                                 fill: '#88e9ad',
    271                                 stroke: '#34343d'
    272                             }
    273                         },
    274                         position: 'top',
    275                         label: {
    276                             position: 'outside'
    277                         }
    278                     },
    279                     'out': {
    280                         attrs: {
    281                             '.port-body': {
    282                                 fill: '#88cae9',
    283                                 stroke: '#34343d'
    284                             }
    285                         },
    286                         position: 'bottom',
    287                         label: {
    288                             position: 'outside'
    289                         }
    290                     }
    291                 }
    292             },
    293             attrs: {
    294                 '.label': {
    295                     text: 'Page Title',
    296                     'ref-x': .5,
    297                     'ref-y': .2
    298                 },
    299                 rect: {
    300                     fill: '#d4edda'
    301                 }
    302             }
    303         });
    304         page.pageTitle = '';
    305         page.children = [];
    306         page.wpPageId = null;
    307         page.parentWpPageId = 0;
    308         page.isChild = !1;
    309         page.parentNodeId = null;
    310         hierarchyData.push(page);
    311         page.addTo(graph)
    312     });
    313     let selectedNode = null;
    314     paper.on('cell:pointerdown', function (cellView, evt, x, y) {
    315         selectedNode = hierarchyData.filter(item => item.id == cellView.model.id)
    316     });
    317     jQuery('#iph-modal-save').on('click', function () {
    318         let sentenceWrappedTextArray = sentenceWrapped(jQuery('#pageTitle').val(), 15, 45);
    319         let finalWrappedText = '';
    320         let yInitialPosition = 0;
    321         for (let i = 0; i < sentenceWrappedTextArray.length; i++) {
    322             let element = sentenceWrappedTextArray[i];
    323             finalWrappedText += '<tspan id="v-18" dy="0em" x="0" y="' + (yInitialPosition += 17) + '" class="v-line">' + element + '</tspan>'
    324         }
    325         selectedNode[0].pageTitle = jQuery('#pageTitle').val();
    326         jQuery('*[model-id="' + selectedNode[0].id + '"]').find('text.label').html(finalWrappedText)
    327     });
    328     paper.on('link:connect', function (evt, cellView, magnet, arrowhead) {
    329         let parent = hierarchyData.filter(node => node.id == evt.sourceView.model.id);
    330         evt.targetView.model.parentNodeId = evt.sourceView.model.id;
    331         evt.targetView.model.isChild = !0;
    332         saveHierarchy('new_page_node');
    333         setTimeout(() => {
    334             parent[0].children.push(evt.targetView.model.wpPageId)
    335         }, 500)
    336     });
    337     paper.on('link:pointerup', function (evt, cellView, magnet, arrowhead) { });
    338     graph.on('remove', function (cell, collection, opt) {
    339         if (cell.isLink()) {
    340             if (cell.attributes.target.id != undefined) {
    341                 let sourceElementId = cell.attributes.source.id;
    342                 let targetElementId = cell.attributes.target.id;
    343                 let sourceElement = hierarchyData.filter(node => node.id == sourceElementId);
    344                 let targetElement = hierarchyData.filter(node => node.id == targetElementId);
    345                 targetElement[0].isChild = !1;
    346                 targetElement[0].parentWpPageId = 0;
    347                 targetElement[0].parentNodeId = null;
    348                 let indexOfChildElement = sourceElement[0].children.indexOf(targetElementId);
    349                 if (indexOfChildElement > -1) {
    350                     sourceElement[0].children.splice(indexOfChildElement, 1)
    351                 }
    352             }
    353         }
    354     });
    355     jQuery(document).on("click", ".Action_Modal", function (event) {
    356         event.preventDefault();
    357         if (selectedNode[0] != undefined) {
    358             jQuery('#ModalOptions').modal('show');
    359             jQuery('#pageTitle').val(selectedNode[0].pageTitle)
    360         }
    361     });
    362     let nodeToRemove = null;
    363     jQuery(document).on("click", ".Action_DeletePage", function (event) {
    364         event.preventDefault();
    365         nodeToRemove = jQuery(this).closest('.joint-cell');
    366         if (selectedNode[0] != undefined) {
    367             jQuery('#ModalDelete').modal('show')
    368         }
    369     });
    370     jQuery(document).on("click", ".DeletePageModalButton", function (event) {
    371         nodeToRemove.remove();
    372         nodeToRemove = null;
    373         graph.removeLinks(selectedNode[0]);
    374         if (selectedNode[0].wpPageId != null) {
    375             if (selectedNode[0].children.length > 0) {
    376                 for (let i = 0; i < selectedNode[0].children.length; i++) {
    377                     let elementToChangeParent = hierarchyData.filter(item => item.wpPageId == selectedNode[0].children[i]);
    378                     elementToChangeParent[0].parentWpPageId = 0;
    379                     elementToChangeParent[0].isChild = !1;
    380                     toastr.success('successfully deleted page');
    381                     jQuery.post(ajaxurl, {
    382                         'action': 'iph_delete_post',
    383                         'id': parseInt(selectedNode[0].wpPageId)
    384                     }, function (response) { })
    385                 }
    386             }
    387             if (selectedNode[0].children.length == 0) {
    388                 toastr.success('successfully deleted page');
    389                 jQuery.post(ajaxurl, {
    390                     'action': 'iph_delete_post',
    391                     'id': parseInt(selectedNode[0].wpPageId)
    392                 }, function (response) {
    393                     let remainingPages = _.remove(hierarchyData, function (n) {
    394                         return n.wpPageId != selectedNode[0].wpPageId
    395                     })
    396                 })
    397             }
    398         } else {
    399             let indexOfSelectedNode = hierarchyData.indexOf(selectedNode[0]);
    400             if (indexOfSelectedNode > -1) {
    401                 hierarchyData.splice(indexOfSelectedNode, 1)
    402             }
    403         }
    404     });
    405     let contextMenuY = 0;
    406     let contextMenuX = 0;
    407     paper.on('blank:contextmenu', function (evt, x, y) {
    408         contextMenuX = x;
    409         contextMenuY = y;
    410         jQuery('#iph-newPage').trigger("click")
    411     });
    412     jQuery('#iph-save').on('click', function (event) {
    413         saveHierarchy('btn_save')
    414     });
    415     async function saveHierarchy(caller) {
    416         let promise = new Promise(function (resolve, reject) {
    417             if (caller == 'btn_save') {
    418                 jQuery('#ModalSaveOverlay').modal('show')
    419             }
    420             for (let i = 0; i < hierarchyData.length; i++) {
    421                 let element = hierarchyData[i];
    422                 if (element.wpPageId == null) {
    423                     jQuery.post(ajaxurl, {
    424                         'action': 'iph_save_pages',
    425                         'postTitle': element.pageTitle
    426                     }, function (response) {
    427                         element.wpPageId = parseInt(response.substring(0, response.length - 1))
    428                     })
    429                 }
    430             }
    431             resolve("done!")
    432         });
    433 
    434         //let result = await promise;
    435        
    436         if (caller != 'new_page_node') {
    437             for (let i = 0; i < hierarchyData.length; i++) {
    438                
    439                 let element = hierarchyData[i];
    440                
    441                 if (element.isChild) {
    442                    
    443                     let parentNodeObject = hierarchyData.filter(parentNode => parentNode.id == element.parentNodeId);
    444                     let parentWpPageId = parseInt(parentNodeObject[0].wpPageId);
    445                    
    446                     element.parentWpPageId = parentWpPageId;
    447                     jQuery.post(ajaxurl, {
    448                         'action': 'iph_update_pages',
    449                         'postTitle': element.pageTitle,
    450                         'postParent': parentWpPageId,
    451                         'id': element.wpPageId,
    452                         'postContent': element.content
    453                     }, function (response) { })
    454                 } else if (!element.isChild && element.parentNodeId == null && element.wpPageId != null) {
    455                     jQuery.post(ajaxurl, {
    456                         'action': 'iph_update_pages',
    457                         'postTitle': element.pageTitle,
    458                         'postParent': 0,
    459                         'id': element.wpPageId,
    460                         'postContent': element.content
    461                     }, function (response) {
    462                         if (caller == 'btn_save') {
    463                             toastr.success('successfully saved');
    464                             jQuery('#ModalSaveOverlay').modal('hide')
    465                         }
    466                     })
    467                 }
    468             }
    469         }
    470     }
    471 })
     1jQuery(document).ready(function(){toastr.options={closeButton:!1,debug:!1,newestOnTop:!1,progressBar:!1,positionClass:"toast-top-right",preventDuplicates:!0,onclick:null,showDuration:"300",hideDuration:"1000",timeOut:"3000",extendedTimeOut:"1000",showEasing:"swing",hideEasing:"linear",showMethod:"fadeIn",hideMethod:"fadeOut"};let t=null,e=null;!function(){function l(){jQuery("#graphContainer").css({height:jQuery(window).height()-170})}t=new joint.dia.Graph,draftModel=joint.shapes.devs.Model.extend({markup:'<g class="element-node"><rect id="pageRectDraft" class="body" rx="5px" ry="5px"></rect><g transform="translate(60, -5)"><a class="Action_Remove_Link" href="#"><rect x="71" y="11" width="20" height="20" style="fill:#e16b5d;" /><path transform="translate(71,11) scale(1.3)" fill="#fefefe" d="M4 7h8v2h-8v-2z"></path><rect class="Action_DeletePage" x="71" y="11" width="20" height="20" style="fill:rgba(242,0,40,0);" /></a><a class="Action_View_Link" href="#" target="_blank"><rect x="71" y="34" width="20" height="20" style="fill:rgba(116,115,116,1);" /><path transform="translate(74,36) scale(.9)" fill="#fefefe" d="M8 3.9c-6.7 0-8 5.1-8 5.1s2.2 4.1 7.9 4.1 8.1-4 8.1-4-1.3-5.2-8-5.2zM5.3 5.4c0.5-0.3 1.3-0.3 1.3-0.3s-0.5 0.9-0.5 1.6c0 0.7 0.2 1.1 0.2 1.1l-1.1 0.2c0 0-0.3-0.5-0.3-1.2 0-0.8 0.4-1.4 0.4-1.4zM7.9 12.1c-4.1 0-6.2-2.3-6.8-3.2 0.3-0.7 1.1-2.2 3.1-3.2-0.1 0.4-0.2 0.8-0.2 1.3 0 2.2 1.8 4 4 4s4-1.8 4-4c0-0.5-0.1-0.9-0.2-1.3 2 0.9 2.8 2.5 3.1 3.2-0.7 0.9-2.8 3.2-7 3.2z"></path><rect class="Action_Eye" x="71" y="34" width="20" height="20" style="fill:rgba(242,0,40,0);" /></a><a class="Action_Edit_Link" href="#"><rect x="71" y="57" width="20" height="20" style="fill:rgba(116,115,116,1);" /><g transform="translate(75,60) scale(.8)"><path fill="#FFFFFF" d="M1 11.9l-1 4.1 4.1-1 9.2-9.2-3.1-3.1-9.2 9.2zM1.5 15l-0.4-0.5 0.4-2 2 2-2 0.5zM10.9 4.4l-8.1 8-0.6-0.6 8.1-8 0.6 0.6z"/><path fill="#FFFFFF" d="M15.3 0.7c-1.1-1.1-2.6-0.5-2.6-0.5l-1.5 1.5 3.1 3.1 1.5-1.5c0-0.1 0.6-1.5-0.5-2.6zM13.4 1.6l-0.5-0.5c0.6-0.6 1.1-0.1 1.1-0.1l-0.6 0.6z"/></g><rect class="Action_Edit" x="71" y="57" width="20" height="20" style="fill:rgba(242,0,40,0);" /></a><a href="#"><rect x="71" y="80" width="20" height="20" style="fill:rgba(116,115,116,1);" /><g transform="translate(75,83) scale(.8)"><path fill="#FFFFFF" d="M16 9v-2l-1.7-0.6c-0.2-0.6-0.4-1.2-0.7-1.8l0.8-1.6-1.4-1.4-1.6 0.8c-0.5-0.3-1.1-0.6-1.8-0.7l-0.6-1.7h-2l-0.6 1.7c-0.6 0.2-1.2 0.4-1.7 0.7l-1.6-0.8-1.5 1.5 0.8 1.6c-0.3 0.5-0.5 1.1-0.7 1.7l-1.7 0.6v2l1.7 0.6c0.2 0.6 0.4 1.2 0.7 1.8l-0.8 1.6 1.4 1.4 1.6-0.8c0.5 0.3 1.1 0.6 1.8 0.7l0.6 1.7h2l0.6-1.7c0.6-0.2 1.2-0.4 1.8-0.7l1.6 0.8 1.4-1.4-0.8-1.6c0.3-0.5 0.6-1.1 0.7-1.8l1.7-0.6zM8 12c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/><path fill="#FFFFFF" d="M10.6 7.9c0 1.381-1.119 2.5-2.5 2.5s-2.5-1.119-2.5-2.5c0-1.381 1.119-2.5 2.5-2.5s2.5 1.119 2.5 2.5z"/></g><rect class="Action_Modal" x="71" y="80" width="20" height="20" style="fill:rgba(242,0,40,0);" /></a></g><text style="fill:#dddddd" id="myText" class="label" y="0.8em" xml:space="preserve" font-size="14" text-anchor="middle" font-family="Arial, helvetica, sans-serif"><tspan  id="v-18" dy="0em" x="0" class="v-line"></tspan></text><g class="inPorts"/><g class="outPorts"/></g>'}),joint.shapes.devs.Model=joint.shapes.devs.Model.extend({markup:'<g class="element-node"><rect id="pageRect" class="body" rx="5px" ry="5px"></rect><g transform="translate(60, -5)"><a class="Action_Remove_Link" href="#"><rect x="71" y="11" width="20" height="20" style="fill:#e16b5d;" /><path transform="translate(71,11) scale(1.3)" fill="#fefefe" d="M4 7h8v2h-8v-2z"></path><rect class="Action_DeletePage" x="71" y="11" width="20" height="20" style="fill:rgba(242,0,40,0);" /></a><a class="Action_View_Link" href="#" target="_blank"><rect x="71" y="34" width="20" height="20" style="fill:rgba(116,115,116,1);" /><path transform="translate(74,36) scale(.9)" fill="#fefefe" d="M8 3.9c-6.7 0-8 5.1-8 5.1s2.2 4.1 7.9 4.1 8.1-4 8.1-4-1.3-5.2-8-5.2zM5.3 5.4c0.5-0.3 1.3-0.3 1.3-0.3s-0.5 0.9-0.5 1.6c0 0.7 0.2 1.1 0.2 1.1l-1.1 0.2c0 0-0.3-0.5-0.3-1.2 0-0.8 0.4-1.4 0.4-1.4zM7.9 12.1c-4.1 0-6.2-2.3-6.8-3.2 0.3-0.7 1.1-2.2 3.1-3.2-0.1 0.4-0.2 0.8-0.2 1.3 0 2.2 1.8 4 4 4s4-1.8 4-4c0-0.5-0.1-0.9-0.2-1.3 2 0.9 2.8 2.5 3.1 3.2-0.7 0.9-2.8 3.2-7 3.2z"></path><rect class="Action_Eye" x="71" y="34" width="20" height="20" style="fill:rgba(242,0,40,0);" /></a><a class="Action_Edit_Link" href="#"><rect x="71" y="57" width="20" height="20" style="fill:rgba(116,115,116,1);" /><g transform="translate(75,60) scale(.8)"><path fill="#FFFFFF" d="M1 11.9l-1 4.1 4.1-1 9.2-9.2-3.1-3.1-9.2 9.2zM1.5 15l-0.4-0.5 0.4-2 2 2-2 0.5zM10.9 4.4l-8.1 8-0.6-0.6 8.1-8 0.6 0.6z"/><path fill="#FFFFFF" d="M15.3 0.7c-1.1-1.1-2.6-0.5-2.6-0.5l-1.5 1.5 3.1 3.1 1.5-1.5c0-0.1 0.6-1.5-0.5-2.6zM13.4 1.6l-0.5-0.5c0.6-0.6 1.1-0.1 1.1-0.1l-0.6 0.6z"/></g><rect class="Action_Edit" x="71" y="57" width="20" height="20" style="fill:rgba(242,0,40,0);" /></a><a href="#"><rect x="71" y="80" width="20" height="20" style="fill:rgba(116,115,116,1);" /><g transform="translate(75,83) scale(.8)"><path fill="#FFFFFF" d="M16 9v-2l-1.7-0.6c-0.2-0.6-0.4-1.2-0.7-1.8l0.8-1.6-1.4-1.4-1.6 0.8c-0.5-0.3-1.1-0.6-1.8-0.7l-0.6-1.7h-2l-0.6 1.7c-0.6 0.2-1.2 0.4-1.7 0.7l-1.6-0.8-1.5 1.5 0.8 1.6c-0.3 0.5-0.5 1.1-0.7 1.7l-1.7 0.6v2l1.7 0.6c0.2 0.6 0.4 1.2 0.7 1.8l-0.8 1.6 1.4 1.4 1.6-0.8c0.5 0.3 1.1 0.6 1.8 0.7l0.6 1.7h2l0.6-1.7c0.6-0.2 1.2-0.4 1.8-0.7l1.6 0.8 1.4-1.4-0.8-1.6c0.3-0.5 0.6-1.1 0.7-1.8l1.7-0.6zM8 12c-2.2 0-4-1.8-4-4s1.8-4 4-4 4 1.8 4 4-1.8 4-4 4z"/><path fill="#FFFFFF" d="M10.6 7.9c0 1.381-1.119 2.5-2.5 2.5s-2.5-1.119-2.5-2.5c0-1.381 1.119-2.5 2.5-2.5s2.5 1.119 2.5 2.5z"/></g><rect class="Action_Modal" x="71" y="80" width="20" height="20" style="fill:rgba(242,0,40,0);" /></a></g><text style="fill:#dddddd" id="myText" class="label" y="0.8em" xml:space="preserve" font-size="14" text-anchor="middle" font-family="Arial, helvetica, sans-serif"><tspan  id="v-18" dy="0em" x="0" class="v-line"></tspan></text><g class="inPorts"/><g class="outPorts"/></g>'}),(e=new joint.dia.Paper({el:jQuery("#myholder"),width:16e3,height:16e3,model:t,gridSize:10,preventDefaultBlankAction:!1,background:{color:"#424250"},snapLinks:!0,linkPinning:!1,defaultLink:new joint.dia.Link({attrs:{".marker-target":{d:"M 10 0 L 0 5 L 10 10 z",fill:"#ffffff",stroke:"#ffffff"},".connection":{"stroke-width":2,stroke:"#a8a8a8"}}}),validateConnection:function(t,e,l,i,a,n){return(!e||"in"!==e.getAttribute("port-group"))&&t!==l&&i&&"in"===i.getAttribute("port-group")},validateMagnet:function(t,e){return"passive"!==e.getAttribute("magnet")}})).setGrid("mesh"),e.drawGrid({color:"#3c3c44",thickness:1}),e.scale(.9,.9),l(),jQuery(window).resize(function(){l()})}();let l=function(t,e,l){let a="";t.length+3>l?(a=t.substring(0,l-3),a+="..."):a=t;let n=a.match(new RegExp(".{1,"+e+"}","g")),s="",o=[];for(i=0;i<n.length;i++)o.push(n[i]),s=s+n[i]+"\n";return o},a=[];function n(){for(let e=0;e<a.length;e++){let l=a[e];if(l.parentWpPageId>0){let e=a.find(function(t){return t.wpPageId==l.parentWpPageId}),i=e.id;l.parentNodeId=e.id,e.children.push(parseInt(l.wpPageId));let n=new joint.dia.Link({source:{id:i,port:"out"},target:{id:l.id,port:"in"},attrs:{".connection":{"stroke-width":2,stroke:"#a8a8a8"}}});t.addCells([n])}}joint.layout.DirectedGraph.layout(t,{setLinkVertices:!1})}!function(){let e=null;jQuery.post(ajaxurl,{action:"gtek_iph_load_wp_pages"},function(i){e=JSON.parse(i.substring(0,i.length-1));for(let i=0;i<e.length;i++){let s=e[i],o="",r="";if(null!=s.post_title){o=l(s.post_title,15,45);for(let t=0;t<o.length;t++){let e=o[t];r+=e+"\n"}}"publish"===s.post_status?jQuery.post(ajaxurl,{action:"iph_get_page_links",id:s.ID},function(l){let o=JSON.parse(l.substring(0,l.length-1)),d=new joint.shapes.devs.Model({position:{x:-1160,y:-1160*i+60},size:{width:140,height:100},inPorts:["in"],outPorts:["out"],ports:{groups:{in:{attrs:{".port-body":{fill:"#88e9ad",stroke:"#34343d"}},position:"top",label:{position:"outside"}},out:{attrs:{".port-body":{fill:"#88cae9",stroke:"#34343d"}},position:"bottom",label:{position:"outside"}}}},attrs:{".label":{text:r,"ref-x":.5,"ref-y":.2},".Action_Edit_Link":{href:o.edit_link},".Action_View_Link":{href:o.view_link},rect:{fill:"#d4edda"}}});d.pageTitle=s.post_title,d.children=[],d.wpPageId=parseInt(s.ID),d.parentWpPageId=s.post_parent,d.isChild=0!=s.post_parent,d.parentNodeId=null,d.content=s.post_content,d.post_status=s.post_status,a.push(d),d.addTo(t),a.length==e.length&&n()}):"draft"===s.post_status&&jQuery.post(ajaxurl,{action:"iph_get_page_links",id:s.ID},function(l){let o=JSON.parse(l.substring(0,l.length-1)),d=new draftModel({position:{x:-1160,y:-1160*i+60},size:{width:140,height:100},inPorts:["in"],outPorts:["out"],ports:{groups:{in:{attrs:{".port-body":{fill:"#88e9ad",stroke:"#34343d"}},position:"top",label:{position:"outside"}},out:{attrs:{".port-body":{fill:"#88cae9",stroke:"#34343d"}},position:"bottom",label:{position:"outside"}}}},attrs:{".label":{text:r+"\n-DRAFT-","ref-x":.5,"ref-y":.2},".Action_Edit_Link":{href:o.edit_link},".Action_View_Link":{href:o.view_link},rect:{fill:"#d4edda"}}});d.pageTitle=s.post_title,d.children=[],d.wpPageId=parseInt(s.ID),d.parentWpPageId=s.post_parent,d.isChild=0!=s.post_parent,d.parentNodeId=null,d.content=s.post_content,d.post_status=s.post_status,a.push(d),d.addTo(t),a.length==e.length&&n()})}})}();let s=null;jQuery("body").bind("click",function(){s=null,jQuery.post(ajaxurl,{action:"gtek_iph_load_wp_pages"},function(t){s=JSON.parse(t.substring(0,t.length-1))})}),jQuery("#iph-newPage").on("click",function(){let e=new joint.shapes.devs.Model({position:{x:p,y:c},size:{width:140,height:100},inPorts:["in"],outPorts:["out"],ports:{groups:{in:{attrs:{".port-body":{fill:"#88e9ad",stroke:"#34343d"}},position:"top",label:{position:"outside"}},out:{attrs:{".port-body":{fill:"#88cae9",stroke:"#34343d"}},position:"bottom",label:{position:"outside"}}}},attrs:{".label":{text:"Page Title","ref-x":.5,"ref-y":.2},rect:{fill:"#d4edda"}}});e.pageTitle="",e.children=[],e.wpPageId=null,e.parentWpPageId=0,e.isChild=!1,e.parentNodeId=null,a.push(e),e.addTo(t)});let o,r=null;e.on("cell:pointerdown",function(t,e,l,i){r=a.filter(e=>e.id==t.model.id)}),jQuery("#iph-modal-save").on("click",function(){let t=l(jQuery("#pageTitle").val(),15,45),e="",i=0;for(let l=0;l<t.length;l++){e+='<tspan id="v-18" dy="0em" x="0" y="'+(i+=17)+'" class="v-line">'+t[l]+"</tspan>"}r[0].pageTitle=jQuery("#pageTitle").val(),r[0].post_status=jQuery("#pageStatus").val(),"draft"===r[0].post_status?jQuery(o).attr("id","pageRectDraft"):"publish"===r[0].post_status&&jQuery(o).attr("id","pageRect"),jQuery('*[model-id="'+r[0].id+'"]').find("text.label").html(e)}),e.on("link:connect",function(t,e,l,i){let n=a.filter(e=>e.id==t.sourceView.model.id);t.targetView.model.parentNodeId=t.sourceView.model.id,t.targetView.model.isChild=!0,u("new_page_node"),setTimeout(()=>{n[0].children.push(t.targetView.model.wpPageId)},500)}),e.on("link:pointerup",function(t,e,l,i){}),t.on("remove",function(t,e,l){if(t.isLink()&&null!=t.attributes.target.id){let e=t.attributes.source.id,l=t.attributes.target.id,i=a.filter(t=>t.id==e),n=a.filter(t=>t.id==l);n[0].isChild=!1,n[0].parentWpPageId=0,n[0].parentNodeId=null;let s=i[0].children.indexOf(l);s>-1&&i[0].children.splice(s,1)}}),jQuery(document).on("click",".Action_Modal",function(t){t.preventDefault(),null!=r[0]&&(jQuery("#ModalOptions").modal("show"),jQuery("#pageTitle").val(r[0].pageTitle),jQuery("#pageStatus").val(r[0].post_status),o=jQuery(this).parent().parent().prev())});let d=null;jQuery(document).on("click",".Action_DeletePage",function(t){t.preventDefault(),d=jQuery(this).closest(".joint-cell"),null!=r[0]&&jQuery("#ModalDelete").modal("show")}),jQuery(document).on("click",".DeletePageModalButton",function(e){if(d.remove(),d=null,t.removeLinks(r[0]),null!=r[0].wpPageId){if(r[0].children.length>0)for(let t=0;t<r[0].children.length;t++){let e=a.filter(e=>e.wpPageId==r[0].children[t]);e[0].parentWpPageId=0,e[0].isChild=!1,toastr.success("successfully deleted page"),jQuery.post(ajaxurl,{action:"iph_delete_post",id:parseInt(r[0].wpPageId)},function(t){})}0==r[0].children.length&&(toastr.success("successfully deleted page"),jQuery.post(ajaxurl,{action:"iph_delete_post",id:parseInt(r[0].wpPageId)},function(t){_.remove(a,function(t){return t.wpPageId!=r[0].wpPageId})}))}else{let t=a.indexOf(r[0]);t>-1&&a.splice(t,1)}});let c=0,p=0;async function u(t){new Promise(function(e,l){"btn_save"==t&&jQuery("#ModalSaveOverlay").modal("show");for(let t=0;t<a.length;t++){let e=a[t];null==e.wpPageId&&jQuery.post(ajaxurl,{action:"iph_save_pages",postTitle:e.pageTitle,postStatus:e.post_status},function(t){e.wpPageId=parseInt(t.substring(0,t.length-1))})}e("done!")});if("new_page_node"!=t)for(let e=0;e<a.length;e++){let l=a[e];if(l.isChild){let t=a.filter(t=>t.id==l.parentNodeId),e=parseInt(t[0].wpPageId);l.parentWpPageId=e,jQuery.post(ajaxurl,{action:"iph_update_pages",postTitle:l.pageTitle,postParent:e,id:l.wpPageId,postContent:l.content,postStatus:l.post_status},function(t){})}else l.isChild||null!=l.parentNodeId||null==l.wpPageId||jQuery.post(ajaxurl,{action:"iph_update_pages",postTitle:l.pageTitle,postParent:0,id:l.wpPageId,postContent:l.content,postStatus:l.post_status},function(e){"btn_save"==t&&(toastr.success("successfully saved"),jQuery("#ModalSaveOverlay").modal("hide"))})}}e.on("blank:contextmenu",function(t,e,l){p=e,c=l,jQuery("#iph-newPage").trigger("click")}),jQuery("#iph-save").on("click",function(t){u("btn_save")})});
  • interactive-page-hierarchy/trunk/readme.txt

    r2061849 r2160754  
     1
    12=== Interactive Page Hierarchy ===
    23Contributors: gtekelis
     
    9596== Changelog ==
    9697
     98= 1.0.1 - 2019-09-22 =
     99* New: draft pages are now supported!
     100* New: load & create draft pages. (Set the status by clicking on the gear icon of a node and then selecting the status from the drop-down list.)
     101* New: draft pages have a purple color. When changing status, color will change accordingly
     102
    97103= 0.1.1 - 2019-04-02 =
    98104* Fix: content persistence when save from within the plugin
     
    100106= 0.1.0 - 2018-12-06 =
    101107* Initial public beta release
     108
     109
Note: See TracChangeset for help on using the changeset viewer.