Unverified Commit a5368433 authored by Tamika Tannis's avatar Tamika Tannis Committed by GitHub

Cleanup ducks folder (#195)

* Code cleanup ducks: feedback, log, and popularTables

* search

* tableMetadata

* user

* Remove unused imports from SearchPage

* restore location of resource and feedback enums
parent 670cbdfc
...@@ -7,10 +7,10 @@ module.exports = { ...@@ -7,10 +7,10 @@ module.exports = {
statements: 50, // 100 statements: 50, // 100
}, },
'./js/components': { './js/components': {
branches: 35, // 75 branches: 40, // 75
functions: 40, // 75 functions: 45, // 75
lines: 45, // 75 lines: 50, // 75
statements: 45, // 75 statements: 50, // 75
}, },
'./js/ducks': { './js/ducks': {
branches: 35, // 75 branches: 35, // 75
......
...@@ -3,7 +3,7 @@ import * as React from 'react'; ...@@ -3,7 +3,7 @@ import * as React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import AbstractFeedbackForm, { FeedbackFormProps } from 'components/Feedback/FeedbackForm'; import AbstractFeedbackForm, { FeedbackFormProps } from 'components/Feedback/FeedbackForm';
import { SendingState } from 'components/Feedback/types'; import { SendingState } from 'interfaces';
import { BugReportFeedbackForm, mapDispatchToProps, mapStateToProps } from '../'; import { BugReportFeedbackForm, mapDispatchToProps, mapStateToProps } from '../';
import { import {
BUG_SUMMARY_LABEL, BUG_SUMMARY_LABEL,
......
...@@ -3,7 +3,7 @@ import * as React from 'react'; ...@@ -3,7 +3,7 @@ import * as React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import AbstractFeedbackForm, { FeedbackFormProps } from 'components/Feedback/FeedbackForm'; import AbstractFeedbackForm, { FeedbackFormProps } from 'components/Feedback/FeedbackForm';
import { SendingState } from 'components/Feedback/types'; import { SendingState } from 'interfaces';
import { RatingFeedbackForm, mapDispatchToProps, mapStateToProps } from '../'; import { RatingFeedbackForm, mapDispatchToProps, mapStateToProps } from '../';
import { import {
COMMENTS_PLACEHOLDER, COMMENTS_PLACEHOLDER,
......
...@@ -3,7 +3,7 @@ import * as React from 'react'; ...@@ -3,7 +3,7 @@ import * as React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import AbstractFeedbackForm, { FeedbackFormProps } from 'components/Feedback/FeedbackForm'; import AbstractFeedbackForm, { FeedbackFormProps } from 'components/Feedback/FeedbackForm';
import { SendingState } from 'components/Feedback/types'; import { SendingState } from 'interfaces';
import { RequestFeedbackForm, mapDispatchToProps, mapStateToProps } from '../'; import { RequestFeedbackForm, mapDispatchToProps, mapStateToProps } from '../';
import { import {
FEATURE_SUMMARY_LABEL, FEATURE_SUMMARY_LABEL,
......
...@@ -5,7 +5,7 @@ import LoadingSpinner from 'components/common/LoadingSpinner'; ...@@ -5,7 +5,7 @@ import LoadingSpinner from 'components/common/LoadingSpinner';
import './styles.scss'; import './styles.scss';
import { ResetFeedbackRequest, SubmitFeedbackRequest } from 'ducks/feedback/types'; import { ResetFeedbackRequest, SubmitFeedbackRequest } from 'ducks/feedback/types';
import { SendingState } from '../types'; import { SendingState } from 'interfaces';
import { import {
SUBMIT_FAILURE_MESSAGE, SUBMIT_FAILURE_MESSAGE,
......
...@@ -3,7 +3,7 @@ import * as React from 'react'; ...@@ -3,7 +3,7 @@ import * as React from 'react';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import LoadingSpinner from 'components/common/LoadingSpinner'; import LoadingSpinner from 'components/common/LoadingSpinner';
import { SendingState } from '../../types'; import { SendingState } from 'interfaces';
import FeedbackForm, { FeedbackFormProps } from '../'; import FeedbackForm, { FeedbackFormProps } from '../';
import { RatingFeedbackForm } from '../RatingFeedbackForm'; import { RatingFeedbackForm } from '../RatingFeedbackForm';
......
export enum SendingState {
ERROR = "error",
IDLE = "idle",
WAITING = "waiting",
COMPLETE = "complete"
}
...@@ -6,9 +6,10 @@ import { connect } from 'react-redux'; ...@@ -6,9 +6,10 @@ import { connect } from 'react-redux';
import AppConfig from 'config/config'; import AppConfig from 'config/config';
import { LinkConfig } from 'config/config-types'; import { LinkConfig } from 'config/config-types';
import { GlobalState } from 'ducks/rootReducer'; import { GlobalState } from 'ducks/rootReducer';
import { LoggedInUser } from 'ducks/user/types';
import { logClick } from 'ducks/utilMethods'; import { logClick } from 'ducks/utilMethods';
import { LoggedInUser } from 'interfaces';
import './styles.scss'; import './styles.scss';
// Props // Props
......
...@@ -10,12 +10,14 @@ import Tabs from 'components/common/Tabs'; ...@@ -10,12 +10,14 @@ import Tabs from 'components/common/Tabs';
import { GlobalState } from 'ducks/rootReducer'; import { GlobalState } from 'ducks/rootReducer';
import { getUserById } from 'ducks/user/reducer'; import { getUserById } from 'ducks/user/reducer';
import { User, GetUserRequest } from 'ducks/user/types'; import { GetUserRequest } from 'ducks/user/types';
import { PeopleUser } from 'interfaces';
import './styles.scss'; import './styles.scss';
interface StateFromProps { interface StateFromProps {
user: User; user: PeopleUser;
} }
interface DispatchFromProps { interface DispatchFromProps {
......
...@@ -5,25 +5,24 @@ import * as DocumentTitle from 'react-document-title'; ...@@ -5,25 +5,24 @@ import * as DocumentTitle from 'react-document-title';
import * as qs from 'simple-query-string'; import * as qs from 'simple-query-string';
import { RouteComponentProps } from 'react-router'; import { RouteComponentProps } from 'react-router';
import SearchBar from './SearchBar';
import LoadingSpinner from 'components/common/LoadingSpinner'; import LoadingSpinner from 'components/common/LoadingSpinner';
import { ResourceType } from 'interfaces';
import InfoButton from 'components/common/InfoButton'; import InfoButton from 'components/common/InfoButton';
import ResourceList from 'components/common/ResourceList'; import ResourceList from 'components/common/ResourceList';
import TabsComponent from 'components/common/Tabs'; import TabsComponent from 'components/common/Tabs';
import SearchBar from './SearchBar';
import { GlobalState } from 'ducks/rootReducer'; import { GlobalState } from 'ducks/rootReducer';
import { searchAll, searchResource } from 'ducks/search/reducer'; import { searchAll, searchResource } from 'ducks/search/reducer';
import { import {
DashboardSearchResults, DashboardSearchResults,
SearchAllOptions,
SearchAllRequest, SearchAllRequest,
SearchResourceRequest, SearchResourceRequest,
TableSearchResults, TableSearchResults,
UserSearchResults UserSearchResults,
} from 'ducks/search/types'; } from 'ducks/search/types';
import { ResourceType, SearchAllOptions } from 'interfaces';
// TODO: Use css-modules instead of 'import' // TODO: Use css-modules instead of 'import'
import './styles.scss'; import './styles.scss';
......
...@@ -5,9 +5,10 @@ import { Button, Modal, OverlayTrigger, Popover, Table } from 'react-bootstrap'; ...@@ -5,9 +5,10 @@ import { Button, Modal, OverlayTrigger, Popover, Table } from 'react-bootstrap';
import Linkify from 'react-linkify' import Linkify from 'react-linkify'
import { GlobalState } from 'ducks/rootReducer'; import { GlobalState } from 'ducks/rootReducer';
import { PreviewData } from '../types';
import { logClick } from 'ducks/utilMethods'; import { logClick } from 'ducks/utilMethods';
import { PreviewData } from 'interfaces';
// TODO: Use css-modules instead of 'import' // TODO: Use css-modules instead of 'import'
import './styles.scss'; import './styles.scss';
......
...@@ -2,8 +2,8 @@ import * as React from 'react'; ...@@ -2,8 +2,8 @@ import * as React from 'react';
import moment from 'moment-timezone'; import moment from 'moment-timezone';
import ColumnDescEditableText from 'components/TableDetail/ColumnDescEditableText'; import ColumnDescEditableText from 'components/TableDetail/ColumnDescEditableText';
import { TableColumn } from 'components/TableDetail/types';
import { logClick } from 'ducks/utilMethods'; import { logClick } from 'ducks/utilMethods';
import { TableColumn } from 'interfaces';
// TODO: Use css-modules instead of 'import' // TODO: Use css-modules instead of 'import'
import './styles.scss'; import './styles.scss';
......
import * as React from 'react'; import * as React from 'react';
import DetailListItem from './DetailListItem'; import DetailListItem from './DetailListItem';
import { TableColumn } from '../types'; import { TableColumn } from 'interfaces';
interface DetailListProps { interface DetailListProps {
columns?: TableColumn[]; columns?: TableColumn[];
......
...@@ -8,7 +8,7 @@ import serialize from 'form-serialize'; ...@@ -8,7 +8,7 @@ import serialize from 'form-serialize';
import AvatarLabel, { AvatarLabelProps } from 'components/common/AvatarLabel'; import AvatarLabel, { AvatarLabelProps } from 'components/common/AvatarLabel';
import LoadingSpinner from 'components/common/LoadingSpinner'; import LoadingSpinner from 'components/common/LoadingSpinner';
import { Modal } from 'react-bootstrap'; import { Modal } from 'react-bootstrap';
import { UpdateMethod } from './types'; import { UpdateMethod } from 'interfaces';
// TODO: Use css-modules instead of 'import' // TODO: Use css-modules instead of 'import'
import './styles.scss'; import './styles.scss';
......
...@@ -3,7 +3,7 @@ import moment from 'moment-timezone'; ...@@ -3,7 +3,7 @@ import moment from 'moment-timezone';
import './styles.scss'; import './styles.scss';
import { Watermark } from '../types'; import { Watermark } from 'interfaces';
interface WatermarkLabelProps { interface WatermarkLabelProps {
watermarks: Watermark[]; watermarks: Watermark[];
......
...@@ -29,7 +29,7 @@ import { logClick } from 'ducks/utilMethods'; ...@@ -29,7 +29,7 @@ import { logClick } from 'ducks/utilMethods';
import { OverlayTrigger, Popover } from 'react-bootstrap'; import { OverlayTrigger, Popover } from 'react-bootstrap';
import { RouteComponentProps } from 'react-router'; import { RouteComponentProps } from 'react-router';
import { PreviewQueryParams, TableMetadata } from './types'; import { PreviewQueryParams, TableMetadata } from 'interfaces';
// TODO: Use css-modules instead of 'import' // TODO: Use css-modules instead of 'import'
import './styles.scss'; import './styles.scss';
......
...@@ -12,8 +12,7 @@ import { updateTags } from 'ducks/tableMetadata/tags/reducer'; ...@@ -12,8 +12,7 @@ import { updateTags } from 'ducks/tableMetadata/tags/reducer';
import { UpdateTagsRequest } from 'ducks/tableMetadata/types'; import { UpdateTagsRequest } from 'ducks/tableMetadata/types';
import TagInfo from "../TagInfo"; import TagInfo from "../TagInfo";
import { Tag } from 'interfaces'; import { Tag, UpdateMethod, UpdateTagData } from 'interfaces';
import { UpdateTagMethod, UpdateTagData } from '../types';
// TODO: Use css-modules instead of 'import' // TODO: Use css-modules instead of 'import'
import './styles.scss'; import './styles.scss';
...@@ -104,10 +103,10 @@ class TagInput extends React.Component<TagInputProps, TagInputState> { ...@@ -104,10 +103,10 @@ class TagInput extends React.Component<TagInputProps, TagInputState> {
const tagArray = Object.keys(this.batchEditSet).reduce((previousValue, tag) => { const tagArray = Object.keys(this.batchEditSet).reduce((previousValue, tag) => {
const action = this.batchEditSet[tag]; const action = this.batchEditSet[tag];
if (action === BatchEditState.DELETE) { if (action === BatchEditState.DELETE) {
previousValue.push({'methodName': UpdateTagMethod.DELETE, 'tagName': tag}); previousValue.push({'methodName': UpdateMethod.DELETE, 'tagName': tag});
} }
else if (action === BatchEditState.PUT) { else if (action === BatchEditState.PUT) {
previousValue.push({'methodName': UpdateTagMethod.PUT, 'tagName': tag}); previousValue.push({'methodName': UpdateMethod.PUT, 'tagName': tag});
} }
return previousValue; return previousValue;
}, []); }, []);
...@@ -159,12 +158,12 @@ class TagInput extends React.Component<TagInputProps, TagInputState> { ...@@ -159,12 +158,12 @@ class TagInput extends React.Component<TagInputProps, TagInputState> {
this.handleShow(); this.handleShow();
} }
else { else {
this.props.updateTags([{'methodName': UpdateTagMethod.PUT, 'tagName': tag}]); this.props.updateTags([{'methodName': UpdateMethod.PUT, 'tagName': tag}]);
} }
} }
else if (actionType === "remove-value" || actionType === "pop-value") { else if (actionType === "remove-value" || actionType === "pop-value") {
tag = actionPayload.removedValue.value; tag = actionPayload.removedValue.value;
this.props.updateTags([{'methodName': UpdateTagMethod.DELETE, 'tagName': tag}]); this.props.updateTags([{'methodName': UpdateMethod.DELETE, 'tagName': tag}]);
} }
}; };
......
export enum UpdateTagMethod {
DELETE = 'DELETE',
PUT = 'PUT',
}
export interface UpdateTagData {
methodName: UpdateTagMethod;
tagName: string;
}
...@@ -9,11 +9,13 @@ import { ...@@ -9,11 +9,13 @@ import {
POPULAR_TABLES_SOURCE_NAME, POPULAR_TABLES_SOURCE_NAME,
POPULAR_TABLES_PER_PAGE POPULAR_TABLES_PER_PAGE
} from './constants'; } from './constants';
import { TableResource } from 'interfaces';
import InfoButton from 'components/common/InfoButton'; import InfoButton from 'components/common/InfoButton';
import ResourceList from 'components/common/ResourceList'; import ResourceList from 'components/common/ResourceList';
import { getPopularTables } from 'ducks/popularTables/reducer'; import { getPopularTables } from 'ducks/popularTables/reducer';
import { GetPopularTablesRequest, TableResource } from 'ducks/popularTables/types'; import { GetPopularTablesRequest } from 'ducks/popularTables/types';
import { GlobalState } from 'ducks/rootReducer'; import { GlobalState } from 'ducks/rootReducer';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
......
import axios, { AxiosResponse, AxiosError } from 'axios'; import axios from 'axios';
import { SubmitFeedbackRequest } from '../types'; export function feedbackSubmit(data: FormData) {
export function feedbackSubmitFeedback(action: SubmitFeedbackRequest) {
return axios({ return axios({
data: action.data, data,
method: 'post', method: 'post',
url: '/api/mail/v0/feedback', url: '/api/mail/v0/feedback',
timeout: 5000, timeout: 5000,
......
import { SendingState } from 'components/Feedback/types'; import { SendingState } from 'interfaces';
import { import {
ResetFeedback, ResetFeedbackRequest, ResetFeedback, ResetFeedbackRequest,
SubmitFeedback, SubmitFeedbackRequest, SubmitFeedbackResponse, SubmitFeedback, SubmitFeedbackRequest,
} from './types'; } from './types';
export type SubmitFeedbackAction = SubmitFeedbackRequest | SubmitFeedbackResponse; /* ACTIONS */
export type ResetFeedbackAction = ResetFeedbackRequest;
export type FeedbackReducerAction = SubmitFeedbackAction | ResetFeedbackAction;
export interface FeedbackReducerState {
sendState: SendingState;
}
export function submitFeedback(formData: FormData): SubmitFeedbackRequest { export function submitFeedback(formData: FormData): SubmitFeedbackRequest {
return { return {
data: formData, payload: {
type: SubmitFeedback.ACTION, data: formData,
},
type: SubmitFeedback.REQUEST,
}; };
} };
export function resetFeedback(): ResetFeedbackRequest {
export function resetFeedback(): ResetFeedbackAction {
return { return {
type: ResetFeedback.ACTION, type: ResetFeedback.REQUEST,
}; };
} };
/* REDUCER */
export interface FeedbackReducerState {
sendState: SendingState;
};
const initialState: FeedbackReducerState = { const initialState: FeedbackReducerState = {
sendState: SendingState.IDLE, sendState: SendingState.IDLE,
}; };
export default function reducer(state: FeedbackReducerState = initialState, action: FeedbackReducerAction): FeedbackReducerState { export default function reducer(state: FeedbackReducerState = initialState, action): FeedbackReducerState {
switch (action.type) { switch (action.type) {
case SubmitFeedback.ACTION: case SubmitFeedback.REQUEST:
return { sendState: SendingState.WAITING }; return { sendState: SendingState.WAITING };
case SubmitFeedback.SUCCESS: case SubmitFeedback.SUCCESS:
return { sendState: SendingState.COMPLETE }; return { sendState: SendingState.COMPLETE };
case SubmitFeedback.FAILURE: case SubmitFeedback.FAILURE:
return { sendState: SendingState.ERROR }; return { sendState: SendingState.ERROR };
case ResetFeedback.ACTION: case ResetFeedback.REQUEST:
return { sendState: SendingState.IDLE }; return { sendState: SendingState.IDLE };
default: default:
return state; return state;
} }
} };
...@@ -2,26 +2,27 @@ ...@@ -2,26 +2,27 @@
import { delay, SagaIterator } from 'redux-saga'; import { delay, SagaIterator } from 'redux-saga';
import { call, put, takeEvery } from 'redux-saga/effects'; import { call, put, takeEvery } from 'redux-saga/effects';
import { feedbackSubmit } from './api/v0';
import { ResetFeedback, SubmitFeedback, SubmitFeedbackRequest } from './types'; import { ResetFeedback, SubmitFeedback, SubmitFeedbackRequest } from './types';
import { feedbackSubmitFeedback } from './api/v0';
function* submitFeedbackWorker(action: SubmitFeedbackRequest): SagaIterator { function* submitFeedbackWorker(action: SubmitFeedbackRequest): SagaIterator {
try { try {
yield call(feedbackSubmitFeedback, action); yield call(feedbackSubmit, action.payload.data);
yield put({ type: SubmitFeedback.SUCCESS }); yield put({ type: SubmitFeedback.SUCCESS });
// TODO - yield delay(2000) on redux-saga upgrade // TODO - yield delay(2000) on redux-saga upgrade
yield call(delay, 2000); yield call(delay, 2000);
yield put({ type: ResetFeedback.ACTION }); yield put({ type: ResetFeedback.REQUEST });
} catch(error) { } catch(error) {
yield put({ type: SubmitFeedback.FAILURE }); yield put({ type: SubmitFeedback.FAILURE });
// TODO - yield delay(2000) on redux-saga upgrade // TODO - yield delay(2000) on redux-saga upgrade
yield call(delay, 2000); yield call(delay, 2000);
yield put({ type: ResetFeedback.ACTION }); yield put({ type: ResetFeedback.REQUEST });
} }
} }
export function* submitFeedbackWatcher(): SagaIterator { export function* submitFeedbackWatcher(): SagaIterator {
yield takeEvery(SubmitFeedback.ACTION, submitFeedbackWorker); yield takeEvery(SubmitFeedback.REQUEST, submitFeedbackWorker);
} }
/* SubmitFeedback */
export enum SubmitFeedback { export enum SubmitFeedback {
ACTION = 'amundsen/feedback/SUBMIT_FEEDBACK', REQUEST = 'amundsen/feedback/SUBMIT_FEEDBACK_REQUEST',
SUCCESS = 'amundsen/feedback/SUBMIT_FEEDBACK_SUCCESS', SUCCESS = 'amundsen/feedback/SUBMIT_FEEDBACK_SUCCESS',
FAILURE = 'amundsen/feedback/SUBMIT_FEEDBACK_FAILURE', FAILURE = 'amundsen/feedback/SUBMIT_FEEDBACK_FAILURE',
} };
export interface SubmitFeedbackRequest { export interface SubmitFeedbackRequest {
type: SubmitFeedback.ACTION; type: SubmitFeedback.REQUEST;
data: FormData; payload: {
} data: FormData;
};
};
export interface SubmitFeedbackResponse { export interface SubmitFeedbackResponse {
type: SubmitFeedback.SUCCESS | SubmitFeedback.FAILURE; type: SubmitFeedback.SUCCESS | SubmitFeedback.FAILURE;
} };
/* ResetFeedback */
export enum ResetFeedback { export enum ResetFeedback {
ACTION = 'amundsen/feedback/RESET_FEEDBACK', REQUEST = 'amundsen/feedback/RESET_FEEDBACK_REQUEST',
} };
export interface ResetFeedbackRequest { export interface ResetFeedbackRequest {
type: ResetFeedback.ACTION; type: ResetFeedback.REQUEST;
} };
import axios, { AxiosResponse, AxiosError } from 'axios'; import axios from 'axios';
export interface ActionLogParams { export interface ActionLogParams {
command?: string; command?: string;
...@@ -11,15 +11,7 @@ export interface ActionLogParams { ...@@ -11,15 +11,7 @@ export interface ActionLogParams {
const BASE_URL = '/api/log/v0/log_event'; const BASE_URL = '/api/log/v0/log_event';
/* TODO: Consider what we want to do on success/failure, if anything */
export function postActionLog(params: ActionLogParams) { export function postActionLog(params: ActionLogParams) {
axios.post(BASE_URL, params) axios.post(BASE_URL, params);
.then((response: AxiosResponse) => { };
return response.data;
})
.catch((error: AxiosError) => {
if (error.response) {
return error.response.data;
}
});
}
import axios, { AxiosResponse, AxiosError } from 'axios'; import axios, { AxiosResponse } from 'axios';
import { PopularTablesResponse } from '../types'; import { TableResource } from 'interfaces';
export type PopularTablesResponse = {
msg: string;
results: TableResource[];
}
export function metadataPopularTables() { export function metadataPopularTables() {
return axios.get('/api/metadata/v0/popular_tables') return axios.get('/api/metadata/v0/popular_tables')
.then((response: AxiosResponse<PopularTablesResponse>) => { .then((response: AxiosResponse<PopularTablesResponse>) => {
return response.data.results; return response.data.results;
})
.catch((error: AxiosError) => {
if (error.response) {
return error.response.data.results;
}
return [];
}); });
} }
import { TableResource } from 'interfaces'
import { import {
GetPopularTables, GetPopularTables,
GetPopularTablesRequest, GetPopularTablesRequest,
GetPopularTablesResponse, GetPopularTablesResponse,
TableResource,
} from './types'; } from './types';
export type PopularTablesReducerAction = GetPopularTablesRequest | GetPopularTablesResponse; /* ACTIONS */
export type PopularTablesReducerState = TableResource[];
export function getPopularTables(): GetPopularTablesRequest { export function getPopularTables(): GetPopularTablesRequest {
return { type: GetPopularTables.ACTION }; return { type: GetPopularTables.REQUEST };
} }
/* REDUCER */
export type PopularTablesReducerState = TableResource[];
const initialState: PopularTablesReducerState = []; const initialState: PopularTablesReducerState = [];
export default function reducer(state: PopularTablesReducerState = initialState, action: PopularTablesReducerAction): PopularTablesReducerState { export default function reducer(state: PopularTablesReducerState = initialState, action): PopularTablesReducerState {
switch (action.type) { switch (action.type) {
case GetPopularTables.SUCCESS: case GetPopularTables.SUCCESS:
case GetPopularTables.FAILURE: case GetPopularTables.FAILURE:
return action.payload; return (<GetPopularTablesResponse>action).payload.tables;
default: default:
return state; return state;
} }
......
import { call, put, takeEvery } from 'redux-saga/effects';
import { SagaIterator } from 'redux-saga'; import { SagaIterator } from 'redux-saga';
import { call, put, takeEvery } from 'redux-saga/effects';
import { GetPopularTables, GetPopularTablesRequest } from './types';
import { metadataPopularTables} from './api/v0'; import { metadataPopularTables} from './api/v0';
import { GetPopularTables } from './types';
export function* getPopularTablesWorker(): SagaIterator { export function* getPopularTablesWorker(): SagaIterator {
try { try {
const popularTables = yield call(metadataPopularTables); const popularTables = yield call(metadataPopularTables);
yield put({ type: GetPopularTables.SUCCESS, payload: popularTables }); yield put({ type: GetPopularTables.SUCCESS, payload: { tables: popularTables } });
} catch (e) { } catch (e) {
yield put({ type: GetPopularTables.FAILURE, payload: [] }); yield put({ type: GetPopularTables.FAILURE, payload: { tables: [] } });
} }
} }
export function* getPopularTablesWatcher(): SagaIterator { export function* getPopularTablesWatcher(): SagaIterator {
yield takeEvery(GetPopularTables.ACTION, getPopularTablesWorker); yield takeEvery(GetPopularTables.REQUEST, getPopularTablesWorker);
} }
import { TableResource } from 'interfaces'; import { TableResource } from 'interfaces';
export { TableResource };
/* API */
export type PopularTablesResponse = {
msg: string;
results: TableResource[];
}
/* getPopularTables */
export enum GetPopularTables { export enum GetPopularTables {
ACTION = 'amundsen/popularTables/GET_POPULAR_TABLES', REQUEST = 'amundsen/popularTables/GET_POPULAR_TABLES_REQUEST',
SUCCESS = 'amundsen/popularTables/GET_POPULAR_TABLES_SUCCESS', SUCCESS = 'amundsen/popularTables/GET_POPULAR_TABLES_SUCCESS',
FAILURE = 'amundsen/popularTables/GET_POPULAR_TABLES_FAILURE', FAILURE = 'amundsen/popularTables/GET_POPULAR_TABLES_FAILURE',
} };
export interface GetPopularTablesRequest { export interface GetPopularTablesRequest {
type: GetPopularTables.ACTION; type: GetPopularTables.REQUEST;
} };
export interface GetPopularTablesResponse { export interface GetPopularTablesResponse {
type: GetPopularTables.SUCCESS | GetPopularTables.FAILURE; type: GetPopularTables.SUCCESS | GetPopularTables.FAILURE;
payload: TableResource[]; payload: {
} tables: TableResource[];
};
};
import axios, { AxiosError, AxiosResponse } from 'axios'; import axios, { AxiosResponse } from 'axios';
import { SearchAllRequest, SearchResponse, SearchResourceRequest } from '../types'; import { ResourceType, SearchAllOptions } from 'interfaces';
import { DashboardSearchResults, TableSearchResults, UserSearchResults } from '../types';
const BASE_URL = '/api/search/v0'; const BASE_URL = '/api/search/v0';
interface SearchAllResponseAPI {
msg: string;
status_code: number;
search_term: string;
dashboards?: DashboardSearchResults;
tables?: TableSearchResults;
users?: UserSearchResults;
}
export function searchAll(action: SearchAllRequest) { export function searchAll(options: SearchAllOptions, term: string) {
const { term, options } = action;
return axios.all([ return axios.all([
axios.get(`${BASE_URL}/table?query=${term}&page_index=${options.tableIndex || 0}`), axios.get(`${BASE_URL}/table?query=${term}&page_index=${options.tableIndex || 0}`),
// TODO PEOPLE - Add request for people here // TODO PEOPLE - Add request for people here
]).then(axios.spread((tableResponse: AxiosResponse<SearchResponse>) => { ]).then(axios.spread((tableResponse: AxiosResponse<SearchAllResponseAPI>) => {
return { return {
search_term: tableResponse.data.search_term, search_term: tableResponse.data.search_term,
tables: tableResponse.data.tables, tables: tableResponse.data.tables,
} }
})).catch((error: AxiosError) => { }));
// TODO - handle errors };
});
}
export function searchResource(pageIndex: number, resource: ResourceType, term: string) {
export function searchResource(action: SearchResourceRequest) {
const { term, pageIndex, resource } = action;
return axios.get(`${BASE_URL}/${resource}?query=${term}&page_index=${pageIndex}`) return axios.get(`${BASE_URL}/${resource}?query=${term}&page_index=${pageIndex}`)
.then((response: AxiosResponse) => { .then((response: AxiosResponse) => {
const { data } = response; const { data } = response;
...@@ -33,7 +38,5 @@ export function searchResource(action: SearchResourceRequest) { ...@@ -33,7 +38,5 @@ export function searchResource(action: SearchResourceRequest) {
} }
}); });
return ret; return ret;
}).catch((error: AxiosError) => {
// TODO - handle errors
}); });
} };
import { ResourceType, SearchAllOptions } from 'interfaces';
import { import {
SearchAll, SearchAll,
SearchAllOptions,
SearchAllRequest, SearchAllRequest,
SearchAllReset, SearchAllReset,
SearchAllResponse, SearchAllResponse,
...@@ -11,9 +12,6 @@ import { ...@@ -11,9 +12,6 @@ import {
TableSearchResults, TableSearchResults,
UserSearchResults, UserSearchResults,
} from './types'; } from './types';
import { ResourceType } from 'interfaces';
export type SearchReducerAction = SearchAllResponse | SearchResourceResponse | SearchAllRequest | SearchResourceRequest | SearchAllReset;
export interface SearchReducerState { export interface SearchReducerState {
search_term: string; search_term: string;
...@@ -21,31 +19,31 @@ export interface SearchReducerState { ...@@ -21,31 +19,31 @@ export interface SearchReducerState {
dashboards: DashboardSearchResults; dashboards: DashboardSearchResults;
tables: TableSearchResults; tables: TableSearchResults;
users: UserSearchResults; users: UserSearchResults;
} };
/* ACTIONS */
export function searchAll(term: string, options: SearchAllOptions = {}): SearchAllRequest { export function searchAll(term: string, options: SearchAllOptions = {}): SearchAllRequest {
return { return {
options, options,
term, term,
type: SearchAll.ACTION, type: SearchAll.REQUEST,
}; };
} };
export function searchResource(resource: ResourceType, term: string, pageIndex: number): SearchResourceRequest { export function searchResource(resource: ResourceType, term: string, pageIndex: number): SearchResourceRequest {
return { return {
pageIndex, pageIndex,
term, term,
resource, resource,
type: SearchResource.ACTION, type: SearchResource.REQUEST,
}; };
} };
export function searchReset(): SearchAllReset { export function searchReset(): SearchAllReset {
return { return {
type: SearchAll.RESET, type: SearchAll.RESET,
}; };
} }
/* REDUCER */
const initialState: SearchReducerState = { const initialState: SearchReducerState = {
search_term: '', search_term: '',
isLoading: false, isLoading: false,
...@@ -66,33 +64,33 @@ const initialState: SearchReducerState = { ...@@ -66,33 +64,33 @@ const initialState: SearchReducerState = {
}, },
}; };
export default function reducer(state: SearchReducerState = initialState, action: SearchReducerAction): SearchReducerState { export default function reducer(state: SearchReducerState = initialState, action): SearchReducerState {
switch (action.type) { switch (action.type) {
// Updates search term to reflect action
case SearchAll.RESET: case SearchAll.RESET:
return initialState; return initialState;
case SearchAll.ACTION: case SearchAll.REQUEST:
// updates search term to reflect action
return { return {
...state, ...state,
search_term: action.term, search_term: (<SearchAllRequest>action).term,
isLoading: true, isLoading: true,
}; };
case SearchResource.ACTION: case SearchResource.REQUEST:
return { return {
...state, ...state,
isLoading: true, isLoading: true,
}; };
// SearchAll will reset all resources with search results or the initial state
case SearchAll.SUCCESS: case SearchAll.SUCCESS:
const newState = action.payload; // resets all resources with initial state then applies search results
const newState = (<SearchAllResponse>action).payload;
return { return {
...initialState, ...initialState,
...newState, ...newState,
isLoading: false, isLoading: false,
}; };
// SearchResource will set only a single resource and preserves search state for other resources
case SearchResource.SUCCESS: case SearchResource.SUCCESS:
const resourceNewState = action.payload; // resets only a single resource and preserves search state for other resources
const resourceNewState = (<SearchResourceResponse>action).payload;
return { return {
...state, ...state,
...resourceNewState, ...resourceNewState,
...@@ -103,8 +101,8 @@ export default function reducer(state: SearchReducerState = initialState, action ...@@ -103,8 +101,8 @@ export default function reducer(state: SearchReducerState = initialState, action
return { return {
...initialState, ...initialState,
isLoading: false, isLoading: false,
}; };
default: default:
return state; return state;
} };
} };
import { call, put, takeEvery } from 'redux-saga/effects';
import { SagaIterator } from 'redux-saga'; import { SagaIterator } from 'redux-saga';
import { call, put, takeEvery } from 'redux-saga/effects';
import { import {
SearchAll, SearchAll,
...@@ -12,32 +12,28 @@ import { ...@@ -12,32 +12,28 @@ import {
searchAll, searchResource, searchAll, searchResource,
} from './api/v0'; } from './api/v0';
// SearchAll
export function* searchAllWorker(action: SearchAllRequest): SagaIterator { export function* searchAllWorker(action: SearchAllRequest): SagaIterator {
const { options, term } = action;
try { try {
const searchResults = yield call(searchAll, action); const searchResults = yield call(searchAll, options, term);
yield put({ type: SearchAll.SUCCESS, payload: searchResults }); yield put({ type: SearchAll.SUCCESS, payload: searchResults });
} catch (e) { } catch (e) {
yield put({ type: SearchAll.FAILURE }); yield put({ type: SearchAll.FAILURE });
} }
} };
export function* searchAllWatcher(): SagaIterator { export function* searchAllWatcher(): SagaIterator {
yield takeEvery(SearchAll.ACTION, searchAllWorker); yield takeEvery(SearchAll.REQUEST, searchAllWorker);
} };
// SearchResource
export function* searchResourceWorker(action: SearchResourceRequest): SagaIterator { export function* searchResourceWorker(action: SearchResourceRequest): SagaIterator {
const { pageIndex, resource, term } = action;
try { try {
const searchResults = yield call(searchResource, action); const searchResults = yield call(searchResource, pageIndex, resource, term);
yield put({ type: SearchResource.SUCCESS, payload: searchResults }); yield put({ type: SearchResource.SUCCESS, payload: searchResults });
} catch (e) { } catch (e) {
yield put({ type: SearchResource.FAILURE }); yield put({ type: SearchResource.FAILURE });
} }
} }
export function* searchResourceWatcher(): SagaIterator { export function* searchResourceWatcher(): SagaIterator {
yield takeEvery(SearchResource.ACTION, searchResourceWorker); yield takeEvery(SearchResource.REQUEST, searchResourceWorker);
} }
import { import {
DashboardResource,
Resource, Resource,
ResourceType, ResourceType,
DashboardResource, SearchAllOptions,
TableResource, TableResource,
UserResource, UserResource,
} from 'interfaces'; } from 'interfaces';
import { SearchReducerState } from './reducer';
interface SearchResults<T extends Resource> { interface SearchResults<T extends Resource> {
page_index: number; page_index: number;
total_results: number; total_results: number;
results: T[]; results: T[];
} };
export type DashboardSearchResults = SearchResults<DashboardResource>; export type DashboardSearchResults = SearchResults<DashboardResource>;
export type TableSearchResults = SearchResults<TableResource>; export type TableSearchResults = SearchResults<TableResource>;
export type UserSearchResults = SearchResults<UserResource>; export type UserSearchResults = SearchResults<UserResource>;
export type SearchResponse = {
msg: string;
status_code: number;
search_term: string;
dashboards?: DashboardSearchResults;
tables?: TableSearchResults;
users?: UserSearchResults;
}
/* searchAll - Search all resource types */
export enum SearchAll { export enum SearchAll {
ACTION = 'amundsen/search/SEARCH_ALL', REQUEST = 'amundsen/search/SEARCH_ALL_REQUEST',
SUCCESS = 'amundsen/search/SEARCH_ALL_SUCCESS', SUCCESS = 'amundsen/search/SEARCH_ALL_SUCCESS',
FAILURE = 'amundsen/search/SEARCH_ALL_FAILURE', FAILURE = 'amundsen/search/SEARCH_ALL_FAILURE',
RESET = 'amundsen/search/SEARCH_ALL_RESET', RESET = 'amundsen/search/SEARCH_ALL_RESET',
} };
export interface SearchAllOptions {
dashboardIndex?: number;
tableIndex?: number;
userIndex?: number;
}
export interface SearchAllRequest { export interface SearchAllRequest {
options: SearchAllOptions; options: SearchAllOptions;
term: string; term: string;
type: SearchAll.ACTION; type: SearchAll.REQUEST;
} };
export interface SearchAllResponse { export interface SearchAllResponse {
type: SearchAll.SUCCESS | SearchAll.FAILURE; type: SearchAll.SUCCESS | SearchAll.FAILURE;
payload?: SearchReducerState; payload?: {
} search_term: string;
isLoading: boolean;
dashboards: DashboardSearchResults;
tables: TableSearchResults;
users: UserSearchResults;
};
};
export interface SearchAllReset { export interface SearchAllReset {
type: SearchAll.RESET; type: SearchAll.RESET;
} }
/* searchResource - Search a single resource type */
export enum SearchResource { export enum SearchResource {
ACTION = 'amundsen/search/SEARCH_RESOURCE', REQUEST = 'amundsen/search/SEARCH_RESOURCE_REQUEST',
SUCCESS = 'amundsen/search/SEARCH_RESOURCE_SUCCESS', SUCCESS = 'amundsen/search/SEARCH_RESOURCE_SUCCESS',
FAILURE = 'amundsen/search/SEARCH_RESOURCE_FAILURE', FAILURE = 'amundsen/search/SEARCH_RESOURCE_FAILURE',
} };
export interface SearchResourceRequest { export interface SearchResourceRequest {
pageIndex: number; pageIndex: number;
resource: ResourceType; resource: ResourceType;
term: string; term: string;
type: SearchResource.ACTION; type: SearchResource.REQUEST;
} };
export interface SearchResourceResponse { export interface SearchResourceResponse {
type: SearchResource.SUCCESS | SearchResource.FAILURE; type: SearchResource.SUCCESS | SearchResource.FAILURE;
payload?: SearchReducerState; payload?: {
} search_term: string;
isLoading: boolean;
dashboards: DashboardSearchResults;
tables: TableSearchResults;
users: UserSearchResults;
};
};
import { GetTableDataRequest, TableMetadata, TableDataResponse, Tag, User } from 'ducks/tableMetadata/types'; import { GetTableDataRequest } from 'ducks/tableMetadata/types';
import { filterFromObj, sortTagsAlphabetical } from 'ducks/utilMethods'; import { filterFromObj, sortTagsAlphabetical } from 'ducks/utilMethods';
import { TableMetadata, Tag, User } from 'interfaces';
import { TableDataResponse } from './v0';
/** /**
* Generates the query string parameters needed for requests that act on a particular table resource. * Generates the query string parameters needed for requests that act on a particular table resource.
*/ */
......
...@@ -2,13 +2,23 @@ import axios, { AxiosResponse, AxiosError } from 'axios'; ...@@ -2,13 +2,23 @@ import axios, { AxiosResponse, AxiosError } from 'axios';
import { Effect } from 'redux-saga'; import { Effect } from 'redux-saga';
import { import {
DescriptionResponse, LastIndexedResponse, PreviewDataResponse, TableDataResponse,
GetPreviewDataRequest, GetTableDataRequest, UpdateTableOwnerRequest, UpdateTagsRequest, GetPreviewDataRequest, GetTableDataRequest, UpdateTableOwnerRequest, UpdateTagsRequest,
PreviewData, TableMetadata, User, Tag
} from 'ducks/tableMetadata/types'; } from 'ducks/tableMetadata/types';
import { PreviewData, PreviewQueryParams, TableMetadata, User, Tag } from 'interfaces';
const API_PATH = '/api/metadata/v0'; const API_PATH = '/api/metadata/v0';
type MessageResponse = { msg: string };
type TableData = TableMetadata & {
owners: User[];
tags: Tag[];
};
export type DescriptionResponse = { description: string; } & MessageResponse;
export type LastIndexedResponse = { timestamp: string; } & MessageResponse;
export type PreviewDataResponse = { previewData: PreviewData; } & MessageResponse;
export type TableDataResponse = { tableData: TableData; } & MessageResponse;
/** HELPERS **/ /** HELPERS **/
import { import {
getTableQueryParams, getTableDataFromResponseData, getTableOwnersFromResponseData, getTableTagsFromResponseData, getTableQueryParams, getTableDataFromResponseData, getTableOwnersFromResponseData, getTableTagsFromResponseData,
...@@ -16,13 +26,9 @@ import { ...@@ -16,13 +26,9 @@ import {
export function metadataTableTags(tableData: TableMetadata) { export function metadataTableTags(tableData: TableMetadata) {
const tableParams = getTableQueryParams(tableData); const tableParams = getTableQueryParams(tableData);
return axios.get(`${API_PATH}/table?${tableParams}&index=&source=`) return axios.get(`${API_PATH}/table?${tableParams}&index=&source=`)
.then((response: AxiosResponse<TableDataResponse>) => { .then((response: AxiosResponse<TableDataResponse>) => {
return getTableTagsFromResponseData(response.data); return getTableTagsFromResponseData(response.data);
})
.catch((error: AxiosError) => {
return [];
}); });
} }
...@@ -53,10 +59,6 @@ export function metadataGetTableData(action: GetTableDataRequest) { ...@@ -53,10 +59,6 @@ export function metadataGetTableData(action: GetTableDataRequest) {
tags: getTableTagsFromResponseData(response.data), tags: getTableTagsFromResponseData(response.data),
statusCode: response.status, statusCode: response.status,
}; };
})
.catch((error: AxiosError) => {
const statusCode = error.response ? error.response.status : 500;
return { statusCode, data: {}, owners: {}, tags: [] };
}); });
} }
...@@ -66,9 +68,6 @@ export function metadataGetTableDescription(tableData: TableMetadata) { ...@@ -66,9 +68,6 @@ export function metadataGetTableDescription(tableData: TableMetadata) {
.then((response: AxiosResponse<DescriptionResponse>) => { .then((response: AxiosResponse<DescriptionResponse>) => {
tableData.table_description = response.data.description; tableData.table_description = response.data.description;
return tableData; return tableData;
})
.catch((error: AxiosError) => {
return tableData;
}); });
} }
...@@ -87,13 +86,9 @@ export function metadataUpdateTableDescription(description: string, tableData: T ...@@ -87,13 +86,9 @@ export function metadataUpdateTableDescription(description: string, tableData: T
export function metadataTableOwners(tableData: TableMetadata) { export function metadataTableOwners(tableData: TableMetadata) {
const tableParams = getTableQueryParams(tableData); const tableParams = getTableQueryParams(tableData);
return axios.get(`${API_PATH}/table?${tableParams}&index=&source=`) return axios.get(`${API_PATH}/table?${tableParams}&index=&source=`)
.then((response: AxiosResponse<TableDataResponse>) => { .then((response: AxiosResponse<TableDataResponse>) => {
return getTableOwnersFromResponseData(response.data); return getTableOwnersFromResponseData(response.data);
})
.catch((error) => {
return {};
}); });
} }
...@@ -120,9 +115,6 @@ export function metadataGetColumnDescription(columnIndex: number, tableData: Tab ...@@ -120,9 +115,6 @@ export function metadataGetColumnDescription(columnIndex: number, tableData: Tab
.then((response: AxiosResponse<DescriptionResponse>) => { .then((response: AxiosResponse<DescriptionResponse>) => {
tableData.columns[columnIndex].description = response.data.description; tableData.columns[columnIndex].description = response.data.description;
return tableData; return tableData;
})
.catch((error: AxiosError) => {
return tableData;
}); });
} }
...@@ -148,18 +140,13 @@ export function metadataGetLastIndexed() { ...@@ -148,18 +140,13 @@ export function metadataGetLastIndexed() {
}); });
} }
export function metadataGetPreviewData(action: GetPreviewDataRequest) { export function metadataGetPreviewData(queryParams: PreviewQueryParams) {
return axios({ return axios({
url: '/api/preview/v0/', url: '/api/preview/v0/',
method: 'POST', method: 'POST',
data: action.queryParams, data: queryParams,
}) })
.then((response: AxiosResponse<PreviewDataResponse>) => { .then((response: AxiosResponse<PreviewDataResponse>) => {
return { data: response.data.previewData, status: response.status }; return { data: response.data.previewData, status: response.status };
})
.catch((error: AxiosError) => {
const data = error.response ? error.response.data : {};
const status = error.response ? error.response.status : null;
return { data, status };
}); });
} }
import { UpdateOwnerPayload, User } from 'interfaces';
import { import {
GetTableData, GetTableDataRequest, GetTableDataResponse, GetTableData, GetTableDataResponse,
UpdateTableOwner, UpdateTableOwnerRequest, UpdateTableOwnerResponse, UpdateTableOwner, UpdateTableOwnerRequest, UpdateTableOwnerResponse,
UpdatePayload, User
} from '../types'; } from '../types';
export type TableOwnerReducerAction = /* ACTIONS */
GetTableDataRequest | GetTableDataResponse | export function updateTableOwner(updateArray: UpdateOwnerPayload[], onSuccess?: () => any, onFailure?: () => any): UpdateTableOwnerRequest {
UpdateTableOwnerRequest | UpdateTableOwnerResponse ;
export interface TableOwnerReducerState {
isLoading: boolean;
owners: { [id: string] : User };
}
export function updateTableOwner(updateArray: UpdatePayload[], onSuccess?: () => any, onFailure?: () => any): UpdateTableOwnerRequest {
return { return {
onSuccess, onSuccess,
onFailure, onFailure,
updateArray, updateArray,
type: UpdateTableOwner.ACTION, type: UpdateTableOwner.REQUEST,
}; };
} };
/* REDUCER */
export interface TableOwnerReducerState {
isLoading: boolean;
owners: { [id: string] : User };
};
export const initialOwnersState: TableOwnerReducerState = { export const initialOwnersState: TableOwnerReducerState = {
isLoading: true, isLoading: true,
owners: {}, owners: {},
}; };
export default function reducer(state: TableOwnerReducerState = initialOwnersState, action: TableOwnerReducerAction): TableOwnerReducerState { export default function reducer(state: TableOwnerReducerState = initialOwnersState, action): TableOwnerReducerState {
switch (action.type) { switch (action.type) {
case GetTableData.ACTION: case GetTableData.REQUEST:
return { isLoading: true, owners: {} }; return { isLoading: true, owners: {} };
case GetTableData.FAILURE: case GetTableData.FAILURE:
case GetTableData.SUCCESS: case GetTableData.SUCCESS:
return { isLoading: false, owners: action.payload.owners }; return { isLoading: false, owners: (<GetTableDataResponse>action).payload.owners };
case UpdateTableOwner.ACTION: case UpdateTableOwner.REQUEST:
return { ...state, isLoading: true }; return { ...state, isLoading: true };
case UpdateTableOwner.FAILURE: case UpdateTableOwner.FAILURE:
case UpdateTableOwner.SUCCESS: case UpdateTableOwner.SUCCESS:
return { isLoading: false, owners: action.payload }; return { isLoading: false, owners: (<UpdateTableOwnerResponse>action).payload.owners };
default: default:
return state; return state;
} }
......
import { all, call, put, select, takeEvery } from 'redux-saga/effects';
import { SagaIterator } from 'redux-saga'; import { SagaIterator } from 'redux-saga';
import { all, call, put, select, takeEvery } from 'redux-saga/effects';
import { UpdateTableOwner, UpdateTableOwnerRequest } from '../types'; import { UpdateTableOwner, UpdateTableOwnerRequest } from '../types';
import { metadataUpdateTableOwner, metadataTableOwners } from '../api/v0'; import { metadataUpdateTableOwner, metadataTableOwners } from '../api/v0';
// updateTableOwner
export function* updateTableOwnerWorker(action: UpdateTableOwnerRequest): SagaIterator { export function* updateTableOwnerWorker(action: UpdateTableOwnerRequest): SagaIterator {
const state = yield select(); const state = yield select();
const tableData = state.tableMetadata.tableData; const tableData = state.tableMetadata.tableData;
try { try {
/* TODO: Pass explicit params into api method and not action */
yield all(metadataUpdateTableOwner(action, tableData)); yield all(metadataUpdateTableOwner(action, tableData));
const newOwners = yield call(metadataTableOwners, tableData); const newOwners = yield call(metadataTableOwners, tableData);
yield put({ type: UpdateTableOwner.SUCCESS, payload: newOwners }); yield put({ type: UpdateTableOwner.SUCCESS, payload: { owners: newOwners } });
if (action.onSuccess) { if (action.onSuccess) {
yield call(action.onSuccess); yield call(action.onSuccess);
} }
} catch (e) { } catch (e) {
yield put({ type: UpdateTableOwner.FAILURE, payload: state.tableMetadata.tableOwners.owners }); yield put({ type: UpdateTableOwner.FAILURE, payload: { owners: state.tableMetadata.tableOwners.owners } });
if (action.onFailure) { if (action.onFailure) {
yield call(action.onFailure); yield call(action.onFailure);
} }
} }
} };
export function* updateTableOwnerWatcher(): SagaIterator { export function* updateTableOwnerWatcher(): SagaIterator {
yield takeEvery(UpdateTableOwner.ACTION, updateTableOwnerWorker); yield takeEvery(UpdateTableOwner.REQUEST, updateTableOwnerWorker);
} };
import { PreviewData, PreviewQueryParams, TableMetadata } from 'interfaces';
import { import {
GetTableData, GetTableDataRequest, GetTableDataResponse, TableMetadata, GetTableData, GetTableDataRequest, GetTableDataResponse,
GetTableDescription, GetTableDescriptionRequest, GetTableDescriptionResponse, GetTableDescription, GetTableDescriptionRequest, GetTableDescriptionResponse,
UpdateTableDescription, UpdateTableDescriptionRequest, UpdateTableDescriptionResponse, UpdateTableDescription, UpdateTableDescriptionRequest, UpdateTableDescriptionResponse,
GetColumnDescription, GetColumnDescriptionResponse, GetColumnDescriptionRequest, GetColumnDescription, GetColumnDescriptionResponse, GetColumnDescriptionRequest,
UpdateColumnDescription, UpdateColumnDescriptionRequest, UpdateColumnDescriptionResponse, UpdateColumnDescription, UpdateColumnDescriptionRequest, UpdateColumnDescriptionResponse,
GetLastIndexed, GetLastIndexedRequest, GetLastIndexedResponse, GetLastIndexed, GetLastIndexedRequest, GetLastIndexedResponse,
GetPreviewData, GetPreviewDataRequest, GetPreviewDataResponse, PreviewQueryParams, PreviewDataState, GetPreviewData, GetPreviewDataRequest, GetPreviewDataResponse,
UpdateTableOwner, UpdateTableOwner,
UpdateTags, UpdateTags,
} from './types'; } from './types';
import tableOwnersReducer, { import tableOwnersReducer, { initialOwnersState, TableOwnerReducerState } from './owners/reducer';
initialOwnersState, TableOwnerReducerAction, TableOwnerReducerState,
} from './owners/reducer';
import tableTagsReducer, {
initialTagsState, TableTagsReducerAction, TableTagsReducerState,
} from './tags/reducer';
export type TableMetadataReducerAction =
GetTableDataRequest | GetTableDataResponse |
GetTableDescriptionRequest | GetTableDescriptionResponse |
UpdateTableDescriptionRequest | UpdateTableDescriptionResponse |
GetColumnDescriptionRequest | GetColumnDescriptionResponse |
UpdateColumnDescriptionRequest | UpdateColumnDescriptionResponse |
GetLastIndexedRequest | GetLastIndexedResponse |
GetPreviewDataRequest | GetPreviewDataResponse |
TableOwnerReducerAction | TableTagsReducerAction ;
export interface TableMetadataReducerState { import tableTagsReducer, { initialTagsState, TableTagsReducerState } from './tags/reducer';
isLoading: boolean;
lastIndexed: number;
preview: PreviewDataState;
statusCode: number;
tableData: TableMetadata;
tableOwners: TableOwnerReducerState;
tableTags: TableTagsReducerState;
}
/* ACTIONS */
export function getTableData(key: string, searchIndex?: string, source?: string): GetTableDataRequest { export function getTableData(key: string, searchIndex?: string, source?: string): GetTableDataRequest {
return { return {
key, key,
searchIndex, searchIndex,
source, source,
type: GetTableData.ACTION, type: GetTableData.REQUEST,
}; };
} };
export function getTableDescription(onSuccess?: () => any, onFailure?: () => any): GetTableDescriptionRequest { export function getTableDescription(onSuccess?: () => any, onFailure?: () => any): GetTableDescriptionRequest {
return { return {
onSuccess, onSuccess,
onFailure, onFailure,
type: GetTableDescription.ACTION, type: GetTableDescription.REQUEST,
}; };
} };
export function updateTableDescription(newValue: string, onSuccess?: () => any, onFailure?: () => any): UpdateTableDescriptionRequest { export function updateTableDescription(newValue: string, onSuccess?: () => any, onFailure?: () => any): UpdateTableDescriptionRequest {
return { return {
newValue, newValue,
onSuccess, onSuccess,
onFailure, onFailure,
type: UpdateTableDescription.ACTION, type: UpdateTableDescription.REQUEST,
}; };
} };
export function getColumnDescription(columnIndex: number, onSuccess?: () => any, onFailure?: () => any): GetColumnDescriptionRequest { export function getColumnDescription(columnIndex: number, onSuccess?: () => any, onFailure?: () => any): GetColumnDescriptionRequest {
return { return {
onSuccess, onSuccess,
onFailure, onFailure,
columnIndex, columnIndex,
type: GetColumnDescription.ACTION, type: GetColumnDescription.REQUEST,
}; };
} };
export function updateColumnDescription(newValue: string, columnIndex: number, onSuccess?: () => any, onFailure?: () => any): UpdateColumnDescriptionRequest { export function updateColumnDescription(newValue: string, columnIndex: number, onSuccess?: () => any, onFailure?: () => any): UpdateColumnDescriptionRequest {
return { return {
newValue, newValue,
columnIndex, columnIndex,
onSuccess, onSuccess,
onFailure, onFailure,
type: UpdateColumnDescription.ACTION, type: UpdateColumnDescription.REQUEST,
}; };
} };
export function getLastIndexed(): GetLastIndexedRequest { export function getLastIndexed(): GetLastIndexedRequest {
return { type: GetLastIndexed.ACTION }; return { type: GetLastIndexed.REQUEST };
} };
export function getPreviewData(queryParams: PreviewQueryParams): GetPreviewDataRequest { export function getPreviewData(queryParams: PreviewQueryParams): GetPreviewDataRequest {
return { queryParams, type: GetPreviewData.ACTION }; return { queryParams, type: GetPreviewData.REQUEST };
} };
/* REDUCER */
export interface TableMetadataReducerState {
isLoading: boolean;
lastIndexed: number;
preview: {
data: PreviewData;
status: number | null;
};
statusCode: number;
tableData: TableMetadata;
tableOwners: TableOwnerReducerState;
tableTags: TableTagsReducerState;
};
const initialPreviewState = { const initialPreviewState = {
data: {}, data: {},
status: null, status: null,
}; };
const initialTableDataState: TableMetadata = { const initialTableDataState: TableMetadata = {
cluster: '', cluster: '',
columns: [], columns: [],
...@@ -111,6 +99,7 @@ const initialTableDataState: TableMetadata = { ...@@ -111,6 +99,7 @@ const initialTableDataState: TableMetadata = {
source: { source: '', source_type: '' }, source: { source: '', source_type: '' },
watermarks: [], watermarks: [],
}; };
const initialState: TableMetadataReducerState = { const initialState: TableMetadataReducerState = {
isLoading: true, isLoading: true,
lastIndexed: null, lastIndexed: null,
...@@ -121,9 +110,9 @@ const initialState: TableMetadataReducerState = { ...@@ -121,9 +110,9 @@ const initialState: TableMetadataReducerState = {
tableTags: initialTagsState, tableTags: initialTagsState,
}; };
export default function reducer(state: TableMetadataReducerState = initialState, action: TableMetadataReducerAction): TableMetadataReducerState { export default function reducer(state: TableMetadataReducerState = initialState, action): TableMetadataReducerState {
switch (action.type) { switch (action.type) {
case GetTableData.ACTION: case GetTableData.REQUEST:
return { return {
...state, ...state,
isLoading: true, isLoading: true,
...@@ -137,7 +126,7 @@ export default function reducer(state: TableMetadataReducerState = initialState, ...@@ -137,7 +126,7 @@ export default function reducer(state: TableMetadataReducerState = initialState,
...state, ...state,
isLoading: false, isLoading: false,
preview: initialPreviewState, preview: initialPreviewState,
statusCode: action.payload.statusCode, statusCode: (<GetTableDataResponse>action).payload.statusCode,
tableData: initialTableDataState, tableData: initialTableDataState,
tableOwners: tableOwnersReducer(state.tableOwners, action), tableOwners: tableOwnersReducer(state.tableOwners, action),
tableTags: tableTagsReducer(state.tableTags, action), tableTags: tableTagsReducer(state.tableTags, action),
...@@ -146,30 +135,30 @@ export default function reducer(state: TableMetadataReducerState = initialState, ...@@ -146,30 +135,30 @@ export default function reducer(state: TableMetadataReducerState = initialState,
return { return {
...state, ...state,
isLoading: false, isLoading: false,
statusCode: action.payload.statusCode, statusCode: (<GetTableDataResponse>action).payload.statusCode,
tableData: action.payload.data, tableData: (<GetTableDataResponse>action).payload.data,
tableOwners: tableOwnersReducer(state.tableOwners, action), tableOwners: tableOwnersReducer(state.tableOwners, action),
tableTags: tableTagsReducer(state.tableTags, action), tableTags: tableTagsReducer(state.tableTags, action),
}; };
case GetTableDescription.FAILURE: case GetTableDescription.FAILURE:
case GetTableDescription.SUCCESS: case GetTableDescription.SUCCESS:
return { ...state, tableData: action.payload }; return { ...state, tableData: (<GetTableDescriptionResponse>action).payload.tableMetadata };
case GetColumnDescription.FAILURE: case GetColumnDescription.FAILURE:
case GetColumnDescription.SUCCESS: case GetColumnDescription.SUCCESS:
return { ...state, tableData: action.payload }; return { ...state, tableData: (<GetColumnDescriptionResponse>action).payload.tableMetadata };
case GetLastIndexed.FAILURE: case GetLastIndexed.FAILURE:
return { ...state, lastIndexed: null }; return { ...state, lastIndexed: null };
case GetLastIndexed.SUCCESS: case GetLastIndexed.SUCCESS:
return { ...state, lastIndexed: action.payload }; return { ...state, lastIndexed: (<GetLastIndexedResponse>action).payload.lastIndexedEpoch };
case GetPreviewData.FAILURE: case GetPreviewData.FAILURE:
return { ...state, preview: initialPreviewState }; return { ...state, preview: initialPreviewState };
case GetPreviewData.SUCCESS: case GetPreviewData.SUCCESS:
return { ...state, preview: action.payload }; return { ...state, preview: (<GetPreviewDataResponse>action).payload };
case UpdateTableOwner.ACTION: case UpdateTableOwner.REQUEST:
case UpdateTableOwner.FAILURE: case UpdateTableOwner.FAILURE:
case UpdateTableOwner.SUCCESS: case UpdateTableOwner.SUCCESS:
return { ...state, tableOwners: tableOwnersReducer(state.tableOwners, action) }; return { ...state, tableOwners: tableOwnersReducer(state.tableOwners, action) };
case UpdateTags.ACTION: case UpdateTags.REQUEST:
case UpdateTags.FAILURE: case UpdateTags.FAILURE:
case UpdateTags.SUCCESS: case UpdateTags.SUCCESS:
return { ...state, tableTags: tableTagsReducer(state.tableTags, action) }; return { ...state, tableTags: tableTagsReducer(state.tableTags, action) };
......
import { all, call, put, select, takeEvery } from 'redux-saga/effects';
import { SagaIterator } from 'redux-saga'; import { SagaIterator } from 'redux-saga';
import { all, call, put, select, takeEvery } from 'redux-saga/effects';
import { import {
GetLastIndexed, GetLastIndexedRequest, GetLastIndexed, GetLastIndexedRequest,
...@@ -21,43 +21,39 @@ import { ...@@ -21,43 +21,39 @@ import {
metadataUpdateTableDescription, metadataUpdateTableDescription,
} from './api/v0'; } from './api/v0';
// getTableData
export function* getTableDataWorker(action: GetTableDataRequest): SagaIterator { export function* getTableDataWorker(action: GetTableDataRequest): SagaIterator {
try { try {
/* TODO: Pass explicit params into api method and not action */
const { data, owners, statusCode, tags } = yield call(metadataGetTableData, action); const { data, owners, statusCode, tags } = yield call(metadataGetTableData, action);
yield put({ type: GetTableData.SUCCESS, payload: { data, owners, statusCode, tags } }); yield put({ type: GetTableData.SUCCESS, payload: { data, owners, statusCode, tags } });
} catch (e) { } catch (e) {
yield put({ type: GetTableData.FAILURE, payload: { data: {}, owners: [], statusCode: 500, tags: [] } }); yield put({ type: GetTableData.FAILURE, payload: { data: {}, owners: [], statusCode: 500, tags: [] } });
} }
} };
export function* getTableDataWatcher(): SagaIterator { export function* getTableDataWatcher(): SagaIterator {
yield takeEvery(GetTableData.ACTION, getTableDataWorker); yield takeEvery(GetTableData.REQUEST, getTableDataWorker);
} };
// getTableDescription
export function* getTableDescriptionWorker(action: GetTableDescriptionRequest): SagaIterator { export function* getTableDescriptionWorker(action: GetTableDescriptionRequest): SagaIterator {
const state = yield select(); const state = yield select();
let tableData; let tableData;
try { try {
tableData = yield call(metadataGetTableDescription, state.tableMetadata.tableData); tableData = yield call(metadataGetTableDescription, state.tableMetadata.tableData);
yield put({ type: GetTableDescription.SUCCESS, payload: tableData }); yield put({ type: GetTableDescription.SUCCESS, payload: { tableMetadata: tableData } });
if (action.onSuccess) { if (action.onSuccess) {
yield call(action.onSuccess); yield call(action.onSuccess);
} }
} catch (e) { } catch (e) {
yield put({ type: GetTableDescription.FAILURE, payload: tableData }); yield put({ type: GetTableDescription.FAILURE, payload: { tableMetadata: tableData } });
if (action.onFailure) { if (action.onFailure) {
yield call(action.onFailure); yield call(action.onFailure);
} }
} }
} };
export function* getTableDescriptionWatcher(): SagaIterator { export function* getTableDescriptionWatcher(): SagaIterator {
yield takeEvery(GetTableDescription.ACTION, getTableDescriptionWorker); yield takeEvery(GetTableDescription.REQUEST, getTableDescriptionWorker);
} };
// updateTableDescription
export function* updateTableDescriptionWorker(action: UpdateTableDescriptionRequest): SagaIterator { export function* updateTableDescriptionWorker(action: UpdateTableDescriptionRequest): SagaIterator {
const state = yield select(); const state = yield select();
try { try {
...@@ -70,35 +66,31 @@ export function* updateTableDescriptionWorker(action: UpdateTableDescriptionRequ ...@@ -70,35 +66,31 @@ export function* updateTableDescriptionWorker(action: UpdateTableDescriptionRequ
yield call(action.onFailure); yield call(action.onFailure);
} }
} }
} };
export function* updateTableDescriptionWatcher(): SagaIterator { export function* updateTableDescriptionWatcher(): SagaIterator {
yield takeEvery(UpdateTableDescription.ACTION, updateTableDescriptionWorker); yield takeEvery(UpdateTableDescription.REQUEST, updateTableDescriptionWorker);
} };
// getColumnDescription
export function* getColumnDescriptionWorker(action: GetColumnDescriptionRequest): SagaIterator { export function* getColumnDescriptionWorker(action: GetColumnDescriptionRequest): SagaIterator {
const state = yield select(); const state = yield select();
let tableData; let tableData;
try { try {
tableData = yield call(metadataGetColumnDescription, action.columnIndex, state.tableMetadata.tableData); tableData = yield call(metadataGetColumnDescription, action.columnIndex, state.tableMetadata.tableData);
yield put({ type: GetColumnDescription.SUCCESS, payload: tableData }); yield put({ type: GetColumnDescription.SUCCESS, payload: { tableMetadata: tableData } });
if (action.onSuccess) { if (action.onSuccess) {
yield call(action.onSuccess); yield call(action.onSuccess);
} }
} catch (e) { } catch (e) {
yield put({ type: GetColumnDescription.FAILURE, payload: tableData }); yield put({ type: GetColumnDescription.FAILURE, payload: { tableMetadata: tableData } });
if (action.onFailure) { if (action.onFailure) {
yield call(action.onFailure); yield call(action.onFailure);
} }
} }
} };
export function* getColumnDescriptionWatcher(): SagaIterator { export function* getColumnDescriptionWatcher(): SagaIterator {
yield takeEvery(GetColumnDescription.ACTION, getColumnDescriptionWorker); yield takeEvery(GetColumnDescription.REQUEST, getColumnDescriptionWorker);
} };
// updateColumnDescription
export function* updateColumnDescriptionWorker(action: UpdateColumnDescriptionRequest): SagaIterator { export function* updateColumnDescriptionWorker(action: UpdateColumnDescriptionRequest): SagaIterator {
const state = yield select(); const state = yield select();
try { try {
...@@ -111,37 +103,34 @@ export function* updateColumnDescriptionWorker(action: UpdateColumnDescriptionRe ...@@ -111,37 +103,34 @@ export function* updateColumnDescriptionWorker(action: UpdateColumnDescriptionRe
yield call(action.onFailure); yield call(action.onFailure);
} }
} }
} };
export function* updateColumnDescriptionWatcher(): SagaIterator { export function* updateColumnDescriptionWatcher(): SagaIterator {
yield takeEvery(UpdateColumnDescription.ACTION, updateColumnDescriptionWorker); yield takeEvery(UpdateColumnDescription.REQUEST, updateColumnDescriptionWorker);
} };
// getLastIndexed
export function* getLastIndexedWorker(action: GetLastIndexedRequest): SagaIterator { export function* getLastIndexedWorker(action: GetLastIndexedRequest): SagaIterator {
try { try {
const lastIndexed = yield call(metadataGetLastIndexed); const lastIndexed = yield call(metadataGetLastIndexed);
yield put({ type: GetLastIndexed.SUCCESS, payload: lastIndexed }); yield put({ type: GetLastIndexed.SUCCESS, payload: { lastIndexedEpoch: lastIndexed } });
} catch (e) { } catch (e) {
yield put({ type: GetLastIndexed.FAILURE }); yield put({ type: GetLastIndexed.FAILURE });
} }
} };
export function* getLastIndexedWatcher(): SagaIterator { export function* getLastIndexedWatcher(): SagaIterator {
yield takeEvery(GetLastIndexed.ACTION, getLastIndexedWorker) yield takeEvery(GetLastIndexed.REQUEST, getLastIndexedWorker)
} };
// getPreviewData
export function* getPreviewDataWorker(action: GetPreviewDataRequest): SagaIterator { export function* getPreviewDataWorker(action: GetPreviewDataRequest): SagaIterator {
let response;
try { try {
response = yield call(metadataGetPreviewData, action); const response = yield call(metadataGetPreviewData, action.queryParams);
yield put({ type: GetPreviewData.SUCCESS, payload: response }); const { data, status } = response;
yield put({ type: GetPreviewData.SUCCESS, payload: { data, status } });
} catch (e) { } catch (e) {
yield put({ type: GetPreviewData.FAILURE, payload: response }); const data = e.response ? e.response.data : {};
const status = e.response ? e.response.status : null;
yield put({ type: GetPreviewData.FAILURE, payload: { data, status } });
} }
} };
export function* getPreviewDataWatcher(): SagaIterator { export function* getPreviewDataWatcher(): SagaIterator {
yield takeEvery(GetPreviewData.ACTION, getPreviewDataWorker); yield takeEvery(GetPreviewData.REQUEST, getPreviewDataWorker);
} };
import { UpdateTagData, Tag } from 'interfaces';
import { import {
GetTableData, GetTableDataRequest, GetTableDataResponse, GetTableData, GetTableDataResponse,
UpdateTags, UpdateTagsRequest, UpdateTagsResponse, UpdateTags, UpdateTagsRequest, UpdateTagsResponse,
UpdateTagData, Tag,
} from '../types'; } from '../types';
export type TableTagsReducerAction = /* ACTIONS */
GetTableDataRequest | GetTableDataResponse |
UpdateTagsRequest | UpdateTagsResponse;
export interface TableTagsReducerState {
isLoading: boolean;
tags: Tag[];
}
export function updateTags(tagArray: UpdateTagData[]): UpdateTagsRequest { export function updateTags(tagArray: UpdateTagData[]): UpdateTagsRequest {
return { return {
tagArray, tagArray,
type: UpdateTags.ACTION, type: UpdateTags.REQUEST,
}; };
} };
/* REDUCER */
export interface TableTagsReducerState {
isLoading: boolean;
tags: Tag[];
};
export const initialTagsState: TableTagsReducerState = { export const initialTagsState: TableTagsReducerState = {
isLoading: true, isLoading: true,
tags: [], tags: [],
}; };
export default function reducer(state: TableTagsReducerState = initialTagsState, action: TableTagsReducerAction): TableTagsReducerState { export default function reducer(state: TableTagsReducerState = initialTagsState, action): TableTagsReducerState {
switch (action.type) { switch (action.type) {
case GetTableData.ACTION: case GetTableData.REQUEST:
return { isLoading: true, tags: [] }; return { isLoading: true, tags: [] };
case GetTableData.FAILURE: case GetTableData.FAILURE:
case GetTableData.SUCCESS: case GetTableData.SUCCESS:
return { isLoading: false, tags: action.payload.tags }; return { isLoading: false, tags: (<GetTableDataResponse>action).payload.tags };
case UpdateTags.FAILURE: case UpdateTags.FAILURE:
return { ...state, isLoading: false }; return { ...state, isLoading: false };
case UpdateTags.SUCCESS: case UpdateTags.SUCCESS:
return { isLoading: false, tags: action.payload }; return { isLoading: false, tags: (<UpdateTagsResponse>action).payload.tags };
case UpdateTags.ACTION: case UpdateTags.REQUEST:
return { ...state, isLoading: true }; return { ...state, isLoading: true };
default: default:
return state; return state;
} }
} };
import { all, call, put, select, takeEvery } from 'redux-saga/effects';
import { SagaIterator } from 'redux-saga'; import { SagaIterator } from 'redux-saga';
import { all, call, put, select, takeEvery } from 'redux-saga/effects';
import { UpdateTags, UpdateTagsRequest } from '../types'; import { UpdateTags, UpdateTagsRequest } from '../types';
import { metadataUpdateTableTags, metadataTableTags } from '../api/v0'; import { metadataUpdateTableTags, metadataTableTags } from '../api/v0';
// updateTags
export function* updateTableTagsWorker(action: UpdateTagsRequest): SagaIterator { export function* updateTableTagsWorker(action: UpdateTagsRequest): SagaIterator {
const state = yield select(); const state = yield select();
const tableData = state.tableMetadata.tableData; const tableData = state.tableMetadata.tableData;
try { try {
/* TODO: Pass explicit params into api method and not action */
yield all(metadataUpdateTableTags(action, tableData)); yield all(metadataUpdateTableTags(action, tableData));
const newTags = yield call(metadataTableTags, tableData); const newTags = yield call(metadataTableTags, tableData);
yield put({ type: UpdateTags.SUCCESS, payload: newTags }); yield put({ type: UpdateTags.SUCCESS, payload: { tags: newTags } });
} catch (e) { } catch (e) {
yield put({ type: UpdateTags.FAILURE, payload: [] }); yield put({ type: UpdateTags.FAILURE, payload: { tags: [] } });
} }
} };
export function* updateTableTagsWatcher(): SagaIterator { export function* updateTableTagsWatcher(): SagaIterator {
yield takeEvery(UpdateTags.ACTION, updateTableTagsWorker); yield takeEvery(UpdateTags.REQUEST, updateTableTagsWorker);
} };
import { PreviewData, PreviewQueryParams, TableMetadata, User } from 'components/TableDetail/types'; import {
import { UpdateTagData } from 'components/Tags/types'; PreviewData,
import { UpdateMethod } from 'components/TableDetail/OwnerEditor/types'; PreviewQueryParams,
import { Tag } from 'interfaces'; TableMetadata,
UpdateOwnerPayload,
UpdateTagData,
User,
Tag,
} from 'interfaces';
export { PreviewData, PreviewQueryParams, TableMetadata, User, Tag, UpdateMethod, UpdateTagData };
type MessageResponse = { msg: string };
type TableData = TableMetadata & {
owners: User[];
tags: Tag[];
};
export type DescriptionResponse = { description: string; } & MessageResponse;
export type LastIndexedResponse = { timestamp: string; } & MessageResponse;
export type PreviewDataResponse = { previewData: PreviewData; } & MessageResponse;
export type TableDataResponse = { tableData: TableData; } & MessageResponse;
/* getTableData */
export enum GetTableData { export enum GetTableData {
ACTION = 'amundsen/tableMetadata/GET_TABLE_DATA', REQUEST = 'amundsen/tableMetadata/GET_TABLE_DATA_REQUEST',
SUCCESS = 'amundsen/tableMetadata/GET_TABLE_DATA_SUCCESS', SUCCESS = 'amundsen/tableMetadata/GET_TABLE_DATA_SUCCESS',
FAILURE = 'amundsen/tableMetadata/GET_TABLE_DATA_FAILURE', FAILURE = 'amundsen/tableMetadata/GET_TABLE_DATA_FAILURE',
} };
export interface GetTableDataRequest { export interface GetTableDataRequest {
type: GetTableData.ACTION; type: GetTableData.REQUEST;
key: string; key: string;
searchIndex?: string; searchIndex?: string;
source?: string; source?: string;
} };
export interface GetTableDataResponse { export interface GetTableDataResponse {
type: GetTableData.SUCCESS | GetTableData.FAILURE; type: GetTableData.SUCCESS | GetTableData.FAILURE;
payload: { payload: {
...@@ -36,140 +27,137 @@ export interface GetTableDataResponse { ...@@ -36,140 +27,137 @@ export interface GetTableDataResponse {
owners: { [id: string] : User }; owners: { [id: string] : User };
tags: Tag[]; tags: Tag[];
} }
} };
/* getTableDescription */
export enum GetTableDescription { export enum GetTableDescription {
ACTION = 'amundsen/tableMetadata/GET_TABLE_DESCRIPTION', REQUEST = 'amundsen/tableMetadata/GET_TABLE_DESCRIPTION_REQUEST',
SUCCESS = 'amundsen/tableMetadata/GET_TABLE_DESCRIPTION_SUCCESS', SUCCESS = 'amundsen/tableMetadata/GET_TABLE_DESCRIPTION_SUCCESS',
FAILURE = 'amundsen/tableMetadata/GET_TABLE_DESCRIPTION_FAILURE', FAILURE = 'amundsen/tableMetadata/GET_TABLE_DESCRIPTION_FAILURE',
} };
export interface GetTableDescriptionRequest { export interface GetTableDescriptionRequest {
type: GetTableDescription.ACTION; type: GetTableDescription.REQUEST;
onSuccess?: () => any; onSuccess?: () => any;
onFailure?: () => any; onFailure?: () => any;
} };
export interface GetTableDescriptionResponse { export interface GetTableDescriptionResponse {
type: GetTableDescription.SUCCESS | GetTableDescription.FAILURE; type: GetTableDescription.SUCCESS | GetTableDescription.FAILURE;
payload: TableMetadata; payload: {
} tableMetadata: TableMetadata;
};
};
/* updateTableDescription */
export enum UpdateTableDescription { export enum UpdateTableDescription {
ACTION = 'amundsen/tableMetadata/UPDATE_TABLE_DESCRIPTION', REQUEST = 'amundsen/tableMetadata/UPDATE_TABLE_DESCRIPTION_REQUEST',
SUCCESS = 'amundsen/tableMetadata/UPDATE_TABLE_DESCRIPTION_SUCCESS', SUCCESS = 'amundsen/tableMetadata/UPDATE_TABLE_DESCRIPTION_SUCCESS',
FAILURE = 'amundsen/tableMetadata/UPDATE_TABLE_DESCRIPTION_FAILURE', FAILURE = 'amundsen/tableMetadata/UPDATE_TABLE_DESCRIPTION_FAILURE',
} };
export interface UpdateTableDescriptionRequest { export interface UpdateTableDescriptionRequest {
type: UpdateTableDescription.ACTION; type: UpdateTableDescription.REQUEST;
newValue: string; newValue: string;
onSuccess?: () => any; onSuccess?: () => any;
onFailure?: () => any; onFailure?: () => any;
} };
export interface UpdateTableDescriptionResponse { export interface UpdateTableDescriptionResponse {
type: UpdateTableDescription.SUCCESS | UpdateTableDescription.FAILURE; type: UpdateTableDescription.SUCCESS | UpdateTableDescription.FAILURE;
} };
/* getColumnDescription */
export enum GetColumnDescription { export enum GetColumnDescription {
ACTION = 'amundsen/tableMetadata/GET_COLUMN_DESCRIPTION', REQUEST = 'amundsen/tableMetadata/GET_COLUMN_DESCRIPTION_REQUEST',
SUCCESS = 'amundsen/tableMetadata/GET_COLUMN_DESCRIPTION_SUCCESS', SUCCESS = 'amundsen/tableMetadata/GET_COLUMN_DESCRIPTION_SUCCESS',
FAILURE = 'amundsen/tableMetadata/GET_COLUMN_DESCRIPTION_FAILURE', FAILURE = 'amundsen/tableMetadata/GET_COLUMN_DESCRIPTION_FAILURE',
} };
export interface GetColumnDescriptionRequest { export interface GetColumnDescriptionRequest {
type: GetColumnDescription.ACTION; type: GetColumnDescription.REQUEST;
columnIndex: number; columnIndex: number;
onSuccess?: () => any; onSuccess?: () => any;
onFailure?: () => any; onFailure?: () => any;
} };
export interface GetColumnDescriptionResponse { export interface GetColumnDescriptionResponse {
type: GetColumnDescription.SUCCESS | GetColumnDescription.FAILURE; type: GetColumnDescription.SUCCESS | GetColumnDescription.FAILURE;
payload: TableMetadata; payload: {
} tableMetadata: TableMetadata;
};
};
/* updateColumnDescription */
export enum UpdateColumnDescription { export enum UpdateColumnDescription {
ACTION = 'amundsen/tableMetadata/UPDATE_COLUMN_DESCRIPTION', REQUEST = 'amundsen/tableMetadata/UPDATE_COLUMN_DESCRIPTION_REQUEST',
SUCCESS = 'amundsen/tableMetadata/UPDATE_COLUMN_DESCRIPTION_SUCCESS', SUCCESS = 'amundsen/tableMetadata/UPDATE_COLUMN_DESCRIPTION_SUCCESS',
FAILURE = 'amundsen/tableMetadata/UPDATE_COLUMN_DESCRIPTION_FAILURE', FAILURE = 'amundsen/tableMetadata/UPDATE_COLUMN_DESCRIPTION_FAILURE',
} };
export interface UpdateColumnDescriptionRequest { export interface UpdateColumnDescriptionRequest {
type: UpdateColumnDescription.ACTION; type: UpdateColumnDescription.REQUEST;
newValue: string; newValue: string;
columnIndex: number; columnIndex: number;
onSuccess?: () => any; onSuccess?: () => any;
onFailure?: () => any; onFailure?: () => any;
} };
export interface UpdateColumnDescriptionResponse { export interface UpdateColumnDescriptionResponse {
type: UpdateColumnDescription.SUCCESS | UpdateColumnDescription.FAILURE; type: UpdateColumnDescription.SUCCESS | UpdateColumnDescription.FAILURE;
} };
/* getLastIndexed */
export enum GetLastIndexed { export enum GetLastIndexed {
ACTION = 'amundsen/tableMetadata/GET_LAST_UPDATED', REQUEST = 'amundsen/tableMetadata/GET_LAST_UPDATED_REQUEST',
SUCCESS = 'amundsen/tableMetadata/GET_LAST_UPDATED_SUCCESS', SUCCESS = 'amundsen/tableMetadata/GET_LAST_UPDATED_SUCCESS',
FAILURE = 'amundsen/tableMetadata/GET_LAST_UPDATED_FAILURE', FAILURE = 'amundsen/tableMetadata/GET_LAST_UPDATED_FAILURE',
} };
export interface GetLastIndexedRequest { export interface GetLastIndexedRequest {
type: GetLastIndexed.ACTION; type: GetLastIndexed.REQUEST;
} };
export interface GetLastIndexedResponse { export interface GetLastIndexedResponse {
type: GetLastIndexed.SUCCESS | GetLastIndexed.FAILURE; type: GetLastIndexed.SUCCESS | GetLastIndexed.FAILURE;
payload?: number; payload?: {
} lastIndexedEpoch: number;
};
};
/* getPreviewData */
export interface PreviewDataState {
data: PreviewData;
status: number | null;
}
export enum GetPreviewData { export enum GetPreviewData {
ACTION = 'amundsen/preview/GET_PREVIEW_DATA', REQUEST = 'amundsen/preview/GET_PREVIEW_DATA_REQUEST',
SUCCESS = 'amundsen/preview/GET_PREVIEW_DATA_SUCCESS', SUCCESS = 'amundsen/preview/GET_PREVIEW_DATA_SUCCESS',
FAILURE = 'amundsen/preview/GET_PREVIEW_DATA_FAILURE', FAILURE = 'amundsen/preview/GET_PREVIEW_DATA_FAILURE',
} };
export interface GetPreviewDataRequest { export interface GetPreviewDataRequest {
type: GetPreviewData.ACTION; type: GetPreviewData.REQUEST;
queryParams: PreviewQueryParams; queryParams: PreviewQueryParams;
} };
export interface GetPreviewDataResponse { export interface GetPreviewDataResponse {
type: GetPreviewData.SUCCESS | GetPreviewData.FAILURE; type: GetPreviewData.SUCCESS | GetPreviewData.FAILURE;
payload: PreviewDataState; payload: {
} data: PreviewData;
status: number | null;
};
};
/* updateTableOwner */
export interface UpdatePayload {
method: UpdateMethod;
id: string;
}
export enum UpdateTableOwner { export enum UpdateTableOwner {
ACTION = 'amundsen/tableMetadata/UPDATE_TABLE_OWNER', REQUEST = 'amundsen/tableMetadata/UPDATE_TABLE_OWNER_REQUEST',
SUCCESS = 'amundsen/tableMetadata/UPDATE_TABLE_OWNER_SUCCESS', SUCCESS = 'amundsen/tableMetadata/UPDATE_TABLE_OWNER_SUCCESS',
FAILURE = 'amundsen/tableMetadata/UPDATE_TABLE_OWNER_FAILURE', FAILURE = 'amundsen/tableMetadata/UPDATE_TABLE_OWNER_FAILURE',
} };
export interface UpdateTableOwnerRequest { export interface UpdateTableOwnerRequest {
type: UpdateTableOwner.ACTION; type: UpdateTableOwner.REQUEST;
updateArray: UpdatePayload[]; updateArray: UpdateOwnerPayload[];
onSuccess?: () => any; onSuccess?: () => any;
onFailure?: () => any; onFailure?: () => any;
} };
export interface UpdateTableOwnerResponse { export interface UpdateTableOwnerResponse {
type: UpdateTableOwner.SUCCESS | UpdateTableOwner.FAILURE; type: UpdateTableOwner.SUCCESS | UpdateTableOwner.FAILURE;
payload: { [id: string] : User }; payload: {
} owners: { [id: string] : User };
};
};
/* updateTags */
export enum UpdateTags { export enum UpdateTags {
ACTION = 'amundsen/tags/UPDATE_TAGS', REQUEST = 'amundsen/tags/UPDATE_TAGS_REQUEST',
SUCCESS = 'amundsen/tags/UPDATE_TAGS_SUCCESS', SUCCESS = 'amundsen/tags/UPDATE_TAGS_SUCCESS',
FAILURE = 'amundsen/tags/UPDATE_TAGS_FAILURE', FAILURE = 'amundsen/tags/UPDATE_TAGS_FAILURE',
} };
export interface UpdateTagsRequest { export interface UpdateTagsRequest {
type: UpdateTags.ACTION, type: UpdateTags.REQUEST,
tagArray: UpdateTagData[]; tagArray: UpdateTagData[];
} };
export interface UpdateTagsResponse { export interface UpdateTagsResponse {
type: UpdateTags.SUCCESS | UpdateTags.FAILURE, type: UpdateTags.SUCCESS | UpdateTags.FAILURE,
payload: Tag[]; payload: {
} tags: Tag[];
}
};
import axios, { AxiosResponse, AxiosError } from 'axios'; import axios, { AxiosResponse } from 'axios';
import { LoggedInUserResponse, UserResponse } from '../types'; import { LoggedInUser, PeopleUser } from 'interfaces';
export type LoggedInUserResponse = { user: LoggedInUser; msg: string; };
export type UserResponse = { user: PeopleUser; msg: string; };
export function getLoggedInUser() { export function getLoggedInUser() {
return axios.get(`/api/auth_user`) return axios.get(`/api/auth_user`)
.then((response: AxiosResponse<LoggedInUserResponse>) => { .then((response: AxiosResponse<LoggedInUserResponse>) => {
return response.data.user; return response.data.user;
}).catch((error: AxiosError) => {
return {};
}); });
} }
...@@ -15,8 +16,5 @@ export function getUserById(userId: string) { ...@@ -15,8 +16,5 @@ export function getUserById(userId: string) {
return axios.get(`/api/metadata/v0/user?user_id=${userId}`) return axios.get(`/api/metadata/v0/user?user_id=${userId}`)
.then((response: AxiosResponse<UserResponse>) => { .then((response: AxiosResponse<UserResponse>) => {
return response.data.user; return response.data.user;
})
.catch((error: AxiosError) => {
return {};
}); });
} }
import { LoggedInUser, PeopleUser } from 'interfaces';
import { import {
GetLoggedInUser, GetLoggedInUser,
GetLoggedInUserRequest, GetLoggedInUserRequest,
...@@ -5,26 +7,21 @@ import { ...@@ -5,26 +7,21 @@ import {
GetUser, GetUser,
GetUserRequest, GetUserRequest,
GetUserResponse, GetUserResponse,
LoggedInUser, User
} from './types'; } from './types';
type UserReducerAction = /* ACTIONS */
GetLoggedInUserRequest | GetLoggedInUserResponse |
GetUserRequest | GetUserResponse ;
export interface UserReducerState {
loggedInUser: LoggedInUser;
profileUser: User;
}
export function getLoggedInUser(): GetLoggedInUserRequest { export function getLoggedInUser(): GetLoggedInUserRequest {
return { type: GetLoggedInUser.ACTION }; return { type: GetLoggedInUser.REQUEST };
} };
export function getUserById(userId: string): GetUserRequest { export function getUserById(userId: string): GetUserRequest {
return { userId, type: GetUser.ACTION }; return { userId, type: GetUser.REQUEST };
} };
/* REDUCER */
export interface UserReducerState {
loggedInUser: LoggedInUser;
profileUser: PeopleUser;
};
const defaultUser = { const defaultUser = {
display_name: '', display_name: '',
...@@ -47,15 +44,15 @@ const initialState: UserReducerState = { ...@@ -47,15 +44,15 @@ const initialState: UserReducerState = {
profileUser: defaultUser, profileUser: defaultUser,
}; };
export default function reducer(state: UserReducerState = initialState, action: UserReducerAction): UserReducerState { export default function reducer(state: UserReducerState = initialState, action): UserReducerState {
switch (action.type) { switch (action.type) {
case GetLoggedInUser.SUCCESS: case GetLoggedInUser.SUCCESS:
return { ...state, loggedInUser: action.payload }; return { ...state, loggedInUser: (<GetLoggedInUserResponse>action).payload.user };
case GetUser.ACTION: case GetUser.REQUEST:
case GetUser.FAILURE: case GetUser.FAILURE:
return { ...state, profileUser: defaultUser }; return { ...state, profileUser: defaultUser };
case GetUser.SUCCESS: case GetUser.SUCCESS:
return { ...state, profileUser: action.payload }; return { ...state, profileUser: (<GetUserResponse>action).payload.user };
default: default:
return state; return state;
} }
......
...@@ -7,25 +7,23 @@ import { getLoggedInUser, getUserById } from './api/v0'; ...@@ -7,25 +7,23 @@ import { getLoggedInUser, getUserById } from './api/v0';
export function* getLoggedInUserWorker(): SagaIterator { export function* getLoggedInUserWorker(): SagaIterator {
try { try {
const user = yield call(getLoggedInUser); const user = yield call(getLoggedInUser);
yield put({ type: GetLoggedInUser.SUCCESS, payload: user }); yield put({ type: GetLoggedInUser.SUCCESS, payload: { user } });
} catch (e) { } catch (e) {
yield put({ type: GetLoggedInUser.FAILURE }); yield put({ type: GetLoggedInUser.FAILURE });
} }
} };
export function* getLoggedInUserWatcher(): SagaIterator { export function* getLoggedInUserWatcher(): SagaIterator {
yield takeEvery(GetLoggedInUser.ACTION, getLoggedInUserWorker); yield takeEvery(GetLoggedInUser.REQUEST, getLoggedInUserWorker);
} };
export function* getUserWorker(action: GetUserRequest): SagaIterator { export function* getUserWorker(action: GetUserRequest): SagaIterator {
try { try {
const user = yield call(getUserById, action.userId); const user = yield call(getUserById, action.userId);
yield put({ type: GetUser.SUCCESS, payload: user }); yield put({ type: GetUser.SUCCESS, payload: { user } });
} catch (e) { } catch (e) {
yield put({ type: GetUser.FAILURE}); yield put({ type: GetUser.FAILURE});
} }
} };
export function* getUserWatcher(): SagaIterator { export function* getUserWatcher(): SagaIterator {
yield takeEvery(GetUser.ACTION, getUserWorker); yield takeEvery(GetUser.REQUEST, getUserWorker);
} };
// Setting up different types for now so we can iterate faster as shared params change import { LoggedInUser, PeopleUser } from 'interfaces';
export interface User {
email: string;
employee_type: string;
display_name: string;
first_name: string;
full_name: string;
github_username: string;
is_active: boolean;
last_name: string;
manager_fullname: string;
profile_url: string;
role_name?: string;
slack_id: string;
team_name: string;
user_id: string;
}
export type LoggedInUser = User & {};
export type LoggedInUserResponse = { user: LoggedInUser; msg: string; };
export type UserResponse = { user: User; msg: string; };
/* getLoggedInUser */
export enum GetLoggedInUser { export enum GetLoggedInUser {
ACTION = 'amundsen/current_user/GET_ACTION', REQUEST = 'amundsen/current_user/GET_REQUEST',
SUCCESS = 'amundsen/current_user/GET_SUCCESS', SUCCESS = 'amundsen/current_user/GET_SUCCESS',
FAILURE = 'amundsen/current_user/GET_FAILURE', FAILURE = 'amundsen/current_user/GET_FAILURE',
} };
export interface GetLoggedInUserRequest { export interface GetLoggedInUserRequest {
type: GetLoggedInUser.ACTION; type: GetLoggedInUser.REQUEST;
} };
export interface GetLoggedInUserResponse { export interface GetLoggedInUserResponse {
type: GetLoggedInUser.SUCCESS | GetLoggedInUser.FAILURE; type: GetLoggedInUser.SUCCESS | GetLoggedInUser.FAILURE;
payload?: LoggedInUser; payload?: {
} user: LoggedInUser;
};
};
/* getUserById */
export enum GetUser { export enum GetUser {
ACTION = 'amundsen/user/GET_ACTION', REQUEST = 'amundsen/user/GET_REQUEST',
SUCCESS = 'amundsen/user/GET_SUCCESS', SUCCESS = 'amundsen/user/GET_SUCCESS',
FAILURE = 'amundsen/user/GET_FAILURE', FAILURE = 'amundsen/user/GET_FAILURE',
} };
export interface GetUserRequest { export interface GetUserRequest {
type: GetUser.ACTION; type: GetUser.REQUEST;
userId: string; userId: string;
} };
export interface GetUserResponse { export interface GetUserResponse {
type: GetUser.SUCCESS | GetUser.FAILURE; type: GetUser.SUCCESS | GetUser.FAILURE;
payload?: User; payload?: {
} user: PeopleUser;
};
};
import { GlobalState } from 'ducks/rootReducer'; import { GlobalState } from 'ducks/rootReducer';
import { ResourceType, SendingState } from 'interfaces';
import { SendingState } from 'components/Feedback/types';
import { ResourceType } from 'interfaces';
const globalState: GlobalState = { const globalState: GlobalState = {
announcements: { announcements: {
......
export enum UpdateMethod { export enum UpdateMethod {
PUT = 'PUT', PUT = 'PUT',
DELETE = 'DELETE', DELETE = 'DELETE',
} };
export enum SendingState {
ERROR = "error",
IDLE = "idle",
WAITING = "waiting",
COMPLETE = "complete"
};
export interface SearchAllOptions {
dashboardIndex?: number;
tableIndex?: number;
userIndex?: number;
}
import { UpdateMethod } from './Enums';
import { User } from './User';
interface PartitionData { interface PartitionData {
is_partitioned: boolean; is_partitioned: boolean;
key?: string; key?: string;
...@@ -39,11 +42,6 @@ interface TableWriter { ...@@ -39,11 +42,6 @@ interface TableWriter {
name: string; name: string;
} }
export interface User {
display_name: string;
profile_url: string;
}
export interface PreviewQueryParams { export interface PreviewQueryParams {
database: string; database: string;
schema: string; schema: string;
...@@ -86,6 +84,11 @@ export interface TableMetadata { ...@@ -86,6 +84,11 @@ export interface TableMetadata {
watermarks: Watermark[]; watermarks: Watermark[];
} }
export interface UpdateOwnerPayload {
method: UpdateMethod;
id: string;
}
export interface Watermark { export interface Watermark {
create_time: string; create_time: string;
partition_key: string; partition_key: string;
......
import { UpdateMethod } from './Enums';
export interface UpdateTagData {
methodName: UpdateMethod;
tagName: string;
}
export interface Tag { export interface Tag {
tag_count: number; tag_count: number;
tag_name: string; tag_name: string;
......
export interface User {
display_name: string;
profile_url: string;
};
// Not a good name, not sure if we can consolidate yet
// TODO: Change to User when ready.
export interface PeopleUser {
email: string;
employee_type: string;
display_name: string;
first_name: string;
full_name: string;
github_username: string;
is_active: boolean;
last_name: string;
manager_fullname: string;
profile_url: string;
role_name?: string;
slack_id: string;
team_name: string;
user_id: string;
};
export type LoggedInUser = PeopleUser & {};
export * from './Announcements'; export * from './Announcements';
export * from './Enums';
export * from './Feedback';
export * from './Resources'; export * from './Resources';
export * from './Search';
export * from './TableMetadata';
export * from './Tags'; export * from './Tags';
export * from './User';
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment