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

Me/dh/records published by my org #640

Merged
merged 1 commit into from
Oct 13, 2023
Merged

Conversation

cmoinier
Copy link
Collaborator

@cmoinier cmoinier commented Oct 2, 2023

TO-DO

In the "My Organization" menu item:

  • The title should be the logo + name of the organization
  • Right of the title, the amount of published records should be shown in a numerical figure; when clicked, the user is taken to the datahub with the corresponding filter (amount of records should match!)
  • Right of the title, the amount of users should be shown in a numerical figure; when clicked, the user is taken to the "/users/my-org" route
  • On this route, a list of users in the organization is shown (using the same layout as the records list); fields shown are name, username, email)

How to test

For testing purposes, I left commented lines at :

You might need to restore the commented line depending on the user you're using/your docker compo.
For instance, the user Barbie has the organization name Barbie Inc. which doesn't match any record or user organization and prevents testing here.
The comments will be removed before merging.

  • In default.toml, (line 27) the link to the datahub is to be set to your localhost where datahub is running.

@cmoinier cmoinier requested a review from f-necas October 2, 2023 15:29
@cmoinier cmoinier marked this pull request as draft October 2, 2023 15:30
@cmoinier cmoinier force-pushed the ME/records-published-by-my-org branch from 2514f1b to b8b4dcc Compare October 3, 2023 13:28
@github-actions
Copy link
Contributor

github-actions bot commented Oct 3, 2023

Affected libs: api-repository, feature-catalog, feature-record, feature-router, feature-search, feature-map, feature-dataviz, feature-auth, common-domain, api-metadata-converter, feature-editor, ui-search, common-fixtures, ui-elements, ui-catalog, util-shared, ui-widgets, ui-inputs, ui-map, ui-dataviz, util-app-config,
Affected apps: datahub, metadata-editor, demo, webcomponents, search, map-viewer, datafeeder, metadata-converter, data-platform,

  • 🚀 Build and deploy storybook and demo on GitHub Pages
  • 📦 Build and push affected docker images

@cmoinier cmoinier marked this pull request as ready for review October 3, 2023 14:13
@coveralls
Copy link

Coverage Status

coverage: 82.713% (-3.5%) from 86.261% when pulling 608ff82 on ME/records-published-by-my-org into 7c8b49c on main.

f-necas
f-necas previously requested changes Oct 4, 2023
Copy link
Collaborator

@f-necas f-necas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done @cmoinier for this huge work.
I've let some comments, some debatable. Feel free to remove the comments either.

Maybe a nice things to have is a 'no record for this organisation/ no user for this organisation' placeholder instead of blank page.

@jahow jahow changed the base branch from main to develop October 5, 2023 08:58
@cmoinier cmoinier requested a review from f-necas October 6, 2023 07:01
Copy link
Collaborator

@f-necas f-necas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Camille for those nice improvements ! If @jahow can tell us what she thinks about it.

Otherwise, it seems to be good :)

libs/feature/catalog/src/lib/my-org/my-org.service.ts Outdated Show resolved Hide resolved
Comment on lines 45 to 64
this.orgService.organisations$.subscribe((orgs) => {
const orgName = this.myOrgDataSubject.value.orgName
const org = orgs.find((org) => org.name === orgName)
const logoUrl = org?.logoUrl?.href.toString()
const recordCount = org?.recordCount
this.myOrgDataSubject.next({
...this.myOrgDataSubject.value,
logoUrl,
recordCount,
})
})

this.authService.allUsers$.subscribe((users) => {
const orgName = this.myOrgDataSubject.value.orgName
// const orgName = 'Barbie Inc.'
const userList = users.filter((user) => user.organisation === orgName)
const userCount = userList.length
this.myOrgDataSubject.next({ ...this.myOrgDataSubject.value, userList })
this.myOrgDataSubject.next({ ...this.myOrgDataSubject.value, userCount })
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am skeptical for this. I may need @jahow advice there ...

Instead of subscribing to 3 observables, it may be good to do it with rxjs with some kind of (with combineLatest or zip, or something else if it exists.) :

const orgData$ = combineLatest([users$, allUsers$, organisations]).pipe(
  map(([a,b,c]) => resolve resolve),
);

and in html using an async pipe to get datas.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed this is a good exercise for observables 🙂

RxJS offers you tools to avoid creating your own observable and calling next() yourself. Something like what @f-necas was suggesting:

myOrgData$ = combineLatest([this.authService.user$, this.authService.allUsers$, this.orgService.organisations$]).pipe(
  map(([user, allUsers, orgs]) => {
      const orgName = user.organisation
      const org = orgs.find((org) => org.name === orgName)
      const logoUrl = org?.logoUrl?.href.toString()
      const recordCount = org?.recordCount
      const userList = users.filter((user) => user.organisation === orgName)
      const userCount = userList.length
      return {
        logoUrl,
        recordCount,
        userList,
        userCount,
      }
  })
);

(this is not tested!)

As for what you did originally, the problem is that you "break" the observable pattern by using the myOrgDataSubject to share information between various contexts (namely the orgName value). Although it works, it might be difficult to read for others because of the convoluted logic.

As a rule of thumb, an ideal use of observables is:

  • no manual subscribing (only in the html with | async)
  • no creation of observables yourself (most observables should be derived from something else: HTTP requests, events, etc.)

Don't hesitate to ask if something is unclear! And yes, this should go in the docs eventually. 👼

Copy link
Collaborator Author

@cmoinier cmoinier Oct 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, thanks for the extensive explaination 🙂
Following this guidance, should I change the way my-org-records.component.html receives its data?
Go from : orgData?.logoUrl to something like myOrgRecordsService.myOrgData$.logoUrl | async ?

Copy link
Collaborator

@jahow jahow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the extensive work! It feels like you tackled quite a complex task with this story. I've added some comments, and I think it could be great if you could address them.

The metadata-editor components will still need some work for the future and that's fine, let's keep this an iterative process. I hope my comments are clear enough 🙂

libs/api/repository/src/lib/gn4/auth/auth.service.ts Outdated Show resolved Hide resolved
libs/feature/catalog/src/lib/my-org/my-org.service.spec.ts Outdated Show resolved Hide resolved
Comment on lines 45 to 64
this.orgService.organisations$.subscribe((orgs) => {
const orgName = this.myOrgDataSubject.value.orgName
const org = orgs.find((org) => org.name === orgName)
const logoUrl = org?.logoUrl?.href.toString()
const recordCount = org?.recordCount
this.myOrgDataSubject.next({
...this.myOrgDataSubject.value,
logoUrl,
recordCount,
})
})

this.authService.allUsers$.subscribe((users) => {
const orgName = this.myOrgDataSubject.value.orgName
// const orgName = 'Barbie Inc.'
const userList = users.filter((user) => user.organisation === orgName)
const userCount = userList.length
this.myOrgDataSubject.next({ ...this.myOrgDataSubject.value, userList })
this.myOrgDataSubject.next({ ...this.myOrgDataSubject.value, userCount })
})
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed this is a good exercise for observables 🙂

RxJS offers you tools to avoid creating your own observable and calling next() yourself. Something like what @f-necas was suggesting:

myOrgData$ = combineLatest([this.authService.user$, this.authService.allUsers$, this.orgService.organisations$]).pipe(
  map(([user, allUsers, orgs]) => {
      const orgName = user.organisation
      const org = orgs.find((org) => org.name === orgName)
      const logoUrl = org?.logoUrl?.href.toString()
      const recordCount = org?.recordCount
      const userList = users.filter((user) => user.organisation === orgName)
      const userCount = userList.length
      return {
        logoUrl,
        recordCount,
        userList,
        userCount,
      }
  })
);

(this is not tested!)

As for what you did originally, the problem is that you "break" the observable pattern by using the myOrgDataSubject to share information between various contexts (namely the orgName value). Although it works, it might be difficult to read for others because of the convoluted logic.

As a rule of thumb, an ideal use of observables is:

  • no manual subscribing (only in the html with | async)
  • no creation of observables yourself (most observables should be derived from something else: HTTP requests, events, etc.)

Don't hesitate to ask if something is unclear! And yes, this should go in the docs eventually. 👼

@cmoinier
Copy link
Collaborator Author

cmoinier commented Oct 12, 2023

Thanks @jahow for this review and for your advice. I think the last two commits cover pretty much everything 🙂

For some reason I couldn't comment back on your comment . Here it is :

I know, the union type is behaving weirdly, I thought it would work too when I first tried.
Yes I know... At first, I did start to make a whole different table in my-org-records, but ended up with almost the same code as this component, in both template and functionalities, and figured it was going to be a whole lot of duplicate code, as you say. Hence why I ended up doing this and I know it's far from ideal. And yes, I think your idea about having an agnostic presentation component is great, but doing it now for this PR is going to be a lot of work.

@cmoinier cmoinier force-pushed the ME/records-published-by-my-org branch from 55fb41e to c4b5817 Compare October 13, 2023 09:33
@cmoinier cmoinier requested a review from jahow October 13, 2023 11:11
Copy link
Collaborator

@jahow jahow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for getting my comments addressed, I think it can be merged now 🙂

Could you please rebase the branch on develop before merging and remove the merge commit in the PR history? We generally try to avoid merge commits in Pull Requests as much as possible, thanks!

@cmoinier cmoinier dismissed f-necas’s stale review October 13, 2023 11:24

changes made & checked by other team member

@cmoinier cmoinier force-pushed the ME/records-published-by-my-org branch from 1a71268 to 1d7afe4 Compare October 13, 2023 13:40
@cmoinier cmoinier merged commit a12b13c into develop Oct 13, 2023
5 checks passed
@jahow jahow deleted the ME/records-published-by-my-org branch October 19, 2023 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants