"Duplicate Site" function. Tweaked site admin menu, pushed it further down into the...
authorgfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Wed, 20 Apr 2011 02:43:39 +0000 (02:43 +0000)
committergfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Wed, 20 Apr 2011 02:43:39 +0000 (02:43 +0000)
Duplicate Site will create a new site, based on the information and contents of the current site.

git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/trunk@1405 6d9bc8c9-1ec2-4278-b937-99fde70a366f

conifer/static/main.css
conifer/syrup/urls.py
conifer/syrup/views/sites.py
conifer/templates/edit_site.xhtml
conifer/templates/site_detail.xhtml

index e1f7dff..c00c41c 100644 (file)
@@ -159,8 +159,10 @@ span.final_item { font-weight: bold; font-size: 110%; }
 
 /* item trees (tree of headings and items in a site */
 
-#sidepanel { width: 183px; float: right; text-align: right;}
+#sidepanel { width: 183px; float: right; text-align: right; font-size: 90%; }
+#sidepanel.editor { margin: 3em 2em 0 2em; }
 #sidepanel div { margin: 6px 0; }
+#sidepanel a { color: navy; }
 
 #treepanel { width: 740px; margin-top: 24px; }
 
@@ -202,7 +204,7 @@ span.final_item { font-weight: bold; font-size: 110%; }
     margin-top: 30px; font-size: 90%;
     padding: 10px; 
     background-color: #eef; 
-    clear: both;
+//    clear: both;
 }
 .itemadd li {     
     margin: 10px; 
index d402cd7..9a2594c 100644 (file)
@@ -71,4 +71,5 @@ urlpatterns = patterns('conifer.syrup.views',
     (r'^site/(?P<site_id>\d+)/copy_from/$', 'site_clipboard_copy_from'),
     (r'^site/(?P<site_id>\d+)/paste_to/$', 'site_clipboard_paste_to'),
     (r'^site/(?P<site_id>\d+)/paste_undo/$', 'site_clipboard_paste_undo'),
+    (r'^site/(?P<site_id>\d+)/copy_whole/$', 'site_clipboard_copy_whole'),
 )
index 9edc595..9b64b8e 100644 (file)
@@ -39,7 +39,7 @@ def edit_site(request, site_id):
     instance = get_object_or_404(models.Site, pk=site_id)
     return _add_or_edit_site(request, instance=instance)
 
-def _add_or_edit_site(request, instance=None):
+def _add_or_edit_site(request, instance=None, basis=None):
     is_add = (instance is None)
     
     # Are we looking up owners, or selecting them from a fixed list?
@@ -47,6 +47,13 @@ def _add_or_edit_site(request, instance=None):
 
     if is_add:
         instance = models.Site()
+        if basis:
+            dct = dict((k,v) for k,v in basis.__dict__.items() 
+                       if not k.startswith('_')
+                       and not k in ['start_term_id', 'end_term_id'])
+            del dct['id']
+            instance.__dict__.update(dct)
+
     if request.method != 'POST':
         form = NewSiteForm(instance=instance)
         return g.render('edit_site.xhtml', **locals())
@@ -74,6 +81,10 @@ def _add_or_edit_site(request, instance=None):
             site = form.instance
             assert site.id
 
+            if 'basis' in POST:
+                # We are duplicating a site. Copy all the items over into the new site.
+                source_site = models.Site.objects.get(pk=POST['basis'])
+                _copy_contents(request, source_site, site)
             if is_add:
                 # we need to configure permissions.
                 return HttpResponseRedirect(site.site_url('edit/permission/'))
@@ -247,13 +258,8 @@ def site_clipboard_copy_from(request, site_id):
                           _('This site has been marked as the copying source. Visit the new site, '
                             'and click "Paste to Here," to copy this site\'s materials into the new site.'))
 
-def site_clipboard_paste_to(request, site_id):
-    source_id = request.session['copy_source']
-    source_site = get_object_or_404(models.Site, pk=source_id)
-    site = get_object_or_404(models.Site, pk=site_id)
-    if request.method != 'POST':
-        return g.render('site_confirm_paste.xhtml', **locals())
 
+def _copy_contents(request, source_site, dest_site):
     item_map = {}
 
     def process_item(parent, (item, subitems)):
@@ -262,7 +268,7 @@ def site_clipboard_paste_to(request, site_id):
         del dct['id']
         dct['parent_heading_id'] = parent.id if parent else None
         newitem = models.Item.objects.create(**dct)
-        newitem.site = site
+        newitem.site = dest_site
         newitem.save()
         item_map[old_id] = newitem.id
         for sub in subitems:
@@ -270,7 +276,15 @@ def site_clipboard_paste_to(request, site_id):
 
     for branch in source_site.item_tree():
         process_item(None, branch)
-    request.session['last_paste'] = (source_site.id, site.id, item_map.values())
+    request.session['last_paste'] = (source_site.id, dest_site.id, item_map.values())
+
+def site_clipboard_paste_to(request, site_id):
+    source_id = request.session['copy_source']
+    source_site = get_object_or_404(models.Site, pk=source_id)
+    site = get_object_or_404(models.Site, pk=site_id)
+    if request.method != 'POST':
+        return g.render('site_confirm_paste.xhtml', **locals())
+    _copy_contents(request, source_site, site)
     return HttpResponseRedirect('../')
 
 def site_clipboard_paste_undo(request, site_id):
@@ -288,3 +302,8 @@ def site_clipboard_paste_undo(request, site_id):
             pass
     del request.session['last_paste']
     return HttpResponseRedirect('../')
+
+
+def site_clipboard_copy_whole(request, site_id):
+    site = get_object_or_404(models.Site, pk=site_id)
+    return _add_or_edit_site(request, basis=site)
index b14e174..0ae111e 100644 (file)
@@ -1,6 +1,8 @@
 <?python
 if instance.id:
     title = _('Site setup')
+elif basis:
+    title = _('Duplicate this site')
 else:
     title = _('Create a new site')
 owner = instance.owner if instance.owner_id else None
@@ -22,12 +24,14 @@ owner = instance.owner if instance.owner_id else None
 <body>
   <div py:if="instance.id">${site_banner(instance)}</div>
   <h1>${title}</h1>
+  <p>All items in this site will be copied into the new site.</p>
   <div py:with="nfe=form.non_field_errors()">
     <ul py:if="nfe" class="errorlist">
       <li py:for="err in nfe">${err}</li>
     </ul>
   </div>
   <form action="." method="POST" autocomplete="off">
+    <input py:if="basis" type="hidden" name="basis" value="${basis.id}"/>
     <tr py:def="field_row(field, example=None)">
       <th>${field.label}</th>
       <td>
index 5142a45..cf498e6 100644 (file)
@@ -23,7 +23,11 @@ is_joinable = site.is_joinable_by(request.user)
       ${show_tree(item_tree, edit=is_editor)}
     </div>
     <!-- still not perfect placement, but big help for IE -->
-    <div id="sidepanel">
+    <div id="sidepanel" class="${is_editor and 'editor' or ''}">
+      <div id="non_copy_stuff">
+      <div py:if="is_editor" id="feeds" class="little_action_panel">
+       <a href="${site.site_url()}feeds/">Feeds</a>
+      </div>
       <div py:if="is_editor" id="edit_site" class="little_action_panel">
        <div><a href="${site.site_url()}edit/">Setup</a></div>
        <div><a href="${site.site_url()}edit/permission/">Permissions</a></div>
@@ -31,21 +35,28 @@ is_joinable = site.is_joinable_by(request.user)
       <div py:if="is_joinable">
        <a href="${site.site_url()}join/">Join this site</a>
       </div>
-      <div py:if="is_editor" id="feeds" class="little_action_panel">
-       <a href="${site.site_url()}feeds/">Feeds</a>
-      </div>
-      <div py:if="is_editor" id="copy_from" class="little_action_panel">
-       <a href="${site.site_url()}copy_from/">Copy from here</a>
       </div>
-      <div py:if="is_editor and request.session.get('copy_source')" id="paste_to" class="little_action_panel">
-       <a href="${site.site_url()}paste_to/">Paste to here</a>
+      <div py:if="is_editor">
+       <a href="javascript:void($('#copypastepanel,#non_copy_stuff').toggle(300));"
+          style="text-decoration: underline;">Copy and Paste</a>
       </div>
-      <div py:if="is_editor and request.session.get('last_paste', (0,0,0))[1] == site.id" 
-          id="paste_undo" class="little_action_panel">
-       <a href="${site.site_url()}paste_undo/">Undo last paste</a>
+      <div py:if="is_editor" id="copypastepanel" style="display: none;">
+       <div id="copy_from" class="little_action_panel">
+         <a href="${site.site_url()}copy_from/">Copy from here</a>
+       </div>
+       <div py:if="request.session.get('copy_source')" id="paste_to" class="little_action_panel">
+         <a href="${site.site_url()}paste_to/">Paste to here</a>
+       </div>
+       <div py:if="request.session.get('last_paste', (0,0,0))[1] == site.id" 
+            id="paste_undo" class="little_action_panel">
+         <a href="${site.site_url()}paste_undo/">Undo last paste</a>
+       </div>
+       <div id="copy_source" class="little_action_panel">
+         <a href="${site.site_url()}copy_whole/">Duplicate site</a>
+       </div>
       </div>
-
     </div>
     <div py:if="is_editor">${add_subs()}</div>
+    <div style="clear: right;"/>
   </body>
 </html>