Add support for cloning an upgrade record

until this is all ironed out, seems like it will often be helpful
This commit is contained in:
Lance Edgar 2017-08-08 21:26:06 -05:00
parent 77880abb87
commit d7f5211fc4
6 changed files with 81 additions and 17 deletions

View file

@ -174,6 +174,9 @@ $(function() {
$('button, a.button').button();
$('input[type=submit]').button();
$('input[type=reset]').button();
$('a.button.autodisable').click(function() {
disable_button(this);
});
$('input[type="submit"].autodisable').click(function() {
disable_button(this);
});

View file

@ -0,0 +1,24 @@
## -*- coding: utf-8; -*-
<%inherit file="/base.mako" />
<%def name="title()">Clone ${model_title}: ${instance_title}</%def>
<br />
<p>You are about to clone the following ${model_title} as a new record:</p>
<div class="form-wrapper">
${form.render()|n}
</div><!-- form-wrapper -->
<br />
<p>Are you sure about this?</p>
<br />
${h.form(request.current_route_url())}
${h.csrf_token(request)}
${h.hidden('clone', value='clone')}
<div class="buttons">
${h.link_to("Whoops, nevermind...", form.cancel_url, class_='button autodisable')}
${h.submit('submit', "Yes, please clone away", class_='autodisable')}
</div>
${h.end_form()}

View file

@ -27,8 +27,10 @@
</%def>
<%def name="context_menu_items()">
<li>${h.link_to("Back to {}".format(model_title_plural), index_url)}</li>
<li>${h.link_to("Permalink for this {}".format(model_title), action_url('view', instance))}</li>
% if master.has_versions and request.rattail_config.versioning_enabled() and request.has_perm('{}.versions'.format(permission_prefix)):
<li>${h.link_to("Version History", action_url('versions', instance))}</li>
% endif
% if master.editable and instance_editable and request.has_perm('{}.edit'.format(permission_prefix)):
<li>${h.link_to("Edit this {}".format(model_title), action_url('edit', instance))}</li>
% endif
@ -38,6 +40,9 @@
% if master.creatable and request.has_perm('{}.create'.format(permission_prefix)):
<li>${h.link_to("Create a new {}".format(model_title), url('{}.create'.format(route_prefix)))}</li>
% endif
% if master.cloneable and request.has_perm('{}.clone'.format(permission_prefix)):
<li>${h.link_to("Clone this as new {}".format(model_title), url('{}.clone'.format(route_prefix), uuid=instance.uuid))}</li>
% endif
</%def>
<ul id="context-menu">

View file

@ -5,20 +5,4 @@
<h1>${instance_title}</h1>
</%def>
<%def name="context_menu_items()">
<li>${h.link_to("Permalink for this {}".format(model_title), action_url('view', instance))}</li>
% if master.has_versions and request.rattail_config.versioning_enabled() and request.has_perm('{}.versions'.format(permission_prefix)):
<li>${h.link_to("Version History", action_url('versions', instance))}</li>
% endif
% if master.editable and instance_editable and request.has_perm('{}.edit'.format(permission_prefix)):
<li>${h.link_to("Edit this {}".format(model_title), action_url('edit', instance))}</li>
% endif
% if master.deletable and instance_deletable and request.has_perm('{}.delete'.format(permission_prefix)):
<li>${h.link_to("Delete this {}".format(model_title), action_url('delete', instance))}</li>
% endif
% if master.creatable and request.has_perm('{}.create'.format(permission_prefix)):
<li>${h.link_to("Create a new {}".format(model_title), url('{}.create'.format(route_prefix)))}</li>
% endif
</%def>
${parent.body()}

View file

@ -72,6 +72,7 @@ class MasterView(View):
mergeable = False
downloadable = False
executable = False
cloneable = False
supports_mobile = False
mobile_creatable = False
@ -312,6 +313,30 @@ class MasterView(View):
tools=self.make_row_grid_tools(instance))
return self.render_to_response('view', context)
def clone(self):
"""
View for cloning an object's data into a new object.
"""
self.viewing = True
instance = self.get_instance()
form = self.make_form(instance)
self.configure_clone_form(form)
if self.request.method == 'POST' and self.request.POST.get('clone') == 'clone':
cloned = self.clone_instance(instance)
return self.redirect(self.get_action_url('view', cloned))
return self.render_to_response('clone', {
'instance': instance,
'instance_title': self.get_instance_title(instance),
'instance_url': self.get_action_url('view', instance),
'form': form,
})
def configure_clone_form(self, form):
pass
def clone_instance(self, instance):
raise NotImplementedError
def versions(self):
"""
View to list version history for an object.
@ -1805,6 +1830,14 @@ class MasterView(View):
config.add_view(cls, attr='view_version', route_name='{}.version'.format(route_prefix),
permission='{}.versions'.format(permission_prefix))
# clone
if cls.cloneable:
config.add_tailbone_permission(permission_prefix, '{}.clone'.format(permission_prefix),
"Clone an existing {0} as a new {0}".format(model_title))
config.add_route('{}.clone'.format(route_prefix), '{}/{{{}}}/clone'.format(url_prefix, model_key))
config.add_view(cls, attr='clone', route_name='{}.clone'.format(route_prefix),
permission='{}.clone'.format(permission_prefix))
# download
if cls.downloadable:
config.add_route('{}.download'.format(route_prefix), '{}/{{{}}}/download'.format(url_prefix, model_key))

View file

@ -53,6 +53,7 @@ class UpgradeView(MasterView):
model_class = model.Upgrade
executable = True
downloadable = True
cloneable = True
labels = {
'executed_by': "Executed by",
'status_code': "Status",
@ -165,6 +166,20 @@ class UpgradeView(MasterView):
f.remove_field('package_diff')
f.remove_field('exit_code')
def configure_clone_form(self, f):
f.fields = ['description', 'notes', 'enabled']
def clone_instance(self, original):
cloned = self.model_class()
cloned.created = make_utc()
cloned.created_by = self.request.user
cloned.description = original.description
cloned.notes = original.notes
cloned.enabled = original.enabled
self.Session.add(cloned)
self.Session.flush()
return cloned
def render_stdout_file(self, upgrade, fieldname):
if fieldname.startswith('stderr'):
filename = 'stderr.log'