Пример #1
0
    def get_display(self):

        top = self.top
        top.add_color("background", "background")
        top.add_border()
        top.add_style("padding: 10px")
        top.add_style("font-size: 12px")

        from tactic.ui.container import WizardWdg

        title = DivWdg()
        title.add("Share Project")


        wizard = WizardWdg(title=title, submit_title="Save", command="tactic.ui.sync.SyncServerAddCbk")

        top.add(wizard)


        #wizard.add(self.get_local_wdg(), "Local")
        wizard.add(self.get_info_wdg(), "Info")
        wizard.add(self.get_sync_mode_wdg(), "Mode")
        #wizard.add(self.get_export_wdg(), "Export")
        #wizard.add(self.get_security_wdg(), "Security")

        return top
Пример #2
0
    def get_display(my):
        top = DivWdg()
     
        top.add_style("width: 100%")
        top.add_color("background", "background", -10)
        top.add_style("padding-top: 30px")
        top.add_style("padding-bottom: 50px")
        top.add_class("twog_wizard_top")

        inner = DivWdg()
        top.add(inner)

        # set the width and height here
        inner.add_style("width: 800px")
        inner.add_style("min-height: 600px")
        inner.add_style("float: center")
        inner.add_border()
        inner.center()
        inner.add_style("padding: 20px")
        inner.add_color("background", "background")


        from tactic.ui.container import WizardWdg


        title = DivWdg()
        title.add("Step 1")

        wizard = WizardWdg(title=title)
        my.wizard = wizard
        inner.add(wizard)


        help_button = ActionButtonWdg(title="?", tip="Step 1 Help", size='s')
        title.add(help_button)
        help_button.add_style("float: right")
        help_button.add_style("margin-top: -20px")
        help_button.add_style("margin-right: -10px")
        help_button.add_behavior({
            'type': 'click_up',
            'cbjs_action': '''
            spt.help.set_top();
            spt.help.load_alias("order_wdg");
            '''
        })

        page_one = my.get_page_one()
        wizard.add(page_one, 'Step 1')
        page_two = my.get_page_two()
        wizard.add(page_two, 'Step 2')
        page_three = my.get_page_three()
        wizard.add(page_three, 'Step 3')
        page_four = my.get_page_four()
        wizard.add(page_four, 'Step 4')


        return top
Пример #3
0
    def get_display(self):

        top = self.top
        top.add_style("padding: 20px")

        wizard = WizardWdg(title="Database Resource Manager")
        top.add(wizard)

        wizard.add(self.get_vendor_wdg(), "Vendor")
        wizard.add(self.get_connect_wdg(), "Connection")
        wizard.add(self.get_tables_wdg(), "Tables")

        return top
Пример #4
0
    def get_display(my):

        top = my.top
        top.add_color("background", "background")
        top.add_border()
        top.add_style("padding: 10px")
        top.add_style("font-size: 12px")

        from tactic.ui.container import WizardWdg

        title = DivWdg()
        title.add("Share Project")

        wizard = WizardWdg(title=title,
                           submit_title="Save",
                           command="tactic.ui.sync.SyncServerAddCbk")

        top.add(wizard)

        #wizard.add(my.get_local_wdg(), "Local")
        wizard.add(my.get_info_wdg(), "Info")
        wizard.add(my.get_sync_mode_wdg(), "Mode")
        #wizard.add(my.get_export_wdg(), "Export")
        #wizard.add(my.get_security_wdg(), "Security")

        return top
Пример #5
0
    def get_display(my):

        top = my.top
        top.add_style("padding: 20px")

        wizard = WizardWdg(title="Database Resource Manager")
        top.add(wizard)


        wizard.add(my.get_vendor_wdg(), "Vendor" )
        wizard.add(my.get_connect_wdg(), "Connection" )
        wizard.add(my.get_tables_wdg(), "Tables" )
        

        return top
Пример #6
0
    def get_display(my):
        top = my.top
        my.set_as_panel(top)
        top.add_behavior( {
            'type': 'load',
            'cbjs_action': '''
            spt.named_events.fire_event("side_bar|hide")
            '''
        } )
        top.add_style("width: 100%")
        top.add_color("background", "background", -10)
        top.add_style("padding-top: 10px")
        top.add_style("padding-bottom: 50px")
        top.add_class("spt_project_top")

        inner = DivWdg()
        top.add(inner)
        inner.add_style("width: 700px")
        inner.add_style("float: center")
        inner.add_border()
        inner.center()
        inner.add_style("padding: 30px")
        inner.add_color("background", "background")


        from tactic.ui.container import WizardWdg


        title = DivWdg()
        title.add("Create A New Project")

        wizard = WizardWdg(title=title, width="100%")
        inner.add(wizard)


        help_button = ActionButtonWdg(title="?", tip="Create Project Help", size='s')
        title.add(help_button)
        help_button.add_style("float: right")
        help_button.add_style("margin-top: -20px")
        help_button.add_style("margin-right: -10px")
        help_button.add_behavior({
            'type': 'click_up',
            'cbjs_action': '''
            spt.help.set_top();
            spt.help.load_alias("create-new-project");
            '''
        })




        info_page = DivWdg()
        wizard.add(info_page, 'Info')
        info_page.add_class("spt_project_top")
        info_page.add_style("font-size: 12px")
        info_page.add_color("background", "background")
        info_page.add_color("color", "color")
        info_page.add_style("padding: 20px")



        from tactic.ui.input import TextInputWdg

        info_page.add("<b>Project Title:</b> &nbsp;&nbsp;")
    
        text = TextWdg("project_title")
        text.add_behavior( {
            'type': 'blur',
            'cbjs_action': '''
            if (bvr.src_el.value == '') {
                spt.alert("You must enter a project title");
                return;
            }
        '''})

        #text = TextInputWdg(title="project_title")
        info_page.add(text)
        text.add_style("width: 250px")
        info_page.add(HtmlElement.br(3))
        span = DivWdg()
        info_page.add(span)
        span.add_style("padding: 20px 20px 20px 20px")
        span.add(IconWdg("INFO", IconWdg.CREATE))
        span.add_color("background", "background3")
        span.add("The project title can be descriptive and contain spaces and special characters.")
        info_page.add("<br/><br/><hr/><br/><br/>")
        text.add_behavior( {
        'type': 'change',
        'cbjs_action': '''
        var title = bvr.src_el.value;
        if (title.length > 100) {
            spt.alert("Title cannot exceed 100 characters.");
            return;
        }
        var code = spt.convert_to_alpha_numeric(title);
        code = code.substring(0,30);
        var top = bvr.src_el.getParent(".spt_project_top");
        var code_el = top.getElement(".spt_project_code");
        code_el.value = code;
        '''
        } )


        info_page.add("<b>Project Code: &nbsp;&nbsp;</b>")
        text = TextWdg("project_code")
        #text = TextInputWdg(title="project_code")
        text.add_behavior( {
            'type': 'blur',
            'cbjs_action': '''
            var value = bvr.src_el.value;
            var code = spt.convert_to_alpha_numeric(value);
            bvr.src_el.value = code;
            
            if (code == '') {
                spt.alert("You must enter a project code.");
                return;
            }
            if (spt.input.has_special_chars(code)) {
                spt.alert("Project code cannot contain special characters.");
                return;
            }
        
            if (code.test(/^\d/)) {
                spt.alert("Project code cannot start with a number.");
                return;
            }
            if (code.length > 30) {
                 spt.alert("Project code cannot exceed 30 characters.");
                return;
            }
       
            '''
        } )


        info_page.add(text)
        text.add_style("width: 250px")
        text.add_class("spt_project_code")
        info_page.add(HtmlElement.br(4))

        span = DivWdg()
        info_page.add(span)
        span.add_style("padding: 20px 20px 20px 20px")
        span.add(IconWdg("INFO", IconWdg.CREATE))
        span.add_color("background", "background3")
        span.add("The project code is a very important key that will tie many components of the project together.")
        span.add("<br/><br/>")
        span.add("* Note: the project code must contain only alphanumeric characters [A-Z]/[0-9] and only an '_' as a separator")
        info_page.add(span)

        info_page.add("<br/>"*2)


        projects = Project.get_all_projects()

        info_page.add("<b>Is Main Project? </b>")

        checkbox = CheckboxWdg("is_main_project")
        default_project_code = Config.get_value("install", "default_project")
        info_page.add(checkbox)
        if default_project_code:
            default_project = Project.get_by_code(default_project_code)
        else:
            default_project = None

        if default_project:
            default_title = default_project.get_value("title")
            info_span = SpanWdg()
            info_page.add(info_span)
            info_span.add("%sCurrent: %s (%s)" % ("&nbsp;"*3, default_title, default_project_code))
            info_span.add_style("font-size: 0.9em")
            info_span.add_style("font-style: italic")
        else:
            if len(projects) == 0:
                checkbox.set_checked()

        info_page.add("<br/>"*2)

        span = DivWdg()
        info_page.add(span)
        span.add_style("padding: 20px 20px 20px 20px")
        span.add(IconWdg("INFO", IconWdg.CREATE))
        span.add_color("background", "background3")
        span.add("A TACTIC installation can have multiple projects, but one can be designated as the main project.  This project will appear at the root of the url. This is meant for building custom project launcher which is based on a main project.")
        span.add("<br/>"*2)
        span.add("* Note: TACTIC may need to be restarted in order for this to take effect")
        info_page.add(span)

        info_page.add("<br/>")









        # add an icon for this project
        image_div = DivWdg()
        wizard.add(image_div, 'Preview Image')
        image_div.add_class("spt_image_top")
        image_div.add_color("background", "background")
        image_div.add_color("color", "color")
        image_div.add_style("padding: 20px")


        image_div.add("<b>Project Image: </b>")
        image_div.add("<br/>"*3)
        on_complete = '''var server = TacticServerStub.get();
        var file = spt.html5upload.get_file(); 
        if (file) { 

            var top = bvr.src_el.getParent(".spt_image_top");
            var text = top.getElement(".spt_image_path");
            var display = top.getElement(".spt_path_display");
            var check_icon = top.getElement(".spt_check_icon");

            var server = TacticServerStub.get();
            var ticket = spt.Environment.get().get_ticket();


            display.innerHTML = "Uploaded: " + file.name;
            display.setStyle("padding", "10px");
            check_icon.setStyle("display", "");
          
          
            var filename = file.name;
            filename = spt.path.get_filesystem_name(filename);
            var kwargs = {
                ticket: ticket,
                filename: filename
            }
            try {
                var ret_val = server.execute_cmd("tactic.command.CopyFileToAssetTempCmd", kwargs);
                var info = ret_val.info;
                var path = info.web_path;
                text.value = info.lib_path;
                display.innerHTML = display.innerHTML + "<br/><br/><div style='text-align: center'><img style='width: 80px;' src='"+path+"'/></div>";
            }
            catch(e) {
                spt.alert(spt.exception.handler(e));
            }
            spt.app_busy.hide();
            }
        else {
            spt.alert('Error: file object cannot be found.') 
        }
            spt.app_busy.hide();
        '''
        button = UploadButtonWdg(title="Browse", on_complete=on_complete) 
        button.add_style("margin-left: auto")
        button.add_style("margin-right: auto")
        image_div.add(button)


        text = HiddenWdg("project_image_path")
        text.add_class("spt_image_path")
        image_div.add(text)

        check_div = DivWdg()
        image_div.add(check_div)
        check_div.add_class("spt_check_icon")
        check_icon = IconWdg("Image uploaded", IconWdg.CHECK)
        check_div.add(check_icon)
        check_div.add_style("display: none")
        check_div.add_style("float: left")
        check_div.add_style("padding-top: 8px")

        path_div = DivWdg()
        image_div.add(path_div)
        path_div.add_class("spt_path_display")

        image_div.add(HtmlElement.br(3))
        span = DivWdg()
        image_div.add(span)
        span.add_style("padding: 20px 20px 20px 20px")
        span.add_color("background", "background3")
        span.add(IconWdg("INFO", IconWdg.CREATE))
        span.add("The project image is a small image that will be used in various places as a visual representation of this project.")

        info_page.add("<br/><br/>")





        # get all of the template projects that are installed
        copy_div = DivWdg()
        wizard.add(copy_div, "Template")
        copy_div.add_style("padding-top: 20px")





        template = ActionButtonWdg(title="Manage", tip="Manage Templates")
        copy_div.add(template)
        template.add_style("float: right")
        template.add_behavior( {
            'type': 'click_up',
            'cbjs_action': '''
                var class_name = 'tactic.ui.app.ProjectTemplateWdg'
                spt.panel.load_popup("Templates", class_name)
            '''
        } )
        template.add_style("margin-top: -5px")




        copy_div.add("<b>Copy From Template: &nbsp;&nbsp;</b>")



        search = Search("sthpw/project")
        search.add_filter("is_template", True)
        template_projects = search.get_sobjects()
        values = [x.get_value("code") for x in template_projects]
        labels = [x.get_value("title") for x in template_projects]


        # find all of the template projects installed
        template_dir = Environment.get_template_dir()
        import os
        if not os.path.exists(template_dir):
            paths = []
        else:
            paths = os.listdir(template_dir);


            file_values = []
            file_labels = []
            for path in paths:
                if path.endswith("zip"):
                    orig_path = '%s/%s'%(template_dir, path)
                    path = path.replace(".zip", "")
                    parts = path.split("-")
                    plugin_code = parts[0]

                    # skip if there is a matching project in the database
                    #match_project = plugin_code.replace("_template", "")
                    
                    match_project = plugin_code
                    old_style_plugin_code = re.sub( '_template$', '', plugin_code)

                    if match_project in values:
                        continue
                    elif old_style_plugin_code in values:
                        continue

                    label = "%s (from file)" % Common.get_display_title(match_project)

                    # for zip file, we want the path as well
                    value = '%s|%s'%(plugin_code, orig_path)
                    file_values.append(value)
                    file_labels.append(label)

            if file_values:
                values.extend(file_values)
                labels.extend(file_labels)


        values.insert(0, "_empty")
        labels.insert(0, "- Empty Project -")

        select = SelectWdg("project_source")
        copy_div.add(select)
        select.set_option("values", values)
        select.set_option("labels", labels)
        #select.add_empty_option("-- Select --")

        select.add_behavior( {
        'type': 'change',
        'cbjs_action': '''
        var value = bvr.src_el.value;
        var top = bvr.src_el.getParent(".spt_project_top");
        var type = top.getElement(".spt_custom_project_top");
        var namespace_option = top.getElement(".spt_custom_namespace_top");

        var theme_el = top.getElement(".spt_theme_top");

        if (bvr.src_el.value == "_empty") {
            spt.show(type);
            spt.show(namespace_option);

            spt.show(theme_el);

        }
        else {
            spt.hide(type);
            spt.hide(namespace_option);

            spt.hide(theme_el);
        }
        '''
        } )



        copy_div.add(HtmlElement.br(3))
        span = DivWdg()
        copy_div.add(span)
        span.add_style("padding: 20px 20px 20px 20px")
        span.add(IconWdg("INFO", IconWdg.CREATE))
        span.add_color("background", "background3")
        span.add("This will use the selected project template as a basis and copy all of the configuration elements.  Only template projects should be copied.")

        #copy_div.add(HtmlElement.br(2))
        #span = DivWdg("This will create an empty project with no predefined configuration.")
        #copy_div.add(span)

        #
        # Theme
        #
        theme_div = DivWdg()
        theme_div.add_class("spt_theme_top")
        theme_div.add_style("padding: 10px")
        theme_div.add_style("margin-top: 20px")
        copy_div.add(theme_div)
        theme_div.add("<b>Theme: </b>&nbsp; ")
        theme_div.add_style('padding-right: 6px')

        theme_select = SelectWdg('project_theme')
        theme_div.add(theme_select)



        # look in the plugins for all of the themes?
        from pyasm.biz import PluginUtil
        plugin_util = PluginUtil()
        data = plugin_util.get_plugins_data("theme")

        builtin_dir = Environment.get_builtin_plugin_dir()
        plugin_util = PluginUtil(base_dir=builtin_dir)

        data2 = plugin_util.get_plugins_data("theme")


        data = dict(data.items() + data2.items())

        themes = data.keys()
        themes.sort()




        theme_select.set_option("values", themes)
        theme_select.add_empty_option('- No Theme -')
        default_theme = "TACTIC/default_theme"
        theme_select.set_value(default_theme)

        theme_select.add_behavior( {
            'type': 'change',
            'cbjs_action': '''
            var top = bvr.src_el.getParent(".spt_project_top");
            var img_div = top.getElement(".spt_project_theme_div");
            var theme = bvr.src_el.value;

            var img_els = img_div.getElements(".spt_project_theme_image");
            for (var i = 0; i < img_els.length; i++) {
                if (theme == img_els[i].getAttribute("spt_theme") ) {
                    img_els[i].setStyle("display", "");
                }
                else {
                    img_els[i].setStyle("display", "none");
                }
            }
            '''
        } )

        theme_img_div = DivWdg()
        theme_div.add(theme_img_div)
        theme_img_div.add_class("spt_project_theme_div")

        for theme in themes:
            theme_item = DivWdg()
            theme_item.add_style("margin: 15px")
            theme_img_div.add(theme_item)
            theme_item.add_attr("spt_theme", theme)
            theme_item.add_class("spt_project_theme_image")
            if theme != default_theme:
                theme_item.add_style("display: none")

            table = Table()
            theme_item.add(table)
            table.add_row()

            if Environment.is_builtin_plugin(theme):
                theme_img = HtmlElement.img(src="/tactic/builtin_plugins/%s/media/screenshot.jpg" % theme)
            else:
                theme_img = HtmlElement.img(src="/tactic/plugins/%s/media/screenshot.jpg" % theme)
            theme_img.add_border()
            theme_img.set_box_shadow("1px 1px 1px 1px")
            theme_img.add_style("margin: 20px 10px")
            theme_img.add_style("width: 240px")

            plugin_data = data.get(theme)

            description = plugin_data.get("description")
            if not description:
                description = "No Description"

            table.add_cell(theme_img)
            table.add_cell( description )



        theme_img_div.add_style("text-align: center")
        theme_img_div.add_style("margin: 10px")

 

        #
        # namespace
        #
        ns_div = DivWdg()
        ns_div.add_class("spt_custom_namespace_top")
        ns_div.add_style("padding: 10px")
        copy_div.add(ns_div)
        ns_div.add("<br/>")
        ns = HtmlElement.b("Namespace:")
        ns.add_style('padding-right: 6px')
        ns_div.add(ns)

        text = TextWdg('custom_namespace')
        text.add_class("spt_custom_namespace")
        text.add_behavior( {
            'type': 'blur',
            'cbjs_action': '''
                 var project_namespace = bvr.src_el.value;
                 if (['sthpw','prod'].contains(project_namespace)) 
                    spt.alert('Namespace [' + project_namespace + '] is reserved.');

                 if (project_namespace.strip()=='') 
                    spt.alert('A "default" namespace will be used if you leave it empty.');
            
            '''})

        ns_div.add(text)

        hint = HintWdg('This will be used as the prefix for your sTypes. You can use your company name for instance')
        ns_div.add(hint)

        # is_template
        is_template_div = DivWdg()
        #is_template_div.add_style('display: none')

        is_template_div.add_class("spt_custom_project_top")
        is_template_div.add_style("padding: 10px")
        copy_div.add(is_template_div)
        is_template_div.add("<br/>")
        is_template_div.add("<b>Is this project a template: </b>")

        text = CheckboxWdg("custom_is_template")
        text.add_class("spt_custom_is_template")
        is_template_div.add(text)

        is_template_div.add(HtmlElement.br(2))
        span = DivWdg("Template projects are used as a blueprint for generating new projects.")
        is_template_div.add(span)



        # Disabling for now ... advanced feature and may not be necessary
        #stypes_div = my.get_stypes_div()
        #is_template_div.add(stypes_div)








        last_page = DivWdg()
        wizard.add(last_page, "Complete")

        last_page.add_style("padding-top: 80px")
        last_page.add_style("padding-left: 30px")

        cb = RadioWdg('jump_project', label='Jump to New Project')
        cb.set_option("value", "project")
        #cb.set_option('disabled','disabled')
        cb.set_checked()
        last_page.add(cb)

        last_page.add(HtmlElement.br(2))

        cb = RadioWdg('jump_project', label='Jump to Project Admin')
        cb.set_option("value", "admin")
        last_page.add(cb)


        last_page.add(HtmlElement.br(2))

        cb = RadioWdg('jump_project', label='Create Another Project')
        cb.set_option("value", "new")
        last_page.add(cb)




        last_page.add(HtmlElement.br(5))


        button_div = DivWdg()

        create_button = ActionButtonWdg(title="Create >>", tip="Create new project")
        wizard.add_submit_button(create_button)
        #button_div.add(create_button)
        create_button.add_style("float: right")

        create_button.add_behavior({
        'type': "click_up",
        'cbjs_action': '''
        var top = bvr.src_el.getParent(".spt_project_top");
        var values = spt.api.Utility.get_input_values(top, null, null, null, {cb_boolean: true});

        var project_code = values['project_code'][0];
        if (project_code == '') {
            spt.alert("You must enter a project code.");
            return;
        }
        if (spt.input.has_special_chars(project_code)) {
            spt.alert("Project code cannot contain special characters.");
            return;
        }
        
        if (project_code.test(/^\d/)) {
            spt.alert("Project code cannot start with a number.");
            return;
        }
        if (values['project_title'] == '') {
            spt.alert("You must enter a project title");
            return;
        }

        var project_source = values.project_source[0];

        var project_image_path = values['project_image_path'][0];

        var project_theme = values['project_theme'][0];

        var options = {
            'project_code': project_code,
            'project_title': values['project_title'][0],
            'project_image_path': project_image_path,
            'project_theme': project_theme,
        }

        //'copy_pipelines': values['copy_pipelines'][0]

        var class_name;
        var busy_title;
        var busy_msg;
        var use_transaction;
        if (project_source == '') {
            spt.alert("Please select a template to copy or select create an empty project");
            return;
        }
        else if (project_source != '_empty') {
            busy_title = "Copying Project"; 
            busy_msg = "Copying project ["+project_source+"] ...";
            use_transaction = false;

            class_name = 'tactic.command.ProjectTemplateInstallerCmd';
            if (project_source.test(/\|/)) {
                var tmps = project_source.split('|');
                project_source = tmps[0];
                var path = tmps[1];
                options['path'] = path;
            }
            options['template_code'] = project_source;
            options['force_database'] = true;

        }
        else {
            class_name = "tactic.command.CreateProjectCmd";
            busy_title = "Creating New Project"; 
            busy_msg = "Creating new project based on project info ...";
            use_transaction = true;

            // use project code as the project type if namespace is not specified
            var project_namespace = values['custom_namespace'][0];
            if (['sthpw','prod'].contains(project_namespace)) {
                spt.alert('Namespace [' + project_namespace + '] is reserved.');
                return;
            }
            options['project_type'] =  project_namespace ? project_namespace : project_code
            var is_template = values['custom_is_template'];
            if (is_template) {
                options['is_template'] = is_template[0];
            }
            // This has been commented out in the UI
            //options['project_stype'] = values['project_stype'].slice(1);


            var is_main_project = values['is_main_project'];
            if (is_main_project) {
                options['is_main_project'] = is_main_project[0];
            }

        }

        // Display app busy pop-up until create project command
        // has completed executing.
        spt.app_busy.show( busy_title, busy_msg ); 

        setTimeout( function() {

            var ret_val = '';
            var server = TacticServerStub.get();
            try {
                ret_val = server.execute_cmd(class_name, options, {}, {use_transaction: true});
            }
            catch(e) {
                spt.app_busy.hide();
                spt.alert("Error: " + spt.exception.handler(e));
                return;
                throw(e);
            }
            spt.api.Utility.clear_inputs(top);

            // show feedback at the end
            var jump = values['jump_project'][0];
            if (jump == 'project' || jump == 'admin') {
                var location;
                if (jump == 'admin') {
                    location = "/tactic/" + project_code + "/admin";
                }
                else if (project_theme) {
                    location = "/tactic/" + project_code + "/";
                }
                else {
                    location = "/tactic/" + project_code + "/admin/link/_startup";
                }
                setTimeout( function() {
                    document.location = location;
                    }, 1000);
            }
            else { 
                // Refresh header
                spt.panel.refresh(top);
                setTimeout( function() {
                    spt.panel.refresh('ProjectSelectWdg');
                }, 2800);


                spt.app_busy.hide();
            }

            // don't hide because it gives the false impression that nothing
            // happened as it waits for the timeout
            //spt.app_busy.hide();
        }, 0 );

        '''


        })


        cancel_script = my.kwargs.get("cancel_script")
        if cancel_script:
            cancel_button = ActionButtonWdg(title="Cancel")
            cancel_button.add_style("float: left")

            cancel_button.add_behavior({
                'type': "click_up",
                'cbjs_action': cancel_script
            })

            button_div.add(cancel_button)

            create_button.add_style("margin-right: 15px")
            create_button.add_style("margin-left: 75px")


        button_div.add("<br clear='all'/>")

        last_page.add(button_div)


        inner.add(HtmlElement.br())
   
        return top