Initial commit

This commit is contained in:
zhongjin
2020-06-15 10:58:47 +08:00
commit 4f1dfe7564
8590 changed files with 1516878 additions and 0 deletions
@@ -0,0 +1,64 @@
export function fetch (fetchFunctionName) {
return function (context) {
const { api_key: apiKey } = context.rootState.user;
context.commit('setFetchingState');
context.rootState.client[fetchFunctionName](apiKey, function (err, _, data) {
if (err) {
const error = data.responseJSON && data.responseJSON.errors ||
{ message: data.responseText || data.statusText };
context.commit('setRequestError', error);
return;
}
context.commit('setApps', data.result);
});
};
}
export function createOAuth (context, app) {
const { api_key: apiKey } = context.rootState.user;
return new Promise((resolve, reject) => {
context.rootState.client.createApp(apiKey, app, function (err, _, data) {
if (err) {
const error = data.responseJSON && data.responseJSON.errors ||
{ message: data.responseText || data.statusText };
return reject(error);
}
context.commit('addApp', data);
resolve(data);
});
});
}
export function updateOAuth (context, app) {
const { api_key: apiKey } = context.rootState.user;
return new Promise((resolve, reject) => {
context.rootState.client.updateApp(apiKey, app, function (err, _, data) {
if (err) {
const error = data.responseJSON && data.responseJSON.errors ||
{ message: data.responseText || data.statusText };
return reject(error);
}
context.commit('updateOAuthApp', data);
resolve(data);
});
});
}
export function regenerateCredentials (context, app) {
const { api_key: apiKey } = context.rootState.user;
context.rootState.client.regenerateClientSecret(apiKey, app, function (err, _, data) {
if (err) {
context.commit('setRequestError', [data.responseText]);
return;
}
context.commit('updateOAuthApp', data);
});
}
@@ -0,0 +1,188 @@
export function fetchCategories (context) {
context.commit('setFetchingState');
/* Using SQL API with observatory account
https://{username}.carto.com/api/v2/sql?q={SQL statement} */
const CONFIG_PATH = [`api/v2/sql?q=`];
const q = `SELECT
DISTINCT category
FROM carto_do_catalog_master_datasets
WHERE include_in_public_web = true`;
const PATH = CONFIG_PATH + q;
const opts = {
baseUrl: 'https://observatory.carto.com',
doNoSetDefaultContentType: true
};
return new Promise((resolve, reject) => {
context.rootState.client.get([PATH], opts, function (err, _, data) {
if (err) {
context.commit('setRequestError', err);
return reject(err);
}
context.commit('setCategories', data.rows);
resolve();
});
});
}
export function fetchCountries (context, category) {
context.commit('setFetchingState');
/* Using SQL API with observatory account
https://{username}.carto.com/api/v2/sql?q={SQL statement} */
const CONFIG_PATH = [`api/v2/sql?q=`];
const q = `SELECT
country
FROM carto_do_catalog_master_datasets
WHERE category='${category}'
and include_in_public_web = true
GROUP BY country
ORDER BY country ASC`;
const PATH = CONFIG_PATH + q;
const opts = {
baseUrl: 'https://observatory.carto.com',
doNoSetDefaultContentType: true
};
return new Promise((resolve, reject) => {
context.rootState.client.get([PATH], opts, function (err, _, data) {
if (err) {
context.commit('setRequestError', err);
return reject(err);
}
context.commit('setCountries', data.rows);
resolve();
});
});
}
export function fetchDatasets (context, params) {
context.commit('setFetchingState');
/* Using SQL API with observatory account
https://{username}.carto.com/api/v2/sql?q={SQL statement} */
const CONFIG_PATH = [`api/v2/sql?q=`];
const q = `SELECT dataset AS name,
category,
description,
country,
ARRAY_AGG(DISTINCT spatial_aggregations) AS spatial_aggregations,
ARRAY_AGG(DISTINCT temporal_aggregations) AS frequency,
ARRAY_AGG(DISTINCT provider) AS source,
ARRAY_AGG(DISTINCT variable_name) AS variable_name,
MIN(cartodb_id) AS id
FROM carto_do_catalog_master_datasets
WHERE category='${params.category}'
and country='${params.country}'
and include_in_public_web = true
GROUP BY(dataset, category, country, description)`;
const PATH = CONFIG_PATH + q;
const opts = {
baseUrl: 'https://observatory.carto.com',
doNoSetDefaultContentType: true
};
return new Promise((resolve, reject) => {
context.rootState.client.get([PATH], opts, function (err, _, data) {
if (err) {
context.commit('setRequestError', err);
return reject(err);
}
context.commit('setDatasets', data.rows);
context.commit('setPagination', context.state.page);
resolve();
});
});
}
export function setURLOptions (context, options) {
context.commit('setPagination', parseInt(options.page || 1));
context.commit('setOrder', { order: options.order, direction: options.order_direction });
}
export function order (context, orderOptions) {
context.commit('setPagination', 1);
context.commit('setOrder', orderOptions);
context.commit('orderDatasets');
}
export function clearList (context) {
context.commit('setDatasets', []);
context.commit('setPagination', 1);
}
export function requestDataset (context, { user, dataset }) {
/* Using V3 hubspot API
https://api.hsforms.com/submissions/v3/integration/submit/:portalId/:formGuid */
const hubspot_id = '474999';
const form_id = '507ead6f-06d9-434a-95e1-a9616c576796';
const CONFIG_PATH = [`submissions/v3/integration/submit/${hubspot_id}/${form_id}`];
const data = getFormData(user, dataset);
const opts = {
data,
baseUrl: 'https://api.hsforms.com'
};
return new Promise((resolve, reject) => {
context.rootState.client.post([CONFIG_PATH], opts, function (err, _, data) {
if (err) {
return reject(err);
}
resolve();
});
});
}
function getFormData (user, dataset) {
return JSON.stringify({
'fields': [
{
'name': 'email',
'value': user.email
},
{
'name': 'lastname',
'value': user.last_name || 'no_last_name'
},
{
'name': 'firstname',
'value': user.name || 'no_firstname'
},
{
'name': 'jobtitle',
'value': user.job_role || 'no_jobtitle'
},
{
'name': 'company',
'value': user.company || 'no_company'
},
{
'name': 'phone',
'value': user.phone || 'no_phone'
},
{
'name': 'country_data',
'value': dataset.country
},
{
'name': 'data_category',
'value': dataset.category
},
{
'name': 'datastream_name',
'value': dataset.name
},
{
'name': 'data_purpose',
'value': 'no_data_purpose'
}
],
'context': {
'pageUri': 'www.carto.com/dashboard/catalog',
'pageName': 'Catalog page in Dashboard'
}
});
}
@@ -0,0 +1,118 @@
export function deleteLike (context, visualization) {
const currentLikeStatus = visualization.liked;
context.dispatch('updateVisualization', {
visualizationId: visualization.id,
visualizationAttributes: {
liked: false
}
});
context.rootState.client.deleteLike(visualization.id,
function (err, _, data) {
if (err) {
context.dispatch('updateVisualization', {
visualizationId: visualization.id,
visualizationAttributes: {
liked: currentLikeStatus
}
});
return;
}
context.commit('updateNumberLikes', {
visualizationId: visualization.id,
visualizationAttributes: {
liked: data.liked
}
});
}
);
}
export function fetchVisualizations (context, parameters) {
context.commit('setFetchingState');
context.rootState.client.getVisualization('',
parameters,
function (err, _, data) {
if (err) {
context.commit('setRequestError', err);
return;
}
context.commit('setVisualizations', data);
context.commit('setPagination', context.state.page);
});
}
export function filter (context, filter) {
context.commit('setPagination', 1);
context.commit('setFilterType', filter);
context.dispatch('fetch');
}
export function like (context, visualization) {
const currentLikeStatus = visualization.liked;
context.dispatch('updateVisualization', {
visualizationId: visualization.id,
visualizationAttributes: {
liked: true
}
});
context.rootState.client.like(visualization.id,
function (err, _, data) {
if (err) {
context.dispatch('updateVisualization', {
visualizationId: visualization.id,
visualizationAttributes: {
liked: currentLikeStatus
}
});
return;
}
context.commit('updateNumberLikes', {
visualizationId: visualization.id,
visualizationAttributes: {
liked: data.liked
}
});
}
);
}
export function order (context, orderOptions) {
context.commit('setPagination', 1);
context.commit('setOrder', orderOptions);
context.dispatch('fetch');
}
export function resetFilters (DEFAULT_VALUES) {
return function (context) {
context.commit('setPagination', 1);
context.commit('setFilterType', 'mine');
context.commit('setResultsPerPage', 12);
context.commit('setOrder', { order: DEFAULT_VALUES.order, direction: DEFAULT_VALUES.orderDirection });
};
}
export function setResultsPerPage (context, perPage) {
context.commit('setResultsPerPage', perPage);
}
export function setURLOptions (context, options) {
context.commit('setPagination', parseInt(options.page || 1));
context.commit('setFilterType', options.filter);
context.commit('setOrder', { order: options.order, direction: options.order_direction });
context.dispatch('fetch');
}
export function updateVisualization (context, visualizationOptions) {
context.commit('maps/updateVisualization', visualizationOptions, { root: true });
context.commit('datasets/updateVisualization', visualizationOptions, { root: true });
context.commit('recentContent/updateVisualization', visualizationOptions, { root: true });
context.commit('search/updateVisualization', visualizationOptions, { root: true });
}
@@ -0,0 +1,38 @@
import Vue from 'vue';
import Vuex from 'vuex';
import CartoNode from 'carto-node';
// Store Modules
import user from './modules/user';
import config from './modules/config';
import maps from './modules/maps';
import datasets from './modules/data/datasets';
import catalog from './modules/data/catalog';
import search from './modules/search';
import notifications from './modules/notifications';
import recentContent from './modules/recent-content';
import oAuthApps from './modules/apps/oAuth';
import connectedApps from './modules/apps/connected';
Vue.use(Vuex);
const storeOptions = {
state: {
client: new CartoNode.AuthenticatedClient()
},
getters: {},
modules: {
config,
user,
maps,
datasets,
catalog,
search,
notifications,
recentContent,
oAuthApps,
connectedApps
}
};
export default new Vuex.Store(storeOptions);
@@ -0,0 +1,37 @@
import * as AppsMutations from '../../../mutations/apps';
import * as AppsActions from '../../../actions/apps';
const connectedApps = {
namespaced: true,
state: {
isFetching: false,
isErrored: false,
error: [],
list: {}
},
computed: {},
getters: {},
mutations: {
setApps: AppsMutations.setApps,
setRequestError: AppsMutations.setRequestError,
setFetchingState: AppsMutations.setFetchingState
},
actions: {
fetch: AppsActions.fetch('getConnectedApps'),
revoke (context, app) {
const { api_key: apiKey } = context.rootState.user;
return new Promise((resolve, reject) => {
context.rootState.client.revokeOAuthApp(apiKey, app, function (err, _, data) {
if (err) {
return reject(data.responseJSON.errors);
}
resolve();
});
});
}
}
};
export default connectedApps;
@@ -0,0 +1,43 @@
import * as AppsMutations from '../../../mutations/apps';
import * as AppsActions from '../../../actions/apps';
const oAuthApps = {
namespaced: true,
state: {
isFetching: false,
isErrored: false,
error: [],
list: {}
},
computed: {},
getters: {},
mutations: {
setApps: AppsMutations.setApps,
addApp: AppsMutations.addApp,
setFetchingState: AppsMutations.setFetchingState,
setRequestError: AppsMutations.setRequestError,
updateOAuthApp: AppsMutations.updateOAuthApp
},
actions: {
fetch: AppsActions.fetch('getOAuthApps'),
create: AppsActions.createOAuth,
update: AppsActions.updateOAuth,
setApps: AppsMutations.setApps,
regenerateCredentials: AppsActions.regenerateCredentials,
delete (context, app) {
const { api_key: apiKey } = context.rootState.user;
return new Promise((resolve, reject) => {
context.rootState.client.deleteApp(apiKey, app, function (err, _, data) {
if (err) {
return reject(data.responseJSON.errors);
}
resolve();
});
});
}
}
};
export default oAuthApps;
@@ -0,0 +1,24 @@
import getCARTOData from 'new-dashboard/store/utils/getCARTOData';
// Data coming from Static Page Loading,
// which requests user and config data from
// /me API endpoint.
const CARTOData = getCARTOData();
const CARTOUserData = CARTOData.user_data;
const config = {
namespaced: true,
state: {
...CARTOData.config,
base_url: CARTOUserData.base_url,
default_fallback_basemap: CARTOData.default_fallback_basemap,
isFirstTimeViewingDashboard: CARTOData.is_first_time_viewing_dashboard,
url_prefix: CARTOUserData.base_url,
plan_url: CARTOData.plan_url
},
getters: {},
mutations: {},
actions: {}
};
export default config;
@@ -0,0 +1,48 @@
import * as CatalogActions from '../../../actions/catalog';
import * as CatalogMutations from '../../../mutations/catalog';
const DEFAULT_VALUES = {
order: '',
orderDirection: ''
};
const catalog = {
namespaced: true,
state: {
isFetching: false,
isErrored: false,
error: [],
list: [],
categories: [],
countries: [],
page: 1,
numPages: 1,
resultsPerPage: 12,
order: DEFAULT_VALUES.order,
orderDirection: DEFAULT_VALUES.orderDirection
},
computed: {},
getters: {},
mutations: {
setDatasets: CatalogMutations.setDatasets,
setCategories: CatalogMutations.setCategories,
setCountries: CatalogMutations.setCountries,
setFetchingState: CatalogMutations.setFetchingState,
setRequestError: CatalogMutations.setRequestError,
setPagination: CatalogMutations.setPagination,
setResultsPerPage: CatalogMutations.setResultsPerPage,
setOrder: CatalogMutations.setOrder(DEFAULT_VALUES),
orderDatasets: CatalogMutations.orderDatasets
},
actions: {
setURLOptions: CatalogActions.setURLOptions,
order: CatalogActions.order,
fetchCountries: CatalogActions.fetchCountries,
fetchDatasets: CatalogActions.fetchDatasets,
clearList: CatalogActions.clearList,
fetchCategories: CatalogActions.fetchCategories,
requestDataset: CatalogActions.requestDataset
}
};
export default catalog;
@@ -0,0 +1,65 @@
import Filters from 'new-dashboard/core/configuration/filters';
import * as VisualizationActions from '../../../actions/visualizations';
import * as VisualizationMutations from '../../../mutations/visualizations';
const DEFAULT_VALUES = {
filter: 'mine',
order: 'favorited,updated_at',
orderDirection: 'desc,desc'
};
const datasets = {
namespaced: true,
state: {
isFetching: false,
isFiltered: false,
isErrored: false,
error: {},
filterType: DEFAULT_VALUES.filter,
order: DEFAULT_VALUES.order,
orderDirection: DEFAULT_VALUES.orderDirection,
list: {},
metadata: {},
page: 1,
numPages: 1,
resultsPerPage: 1
},
mutations: {
setFetchingState: VisualizationMutations.setFetchingState,
setFilterType: VisualizationMutations.setFilterType,
setOrder: VisualizationMutations.setOrder(DEFAULT_VALUES),
setPagination: VisualizationMutations.setPagination,
setResultsPerPage: VisualizationMutations.setResultsPerPage,
setRequestError: VisualizationMutations.setRequestError,
setVisualizations: VisualizationMutations.setVisualizations,
updateNumberLikes: VisualizationMutations.updateNumberLikes,
updateVisualization: VisualizationMutations.updateVisualization
},
actions: {
deleteLike: VisualizationActions.deleteLike,
filter: VisualizationActions.filter,
like: VisualizationActions.like,
order: VisualizationActions.order,
resetFilters: VisualizationActions.resetFilters(DEFAULT_VALUES),
setResultsPerPage: VisualizationActions.setResultsPerPage,
setURLOptions: VisualizationActions.setURLOptions,
updateVisualization: VisualizationActions.updateVisualization,
fetch (context) {
const params = {
...Filters[context.state.filterType],
types: 'table',
page: context.state.page,
order: context.state.order,
order_direction: context.state.orderDirection,
per_page: context.state.resultsPerPage,
with_dependent_visualizations: 10
};
VisualizationActions.fetchVisualizations(context, params);
}
}
};
export default datasets;
@@ -0,0 +1,72 @@
import CartoNode from 'carto-node';
import toObject from 'new-dashboard/utils/to-object';
import { defaultParams as filtersDefaultParams } from 'new-dashboard/core/configuration/filters';
const client = new CartoNode.AuthenticatedClient();
const featuredFavoritedMaps = {
namespaced: true,
state: {
isFetching: false,
isFiltered: false,
isErrored: false,
error: {},
list: {},
metadata: {},
order: 'updated_at',
params: {
per_page: 2,
only_liked: true
}
},
getters: {},
mutations: {
setRequestError (state, error) {
state.isFetching = false;
state.isErrored = true;
state.error = error;
},
setFeaturedFavoritedMaps (state, maps) {
state.list = toObject(maps.visualizations, 'id');
state.metadata = {
total_entries: maps.total_entries,
total_likes: maps.total_likes,
total_shared: maps.total_shared,
total_user_entries: maps.total_user_entries
};
state.isFetching = false;
},
setFetchingState (state) {
state.isFetching = true;
state.isErrored = false;
state.error = {};
}
},
actions: {
fetchMaps (context) {
const favoritedParams = {
...filtersDefaultParams,
...context.state.params,
order: context.state.order
};
context.commit('setFetchingState');
client.getVisualization('',
favoritedParams,
function (err, _, data) {
if (err) {
context.commit('setRequestError', err);
return;
}
context.commit('setFeaturedFavoritedMaps', data);
}
);
}
}
};
export default featuredFavoritedMaps;
@@ -0,0 +1,70 @@
import featuredFavoritedMaps from 'new-dashboard/store/modules/maps/featured-favorited-maps';
import Filters from 'new-dashboard/core/configuration/filters';
import * as VisualizationActions from '../../actions/visualizations';
import * as VisualizationMutations from '../../mutations/visualizations';
const DEFAULT_VALUES = {
filter: 'mine',
order: 'favorited,updated_at',
orderDirection: 'desc,desc'
};
const maps = {
namespaced: true,
modules: {
featuredFavoritedMaps
},
state: {
isFetching: false,
isFiltered: false,
isErrored: false,
error: {},
filterType: DEFAULT_VALUES.filter,
order: DEFAULT_VALUES.order,
orderDirection: DEFAULT_VALUES.orderDirection,
list: {},
metadata: {},
page: 1,
numPages: 1,
resultsPerPage: 12
},
getters: {},
mutations: {
setFetchingState: VisualizationMutations.setFetchingState,
setFilterType: VisualizationMutations.setFilterType,
setOrder: VisualizationMutations.setOrder(DEFAULT_VALUES),
setPagination: VisualizationMutations.setPagination,
setResultsPerPage: VisualizationMutations.setResultsPerPage,
setRequestError: VisualizationMutations.setRequestError,
setVisualizations: VisualizationMutations.setVisualizations,
updateNumberLikes: VisualizationMutations.updateNumberLikes,
updateVisualization: VisualizationMutations.updateVisualization
},
actions: {
deleteLike: VisualizationActions.deleteLike,
filter: VisualizationActions.filter,
like: VisualizationActions.like,
order: VisualizationActions.order,
resetFilters: VisualizationActions.resetFilters(DEFAULT_VALUES),
setResultsPerPage: VisualizationActions.setResultsPerPage,
setURLOptions: VisualizationActions.setURLOptions,
updateVisualization: VisualizationActions.updateVisualization,
fetch (context) {
const params = {
...Filters[context.state.filterType],
types: 'derived',
page: context.state.page,
order: context.state.order,
order_direction: context.state.orderDirection,
per_page: context.state.resultsPerPage
};
VisualizationActions.fetchVisualizations(context, params);
}
}
};
export default maps;
@@ -0,0 +1,59 @@
const notifications = {
namespaced: true,
state: {
isFetching: false,
isErrored: false,
error: {},
notifications: []
},
computed: {},
getters: {},
mutations: {
setNotifications (state, notifications) {
state.notifications = notifications;
state.isFetching = false;
state.isErrored = false;
state.error = [];
},
setRequestError (state, error) {
state.isFetching = false;
state.isErrored = true;
state.error = error;
state.notifications = [];
},
setFetchingState (state) {
state.isFetching = true;
state.isErrored = false;
state.error = [];
state.notifications = [];
}
},
actions: {
fetchNotifications (context, options) {
context.commit('setFetchingState');
context.rootState.client.getConfig(function (err, _, data) {
if (err) {
context.commit('setRequestError', err);
return;
}
context.commit('setNotifications', data.unfiltered_organization_notifications);
context.dispatch('markNotificationsAsRead', options);
});
},
markNotificationsAsRead (context, options) {
const nowString = new Date().toISOString();
context.state.notifications.forEach(notification => {
const { userId, apiKey } = options;
if (!notification.read_at) {
const notificationCopy = { ...notification, read_at: nowString };
context.rootState.client.updateNotification(userId, apiKey, notificationCopy, () => {});
}
});
}
}
};
export default notifications;
@@ -0,0 +1,67 @@
import { defaultParams as filtersDefaultParams } from 'new-dashboard/core/configuration/filters';
import toObject from 'new-dashboard/utils/to-object';
import * as VisualizationActions from '../../actions/visualizations';
import * as VisualizationMutations from '../../mutations/visualizations';
const recentContent = {
namespaced: true,
state: {
isFetching: false,
isErrored: false,
error: {},
list: {},
metadata: {
total_entries: 0
}
},
getters: {
hasRecentContent (state) {
return state.metadata.total_entries > 0;
}
},
mutations: {
setFetchingState: VisualizationMutations.setFetchingState,
setRequestError: VisualizationMutations.setRequestError,
updateNumberLikes: VisualizationMutations.updateNumberLikes,
updateVisualization: VisualizationMutations.updateVisualization,
setRecentContent (state, recentContent) {
state.list = toObject(recentContent.visualizations, 'id');
state.metadata = { total_entries: recentContent.total_entries };
state.isFetching = false;
}
},
actions: {
like: VisualizationActions.like,
deleteLike: VisualizationActions.deleteLike,
updateVisualization: VisualizationActions.updateVisualization,
fetch (context) {
context.commit('setFetchingState');
const params = {
...filtersDefaultParams,
order: 'updated_at',
order_direction: 'desc',
types: 'table,derived',
per_page: 3,
page: 1
};
context.rootState.client.getVisualization('',
params,
function (err, _, data) {
if (err) {
context.commit('setRequestError', err);
return;
}
context.commit('setRecentContent', data);
}
);
}
}
};
export default recentContent;
@@ -0,0 +1,213 @@
import toObject from 'new-dashboard/utils/to-object';
import * as VisualizationActions from '../../actions/visualizations';
const search = {
namespaced: true,
state: {
searchTerm: '',
tag: '',
resultsPerPage: 6,
maps: {
isFetching: false,
isErrored: false,
results: {},
error: {},
page: 1,
numPages: 1,
numResults: 0
},
datasets: {
isFetching: false,
isErrored: false,
results: {},
error: {},
page: 1,
numPages: 1,
numResults: 0
},
tags: {
isFetching: false,
isErrored: false,
results: [],
error: {},
page: 1,
numPages: 1,
numResults: 0
}
},
getters: {
requestParameters (state) {
const parameters = {
per_page: state.resultsPerPage,
shared: 'yes',
exclude_shared: false
};
if (state.searchTerm) {
parameters.q = state.searchTerm;
}
if (state.tag) {
parameters.tags = state.tag;
}
return parameters;
}
},
mutations: {
updatePage (state, { section, page }) {
state[section].page = page;
},
updateSearchTerm (state, { query, tag }) {
state.searchTerm = query;
state.tag = tag;
},
setFetchingState (state, section) {
state[section].isFetching = true;
},
setRequestError (state, { requestType, error }) {
state[requestType].error = error;
},
setMaps (state, maps) {
state.maps.results = toObject(maps.visualizations, 'id');
state.maps.numResults = maps.total_entries;
state.maps.numPages = Math.ceil(maps.total_entries / state.resultsPerPage);
state.maps.isFetching = false;
},
setDatasets (state, datasets) {
state.datasets.results = toObject(datasets.visualizations, 'id');
state.datasets.numResults = datasets.total_entries;
state.datasets.numPages = Math.ceil(datasets.total_entries / state.resultsPerPage);
state.datasets.isFetching = false;
},
setTags (state, tags) {
state.tags.results = tags.result;
state.tags.numResults = tags.total;
state.tags.numPages = Math.ceil(tags.total / state.resultsPerPage);
state.tags.isFetching = false;
},
updateNumberLikes () {
// NOOP. This method avoids action not finding mutation.
},
updateVisualization (state, { visualizationId, visualizationAttributes }) {
const visualization = state.maps.results[visualizationId] || state.datasets.results[visualizationId];
if (visualization) {
Object.assign(visualization, visualizationAttributes);
}
},
resetState (state) {
state.searchTerm = '';
state.tag = '';
state.maps = {
isFetching: false,
isErrored: false,
results: {},
error: {},
page: 1,
numPages: 1,
numResults: 0
};
state.datasets = {
isFetching: false,
isErrored: false,
results: {},
error: {},
page: 1,
numPages: 1,
numResults: 0
};
state.tags = {
isFetching: false,
isErrored: false,
results: [],
error: {},
page: 1,
numPages: 1,
numResults: 0
};
}
},
actions: {
deleteLike: VisualizationActions.deleteLike,
like: VisualizationActions.like,
doSearch (context, searchParameters) {
context.commit('updateSearchTerm', searchParameters);
context.commit('setFetchingState', 'maps');
context.commit('setFetchingState', 'datasets');
context.dispatch('fetchMaps', context.getters.requestParameters);
context.dispatch('fetchDatasets', context.getters.requestParameters);
if (searchParameters.query) {
context.dispatch('fetchTags', context.getters.requestParameters);
context.commit('setFetchingState', 'tags');
}
},
changeSectionPage (context, pageOptions) {
context.commit('setFetchingState', pageOptions.section);
const sectionCapitalized = pageOptions.section[0].toUpperCase() + pageOptions.section.substr(1);
context.commit('updatePage', pageOptions);
context.dispatch(`fetch${sectionCapitalized}`, context.getters.requestParameters);
},
fetchMaps (context, parameters) {
context.rootState.client.getVisualization('',
{ ...parameters,
type: 'derived',
page: context.state.maps.page },
function (error, _, data) {
if (error) {
return context.commit('setRequestError', { requestType: 'maps', error });
}
context.commit('setMaps', data);
}
);
},
fetchDatasets (context, parameters) {
context.rootState.client.getVisualization('',
{ ...parameters,
type: 'table',
page: context.state.datasets.page,
with_dependent_visualizations: 10
},
function (error, _, data) {
if (error) {
return context.commit('setRequestError', { requestType: 'datasets', error });
}
context.commit('setDatasets', data);
}
);
},
fetchTags (context, parameters) {
context.rootState.client.getTags(
{ ...parameters,
types: 'table,derived',
page: context.state.tags.page,
include_shared: true
},
function (error, _, data) {
if (error) {
return context.commit('setRequestError', { requestType: 'tags', error });
}
context.commit('setTags', data);
}
);
},
resetState (context) {
context.commit('resetState');
}
}
};
export default search;
@@ -0,0 +1,59 @@
export function canCreateDatasets (state) {
if (!state.remaining_byte_quota || state.remaining_byte_quota <= 0 || isOutOfDatasetsQuota(state)) {
return false;
}
return hasCreateDatasetsFeature(state);
}
export function hasCreateDatasetsFeature (state) {
return isBuilder(state);
}
export function isBuilder (state) {
return !isViewer(state);
}
export function isViewer (state) {
return state.viewer === true;
}
export function hasEngine (state) {
return state.actions.engine_enabled === true;
}
export function isNotificationVisible (state) {
return state.notification && state.showNotification;
}
export function userNotification (state) {
return state.notification ? state.notification : null;
}
export function getPublicMapsCount (state) {
return (state.link_privacy_map_count + state.password_privacy_map_count + state.public_privacy_map_count) || 0;
}
export function getPublicMapsQuota (state) {
return state.public_map_quota;
}
export function isOutOfPublicMapsQuota (state) {
return getPublicMapsQuota(state) && getPublicMapsCount(state) >= getPublicMapsQuota(state);
}
export function getDatasetsCount (state) {
return state.table_count;
}
export function getDatasetsQuota (state) {
return state.table_quota;
}
export function isOutOfDatasetsQuota (state) {
return getDatasetsQuota(state) && getDatasetsCount(state) >= getDatasetsQuota(state);
}
export function isOrganizationUser (state) {
return Boolean(state.organization);
}
@@ -0,0 +1,70 @@
import CartoNode from 'carto-node';
import getCARTOData from 'new-dashboard/store/utils/getCARTOData';
import * as getters from './getters';
const client = new CartoNode.AuthenticatedClient();
// Data coming from Static Page Loading,
// which requests user and config data from
// /me API endpoint.
const CARTOData = getCARTOData();
const user = {
namespaced: true,
state: {
...CARTOData.user_data,
organizationNotifications: CARTOData.organization_notifications || [],
showNotification: true
},
getters: {
canCreateDatasets: getters.canCreateDatasets,
isViewer: getters.isViewer,
hasEngine: getters.hasEngine,
userNotification: getters.userNotification,
isNotificationVisible: getters.isNotificationVisible,
publicMapsCount: getters.getPublicMapsCount,
publicMapsQuota: getters.getPublicMapsQuota,
isOutOfPublicMapsQuota: getters.isOutOfPublicMapsQuota,
datasetsCount: getters.getDatasetsCount,
datasetsQuota: getters.getDatasetsQuota,
isOutOfDatasetsQuota: getters.isOutOfDatasetsQuota,
isOrganizationUser: getters.isOrganizationUser
},
mutations: {
setUserData (state, userData) {
Object.assign(state, userData);
},
setOrganizationNotifications (state, organizationNotifications) {
state.organizationNotifications = organizationNotifications;
},
setShowNotification (state, showNotification) {
state.showNotification = showNotification;
},
updateTableCount (state, newTableCount) {
state.table_count = newTableCount;
}
},
actions: {
updateData (context) {
client.getConfig(function (err, _, data) {
if (err) {
return;
}
context.commit('setUserData', data.user_data);
});
},
resetOrganizationNotifications (context) {
context.commit('setOrganizationNotifications', []);
},
hideUserNotification (context) {
context.commit('setShowNotification', false);
},
updateTableCount (context, newTableCount) {
context.commit('updateTableCount', newTableCount);
}
}
};
export default user;
@@ -0,0 +1,34 @@
import toObject from 'new-dashboard/utils/to-object';
export function setApps (state, apps) {
state.list = toObject(apps, 'id');
state.isFetching = false;
state.isErrored = false;
state.error = [];
}
export function addApp (state, app) {
state.list = { ...state.list, [app.id]: app };
}
export function updateOAuthApp (state, app) {
const isOAuthAppPresent = state.list.hasOwnProperty(app.id);
if (isOAuthAppPresent) {
Object.assign(state.list[app.id], app);
}
}
export function setRequestError (state, error) {
state.isFetching = false;
state.isErrored = true;
state.error = error;
state.list = {};
}
export function setFetchingState (state) {
state.isFetching = true;
state.isErrored = false;
state.error = [];
state.list = {};
}
@@ -0,0 +1,67 @@
export function setCategories (state, data) {
state.categories = data.map(c => c.category);
state.isFetching = false;
state.isErrored = false;
state.error = [];
}
export function setCountries (state, data) {
state.countries = data.map(c => c.country);
state.isFetching = false;
state.isErrored = false;
state.error = [];
}
export function setDatasets (state, datasets) {
state.list = datasets;
state.isFetching = false;
state.isErrored = false;
state.error = [];
state.numResults = datasets.length;
}
export function setRequestError (state, error) {
state.isFetching = false;
state.isErrored = true;
state.error = error;
state.list = {};
state.numResults = 0;
}
export function setFetchingState (state) {
state.isFetching = true;
state.isErrored = false;
state.error = [];
state.list = {};
}
export function setPagination (state, page = 1) {
state.page = page;
state.numPages = Math.ceil(state.numResults / state.resultsPerPage) || 1;
}
export function setResultsPerPage (state, resultsPerPage = 12) {
state.resultsPerPage = resultsPerPage;
}
export function setOrder (DEFAULT_VALUES) {
return function (state, orderOptions) {
state.order = orderOptions.order || DEFAULT_VALUES.order;
state.orderDirection = orderOptions.direction || DEFAULT_VALUES.orderDirection;
};
}
export function orderDatasets (state) {
const orderAsc = (list, order) => {
list.sort((a, b) => (a[order] > b[order]) ? 1 : -1);
};
const orderDesc = (list, order) => {
list.sort((a, b) => (a[order] < b[order]) ? 1 : -1);
};
const orderByDirection = {
'asc': () => orderAsc(state.list, state.order),
'desc': () => orderDesc(state.list, state.order)
};
return orderByDirection[state.orderDirection]();
}
@@ -0,0 +1,58 @@
import toObject from 'new-dashboard/utils/to-object';
export function setFetchingState (state) {
state.isFetching = true;
state.isErrored = false;
state.error = {};
}
export function setFilterType (state, filterType = 'mine') {
state.filterType = filterType;
}
export function setPagination (state, page = 1) {
state.page = page;
state.numPages = Math.ceil(state.metadata.total_entries / state.resultsPerPage) || 1;
}
export function setOrder (DEFAULT_VALUES) {
return function (state, orderOptions) {
state.order = orderOptions.order || DEFAULT_VALUES.order;
state.orderDirection = orderOptions.direction || DEFAULT_VALUES.orderDirection;
};
}
export function setResultsPerPage (state, resultsPerPage = 12) {
state.resultsPerPage = resultsPerPage;
}
export function setRequestError (state, error) {
state.isFetching = false;
state.isErrored = true;
state.error = error;
}
export function setVisualizations (state, visualizationsData) {
state.list = toObject(visualizationsData.visualizations, 'id');
state.metadata = {
total_entries: visualizationsData.total_entries,
total_likes: visualizationsData.total_likes,
total_shared: visualizationsData.total_shared,
total_locked: visualizationsData.total_locked,
total_user_entries: visualizationsData.total_user_entries
};
state.isFetching = false;
}
export function updateNumberLikes (state, {visualizationAttributes}) {
state.metadata.total_likes += visualizationAttributes.liked ? 1 : -1;
}
export function updateVisualization (state, {visualizationId, visualizationAttributes}) {
const isVisualizationPresent = state.list.hasOwnProperty(visualizationId);
if (isVisualizationPresent) {
Object.assign(state.list[visualizationId], visualizationAttributes);
}
}
@@ -0,0 +1,11 @@
export default function getCARTOData () {
if (window.CartoConfig) {
return window.CartoConfig.data;
}
return {
user_data: window.user_data,
notification: window.user_data.notification,
organization_notifications: window.organization_notifications || []
};
}