Merge master branch
authorMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Thu, 14 Jun 2018 07:32:36 +0000 (09:32 +0200)
committerMichal Klobukowski <michal.klobukowski@contractors.roche.com>
Thu, 14 Jun 2018 07:32:36 +0000 (09:32 +0200)
Feature #13590

Arvados-DCO-1.1-Signed-off-by: Michal Klobukowski <michal.klobukowski@contractors.roche.com>

1  2 
src/components/api-token/api-token.tsx
src/services/auth-service/auth-service.ts
src/services/project-service/project-service.ts
src/store/auth/auth-reducer.ts

index b6616d38bf4942ad5d8442b29fb02ad8de95c608,d63f6e07336d6ee4d9d788c556a92c4737497c08..7656bf873368308f93947d943342d8de3c1471d5
@@@ -17,17 -17,19 +17,19 @@@ class ApiToken extends React.Component<
          const regex = new RegExp('[\\?&]' + safeName + '=([^&#]*)');
          const results = regex.exec(search);
          return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
 -    };
 +    }
  
      componentDidMount() {
          const search = this.props.location ? this.props.location.search : "";
          const apiToken = ApiToken.getUrlParameter(search, 'api_token');
          this.props.dispatch(authActions.SAVE_API_TOKEN(apiToken));
-         this.props.dispatch(authService.getUserDetails());
-         this.props.dispatch(projectService.getProjectList());
+         this.props.dispatch<any>(authService.getUserDetails()).then(() => {
+             const rootUuid = authService.getRootUuid();
+             this.props.dispatch(projectService.getProjectList(rootUuid));
+         });
      }
      render() {
 -        return <Redirect to="/"/>
 +        return <Redirect to="/"/>;
      }
  }
  
index 4e5013807fd7a0ce8e3a41dac2dc52f79dcf7d15,07e0ff0913834ebdda8e72e0131332a933ded949..5878dc6ed5f01e9dc5657d122d41239fc005554d
@@@ -11,11 -11,15 +11,15 @@@ export const API_TOKEN_KEY = 'apiToken'
  export const USER_EMAIL_KEY = 'userEmail';
  export const USER_FIRST_NAME_KEY = 'userFirstName';
  export const USER_LAST_NAME_KEY = 'userLastName';
+ export const USER_UUID_KEY = 'userUuid';
+ export const USER_OWNER_UUID_KEY = 'userOwnerUuid';
  
  export interface UserDetailsResponse {
      email: string;
      first_name: string;
      last_name: string;
+     uuid: string;
+     owner_uuid: string;
      is_admin: boolean;
  }
  
@@@ -33,12 -37,19 +37,19 @@@ export default class AuthService 
          return localStorage.getItem(API_TOKEN_KEY) || undefined;
      }
  
+     public getOwnerUuid() {
+         return localStorage.getItem(USER_OWNER_UUID_KEY) || undefined;
+     }
      public getUser(): User | undefined {
          const email = localStorage.getItem(USER_EMAIL_KEY);
          const firstName = localStorage.getItem(USER_FIRST_NAME_KEY);
          const lastName = localStorage.getItem(USER_LAST_NAME_KEY);
-         return email && firstName && lastName
-             ? { email, firstName, lastName }
+         const uuid = localStorage.getItem(USER_UUID_KEY);
+         const ownerUuid = localStorage.getItem(USER_OWNER_UUID_KEY);
+         return email && firstName && lastName && uuid && ownerUuid
+             ? { email, firstName, lastName, uuid, ownerUuid }
              : undefined;
      }
  
          localStorage.setItem(USER_EMAIL_KEY, user.email);
          localStorage.setItem(USER_FIRST_NAME_KEY, user.firstName);
          localStorage.setItem(USER_LAST_NAME_KEY, user.lastName);
+         localStorage.setItem(USER_UUID_KEY, user.uuid);
+         localStorage.setItem(USER_OWNER_UUID_KEY, user.ownerUuid);
      }
  
      public removeUser() {
          localStorage.removeItem(USER_EMAIL_KEY);
          localStorage.removeItem(USER_FIRST_NAME_KEY);
          localStorage.removeItem(USER_LAST_NAME_KEY);
+         localStorage.removeItem(USER_UUID_KEY);
+         localStorage.removeItem(USER_OWNER_UUID_KEY);
      }
  
      public login() {
          window.location.assign(`${API_HOST}/logout?return_to=${currentUrl}`);
      }
  
-     public getUserDetails = () => (dispatch: Dispatch) => {
+     public getUserDetails = () => (dispatch: Dispatch): Promise<void> => {
          dispatch(actions.USER_DETAILS_REQUEST());
-         serverApi
+         return serverApi
              .get<UserDetailsResponse>('/users/current')
              .then(resp => {
                  dispatch(actions.USER_DETAILS_SUCCESS(resp.data));
              });
-             // .catch(err => {
-             // });
 -    };
++    }
+     public getRootUuid() {
+         const uuid = this.getOwnerUuid();
+         const uuidParts = uuid ? uuid.split('-') : [];
+         return uuidParts.length > 1 ? `${uuidParts[0]}-${uuidParts[1]}` : undefined;
      }
  }
index 939799d2dd62c80b37b9dfd1c81743043c894125,e1e490bbbbe31aeaace718e053b531561f7c42d7..dbc0f9277e43cc270252be7dbd16e7887104878d
@@@ -35,23 -35,26 +35,26 @@@ interface GroupsResponse 
  export default class ProjectService {
      public getProjectList = (parentUuid?: string) => (dispatch: Dispatch): Promise<Project[]> => {
          dispatch(actions.PROJECTS_REQUEST());
-         const ub = new UrlBuilder('/groups');
-         const fb = new FilterBuilder();
-         fb.addEqual(FilterField.OWNER_UUID, parentUuid);
-         const url = ub.addParam('filters', fb.get()).get();
-         return serverApi.get<GroupsResponse>(url).then(groups => {
-             const projects = groups.data.items.map(g => ({
-                 name: g.name,
-                 createdAt: g.created_at,
-                 modifiedAt: g.modified_at,
-                 href: g.href,
-                 uuid: g.uuid,
-                 ownerUuid: g.owner_uuid
-             } as Project));
-             dispatch(actions.PROJECTS_SUCCESS({projects, parentItemId: parentUuid}));
-             return projects;
-         });
+         if (parentUuid) {
+             const fb = new FilterBuilder();
+             fb.addLike(FilterField.OWNER_UUID, parentUuid);
+             return serverApi.get<GroupsResponse>('/groups', { params: {
+                 filters: fb.get()
+             }}).then(groups => {
+                 const projects = groups.data.items.map(g => ({
+                     name: g.name,
+                     createdAt: g.created_at,
+                     modifiedAt: g.modified_at,
+                     href: g.href,
+                     uuid: g.uuid,
+                     ownerUuid: g.owner_uuid
+                 } as Project));
+                 dispatch(actions.PROJECTS_SUCCESS({projects, parentItemId: parentUuid}));
+                 return projects;
+             });
+         } else {
+             dispatch(actions.PROJECTS_SUCCESS({projects: [], parentItemId: parentUuid}));
+             return Promise.resolve([]);
+         }
 -    };
 +    }
  }
index 3fd7044205854574f125202050f009ebf45189c5,e58b2535e6805bf98bd15a32d3f8521698416a25..02b9d30c30dcf422cb7ab631186654de76f6ccdc
@@@ -11,7 -11,7 +11,7 @@@ import { UserDetailsResponse } from "..
  export interface AuthState {
      user?: User;
      apiToken?: string;
 -};
 +}
  
  const authReducer = (state: AuthState = {}, action: AuthAction) => {
      return actions.match(action, {
@@@ -43,7 -43,9 +43,9 @@@
              const user = {
                  email: ud.email,
                  firstName: ud.first_name,
-                 lastName: ud.last_name
+                 lastName: ud.last_name,
+                 uuid: ud.uuid,
+                 ownerUuid: ud.owner_uuid
              };
              authService.saveUser(user);
              return {...state, user};