Skip to content

Commit

Permalink
Merge feature people (amundsen-io#71)
Browse files Browse the repository at this point in the history
* Added support for UserListItems (amundsen-io#43)

* Added support for UserListItem
- Restyled ResourceListItem to support multiple columns
- Added timestamp for TableListItem
- Added UserListItem
- Added $text-medium and $text-light

* Cleanup and PR feedback
- Added Alumni Flag to UserListItem
- Changed usage of Flag LabelStyle to exclude the 'label-' prefix
- Added more space for 'Frequent Users' in TableListItem

* Skeleton implementation of ProfilePage w/ mock data (amundsen-io#44)

* Skeleton implementation w/ mock data

* Some tweaks

* Fix lint errors

* Switch profile icons to btn-flat-icon

* currentUser -> loggedInUser & profilePageUser -> profileUser

* Make a Breadcrumb component

* tweak

* Added support for UserListItems (amundsen-io#43)

* Added support for UserListItem
- Restyled ResourceListItem to support multiple columns
- Added timestamp for TableListItem
- Added UserListItem
- Added $text-medium and $text-light

* Cleanup and PR feedback
- Added Alumni Flag to UserListItem
- Changed usage of Flag LabelStyle to exclude the 'label-' prefix
- Added more space for 'Frequent Users' in TableListItem

* Skeleton implementation w/ mock data

* Some tweaks

* Fix lint errors

* Switch profile icons to btn-flat-icon

* currentUser -> loggedInUser & profilePageUser -> profileUser

* Make a Breadcrumb component

* tweak

* Updated search APIs to support multiple types (amundsen-io#48)

* Updated search APIs to support multiple types
- User search just returns mocked data

* Updated search API tests

* Add breadcrumbs + fix to tableData state management (amundsen-io#49)

* Update search to support multiple resource types (amundsen-io#51)

* Added Tabs to search results
*Split executeSearch into two actions:
- `searchAll` will search all resource types. The options allow you to search different page indexes for different resources. This is useful for loading up &selectedTab=users&tabIndex=5, since you don't necessarily want to fetch page 5 for all tabs.
- `searchResource` will run a search on a single resource type. This is primarily used for search pagination.
The URL should always reflect the current state of the search and can be refreshed or shared to maintain state.

* Improved state management with window URL and user actions
(search submit, pagination, tab change)

* changed 'last_updated' to 'last_updated_epoch' (amundsen-io#53)

- Conditionally hide the timestamp when not present

* Feature people design overhaul (amundsen-io#55)

Overhaul of UI
- NavBar - Resized to 48px, rework bottom border with box-shadow
- Search Bar - Simplify DOM elements, height 60px, font 24px bold, narrower in md, lg screens.
- Container top margin at 96, 64, 32px for lg, md, sm screens.
- Search results has 16px top and bottom
- Consolidated buttons classes to: btn-primary btn-default
- Reworked Tag buttons and labels
- Fixed panel border radiuses
- Fixed NavBar active state highlighting

* Rebase Design Overhaul from Master (amundsen-io#58)

* Overhaul of UI Part 1 (amundsen-io#54)

Overhaul of UI
- NavBar - Resized to 48px, rework bottom border with box-shadow
- Search Bar - Simplify DOM elements, height 60px, font 24px bold, narrower in md, lg screens.
- Container top margin at 96, 64, 32px for lg, md, sm screens.
- Search results has 16px top and bottom
- Consolidated buttons classes to: btn-primary btn-default
- Reworked Tag buttons and labels
- Fixed panel border radiuses
- Fixed NavBar active state highlighting

* Design Overhaul pt2 (amundsen-io#57)

* Design Overhaul pt2
- Standardized button colors, sizes, icons
- Text colors split into $text-dark, $text-medium, and $text-light
- Fixed some styles on search bar
- Updated TagInfo and TagInput
- Made popover colors darker

* Added support for UserListItems (amundsen-io#43)

* Added support for UserListItem
- Restyled ResourceListItem to support multiple columns
- Added timestamp for TableListItem
- Added UserListItem
- Added $text-medium and $text-light

* Cleanup and PR feedback
- Added Alumni Flag to UserListItem
- Changed usage of Flag LabelStyle to exclude the 'label-' prefix
- Added more space for 'Frequent Users' in TableListItem

* Skeleton implementation of ProfilePage w/ mock data (amundsen-io#44)

* Skeleton implementation w/ mock data

* Some tweaks

* Fix lint errors

* Switch profile icons to btn-flat-icon

* currentUser -> loggedInUser & profilePageUser -> profileUser

* Make a Breadcrumb component

* tweak

* Added support for UserListItems (amundsen-io#43)

* Added support for UserListItem
- Restyled ResourceListItem to support multiple columns
- Added timestamp for TableListItem
- Added UserListItem
- Added $text-medium and $text-light

* Cleanup and PR feedback
- Added Alumni Flag to UserListItem
- Changed usage of Flag LabelStyle to exclude the 'label-' prefix
- Added more space for 'Frequent Users' in TableListItem

* Skeleton implementation w/ mock data

* Some tweaks

* Fix lint errors

* Switch profile icons to btn-flat-icon

* currentUser -> loggedInUser & profilePageUser -> profileUser

* Make a Breadcrumb component

* tweak

* Updated search APIs to support multiple types (amundsen-io#48)

* Updated search APIs to support multiple types
- User search just returns mocked data

* Updated search API tests

* Add breadcrumbs + fix to tableData state management (amundsen-io#49)

* Update search to support multiple resource types (amundsen-io#51)

* Added Tabs to search results
*Split executeSearch into two actions:
- `searchAll` will search all resource types. The options allow you to search different page indexes for different resources. This is useful for loading up &selectedTab=users&tabIndex=5, since you don't necessarily want to fetch page 5 for all tabs.
- `searchResource` will run a search on a single resource type. This is primarily used for search pagination.
The URL should always reflect the current state of the search and can be refreshed or shared to maintain state.

* Improved state management with window URL and user actions
(search submit, pagination, tab change)

* changed 'last_updated' to 'last_updated_epoch' (amundsen-io#53)

- Conditionally hide the timestamp when not present

* Feature people design overhaul (amundsen-io#55)

Overhaul of UI
- NavBar - Resized to 48px, rework bottom border with box-shadow
- Search Bar - Simplify DOM elements, height 60px, font 24px bold, narrower in md, lg screens.
- Container top margin at 96, 64, 32px for lg, md, sm screens.
- Search results has 16px top and bottom
- Consolidated buttons classes to: btn-primary btn-default
- Reworked Tag buttons and labels
- Fixed panel border radiuses
- Fixed NavBar active state highlighting

* Fix some issues with rebasing ui overhaul from master

* Pull changes from amundsen-io#56 into feature/people (amundsen-io#60)

* Overhaul of UI Part 1 (amundsen-io#54)

Overhaul of UI
- NavBar - Resized to 48px, rework bottom border with box-shadow
- Search Bar - Simplify DOM elements, height 60px, font 24px bold, narrower in md, lg screens.
- Container top margin at 96, 64, 32px for lg, md, sm screens.
- Search results has 16px top and bottom
- Consolidated buttons classes to: btn-primary btn-default
- Reworked Tag buttons and labels
- Fixed panel border radiuses
- Fixed NavBar active state highlighting

* Design Overhaul pt2 (amundsen-io#57)

* Design Overhaul pt2
- Standardized button colors, sizes, icons
- Text colors split into $text-dark, $text-medium, and $text-light
- Fixed some styles on search bar
- Updated TagInfo and TagInput
- Made popover colors darker

* Consolidate Containers (amundsen-io#56)

* Consolidate un-nested containers

* Consolidate TableDetail related containers

* Consolidate FeedbackForms

* Fix merge mistakes

* Update styles

* - Disabled/Hid most Amundsen people related features
- Fixed list-group-item padding issues and border
- Adjusted column stats hover colors
- Adjusted Breadcrum styles
  • Loading branch information
Daniel committed Apr 11, 2019
1 parent 811ffe1 commit dd9c8c0
Show file tree
Hide file tree
Showing 52 changed files with 1,427 additions and 421 deletions.
31 changes: 31 additions & 0 deletions frontend/amundsen_application/api/metadata/v0.py
Expand Up @@ -553,3 +553,34 @@ def _log_update_table_tags(*, table_key: str, method: str, tag: str) -> None:
logging.exception(message)
payload = jsonify({'msg': message})
return make_response(payload, HTTPStatus.INTERNAL_SERVER_ERROR)


# TODO: Implement real support
@metadata_blueprint.route('/user', methods=['GET'])
def get_user() -> Response:
try:
user_id = get_query_param(request.args, 'user_id')
user_info = {
'first_name': 'Firstname',
'last_name': 'Lastname',
'email': 'test@test.com',
'display_name': 'Firstname Lastname',
'profile_url': 'https://github.com/lyft/amundsenfrontendlibrary',
'user_id': user_id,
'github_name': 'lyft',
'is_active': True,
'manager_name': 'Roald Amundsen',
'role_name': 'Software Engineer',
'slack_url': 'https://slack.com',
'team_name': 'Amundsen Team',
}
if user_id == 'alumni':
user_info['is_active'] = False

status_code = HTTPStatus.OK
payload = jsonify({'user': user_info})
return make_response(payload, status_code)
except Exception as e:
message = 'Encountered exception: ' + str(e)
logging.exception(message)
return make_response(jsonify({'user': {}, 'msg': message}), HTTPStatus.INTERNAL_SERVER_ERROR)
140 changes: 128 additions & 12 deletions frontend/amundsen_application/api/search/v0.py
Expand Up @@ -53,16 +53,29 @@ def _validate_search_term(*, search_term: str, page_index: int) -> Optional[Resp
return None


@search_blueprint.route('/', methods=['GET'])
def search() -> Response:
@search_blueprint.route('/table', methods=['GET'])
def search_table() -> Response:
search_term = get_query_param(request.args, 'query', 'Endpoint takes a "query" parameter')
page_index = get_query_param(request.args, 'page_index', 'Endpoint takes a "page_index" parameter')

error_response = _validate_search_term(search_term=search_term, page_index=int(page_index))
if error_response is not None:
return error_response

results_dict = _search(search_term=search_term, page_index=page_index)
results_dict = _search_table(search_term=search_term, page_index=page_index)
return make_response(jsonify(results_dict), results_dict.get('status_code', HTTPStatus.INTERNAL_SERVER_ERROR))


@search_blueprint.route('/user', methods=['GET'])
def search_user() -> Response:
search_term = get_query_param(request.args, 'query', 'Endpoint takes a "query" parameter')
page_index = get_query_param(request.args, 'page_index', 'Endpoint takes a "page_index" parameter')

error_response = _validate_search_term(search_term=search_term, page_index=int(page_index))
if error_response is not None:
return error_response

results_dict = _search_user(search_term=search_term, page_index=page_index)
return make_response(jsonify(results_dict), results_dict.get('status_code', HTTPStatus.INTERNAL_SERVER_ERROR))


Expand Down Expand Up @@ -98,21 +111,119 @@ def _create_url_with_field(*, search_term: str, page_index: int) -> str:
return url


# TODO - Implement these functions
def _search_tables(*, search_term: str, page_index: int) -> Dict[str, Any]:
return {}
@action_logging
def _search_user(*, search_term: str, page_index: int) -> Dict[str, Any]:
"""
call the search service endpoint and return matching results
:return: a json output containing search results array as 'results'
Schema Defined Here: https://github.com/lyft/
amundsensearchlibrary/blob/master/search_service/api/search.py
def _search_dashboards(*, search_term: str, page_index: int) -> Dict[str, Any]:
return {}
TODO: Define an interface for envoy_client
"""

def _map_user_result(result: Dict) -> Dict:
return {
'type': 'user',
'active': result.get('active', None),
'birthday': result.get('birthday', None),
'department': result.get('department', None),
'email': result.get('email', None),
'first_name': result.get('first_name', None),
'github_username': result.get('github_username', None),
'id': result.get('id', None),
'last_name': result.get('last_name', None),
'manager_email': result.get('manager_email', None),
'name': result.get('name', None),
'offboarded': result.get('offboarded', None),
'office': result.get('office', None),
'role': result.get('role', None),
'start_date': result.get('start_date', None),
'team_name': result.get('team_name', None),
'title': result.get('title', None),
}

users = {
'page_index': int(page_index),
'results': [],
'total_results': 0,
}

def _search_people(*, search_term: str, page_index: int) -> Dict[str, Any]:
return {}
results_dict = {
'search_term': search_term,
'msg': 'Success',
'status_code': HTTPStatus.OK,
'users': users,
}

# TEST CODE
users['total_results'] = 3
users['results'] = [
{
'type': 'user',
'active': True,
'birthday': '10-10-2000',
'department': 'Department',
'email': 'mail@address.com',
'first_name': 'Ash',
'github_username': 'github_user',
'id': 12345,
'last_name': 'Ketchum',
'manager_email': 'manager_email',
'name': 'Ash Ketchum',
'offboarded': False,
'office': 'Kanto Region',
'role': 'Pokemon Trainer',
'start_date': '05-04-2016',
'team_name': 'Kanto Trainers',
'title': 'Pokemon Master',
},
{
'type': 'user',
'active': True,
'birthday': '06-01-2000',
'department': 'Department',
'email': 'mail@address.com',
'first_name': 'Gary',
'github_username': 'github_user',
'id': 12345,
'last_name': 'Oak',
'manager_email': 'manager_email',
'name': 'Gary Oak',
'offboarded': False,
'office': 'Kanto Region',
'role': 'Pokemon Trainer',
'start_date': '05-04-2016',
'team_name': 'Kanto Trainers',
'title': 'Pokemon Master',
},
{
'type': 'user',
'active': False,
'birthday': '06-01-60',
'department': 'Department',
'email': 'mail@address.com',
'first_name': 'Professor',
'github_username': 'github_user',
'id': 12345,
'last_name': 'Oak',
'manager_email': 'manager_email',
'name': 'Professor Oak',
'offboarded': False,
'office': 'Kanto Region',
'role': 'Scientist',
'start_date': '05-04-2016',
'team_name': 'Team Oak',
'title': 'Pokemon Researcher',
},
]

return results_dict


@action_logging
def _search(*, search_term: str, page_index: int) -> Dict[str, Any]:
def _search_table(*, search_term: str, page_index: int) -> Dict[str, Any]:
"""
call the search service endpoint and return matching results
:return: a json output containing search results array as 'results'
Expand All @@ -131,7 +242,7 @@ def _map_table_result(result: Dict) -> Dict:
'description': result.get('description', None),
'database': result.get('database', None),
'schema_name': result.get('schema_name', None),
'last_updated': result.get('last_updated', None),
'last_updated_epoch': result.get('last_updated_epoch', None),
}

tables = {
Expand Down Expand Up @@ -183,3 +294,8 @@ def _map_table_result(result: Dict) -> Dict:
results_dict['msg'] = message
logging.exception(message)
return results_dict


# TODO - Implement
def _search_dashboard(*, search_term: str, page_index: int) -> Dict[str, Any]:
return {}
8 changes: 4 additions & 4 deletions frontend/amundsen_application/api/v0.py
Expand Up @@ -11,11 +11,11 @@
blueprint = Blueprint('api', __name__, url_prefix='/api')


@blueprint.route('/current_user', methods=['GET'])
@blueprint.route('/auth_user', methods=['GET'])
def current_user() -> Response:
if (app.config['CURRENT_USER_METHOD']):
user = app.config['CURRENT_USER_METHOD'](app)
if (app.config['AUTH_USER_METHOD']):
user = app.config['AUTH_USER_METHOD'](app)
else:
user = load_user({'display_name': '*'})
user = load_user({'user_id': 'undefined', 'display_name': '*'})

return user.to_json()
2 changes: 1 addition & 1 deletion frontend/amundsen_application/config.py
Expand Up @@ -39,7 +39,7 @@ class LocalConfig(Config):
'http://{LOCAL_HOST}:{PORT}/tags'.format(LOCAL_HOST=LOCAL_HOST, PORT=METADATA_PORT)
METADATASERVICE_REQUEST_HEADERS = None

CURRENT_USER_METHOD = None
AUTH_USER_METHOD = None
GET_PROFILE_URL = None

MAIL_CLIENT = None
4 changes: 2 additions & 2 deletions frontend/amundsen_application/log/action_log.py
Expand Up @@ -76,8 +76,8 @@ def _build_metrics(func_name: str,
metrics['pos_args_json'] = json.dumps(args)
metrics['keyword_args_json'] = json.dumps(kwargs)

if flask_app.config['CURRENT_USER_METHOD']:
metrics['user'] = flask_app.config['CURRENT_USER_METHOD'](flask_app).email
if flask_app.config['AUTH_USER_METHOD']:
metrics['user'] = flask_app.config['AUTH_USER_METHOD'](flask_app).email
else:
metrics['user'] = getpass.getuser()

Expand Down
30 changes: 29 additions & 1 deletion frontend/amundsen_application/models/user.py
Expand Up @@ -13,18 +13,36 @@


class User:
# TODO: alphabetize after we have the real params
def __init__(self,
first_name: str = None,
last_name: str = None,
email: str = None,
display_name: str = None,
profile_url: str = None) -> None:
profile_url: str = None,
user_id: str = None,
github_name: str = None,
is_active: bool = True,
manager_name: str = None,
role_name: str = None,
slack_url: str = None,
team_name: str = None) -> None:
self.first_name = first_name
self.last_name = last_name
self.email = email
self.display_name = display_name
self.profile_url = profile_url

# TODO: modify the following names as needed after backend support is implemented
self.user_id = user_id
self.github_name = github_name
self.is_active = is_active
self.manager_name = manager_name
self.role_name = role_name
self.slack_url = slack_url
self.team_name = team_name
# TODO: frequent_used, bookmarked, & owned resources

def to_json(self) -> Response:
user_info = dump_user(self)
return jsonify(user_info)
Expand All @@ -37,6 +55,14 @@ class UserSchema(Schema):
display_name = fields.Str(required=True)
profile_url = fields.Str(allow_none=True)

user_id = fields.Str(required=True)
github_name = fields.Str(allow_none=True)
is_active = fields.Bool(allow_none=True)
manager_name = fields.Str(allow_none=True)
role_name = fields.Str(allow_none=True)
slack_url = fields.Str(allow_none=True)
team_name = fields.Str(allow_none=True)

@pre_load
def generate_display_name(self, data: Dict) -> Dict:
if data.get('display_name', None):
Expand Down Expand Up @@ -67,6 +93,8 @@ def make_user(self, data: Dict) -> User:
def validate_user(self, data: Dict) -> None:
if not data.get('display_name', None):
raise ValidationError('One or more must be provided: "first_name", "last_name", "email", "display_name"')
if not data.get('user_id', None):
raise ValidationError('"user_id" must be provided')


def load_user(user_data: Dict) -> User:
Expand Down
20 changes: 20 additions & 0 deletions frontend/amundsen_application/static/css/_icons.scss
Expand Up @@ -31,6 +31,11 @@ img.icon {
mask-image: url('/static/images/icons/Down.svg');
}

&.icon-github {
-webkit-mask-image: url('/static/images/icons/github.svg');
mask-image: url('/static/images/icons/github.svg');
}

&.icon-left {
-webkit-mask-image: url('/static/images/icons/Left.svg');
mask-image: url('/static/images/icons/Left.svg');
Expand All @@ -41,6 +46,11 @@ img.icon {
mask-image: url('/static/images/icons/Loader.svg');
}

&.icon-mail {
-webkit-mask-image: url('/static/images/icons/mail.svg');
mask-image: url('/static/images/icons/mail.svg');
}

&.icon-plus-circle {
-webkit-mask-image: url('/static/images/icons/Plus-Circle.svg');
mask-image: url('/static/images/icons/Plus-Circle.svg');
Expand All @@ -61,10 +71,20 @@ img.icon {
mask-image: url('/static/images/icons/Search.svg');
}

&.icon-slack {
-webkit-mask-image: url('/static/images/icons/slack.svg');
mask-image: url('/static/images/icons/slack.svg');
}

&.icon-up {
-webkit-mask-image: url('/static/images/icons/Up.svg');
mask-image: url('/static/images/icons/Up.svg');
}

&.icon-users {
-webkit-mask-image: url('/static/images/icons/users.svg');
mask-image: url('/static/images/icons/users.svg');
}
}

.disabled,
Expand Down
Expand Up @@ -6,8 +6,7 @@
border-left: none;
border-right: none;
cursor: pointer;
padding-left: 4px;
padding-right: 4px;
padding: 0;

&:hover {
border-color: $gray;
Expand Down
1 change: 0 additions & 1 deletion frontend/amundsen_application/static/css/_variables.scss
Expand Up @@ -4,4 +4,3 @@
@import 'variables-custom';
// Bootstrap Default Values
@import '~bootstrap-sass/assets/stylesheets/bootstrap/variables';

6 changes: 5 additions & 1 deletion frontend/amundsen_application/static/css/styles.scss
Expand Up @@ -35,7 +35,6 @@ form {
margin-bottom: 0;
}


input {
&::-webkit-input-placeholder,
&::-moz-placeholder,
Expand All @@ -46,3 +45,8 @@ input {
}
}

.truncated {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/amundsen_application/static/images/icons/mail.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit dd9c8c0

Please sign in to comment.