Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add feature discovery route and page #1185

Merged
merged 5 commits into from
Jun 9, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,47 @@ const configDefault: AppConfig = {
],
notices: {},
},
[ResourceType.feature]: {
displayName: 'ML Features',
supportedSources: {
bigquery: {
displayName: 'BigQuery',
iconClass: 'icon-bigquery',
},
delta: {
displayName: 'Delta',
iconClass: 'icon-delta',
},
dremio: {
displayName: 'Dremio',
iconClass: 'icon-dremio',
},
druid: {
displayName: 'Druid',
iconClass: 'icon-druid',
},
hive: {
displayName: 'Hive',
iconClass: 'icon-hive',
},
presto: {
displayName: 'Presto',
iconClass: 'icon-presto',
},
postgres: {
displayName: 'Postgres',
iconClass: 'icon-postgres',
},
redshift: {
displayName: 'Redshift',
iconClass: 'icon-redshift',
},
snowflake: {
displayName: 'Snowflake',
iconClass: 'icon-snowflake',
},
},
},
[ResourceType.table]: {
displayName: 'Datasets',
supportedSources: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ interface ResourceConfig {
[ResourceType.dashboard]: BaseResourceConfig;
[ResourceType.table]: TableResourceConfig;
[ResourceType.user]: BaseResourceConfig;
[ResourceType.feature]: BaseResourceConfig;
}

/**
Expand Down
Empty file.
33 changes: 33 additions & 0 deletions frontend/amundsen_application/static/js/ducks/feature/api/v0.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import axios, { AxiosResponse } from 'axios';
import * as qs from 'simple-query-string';

import { FeatureMetadata } from 'interfaces/Feature';

export type GetFeatureAPI = {
msg: string;
featureData: FeatureMetadata;
};

const FEATURE_BASE = '/api/metadata/v0';

export function getFeature(key: string, index?: string, source?: string) {
const queryParams = qs.stringify({ key, index, source });
return axios
.get(`${FEATURE_BASE}/feature?${queryParams}`)
.then((response: AxiosResponse<GetFeatureAPI>) => {
const { data, status } = response;
return {
feature: data.featureData,
statusCode: status,
};
})
.catch((e) => {
const { response } = e;
const statusMessage = response.data?.msg;
const statusCode = response ? response.status || 500 : 500;
return Promise.reject({
statusCode,
statusMessage,
});
});
}
Empty file.
105 changes: 105 additions & 0 deletions frontend/amundsen_application/static/js/ducks/feature/reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import {
GetFeature,
GetFeatureRequest,
GetFeatureResponse,
GetFeaturePayload,
} from 'ducks/feature/types';
import { FeatureMetadata } from 'interfaces/Feature';

/* Actions */

export function getFeature(
key: string,
index?: string,
source?: string
): GetFeatureRequest {
return {
payload: {
key,
index,
source,
},
type: GetFeature.REQUEST,
};
}

export function getFeatureSuccess(payload: GetFeaturePayload) {
return {
payload,
type: GetFeature.SUCCESS,
};
}

export function getFeatureFailure(
payload: GetFeaturePayload
): GetFeatureResponse {
return {
payload,
type: GetFeature.FAILURE,
};
}

/* Reducer */

export interface FeatureReducerState {
isLoading: boolean;
statusCode: number | null;
feature: FeatureMetadata;
}

export const initialFeatureState: FeatureMetadata = {
key: '',
name: '',
version: '',
status: '',
feature_group: '',
entity: [],
data_type: '',
availability: [],
description: '',
owners: [],
badges: [],
owner_tags: [],
tags: [],
programmatic_descriptions: [],
watermarks: [],
stats: [],
last_updated_timestamp: 0,
created_timestamp: 0,
};

export const initialState: FeatureReducerState = {
isLoading: true,
statusCode: null,
feature: initialFeatureState,
};

export default function reducer(
state: FeatureReducerState = initialState,
action
): FeatureReducerState {
switch (action.type) {
case GetFeature.REQUEST:
return {
...state,
statusCode: null,
isLoading: true,
};
case GetFeature.FAILURE:
return {
...state,
isLoading: false,
statusCode: action.payload.statusCode,
feature: initialFeatureState,
};
case GetFeature.SUCCESS:
return {
...state,
isLoading: false,
statusCode: action.payload.statusCode,
feature: action.payload.feature,
};
default:
return state;
}
}
Empty file.
21 changes: 21 additions & 0 deletions frontend/amundsen_application/static/js/ducks/feature/sagas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { SagaIterator } from 'redux-saga';
import { call, put, takeEvery } from 'redux-saga/effects';

import * as API from './api/v0';
import { getFeatureSuccess, getFeatureFailure } from './reducer';
import { GetFeature } from './types';

export function* getFeatureWorker(action): SagaIterator {
try {
const { key, searchIndex, source } = action.payload;
const response = yield call(API.getFeature, key, searchIndex, source);

yield put(getFeatureSuccess(response));
} catch (error) {
yield put(getFeatureFailure(error));
}
}

export function* getFeatureWatcher(): SagaIterator {
yield takeEvery(GetFeature.REQUEST, getFeatureWorker);
}
27 changes: 27 additions & 0 deletions frontend/amundsen_application/static/js/ducks/feature/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { FeatureMetadata } from 'interfaces/Feature';

export enum GetFeature {
REQUEST = 'amundsen/feature/GET_FEATURE_REQUEST',
SUCCESS = 'amundsen/feature/GET_FEATURE_SUCCESS',
FAILURE = 'amundsen/feature/GET_FEATURE_FAILURE',
}

export interface GetFeatureRequest {
type: GetFeature.REQUEST;
payload: {
key: string;
index?: string;
source?: string;
};
}

export interface GetFeatureResponse {
type: GetFeature.SUCCESS | GetFeature.FAILURE;
payload: GetFeaturePayload;
}

export interface GetFeaturePayload {
feature?: FeatureMetadata;
statusCode?: number;
statusMessage?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { combineReducers } from 'redux';

import dashboard, { DashboardReducerState } from 'ducks/dashboard/reducer';
import feature, { FeatureReducerState } from 'ducks/feature/reducer';
import announcements, { AnnouncementsReducerState } from './announcements';
import feedback, { FeedbackReducerState } from './feedback/reducer';
import popularTables, {
Expand All @@ -26,6 +27,7 @@ export interface GlobalState {
announcements: AnnouncementsReducerState;
bookmarks: BookmarkReducerState;
dashboard: DashboardReducerState;
feature: FeatureReducerState;
feedback: FeedbackReducerState;
issue: IssueReducerState;
notification: NotificationReducerState;
Expand All @@ -43,6 +45,7 @@ const rootReducer = combineReducers<GlobalState>({
announcements,
bookmarks,
dashboard,
feature,
feedback,
issue,
notification,
Expand Down
5 changes: 5 additions & 0 deletions frontend/amundsen_application/static/js/ducks/rootSaga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ import {

// Dashboard
import { getDashboardWatcher } from 'ducks/dashboard/sagas';
import { getFeatureWatcher } from 'ducks/feature/sagas';
import { getAnnouncementsWatcher } from './announcements/sagas';

// Notifications
import { submitNotificationWatcher } from './notification/sagas';

// Feature

// FeedbackForm
import { submitFeedbackWatcher } from './feedback/sagas';

Expand Down Expand Up @@ -84,6 +87,8 @@ export default function* rootSaga() {
getDashboardWatcher(),
// Notification
submitNotificationWatcher(),
// Feature
getFeatureWatcher(),
// FeedbackForm
submitFeedbackWatcher(),
// Issues
Expand Down
24 changes: 24 additions & 0 deletions frontend/amundsen_application/static/js/fixtures/globalState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,30 @@ const globalState: GlobalState = {
statusCode: 200,
dashboard: dashboardMetadata,
},
feature: {
statusCode: 200,
isLoading: false,
feature: {
key: '',
name: '',
version: '',
status: '',
feature_group: '',
entity: [],
data_type: '',
availability: [],
description: '',
owners: [],
badges: [],
owner_tags: [],
tags: [],
programmatic_descriptions: [],
watermarks: [],
stats: [],
last_updated_timestamp: 0,
created_timestamp: 0,
},
},
feedback: {
sendState: SendingState.IDLE,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { FeatureMetadata, FeatureSummary } from 'interfaces/Feature';

export const featureSummary: FeatureSummary = {
key: 'test key',
name: 'test feature name',
version: '1.02.0',
availability: ['source 1', 'source 2'],
entity: ['entity 1', 'entity 2'],
description: 'test feature description',
};

export const featureMetadata: FeatureMetadata = {
key: 'test key',
name: 'test feature name',
version: '1.02.0',
status: 'status',
feature_group: 'feature group',
entity: ['entity 1', 'entity 2'],
data_type: 'string',
availability: ['source 1', 'source 2'],
description: 'test feature description',
owners: [
{
display_name: 'test',
email: 'test@email.com',
profile_url: 'profile_url',
user_id: 'user_id',
},
],
badges: [],
owner_tags: [],
tags: [],
programmatic_descriptions: [],
watermarks: [],
stats: [],
last_updated_timestamp: 0,
created_timestamp: 0,
};
4 changes: 3 additions & 1 deletion frontend/amundsen_application/static/js/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ import { pageViewed } from 'ducks/ui';
import rootReducer from 'ducks/rootReducer';
import rootSaga from 'ducks/rootSaga';

import DashboardPage from './pages/DashboardPage';
import AnnouncementPage from './pages/AnnouncementPage';
import BrowsePage from './pages/BrowsePage';
import DashboardPage from './pages/DashboardPage';
import FeaturePage from './pages/FeaturePage';
import HomePage from './pages/HomePage';
import NotFoundPage from './pages/NotFoundPage';
import SearchPage from './pages/SearchPage';
Expand Down Expand Up @@ -64,6 +65,7 @@ const Routes: React.FC = () => {
<Route path="/announcements" component={AnnouncementPage} />
<Route path="/browse" component={BrowsePage} />
<Route path="/dashboard/:uri" component={DashboardPage} />
<Route path="/feature/:group/:name/:version" component={FeaturePage} />
<Route path="/search" component={SearchPage} />
<Route
path="/table_detail/:cluster/:database/:schema/:table"
Expand Down
Loading