Sage-Bionetworks / sagebio-collaboration-portal

Collaboration Portal developed by Sage Bionetworks
1 stars 0 forks source link

Tidy functionality and styling for provenance components #574

Closed jaeddy closed 4 years ago

jaeddy commented 4 years ago

The biggest change in this PR is treating project entities as used references in each activity, such that activities can be filtered within projects. With some corresponding updates to prov-service, activities can also be further filtered based on their type/class.

Additional changes are focused on normalizing class/type names, updating seeds, adjusting graph visualization settings, etc.

EDIT: [2019-10-15] PR should be ready to review. Demonstration of key new features included below.


All Insight entities are associated with a project via the USED relationship for an activity (with project nodes represented as gray suitcase icons to match landing page):

image

Resource entities also associated with projects, and styling added for ResourceRegistration activities:

image

All new insights automatically associated with parent project via (transient) attachment in client component:

Oct-15-2019 22-11-44

All new resources automatically associated with parent project via (transient) attachment in server API controller:

Oct-15-2019 22-12-42

Filter by activity type/class in project activity page:

Oct-15-2019 22-14-01

jaeddy commented 4 years ago

@tschaffter one thing that I wasn't quite sure about how to approach was adding an "All" option to the activity type filters. The filters are initially defined in app.constants.ts:

...
    activityTypeFilters: Object.values(shared.activityTypes).map((activityType: any) => {
        if (activityType.value === shared.activityTypes.REPORT_CREATION.value) {
            activityType.active = true;
        }
        return activityType;
    }),
...

In the ngOnInit() function in the ProjectActivityComponent (L43-L47), I manually add the option to the array:

let activityFilters = config.activityTypeFilters;
activityFilters.push({
    'value': 'all',
    'title': 'All'
});

I then use the value of the selected filter to determine how to format the provenance request (L73-L79):

var filter_str = '*:*';
if (query.activityType !== 'all') {
    filter_str = `class:${query.activityType}`;
}
return (
    this.provenanceService.getProvenanceGraphByReference(root._id, 'down', 'created_at', 'desc', 100, filter_str)
);

If you have better ideas, I'm open to suggestions! 🙂

tschaffter commented 4 years ago

@jaeddy Regarding

let activityFilters = config.activityTypeFilters;
activityFilters.push({
    'value': 'all',
    'title': 'All'
});

Ideally the activity type filters should be defined at the one place. For example, we have datasetOrders in shared.js:

export const datasetOrders = {
    // ALPHA: {  // Sorting by title doesn't seem to work
    //     value: 'title asc',
    //     title: 'Alphabetical',
    //     active: true
    // },
    RELEVANCE: {
        value: 'relevance asc',
        title: 'Relevance',
        active: true,
    },
    NEWEST: {
        value: 'metadata_created desc',
        title: 'Newest Datasets',
    },
    OLDEST: {
        value: 'metadata_created asc',
        title: 'Oldest Datasets',
    },
};

The motivation for having it in shared.js is that both the server and client could refer to the same list of filters. In the client, the filters are used to initialze the list of options. The active property is used to pre-select an option. In the server, when making a call to an API endpoint that returns a list of result, the filter with active = true is used.

It seems to me that we could remove the following from app.constants.ts:

    activityTypeFilters: Object.values(shared.activityTypes).map((activityType: any) => {
        if (activityType.value === shared.activityTypes.REPORT_CREATION.value) {
            activityType.active = true;
        }
        return activityType;
    }),

    resourceTypeFilters: Object.values(shared.resourceTypes).map((resourceType: any) => {
        if (resourceType.value === shared.resourceTypes.DASHBOARD.value) {
            resourceType.active = true;
        }
        return resourceType;
    }),

    insightTypeFilters: Object.values(shared.insightTypes).map((insightType: any) => {
        if (insightType.value === shared.insightTypes.REPORT.value) {
            insightType.active = true;
        }
        return insightType;
    }),

Instead, we should set the active property to true for the corresponding filter in shared.js:

export const insightTypes = {
    REPORT: {
        value: 'Report',
        title: 'Report',
        **active: true**
    },
    MEMO: {
        value: 'Memo',
        title: 'Memo',
    },
};

export const resourceTypes = {
    ARTICLE: {
        value: 'Article',
        title: 'Article',
    },
    DASHBOARD: {
        value: 'Dashboard',
        title: 'Dashboard',
        **active: true**
    },
    STATE: {
        value: 'State',
        title: 'State',
    },
    WEBAPP: {
        value: 'WebApp',
        title: 'WebApp',
    },
};

export const activityTypes = {
    REPORT_CREATION: {
        value: 'ReportCreation',
        title: 'Report Creation',
        **active: true**
    },
    MEMO_CREATION: {
        value: 'MemoCreation',
        title: 'Memo Creation',
    },
    MENTION: {
        value: 'Mention',
        title: 'Mention',
    },
    TOOL_SESSION: {
        value: 'ToolSession',
        title: 'Tool Session',
    },
    RESOURCE_REGISTRATION: {
        value: 'ResourceRegistration',
        title: 'Resource Registration',
    },
};

Finally, change the client component so that they use:

import config from '../../app.constants'; // adapt path
const activityTypeFilters = config.activityTypes

Could you give it a try?

tschaffter commented 4 years ago

Notes on testing this PR before merging it

  1. Clone https://github.com/Sage-Bionetworks/prov-service
  2. Set required env vars (see prov-service doc) and docker-compose -f docker-compose.phccp.yml up -d
  3. git checkout --track origin/develop-prov-tidying
  4. Manually start the portal in development mode

Observation 1: Under the tab Activities of a project, selecting a different filters doesn't seem to change the content of the graph.

tschaffter commented 4 years ago

@jaeddy It looks like there is an issue regarding activity nodes being reused for several resources/insights. Do you want to fix the issue before we merge this PR?

Update: The issue was resolved after using a fresh instance of MongoDB (?).