Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 56 additions & 51 deletions ckanext/in_app_reporting/assets/css/in_app_reporting.css
Original file line number Diff line number Diff line change
@@ -1,63 +1,68 @@
label.control-label[for="field-entity_id"] {
font-size: 18px;
.select2-results .select2-result-label {
padding: 6px 16px;
}
.selectorContainer {
font-weight: 400;
font-size: 14px;
width: 100%;
}
.selectorContainer.select2-container--default .select2-selection--single .select2-selection__placeholder {
font-weight: 400;
font-size: 13px;
color: #666;
}
.selectorContainer.select2-container .select2-choice {
background-color: white;
background-image: none;
}
.selectorContainer input {
margin-bottom: 0;
}
.selectorContainer input:placeholder {
font-size: 11px;
}
.selectorContainer .select2-search {
padding: 0 20px;
}
.selectorContainer.select2-drop {
padding-top: 10px;
}
.selectorContainer .select2-results {
padding-top: 10px;
}
.selectorContainer .select2-results .select2-highlighted {
background: rgb(224, 242, 255);
.select2-results .select2-highlighted {
background-color: #f2f2f2;
color: #000;
}
.metabase-result {
display: block;
padding: 8px 8px 8px 12px;
}
.metabase-result .icon-og-stories {
color: #3192c7;
font-size: 20px;
vertical-align: -3px;
}
.select2-highlighted .icon-og-stories {
color: #fff;
}
.metabase-result .name {
.metabase-result .title {
display: inline-block;
padding-left: 10px;
font-size: 14px;
color: #000;
}
.metabase-result .modified {
display: inline-block;
font-size: 12px;
float: right;
text-align: left;
min-width: 120px;
opacity: .6;
font-size: 12px;
color: #858585;
}

/* Mobile responsive styles for metabase results */
@media (max-width: 1280px) {
.metabase-result .title {
display: block;
margin-bottom: 4px;
}
.metabase-result .modified {
display: block;
float: none;
text-align: left;
min-width: auto;
}
}

/* Loading spinner styles */
.loading-spinner {
display: flex;
align-items: center;
padding: 10px 0;
color: #666;
}
.spinner-circle {
width: 20px;
height: 20px;
border: 3px solid #dddede;
border-top: 3px solid #4b3fff;
border-right: 3px solid #4b3fff;
border-radius: 50%;
animation: spin 650ms linear 0s infinite normal none running;
margin-right: 10px;
flex-shrink: 0;
}
.loading-text {
font-size: 14px;
color: #546574;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

/* Chart selection states */
#chart-loading, #chart-selection, #chart-error {
transition: opacity 0.3s ease-in-out;
}

div[data-module="resource-view-filters-form"] {
display: none;
}
12 changes: 10 additions & 2 deletions ckanext/in_app_reporting/assets/js/card_form.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
globalThis.cardId = null;
ckan.module('get-metabase-collection-items', function (jQuery) {
ckan.module('get-metabase-chart-list', function (jQuery) {
return {
initialize: function () {
const that = this;
Expand All @@ -9,11 +9,19 @@ ckan.module('get-metabase-collection-items', function (jQuery) {
$.getJSON(this.options.source, function (data) {
that.collection_items = data.results;
that.setup();
// Hide spinner and show select2 dropdown
$('#chart-loading').hide();
$('#chart-selection').show();
}).fail(function() {
// Show error state if loading fails
$('#chart-loading').hide();
$('#chart-selection').show();
$('#chart-error').show();
});
},

formatResult: function (result) {
var date = (new Date(result['last-edit-info']['timestamp']));
var date = (new Date(result['updated_at']));
var markup = "<div class='metabase-result'><span class='title'>" + result.name + "</span><span class='modified'>Modified " + date.toLocaleString() + "</span></div>";
return markup;
},
Expand Down
27 changes: 27 additions & 0 deletions ckanext/in_app_reporting/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,27 @@ def get_metabase_collection_items(model_type):
except tk.NotAuthorized:
tk.abort(404, tk._(u'Resource not found'))

def chart_list(resource_id):
if not utils.is_metabase_sso_user(tk.g.userobj):
tk.abort(404, tk._(u'Resource not found'))
try:
context = {
u'model': model,
u'user': tk.g.user,
u'auth_user_obj': tk.g.userobj
}
tk.check_access('metabase_embed', context, {})
resource = tk.get_action('resource_show')(None, {'id': resource_id})

table_id = utils.get_metabase_table_id(resource_id)
chart_list = utils.get_metabase_chart_list(table_id, resource_id)
data = {
'results': chart_list
}
return data
except (tk.ObjectNotFound, tk.NotAuthorized):
tk.abort(404, tk._('Resource not found'))


metabase.add_url_rule(
u'/insights',
Expand Down Expand Up @@ -204,3 +225,9 @@ def get_metabase_collection_items(model_type):
view_func=MetabaseView.get_metabase_collection_items,
methods=[u'GET']
)

metabase.add_url_rule(
u'/metabase/chart_list/<resource_id>',
view_func=MetabaseView.chart_list,
methods=[u'GET']
)
54 changes: 37 additions & 17 deletions ckanext/in_app_reporting/templates/metabase/card_form.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,43 @@
{% if h.is_metabase_sso_user(g.userobj) %}
<div class="row">
<div class="span12 col-md-12">
{% set
entity_id_attrs = {
'data-module': 'get-metabase-collection-items',
'data-module-source': '/metabase/collection_items_list/card',
'data-embeddable': embeddable_cards
}
%}
{{ form.input(
'entity_id',
id='field-entity_id',
label=_('Chart'),
value=data.entity_id,
error=errors.entity_id,
is_required=true,
classes=['control-full'],
attrs=entity_id_attrs
) }}
<!-- Loading state -->
<div id="chart-loading" class="control-group">
<label class="control-label">{{ _('Chart') }}</label>
<div class="controls">
<div class="loading-spinner">
<div class="spinner-circle"></div>
<span class="loading-text">{{ _('Loading Charts') }}</span>
</div>
</div>
</div>

<!-- Chart selection input (initially hidden) -->
<div id="chart-selection" style="display:none;">
{% set
entity_id_attrs = {
'data-module': 'get-metabase-chart-list',
'data-module-source': '/metabase/chart_list/' + resource.id,
'data-embeddable': embeddable_cards
}
%}
{{ form.input(
'entity_id',
id='field-entity_id',
label=_('Chart'),
value=data.entity_id,
error=errors.entity_id,
is_required=true,
classes=['control-full'],
attrs=entity_id_attrs
) }}
</div>

<!-- Error state (initially hidden) -->
<div id="chart-error" class="alert alert-error" style="display:none;">
<p>{{ _('Failed to load charts.') }}</p>
</div>

<div id="publish-warning" class="alert fade in alert-warning" style="display:none"></div>
{{ form.checkbox(
'bordered',
Expand Down
Loading