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 authored Apr 11, 2019
1 parent a7518e8 commit 7b09a2f
Show file tree
Hide file tree
Showing 52 changed files with 1,427 additions and 421 deletions.
31 changes: 31 additions & 0 deletions amundsen_application/api/metadata/v0.py
Original file line number Diff line number Diff line change
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 amundsen_application/api/search/v0.py
Original file line number Diff line number Diff line change
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 amundsen_application/api/v0.py
Original file line number Diff line number Diff line change
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 amundsen_application/config.py
Original file line number Diff line number Diff line change
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 amundsen_application/log/action_log.py
Original file line number Diff line number Diff line change
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 amundsen_application/models/user.py
Original file line number Diff line number Diff line change
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 amundsen_application/static/css/_icons.scss
Original file line number Diff line number Diff line change
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
3 changes: 1 addition & 2 deletions amundsen_application/static/css/_list-group-item.scss
Original file line number Diff line number Diff line change
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 amundsen_application/static/css/_variables.scss
Original file line number Diff line number Diff line change
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 amundsen_application/static/css/styles.scss
Original file line number Diff line number Diff line change
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;
}
1 change: 1 addition & 0 deletions amundsen_application/static/images/icons/github.svg
Loading
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 amundsen_application/static/images/icons/mail.svg
Loading
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 amundsen_application/static/images/icons/slack.svg
Loading
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 amundsen_application/static/images/icons/users.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7b09a2f

Please sign in to comment.