Wrap up steps for new table wizard
it actually works.. :) needs more polish, but will let usage drive that
This commit is contained in:
parent
68ed5942e6
commit
f4bc280da7
|
@ -26,10 +26,10 @@
|
||||||
Enter Details
|
Enter Details
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<b-field label="Schema Branch" horizontal
|
<b-field label="Schema Branch"
|
||||||
message="Leave this set to your custom app branch, unless you know what you're doing.">
|
message="Leave this set to your custom app branch, unless you know what you're doing.">
|
||||||
<b-select v-model="tableBranch">
|
<b-select v-model="alembicBranch">
|
||||||
<option v-for="branch in branchOptions"
|
<option v-for="branch in alembicBranchOptions"
|
||||||
:key="branch"
|
:key="branch"
|
||||||
:value="branch">
|
:value="branch">
|
||||||
{{ branch }}
|
{{ branch }}
|
||||||
|
@ -260,7 +260,7 @@
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<b-field label="Schema Branch" horizontal>
|
<b-field label="Schema Branch" horizontal>
|
||||||
{{ tableBranch }}
|
{{ alembicBranch }}
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field label="Table Name" horizontal>
|
<b-field label="Table Name" horizontal>
|
||||||
|
@ -306,7 +306,8 @@
|
||||||
|
|
||||||
<b-step-item step="3"
|
<b-step-item step="3"
|
||||||
value="review-model"
|
value="review-model"
|
||||||
label="Review Model">
|
label="Review Model"
|
||||||
|
clickable>
|
||||||
<h3 class="is-size-3 block">
|
<h3 class="is-size-3 block">
|
||||||
Review Model
|
Review Model
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -404,12 +405,18 @@
|
||||||
:disabled="!modelImported">
|
:disabled="!modelImported">
|
||||||
Model class looks good!
|
Model class looks good!
|
||||||
</b-button>
|
</b-button>
|
||||||
|
<b-button icon-pack="fas"
|
||||||
|
icon-left="arrow-right"
|
||||||
|
@click="activeStep = 'write-revision'">
|
||||||
|
Skip
|
||||||
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
</b-step-item>
|
</b-step-item>
|
||||||
|
|
||||||
<b-step-item step="4"
|
<b-step-item step="4"
|
||||||
value="write-revision"
|
value="write-revision"
|
||||||
label="Write Revision">
|
label="Write Revision"
|
||||||
|
clickable>
|
||||||
<h3 class="is-size-3 block">
|
<h3 class="is-size-3 block">
|
||||||
Write Revision
|
Write Revision
|
||||||
</h3>
|
</h3>
|
||||||
|
@ -417,9 +424,25 @@
|
||||||
You said the model class looked good, so next we will generate
|
You said the model class looked good, so next we will generate
|
||||||
a revision script, used to modify DB schema.
|
a revision script, used to modify DB schema.
|
||||||
</p>
|
</p>
|
||||||
<p class="block">
|
|
||||||
TODO: write revision script here
|
<b-field label="Schema Branch"
|
||||||
</p>
|
message="Leave this set to your custom app branch, unless you know what you're doing.">
|
||||||
|
<b-select v-model="alembicBranch">
|
||||||
|
<option v-for="branch in alembicBranchOptions"
|
||||||
|
:key="branch"
|
||||||
|
:value="branch">
|
||||||
|
{{ branch }}
|
||||||
|
</option>
|
||||||
|
</b-select>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field label="Message"
|
||||||
|
message="Human-friendly brief description of the changes">
|
||||||
|
<b-input v-model="revisionMessage"></b-input>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<b-button icon-pack="fas"
|
<b-button icon-pack="fas"
|
||||||
icon-left="arrow-left"
|
icon-left="arrow-left"
|
||||||
|
@ -429,8 +452,14 @@
|
||||||
<b-button type="is-primary"
|
<b-button type="is-primary"
|
||||||
icon-pack="fas"
|
icon-pack="fas"
|
||||||
icon-left="save"
|
icon-left="save"
|
||||||
|
@click="writeRevisionScript()"
|
||||||
|
:disabled="writingRevisionScript">
|
||||||
|
{{ writingRevisionScript ? "Working, please wait..." : "Generate revision script" }}
|
||||||
|
</b-button>
|
||||||
|
<b-button icon-pack="fas"
|
||||||
|
icon-left="arrow-right"
|
||||||
@click="activeStep = 'review-revision'">
|
@click="activeStep = 'review-revision'">
|
||||||
Write revision script to file
|
Skip
|
||||||
</b-button>
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
</b-step-item>
|
</b-step-item>
|
||||||
|
@ -441,7 +470,19 @@
|
||||||
<h3 class="is-size-3 block">
|
<h3 class="is-size-3 block">
|
||||||
Review Revision
|
Review Revision
|
||||||
</h3>
|
</h3>
|
||||||
<p class="block">TODO: review revision script here</p>
|
|
||||||
|
<p class="block">
|
||||||
|
Revision script was generated to file:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="block is-family-code" style="padding-left: 3rem;">
|
||||||
|
{{ revisionScript }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="block">
|
||||||
|
Please review that code and adjust to your liking.
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<b-button icon-pack="fas"
|
<b-button icon-pack="fas"
|
||||||
icon-left="arrow-left"
|
icon-left="arrow-left"
|
||||||
|
@ -459,11 +500,16 @@
|
||||||
|
|
||||||
<b-step-item step="6"
|
<b-step-item step="6"
|
||||||
value="upgrade-db"
|
value="upgrade-db"
|
||||||
label="Upgrade DB">
|
label="Upgrade DB"
|
||||||
|
clickable>
|
||||||
<h3 class="is-size-3 block">
|
<h3 class="is-size-3 block">
|
||||||
Upgrade DB
|
Upgrade DB
|
||||||
</h3>
|
</h3>
|
||||||
<p class="block">TODO: upgrade DB here</p>
|
<p class="block">
|
||||||
|
You said the revision script looked good, so next we will use
|
||||||
|
it to upgrade your actual database.
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<b-button icon-pack="fas"
|
<b-button icon-pack="fas"
|
||||||
icon-left="arrow-left"
|
icon-left="arrow-left"
|
||||||
|
@ -472,20 +518,72 @@
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button type="is-primary"
|
<b-button type="is-primary"
|
||||||
icon-pack="fas"
|
icon-pack="fas"
|
||||||
icon-left="check"
|
icon-left="arrow-up"
|
||||||
@click="activeStep = 'review-db'">
|
@click="upgradeDB()"
|
||||||
Upgrade database
|
:disabled="upgradingDB">
|
||||||
|
{{ upgradingDB ? "Working, please wait..." : "Upgrade database" }}
|
||||||
</b-button>
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
</b-step-item>
|
</b-step-item>
|
||||||
|
|
||||||
<b-step-item step="7"
|
<b-step-item step="7"
|
||||||
value="review-db"
|
value="review-db"
|
||||||
label="Review DB">
|
label="Review DB"
|
||||||
|
clickable>
|
||||||
<h3 class="is-size-3 block">
|
<h3 class="is-size-3 block">
|
||||||
Review DB
|
Review DB
|
||||||
</h3>
|
</h3>
|
||||||
<p class="block">TODO: review DB here</p>
|
|
||||||
|
<p class="block">
|
||||||
|
At this point your new table should be present in the DB.
|
||||||
|
Test below.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="card block">
|
||||||
|
<header class="card-header">
|
||||||
|
<p class="card-header-title">
|
||||||
|
Table Status
|
||||||
|
</p>
|
||||||
|
</header>
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="content">
|
||||||
|
<div class="level">
|
||||||
|
<div class="level-left">
|
||||||
|
|
||||||
|
<div class="level-item">
|
||||||
|
<span v-if="!tableCheckAttempted">
|
||||||
|
check not yet attempted
|
||||||
|
</span>
|
||||||
|
<span v-if="tableCheckAttempted && !tableCheckProblem"
|
||||||
|
class="has-text-success has-text-weight-bold">
|
||||||
|
table exists!
|
||||||
|
</span>
|
||||||
|
<span v-if="tableCheckProblem"
|
||||||
|
class="has-text-danger">
|
||||||
|
{{ tableCheckProblem }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="level-right">
|
||||||
|
<div class="level-item">
|
||||||
|
<b-field horizontal label="Table Name">
|
||||||
|
<b-input v-model="tableName"></b-input>
|
||||||
|
</b-field>
|
||||||
|
</div>
|
||||||
|
<div class="level-item">
|
||||||
|
<b-button type="is-primary"
|
||||||
|
icon-pack="fas"
|
||||||
|
icon-left="redo"
|
||||||
|
@click="tableCheck()">
|
||||||
|
Test for Table
|
||||||
|
</b-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<b-button icon-pack="fas"
|
<b-button icon-pack="fas"
|
||||||
icon-left="arrow-left"
|
icon-left="arrow-left"
|
||||||
|
@ -495,7 +593,8 @@
|
||||||
<b-button type="is-primary"
|
<b-button type="is-primary"
|
||||||
icon-pack="fas"
|
icon-pack="fas"
|
||||||
icon-left="check"
|
icon-left="check"
|
||||||
@click="activeStep = 'commit-code'">
|
@click="activeStep = 'commit-code'"
|
||||||
|
:disabled="!tableCheckAttempted || tableCheckProblem">
|
||||||
DB looks good!
|
DB looks good!
|
||||||
</b-button>
|
</b-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -507,19 +606,26 @@
|
||||||
<h3 class="is-size-3 block">
|
<h3 class="is-size-3 block">
|
||||||
Commit Code
|
Commit Code
|
||||||
</h3>
|
</h3>
|
||||||
<p class="block">TODO: commit changes here</p>
|
|
||||||
|
<p class="block">
|
||||||
|
Hope you're having a great day.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="block">
|
||||||
|
Don't forget to commit code changes to your source repo.
|
||||||
|
</p>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<b-button icon-pack="fas"
|
<b-button icon-pack="fas"
|
||||||
icon-left="arrow-left"
|
icon-left="arrow-left"
|
||||||
@click="activeStep = 'review-db'">
|
@click="activeStep = 'review-db'">
|
||||||
Back
|
Back
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-button type="is-primary"
|
<once-button type="is-primary"
|
||||||
icon-pack="fas"
|
tag="a" :href="tableURL"
|
||||||
icon-left="check"
|
icon-left="arrow-right"
|
||||||
@click="alert('TODO: redirect to table view')">
|
:text="`Show me my new table: ${'$'}{tableName}`">
|
||||||
Code changes are committed!
|
</once-button>
|
||||||
</b-button>
|
|
||||||
</div>
|
</div>
|
||||||
</b-step-item>
|
</b-step-item>
|
||||||
</b-steps>
|
</b-steps>
|
||||||
|
@ -530,9 +636,9 @@
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
ThisPageData.activeStep = null
|
ThisPageData.activeStep = null
|
||||||
ThisPageData.branchOptions = ${json.dumps(branch_name_options)|n}
|
ThisPageData.alembicBranchOptions = ${json.dumps(branch_name_options)|n}
|
||||||
|
|
||||||
ThisPageData.tableBranch = ${json.dumps(branch_name)|n}
|
ThisPageData.alembicBranch = ${json.dumps(branch_name)|n}
|
||||||
ThisPageData.tableName = '${rattail_app.get_table_prefix()}_widget'
|
ThisPageData.tableName = '${rattail_app.get_table_prefix()}_widget'
|
||||||
ThisPageData.tableModelName = '${rattail_app.get_class_prefix()}Widget'
|
ThisPageData.tableModelName = '${rattail_app.get_class_prefix()}Widget'
|
||||||
ThisPageData.tableModelTitle = 'Widget'
|
ThisPageData.tableModelTitle = 'Widget'
|
||||||
|
@ -620,7 +726,7 @@
|
||||||
|
|
||||||
let url = '${url('{}.write_model_file'.format(route_prefix))}'
|
let url = '${url('{}.write_model_file'.format(route_prefix))}'
|
||||||
let params = {
|
let params = {
|
||||||
branch_name: this.tableBranch,
|
branch_name: this.alembicBranch,
|
||||||
table_name: this.tableName,
|
table_name: this.tableName,
|
||||||
model_name: this.tableModelName,
|
model_name: this.tableModelName,
|
||||||
model_title: this.tableModelTitle,
|
model_title: this.tableModelTitle,
|
||||||
|
@ -662,10 +768,65 @@
|
||||||
} else {
|
} else {
|
||||||
this.modelImportProblem = false
|
this.modelImportProblem = false
|
||||||
this.modelImported = true
|
this.modelImported = true
|
||||||
|
this.revisionMessage = `add table for ${'$'}{this.tableModelTitlePlural}`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThisPageData.writingRevisionScript = false
|
||||||
|
ThisPageData.revisionMessage = null
|
||||||
|
ThisPageData.revisionScript = null
|
||||||
|
|
||||||
|
ThisPage.methods.writeRevisionScript = function() {
|
||||||
|
this.writingRevisionScript = true
|
||||||
|
|
||||||
|
let url = '${url('{}.write_revision_script'.format(route_prefix))}'
|
||||||
|
let params = {
|
||||||
|
branch: this.alembicBranch,
|
||||||
|
message: this.revisionMessage,
|
||||||
|
}
|
||||||
|
this.submitForm(url, params, response => {
|
||||||
|
this.writingRevisionScript = false
|
||||||
|
this.revisionScript = response.data.script
|
||||||
|
this.activeStep = 'review-revision'
|
||||||
|
}, response => {
|
||||||
|
this.writingRevisionScript = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPageData.upgradingDB = false
|
||||||
|
|
||||||
|
ThisPage.methods.upgradeDB = function() {
|
||||||
|
this.upgradingDB = true
|
||||||
|
|
||||||
|
let url = '${url('{}.upgrade_db'.format(route_prefix))}'
|
||||||
|
let params = {}
|
||||||
|
this.submitForm(url, params, response => {
|
||||||
|
this.upgradingDB = false
|
||||||
|
this.activeStep = 'review-db'
|
||||||
|
}, response => {
|
||||||
|
this.upgradingDB = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPageData.tableCheckAttempted = false
|
||||||
|
ThisPageData.tableCheckProblem = null
|
||||||
|
|
||||||
|
ThisPageData.tableURL = null
|
||||||
|
|
||||||
|
ThisPage.methods.tableCheck = function() {
|
||||||
|
let url = '${url('{}.check_table'.format(route_prefix))}'
|
||||||
|
let params = {table_name: this.tableName}
|
||||||
|
this.submitForm(url, params, response => {
|
||||||
|
if (response.data.problem) {
|
||||||
|
this.tableCheckProblem = response.data.problem
|
||||||
|
} else {
|
||||||
|
this.tableURL = response.data.url
|
||||||
|
}
|
||||||
|
this.tableCheckAttempted = true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</%def>
|
</%def>
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@ import warnings
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
|
||||||
|
from rattail.util import simple_error
|
||||||
|
|
||||||
import colander
|
import colander
|
||||||
from deform import widget as dfwidget
|
from deform import widget as dfwidget
|
||||||
from webhelpers2.html import HTML
|
from webhelpers2.html import HTML
|
||||||
|
@ -111,6 +113,13 @@ class TableView(MasterView):
|
||||||
# row_count
|
# row_count
|
||||||
g.sorters['row_count'] = g.make_simple_sorter('row_count')
|
g.sorters['row_count'] = g.make_simple_sorter('row_count')
|
||||||
|
|
||||||
|
def configure_form(self, f):
|
||||||
|
super(TableView, self).configure_form(f)
|
||||||
|
|
||||||
|
# TODO: should render this instead, by inspecting table
|
||||||
|
if not self.creating:
|
||||||
|
f.remove('versioned')
|
||||||
|
|
||||||
def get_instance(self):
|
def get_instance(self):
|
||||||
from sqlalchemy_utils import get_mapper
|
from sqlalchemy_utils import get_mapper
|
||||||
|
|
||||||
|
@ -205,6 +214,37 @@ class TableView(MasterView):
|
||||||
|
|
||||||
return {'ok': True}
|
return {'ok': True}
|
||||||
|
|
||||||
|
def write_revision_script(self):
|
||||||
|
data = self.request.json_body
|
||||||
|
script = self.db_handler.generate_revision_script(data['branch'],
|
||||||
|
message=data['message'])
|
||||||
|
return {'ok': True,
|
||||||
|
'script': script.path}
|
||||||
|
|
||||||
|
def upgrade_db(self):
|
||||||
|
self.db_handler.upgrade_db()
|
||||||
|
return {'ok': True}
|
||||||
|
|
||||||
|
def check_table(self):
|
||||||
|
model = self.model
|
||||||
|
data = self.request.json_body
|
||||||
|
table_name = data['table_name']
|
||||||
|
|
||||||
|
table = model.Base.metadata.tables.get(table_name)
|
||||||
|
if table is None:
|
||||||
|
return {'ok': True,
|
||||||
|
'problem': "Table does not exist in model metadata!"}
|
||||||
|
|
||||||
|
try:
|
||||||
|
count = self.Session.query(table).count()
|
||||||
|
except Exception as error:
|
||||||
|
return {'ok': True,
|
||||||
|
'problem': simple_error(error)}
|
||||||
|
|
||||||
|
url = self.request.route_url('{}.view'.format(self.get_route_prefix()),
|
||||||
|
table_name=table_name)
|
||||||
|
return {'ok': True, 'url': url}
|
||||||
|
|
||||||
def get_row_data(self, table):
|
def get_row_data(self, table):
|
||||||
data = []
|
data = []
|
||||||
for i, column in enumerate(table['table'].columns, 1):
|
for i, column in enumerate(table['table'].columns, 1):
|
||||||
|
@ -237,6 +277,7 @@ class TableView(MasterView):
|
||||||
g.sorters['nullable'] = g.make_simple_sorter('nullable')
|
g.sorters['nullable'] = g.make_simple_sorter('nullable')
|
||||||
|
|
||||||
g.set_renderer('description', self.render_column_description)
|
g.set_renderer('description', self.render_column_description)
|
||||||
|
g.set_searchable('description')
|
||||||
|
|
||||||
def render_column_description(self, column, field):
|
def render_column_description(self, column, field):
|
||||||
text = column[field]
|
text = column[field]
|
||||||
|
@ -287,6 +328,33 @@ class TableView(MasterView):
|
||||||
renderer='json',
|
renderer='json',
|
||||||
permission='{}.create'.format(permission_prefix))
|
permission='{}.create'.format(permission_prefix))
|
||||||
|
|
||||||
|
# generate revision script
|
||||||
|
config.add_route('{}.write_revision_script'.format(route_prefix),
|
||||||
|
'{}/write-revision-script'.format(url_prefix),
|
||||||
|
request_method='POST')
|
||||||
|
config.add_view(cls, attr='write_revision_script',
|
||||||
|
route_name='{}.write_revision_script'.format(route_prefix),
|
||||||
|
renderer='json',
|
||||||
|
permission='{}.create'.format(permission_prefix))
|
||||||
|
|
||||||
|
# upgrade db
|
||||||
|
config.add_route('{}.upgrade_db'.format(route_prefix),
|
||||||
|
'{}/upgrade-db'.format(url_prefix),
|
||||||
|
request_method='POST')
|
||||||
|
config.add_view(cls, attr='upgrade_db',
|
||||||
|
route_name='{}.upgrade_db'.format(route_prefix),
|
||||||
|
renderer='json',
|
||||||
|
permission='{}.create'.format(permission_prefix))
|
||||||
|
|
||||||
|
# check table
|
||||||
|
config.add_route('{}.check_table'.format(route_prefix),
|
||||||
|
'{}/check-table'.format(url_prefix),
|
||||||
|
request_method='POST')
|
||||||
|
config.add_view(cls, attr='check_table',
|
||||||
|
route_name='{}.check_table'.format(route_prefix),
|
||||||
|
renderer='json',
|
||||||
|
permission='{}.create'.format(permission_prefix))
|
||||||
|
|
||||||
|
|
||||||
class TablesView(TableView):
|
class TablesView(TableView):
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue