return async function(dispatch, getState) { if (databaseId) { try { const action = await dispatch( Databases.actions.fetch({ id: databaseId }, { reload: true }), ); const database = Databases.HACK_getObjectFromAction(action); dispatch.action(INITIALIZE_DATABASE, database); // If the new scheduling toggle isn't set, run the migration if (database.details["let-user-control-scheduling"] == undefined) { dispatch(migrateDatabaseToNewSchedulingSettings(database)); } } catch (error) { if (error.status == 404) { //$location.path('/admin/databases/'); } else { console.error("error fetching database", databaseId, error); } } } else { const newDatabase = { name: "", engine: Object.keys(MetabaseSettings.get("engines"))[0], details: {}, created: false, }; dispatch.action(INITIALIZE_DATABASE, newDatabase); } };
return async function(dispatch, getState) { if (databaseId) { try { const database = await MetabaseApi.db_get({"dbId": databaseId}); dispatch.action(INITIALIZE_DATABASE, database) // If the new scheduling toggle isn't set, run the migration if (database.details["let-user-control-scheduling"] == undefined) { dispatch(migrateDatabaseToNewSchedulingSettings(database)) } } catch (error) { if (error.status == 404) { //$location.path('/admin/databases/'); } else { console.error("error fetching database", databaseId, error); } } } else { const newDatabase = { name: '', engine: Object.keys(MetabaseSettings.get('engines'))[0], details: {}, created: false } dispatch.action(INITIALIZE_DATABASE, newDatabase); } }
export default ({ question, clicked }: ClickActionProps): ClickAction[] => { const query = question.query(); if (!(query instanceof StructuredQuery)) { return []; } // questions with a breakout const dimensions = (clicked && clicked.dimensions) || []; if ( !clicked || dimensions.length === 0 || // xrays must be enabled for this to work !MetabaseSettings.get("enable_xrays") ) { return []; } return [ { name: "compare-dashboard", section: "auto", icon: "bolt", title: t`Compare to the rest`, url: () => { const filters = query .clearFilters() // clear existing filters so we don't duplicate them .question() .drillUnderlyingRecords(dimensions) .query() .filters(); return question.getComparisonDashboardUrl(filters); }, }, ]; };
DatabasesControllers.controller('DatabaseList', ['$scope', '$routeParams', 'Metabase', function($scope, $routeParams, Metabase) { $scope.DatabaseList = DatabaseList; $scope.databases = []; $scope.hasSampleDataset = false; $scope.created = $routeParams['created']; function hasSampleDataset(databases) { for (let i=0; i < databases.length; i++) { if (databases[i].is_sample) return true; } return false; } $scope.delete = function(databaseId) { if ($scope.databases) { Metabase.db_delete({ 'dbId': databaseId }, function(result) { $scope.databases = _.filter($scope.databases, function(database) { return database.id != databaseId; }); $scope.hasSampleDataset = hasSampleDataset($scope.databases); MetabaseAnalytics.trackEvent("Databases", "Delete", "Using List"); }, function(error) { console.log('error deleting database', error); }); } }; $scope.addSampleDataset = function() { if (!hasSampleDataset($scope.databases)) { Metabase.db_add_sample_dataset().$promise.then(function(result) { $scope.databases.push(result); $scope.hasSampleDataset = true; MetabaseAnalytics.trackEvent("Databases", "Add Sample Data"); }, function(error) { console.log('error adding sample dataset', error); }); } }; $scope.engines = MetabaseSettings.get('engines'); // fetch DBs from the backend Metabase.db_list(function(databases) { $scope.databases = databases; $scope.hasSampleDataset = hasSampleDataset(databases); }, function(error) { console.log('error getting database list', error); }); }]);
$rootScope.$on("appstate:site-settings", function(event, settings) { const ga_code = MetabaseSettings.get('ga_code'); if (MetabaseSettings.isTrackingEnabled()) { // we are doing tracking window['ga-disable-'+ga_code] = null; } else { // tracking is disabled window['ga-disable-'+ga_code] = true; } });
trackEvent: function(category: string, action?: string, label?: string, value?: number) { const { tag } = MetabaseSettings.get('version'); // category & action are required, rest are optional if (category && action) { // $FlowFixMe ga('set', 'dimension1', tag); ga('send', 'event', category, action, label, value); } if (DEBUG) { console.log("trackEvent", { category, action, label, value }); } }
trackPageView: function(url: string) { if (url) { // scrub query builder urls to remove serialized json queries from path url = url.lastIndexOf("/q/", 0) === 0 ? "/q/" : url; const { tag } = MetabaseSettings.get("version"); // $FlowFixMe ga("set", "dimension1", tag); ga("set", "page", url); ga("send", "pageview", url); } },
trackPageView: function(url: string) { if (url) { // scrub query builder urls to remove serialized json queries from path url = (url.lastIndexOf('/q/', 0) === 0) ? '/q/' : url; const { tag } = MetabaseSettings.get('version'); // $FlowFixMe ga('set', 'dimension1', tag); ga('set', 'page', url); ga('send', 'pageview', url); } },
export function getGlobalSettingsForColumn(column: Column) { let settings = {}; const customFormatting = MetabaseSettings.get("custom-formatting"); // NOTE: the order of these doesn't matter as long as there's no overlap between settings for (const [type, globalSettings] of Object.entries(customFormatting || {})) { if (isa(column.special_type, type)) { // $FlowFixMe Object.assign(settings, globalSettings); } } return settings; }
trackEvent: function( category: string, action?: ?string, label?: ?(string | number | boolean), value?: ?number, ) { const { tag } = MetabaseSettings.get("version"); // category & action are required, rest are optional if (category && action) { // $FlowFixMe ga("set", "dimension1", tag); ga("send", "event", category, action, label, value); } if (DEBUG) { console.log("trackEvent", { category, action, label, value }); } },
return async function(dispatch, getState) { if (databaseId) { try { return await MetabaseApi.db_get({"dbId": databaseId}); } catch (error) { if (error.status == 404) { //$location.path('/admin/databases/'); } else { console.log("error fetching database", databaseId, error); } } } else { return { name: '', engine: Object.keys(MetabaseSettings.get('engines'))[0], details: {}, created: false }; } }
function($scope, $routeParams, $location, Metabase) { $scope.DatabaseEdit = DatabaseEdit; // if we're adding a new database then hide the SSL field; we'll determine it automatically <3 $scope.hiddenFields = { ssl: true }; $scope.selectEngine = function(engine) { $scope.details.engine = $scope.database.engine = engine; }; // update an existing Database var update = function(database, details) { $scope.$broadcast("form:reset"); database.details = details; return Metabase.db_update(database).$promise.then(function(updated_database) { $scope.database = updated_database; $scope.$broadcast("form:api-success", "Successfully saved!"); MetabaseAnalytics.trackEvent("Databases", "Update", database.engine); }, function(error) { $scope.$broadcast("form:api-error", error); MetabaseAnalytics.trackEvent("Databases", "Update Failed", database.engine); throw error; }); }; // create a new Database var create = function(database, details) { $scope.$broadcast("form:reset"); database.details = details; return Metabase.db_create(database).$promise.then(function(new_database) { $scope.$broadcast("form:api-success", "Successfully created!"); $scope.$emit("database:created", new_database); MetabaseAnalytics.trackEvent("Databases", "Create", database.engine); $location.url('/admin/databases?created'); }, function(error) { $scope.$broadcast("form:api-error", error); MetabaseAnalytics.trackEvent("Databases", "Create Failed", database.engine); throw error; }); }; var save = function(database, details) { if ($routeParams.databaseId) { return update(database, details); } else { return create(database, details); } }; $scope.save = save; $scope.sync = function() { var call = Metabase.db_sync_metadata({ 'dbId': $scope.database.id }); MetabaseAnalytics.trackEvent("Databases", "Manual Sync"); return call.$promise; }; $scope.delete = function() { Metabase.db_delete({ 'dbId': $scope.database.id }, function(result) { MetabaseAnalytics.trackEvent("Databases", "Delete", "Using Detail"); $location.path('/admin/databases/'); }, function(error) { console.log('error deleting database', error); }); }; $scope.redirectToDatabases = function() { $scope.$apply(() => $location.path('/admin/databases/')); }; function loadExistingDB() { // load existing database for editing Metabase.db_get({ 'dbId': $routeParams.databaseId }, function(database) { $scope.hiddenFields = null; $scope.database = database; $scope.details = database.details; }, function(error) { console.log('error loading database', error); if (error.status == 404) { $location.path('/admin/databases/'); } }); } function prepareEmptyDB() { // prepare an empty database for creation $scope.database = { name: '', engine: Object.keys($scope.engines)[0], details: {}, created: false }; $scope.details = {}; } $scope.engines = MetabaseSettings.get('engines'); if ($routeParams.databaseId) { loadExistingDB(); } else { prepareEmptyDB(); } }
export function publicQuestion(uuid, type = null) { const siteUrl = MetabaseSettings.get("site_url"); return `${siteUrl}/public/question/${uuid}` + (type ? `.${type}` : ``); }
getHidden: () => MetabaseSettings.get("available_locales").length < 2,
key: "site-url", display_name: t`Site URL`, type: "string", }, { key: "admin-email", display_name: t`Email Address for Help Requests`, type: "string", }, { key: "report-timezone", display_name: t`Report Timezone`, type: "select", options: [ { name: t`Database Default`, value: "" }, ...MetabaseSettings.get("timezones"), ], placeholder: t`Select a timezone`, note: t`Not all databases support timezones, in which case this setting won't take effect.`, allowValueCollection: true, }, { key: "site-locale", display_name: t`Language`, type: "select", options: (MetabaseSettings.get("available_locales") || []).map( ([value, name]) => ({ name, value }), ), placeholder: t`Select a language`, getHidden: () => MetabaseSettings.get("available_locales").length < 2, },
MetabaseSettings.on("anon_tracking_enabled", () => { window['ga-disable-' + MetabaseSettings.get('ga_code')] = MetabaseSettings.isTrackingEnabled() ? null : true; });
key: "-site-url", display_name: "Site URL", type: "string" }, { key: "admin-email", display_name: "Email Address for Help Requests", type: "string" }, { key: "report-timezone", display_name: "Report Timezone", type: "select", options: [ { name: "Database Default", value: "" }, ...MetabaseSettings.get('timezones') ], placeholder: "Select a timezone", note: "Not all databases support timezones, in which case this setting won't take effect." }, { key: "anon-tracking-enabled", display_name: "Anonymous Tracking", type: "boolean" }, { key: "enable-advanced-humanization", display_name: "Friendly Table and Field Names", type: "boolean" }, {
export function publicDashboard(uuid) { const siteUrl = MetabaseSettings.get("site_url"); return `${siteUrl}/public/dashboard/${uuid}`; }