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