From 5e5db7c6d1ecfece0bd078c6147365fe0096e8b2 Mon Sep 17 00:00:00 2001 From: Tan Khuu Date: Sun, 11 Sep 2016 22:34:51 +0700 Subject: [PATCH 01/10] Fix bugs 6, 7, 9 6) on homepage on the bottom of page, remove the "send us email" 7) remove twitter and fb and keep LinkedIn to https://www.linkedin.com/company/6600918 9) change on homepage this footer: "We Help Leaders to become a better Leader by improving the Decision Making Process." to "STRIVE for Great Leadership" --- imports/ui/containers/LandingPage.js | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/imports/ui/containers/LandingPage.js b/imports/ui/containers/LandingPage.js index 78ee2cb..cf084de 100644 --- a/imports/ui/containers/LandingPage.js +++ b/imports/ui/containers/LandingPage.js @@ -222,16 +222,11 @@ export default class LandingPage extends Component {
- Send us mail

- Or follow us on social platform + Follow us on social platform

    -
  • -
  • -
  • -
  • -
  • +
@@ -239,7 +234,7 @@ export default class LandingPage extends Component {

© 2016 theLeader.io
- We Help Leaders to become a better Leader by improving the Decision Making Process.

+ STRIVE for Great Leadership

From b84ca8ac2569628ed39d7d625840ebccec65d54e Mon Sep 17 00:00:00 2001 From: Tan Khuu Date: Mon, 12 Sep 2016 10:21:16 +0700 Subject: [PATCH 02/10] fix bugs: 1, 13, 1) make the dashboard real-time for counts and graph 13) show the graph in customise profile with the same rule as dashboard --- imports/api/cache/index.js | 3 + imports/api/jobs/workers.js | 31 ++-- imports/api/measures/methods.js | 149 ++++++++++++++++++ imports/api/profiles/methods.js | 2 +- imports/ui/components/ProfileMetricsBox.js | 8 +- imports/ui/containers/PublicProfile.js | 1 + .../DashboardOrganizationContainer.js | 39 +++-- .../CustomizePublicProfileContainer.js | 3 +- 8 files changed, 207 insertions(+), 29 deletions(-) create mode 100644 imports/api/cache/index.js diff --git a/imports/api/cache/index.js b/imports/api/cache/index.js new file mode 100644 index 0000000..4c6a148 --- /dev/null +++ b/imports/api/cache/index.js @@ -0,0 +1,3 @@ +import {Mongo} from 'meteor/mongo'; + +export const MiniMongo = new Mongo.Collection(null); \ No newline at end of file diff --git a/imports/api/jobs/workers.js b/imports/api/jobs/workers.js index 27c5e7c..0882709 100644 --- a/imports/api/jobs/workers.js +++ b/imports/api/jobs/workers.js @@ -13,9 +13,7 @@ import * as EmailActions from '/imports/api/email/methods'; import {getSendingPlans} from '/imports/api/sending_plans/methods'; import {getLocalDate} from '/imports/api/time/functions'; import {setStatus as setSendingPlanStatus} from '/imports/api/sending_plans/methods'; - -// functions -import {measureMonthlyMetricScore} from '/imports/api/measures/functions'; +import {measureMonthlyMetricScore} from '/imports/api/measures/methods'; // constants const LOG_LEVEL = { @@ -148,21 +146,22 @@ const sendSurveys = function (job, cb) { } const measureMetrics = (job, cb) => { - try { - const measure = measureMonthlyMetricScore(); - if(measure) { - jobMessage = `measured metrics for leaders done`; - job.log(jobMessage, {level: LOG_LEVEL.INFO}); - job.done(); + measureMonthlyMetricScore.call({params: {}}, (error, measure) => { + if (!error) { + if (!_.isEmpty(measure)) { + jobMessage = `measured metrics for ${measure.noOfLeader} leaders and ${measure.noOfOrg} organizations done`; + job.log(jobMessage, {level: LOG_LEVEL.INFO}); + job.done(); + } else { + jobMessage = `No data to measure for job: ${job}`; + job.log(jobMessage, {level: LOG_LEVEL.WARNING}); + job.done(); + } } else { - jobMessage = `No data to measure for job: ${job}`; - job.log(jobMessage, {level: LOG_LEVEL.WARNING}); - job.done(); + job.log(error.reason, {level: LOG_LEVEL.CRITICAL}); + job.fail(); } - } catch (error) { - job.log(error.message, {level: LOG_LEVEL.CRITICAL}); - job.fail(); - } + }); } // Start Job diff --git a/imports/api/measures/methods.js b/imports/api/measures/methods.js index d84d04e..eca467e 100644 --- a/imports/api/measures/methods.js +++ b/imports/api/measures/methods.js @@ -3,9 +3,12 @@ import _ from 'lodash'; // collections import {Measures} from './index'; +import {Metrics} from '/imports/api/metrics/index'; +import {MiniMongo} from '/imports/api/cache/index'; // functions import {arraySum} from '/imports/utils/index'; +import {measure} from './functions'; /** @@ -147,4 +150,150 @@ export const getChartData = new ValidatedMethod({ } return result; } +}); + +/** + * @summary Method measure monthly metric score + * @param {Object} params + * @param {String} params.leaderId + * @param {String} params.organizationId + * @param {Date} params.date - the date which is the last month of data + * @return {Number} the number of docs had been upsert + */ +export const measureMonthlyMetricScore = new ValidatedMethod({ + name: "measures.measureMonthlyMetricScore", + validate: null, + run({params}) { + const + MiniMongo = new Mongo.Collection(null), + runDate = (!!params.date ? params.date : new Date()), + year = runDate.getFullYear(), + month = runDate.getMonth(), + nextMonth = month + 1, + haveLeaderId = !!params.leaderId, + haveOrgId = !!params.organizationId + ; + let + jobMessage = "", + selector = {}, + modifier = {}, + leaderList = [], + leaderDocs = [], + orgList = [], + metricList = [], + orgDocs = [], + metricDocs = [], + scoreList = [], + averageScore = 0, + noOfScores = 0, + noOfGoodScores = 0, // count the number of score from 4 to 5 + noOfBadScores = 0, // count the number of score from 1 to 3 + measureDoc = {}, // data of measure for leader + result = false + ; + + // Get list of leaders + if(haveLeaderId) { + selector.leaderId = params.leaderId; + } + if(haveOrgId) { + selector.organizationId = params.organizationId; + } + selector.date = { + $gte: new Date(year, month, 1), + $lt: new Date(year, nextMonth, 1) + } + ; // only get data in current month + modifier = { + fields: { + _id: 0, + leaderId: 1, + organizationId: 1, + metric: 1, + score: 1 + } + }; // only return necessary fields + + // get leaders data in current month + const docs = Metrics.find(selector, modifier).fetch(); + if (!_.isEmpty(docs)) { + MiniMongo.remove({}); + docs.map(doc => { + MiniMongo.insert(doc); + if(!haveLeaderId) { + leaderList.push(doc.leaderId); + } + }); + + if(haveLeaderId) { + leaderList.push(params.leaderId); + } else { + leaderList = _.uniq(leaderList); // get unique leader only + } + + // get average score for every leader + leaderList.map(leaderId => { + //get list of organization for specific leader + if(haveOrgId) { + orgList.push(params.organizationId); + } else { + leaderDocs = MiniMongo.find({leaderId}).fetch(); + leaderDocs.map(leaderDoc => { + orgList.push(leaderDoc.organizationId); + }); + orgList = _.uniq(orgList); + } + + // get list of metric for specific organization + orgList.map(organizationId => { + orgDocs = MiniMongo.find({leaderId, organizationId}).fetch(); + orgDocs.map(orgDoc => { + metricList.push(orgDoc.metric); + }); + metricList = _.uniq(metricList); + // get list of score for specific metric + metricList.map(metric => { + metricDocs = MiniMongo.find({leaderId, organizationId, metric}).fetch(); + metricDocs.map(metricDoc => { + const {score} = metricDoc; + if(score > 3) { + noOfGoodScores++; + } else { + noOfBadScores++; + } + scoreList.push(score); + }); + + noOfScores = scoreList.length; + if(noOfScores > 0) { + averageScore = Number(arraySum(scoreList) / scoreList.length).toFixed(1); + } + + measureDoc = { + leaderId, + organizationId, + type: "metric", + interval: "monthly", + year, + month, + key: metric, + value: { + averageScore, + noOfScores, + noOfGoodScores, + noOfBadScores + } + }; + measure({data: measureDoc}); + }); + }); + }); + return { + noOfLeader: leaderList.length, + noOfOrg: orgList.length + }; + } else { + return {}; + } + } }); \ No newline at end of file diff --git a/imports/api/profiles/methods.js b/imports/api/profiles/methods.js index 7d3f42b..b1b08e6 100644 --- a/imports/api/profiles/methods.js +++ b/imports/api/profiles/methods.js @@ -234,7 +234,7 @@ export const getPublicData = new ValidatedMethod({ leaderId = User._id, noOfPreferences = Preferences.find({userId, name: 'publicInfo'}).count(), ProfileData = Profiles.findOne({userId}), - OrganizationsData = _.orderBy(Organizations.find({leaderId}).fetch(), ['startTime'], ['desc']), + OrganizationsData = _.orderBy(Organizations.find({leaderId}).fetch(), ['isPresent','startTime'], ['desc','desc']), FeedbacksData = Feedbacks.find({leaderId}).fetch(), date = new Date(), months = [ diff --git a/imports/ui/components/ProfileMetricsBox.js b/imports/ui/components/ProfileMetricsBox.js index be5cdf3..e017c73 100644 --- a/imports/ui/components/ProfileMetricsBox.js +++ b/imports/ui/components/ProfileMetricsBox.js @@ -10,11 +10,14 @@ export default class ProfileMetricsBox extends Component { constructor() { super(); - this.state = {} + this.state = {}; } render() { - const {label, preferences, data} = this.props; + const + {isPresent, label, preferences, data} = this.props, + status = isPresent ? "current organization" : "latest organization" + ; if (!_.isEmpty(data)) { const {chart, metrics} = data; @@ -120,6 +123,7 @@ export default class ProfileMetricsBox extends Component { return (
+ {status}
{label}
{ if (!err) { preferences.metrics = DEFAULT_PUBLIC_INFO_PREFERENCES.metrics; @@ -58,13 +67,13 @@ class DashboardOrganization extends Component { } render() { - // console.log(this.props) const { containerReady, measures, noOfEmployees, - noOfFeedbacks + noOfFeedbacks, + isCurrentOrg } = this.props, { ready, @@ -145,6 +154,7 @@ class DashboardOrganization extends Component {
From f39802fd1406f594fad4911e8c5299a29e7298fd Mon Sep 17 00:00:00 2001 From: Tan Khuu Date: Mon, 12 Sep 2016 11:12:01 +0700 Subject: [PATCH 03/10] 5 - add text for tweeter, difficult to do with LinkedIn --- imports/ui/containers/PublicProfile.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/imports/ui/containers/PublicProfile.js b/imports/ui/containers/PublicProfile.js index a8f9c06..ff4f04d 100644 --- a/imports/ui/containers/PublicProfile.js +++ b/imports/ui/containers/PublicProfile.js @@ -62,7 +62,6 @@ export default class PublicProfile extends Component { }); } }); - } render() { @@ -76,9 +75,11 @@ export default class PublicProfile extends Component { ); } if (alias) { - const url = document.location.href; - const {publicInfo, preferences} = this.state; - const { + const + sharedUrl = document.location.href, + sharedText = `Checkout my #leadership scorecard on`, + {publicInfo, preferences} = this.state, + { basic, headline, contact, @@ -107,14 +108,18 @@ export default class PublicProfile extends Component {
    +
  • +
    +
From bf574b833ce21c5b09b8dfbd76cb55a393239480 Mon Sep 17 00:00:00 2001 From: Tan Khuu Date: Mon, 12 Sep 2016 11:29:51 +0700 Subject: [PATCH 04/10] fix bug 12 12) In organization page, we should remove feedback and overall. Also remove the status of current moth and its progress bar. Remove avatars. Instead show the logo of organization. --- .../containers/organizations/Organizations.js | 36 +++++++------------ 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/imports/ui/containers/organizations/Organizations.js b/imports/ui/containers/organizations/Organizations.js index 9e72df0..921a7c8 100644 --- a/imports/ui/containers/organizations/Organizations.js +++ b/imports/ui/containers/organizations/Organizations.js @@ -7,6 +7,11 @@ import { Organizations as OrganizationCollection } from '/imports/api/organizati import { setPageHeading, resetPageHeading } from '/imports/store/modules/pageHeading'; import { actions as orgActions } from '/imports/store/modules/organizations'; +// constants +import {DEFAULT_ORGANIZATION_PHOTO} from '/imports/utils/defaults'; + +// components +import ProfilePhoto from '/imports/ui/components/ProfilePhoto'; // Views import NoOrganization from './NoOrganization'; import Box from '/imports/ui/components/Box'; @@ -66,35 +71,20 @@ class Organizations extends Component {

{ org.jobTitle }

{/* Description */}

{ getShortDescription(org.description) }

-
- member - member - member - member - member -
- {/* Status of response */} -
- Status of current month: -
48%
-
-
-
-
+
+ +
{/* Some numbers*/}
EMPLOYEES
{ org.employees && org.employees.length ? org.employees.length : 0 }
-
-
FEEDBACK
- 23 -
-
-
OVERALL
- 3.4 -
From 05e1f3117626c03dce687c33718efdc3e0e3b203 Mon Sep 17 00:00:00 2001 From: Tan Khuu Date: Mon, 12 Sep 2016 17:15:32 +0700 Subject: [PATCH 05/10] fix chart data in dashboard, remove unimplemented section from navigations --- imports/api/measures/methods.js | 4 +-- imports/ui/common/Navigation.js | 2 -- imports/ui/common/TopNav.js | 1 - .../DashboardOrganizationContainer.js | 32 +++++++++++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/imports/api/measures/methods.js b/imports/api/measures/methods.js index eca467e..7450e4e 100644 --- a/imports/api/measures/methods.js +++ b/imports/api/measures/methods.js @@ -84,8 +84,8 @@ export const getChartData = new ValidatedMethod({ conflict: 0 }, // current score of metrics selector = {}, // conditions for query database - fields = {} // fields will receive from database - MeasuresData = [] + fields = {}, // fields will receive from database + MeasuresData = [] ; // get labels diff --git a/imports/ui/common/Navigation.js b/imports/ui/common/Navigation.js index f41f551..ad293b6 100644 --- a/imports/ui/common/Navigation.js +++ b/imports/ui/common/Navigation.js @@ -11,8 +11,6 @@ class Navigation extends Component { {route: 'app.dashboard', path: FlowRouter.url('app.dashboard'), label: 'Dashboard', icon: 'fa fa-dashboard'}, {route: 'app.preferences', path: FlowRouter.url('app.preferences'), label: 'Preferences', icon: 'fa fa-gears'}, {route: 'app.organizations', path: FlowRouter.url('app.organizations'), label: 'Organizations', icon: 'fa fa-sitemap'}, - {route: '', path: '', label: 'Feedback', icon: 'fa fa-gift'}, - {route: '', path: '', label: 'Measure', icon: 'fa fa-info'}, ] }; } diff --git a/imports/ui/common/TopNav.js b/imports/ui/common/TopNav.js index 4286e8e..9a8cd4d 100644 --- a/imports/ui/common/TopNav.js +++ b/imports/ui/common/TopNav.js @@ -51,7 +51,6 @@ class TopNav extends Component {
  • Dashboard
  • Preferences
  • Organizations
  • -
  • Feedbacks
  • Sign out
  • diff --git a/imports/ui/containers/dashboard/DashboardOrganizationContainer.js b/imports/ui/containers/dashboard/DashboardOrganizationContainer.js index d265a1e..ae0c562 100644 --- a/imports/ui/containers/dashboard/DashboardOrganizationContainer.js +++ b/imports/ui/containers/dashboard/DashboardOrganizationContainer.js @@ -60,12 +60,44 @@ class DashboardOrganization extends Component { }); } else { this.setState({ + ready: true, error: err.reason }); } }); } + componentWillReceiveProps(nextProps) { + const + leaderId = Meteor.userId(), + organizationId = nextProps.organizationId, + date = new Date(), + noOfMonths = 6, + preferences = {}; + ; + if(this.props.organizationId !== organizationId) { + this.setState({ + ready: false, + chart: {} + }); + getChartData.call({leaderId, organizationId, date, noOfMonths}, (err, result) => { + if (!err) { + preferences.metrics = DEFAULT_PUBLIC_INFO_PREFERENCES.metrics; + this.setState({ + ready: true, + chart: result, + preferences + }); + } else { + this.setState({ + ready: true, + error: err.reason + }); + } + }); + } + } + render() { const { From 60faf1db5db8f1b74a5371a37274c85f79d777bd Mon Sep 17 00:00:00 2001 From: Tan Khuu Date: Mon, 12 Sep 2016 17:24:52 +0700 Subject: [PATCH 06/10] measure metrics every time user access to dashboard --- imports/ui/containers/dashboard/Dashboard.js | 9 ++++++++- .../dashboard/DashboardOrganizationContainer.js | 8 -------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/imports/ui/containers/dashboard/Dashboard.js b/imports/ui/containers/dashboard/Dashboard.js index 083dc26..3f2cae3 100644 --- a/imports/ui/containers/dashboard/Dashboard.js +++ b/imports/ui/containers/dashboard/Dashboard.js @@ -6,6 +6,7 @@ import {FlowRouter} from 'meteor/kadira:flow-router'; // methods import {getPresentOrganizations} from '/imports/api/organizations/methods'; import * as Notifications from '/imports/api/notifications/methods'; +import {measureMonthlyMetricScore} from '/imports/api/measures/methods'; // components import Spinner from '/imports/ui/common/Spinner'; @@ -30,6 +31,10 @@ export default class Dashboard extends Component { } componentWillMount() { + const + leaderId = Meteor.userId(), + date = new Date() + ; // get present organizations first getPresentOrganizations.call({leaderId: Meteor.userId(), isPresent: true}, (error, result) => { if (!error) { @@ -60,13 +65,15 @@ export default class Dashboard extends Component { }); } }); + // measure score of metric every time user access to dashboard + measureMonthlyMetricScore.call({params: { leaderId, date}}); } componentDidUpdate() { const {ready, orgList} = this.state; if (ready && orgList.length === 0) { const - closeButton = false, + closeButton = true, title = "You didn't have present organization", message = "Please create one" ; diff --git a/imports/ui/containers/dashboard/DashboardOrganizationContainer.js b/imports/ui/containers/dashboard/DashboardOrganizationContainer.js index ae0c562..db01d9a 100644 --- a/imports/ui/containers/dashboard/DashboardOrganizationContainer.js +++ b/imports/ui/containers/dashboard/DashboardOrganizationContainer.js @@ -15,9 +15,6 @@ import {NoticeForm} from '/imports/ui/common/NoticeForm'; import IboxDashboard from '/imports/ui/components/IboxDashboard'; import ProfileMetricsBox from '/imports/ui/components/ProfileMetricsBox'; -// methods -import {measureMonthlyMetricScore} from '/imports/api/measures/methods'; - // functions import {getChartData} from '/imports/api/measures/methods'; import {getAverageMetrics} from '/imports/api/metrics/functions'; @@ -45,11 +42,6 @@ class DashboardOrganization extends Component { preferences = {}; ; - // measure score of metric every time user access to dashboard - measureMonthlyMetricScore.call({params: { - leaderId, organizationId, date - }}); - getChartData.call({leaderId, organizationId, date, noOfMonths}, (err, result) => { if (!err) { preferences.metrics = DEFAULT_PUBLIC_INFO_PREFERENCES.metrics; From a7356ce6412b53637828d64d524773ce98adcfb6 Mon Sep 17 00:00:00 2001 From: Tan Khuu Date: Tue, 13 Sep 2016 11:57:07 +0700 Subject: [PATCH 07/10] fix bug 3 3) click on whole box of organization should take the user to the edit page --- .../containers/organizations/Organizations.js | 230 +++++++++--------- 1 file changed, 120 insertions(+), 110 deletions(-) diff --git a/imports/ui/containers/organizations/Organizations.js b/imports/ui/containers/organizations/Organizations.js index 921a7c8..c9e4966 100644 --- a/imports/ui/containers/organizations/Organizations.js +++ b/imports/ui/containers/organizations/Organizations.js @@ -1,11 +1,11 @@ -import React, { Component } from 'react'; -import { Meteor } from 'meteor/meteor'; -import { FlowRouter } from 'meteor/kadira:flow-router'; -import { createContainer } from 'meteor/react-meteor-data'; -import { Organizations as OrganizationCollection } from '/imports/api/organizations'; +import React, {Component} from 'react'; +import {Meteor} from 'meteor/meteor'; +import {FlowRouter} from 'meteor/kadira:flow-router'; +import {createContainer} from 'meteor/react-meteor-data'; +import {Organizations as OrganizationCollection} from '/imports/api/organizations'; -import { setPageHeading, resetPageHeading } from '/imports/store/modules/pageHeading'; -import { actions as orgActions } from '/imports/store/modules/organizations'; +import {setPageHeading, resetPageHeading} from '/imports/store/modules/pageHeading'; +import {actions as orgActions} from '/imports/store/modules/organizations'; // constants import {DEFAULT_ORGANIZATION_PHOTO} from '/imports/utils/defaults'; @@ -17,122 +17,132 @@ import NoOrganization from './NoOrganization'; import Box from '/imports/ui/components/Box'; function getShortDescription(str) { - if(!str) return ''; - let words = str.split(' '); - if(words.length > 18) { - words = words.splice(0, 18); - words.push('...'); - } - return words.join(' '); + if (!str) return ''; + let words = str.split(' '); + if (words.length > 18) { + words = words.splice(0, 18); + words.push('...'); + } + return words.join(' '); } class Organizations extends Component { - componentWillMount() { - const actions = ( - - - {' '} - Create Organization - - ) + componentWillMount() { + const actions = ( + + + {' '} + Create Organization + + ) - setPageHeading({ - title: 'Organizations', - breadcrumb: [{ - label: 'Organizations', - active: true - }], - actions, - }); - } + setPageHeading({ + title: 'Organizations', + breadcrumb: [{ + label: 'Organizations', + active: true + }], + actions, + }); + } - componentWillUnmount() { - resetPageHeading(); - orgActions.reset(); - } + componentWillUnmount() { + resetPageHeading(); + orgActions.reset(); + } - _onLoadMore = e => { - e.preventDefault(); - orgActions.loadMore(); - } + _onLoadMore = e => { + e.preventDefault(); + orgActions.loadMore(); + } - render() { - const { isLoading, organizations, hasMore } = this.props; - return ( -
    - {!organizations.length && ( - - )} - {/* Organization list */} -
    - {organizations.map((org, key) => ( -
    - }> -

    { org.jobTitle }

    - {/* Description */} -

    { getShortDescription(org.description) }

    -
    - -
    - {/* Some numbers*/} -
    -
    -
    EMPLOYEES
    - { org.employees && org.employees.length ? org.employees.length : 0 } -
    -
    -
    -
    - ))} -
    + render() { + const + {isLoading, organizations, hasMore} = this.props, + style = { + a: { + "a, a:visited, a:hover, a:active": { + color: 'inherit' + } + } + } + ; + return ( +
    + {!organizations.length && ( + + )} + {/* Organization list */} +
    + {organizations.map((org, key) => ( +
    FlowRouter.go('app.organizations.update', {_id: org._id})}> + }> +

    { org.jobTitle }

    + {/* Description */} +

    { getShortDescription(org.description) }

    +
    + +
    + {/* Some numbers*/} +
    +
    +
    EMPLOYEES
    + { org.employees && org.employees.length ? org.employees.length : 0 } +
    +
    +
    +
    + ))} +
    - {/* show load more button if has more org*/} - { hasMore && ( -
    -
    - -
    -
    - )} -
    - ); - } + {/* show load more button if has more org*/} + { hasMore && ( +
    +
    + +
    +
    + )} +
    + ); + } } const mapMeteorToProps = params => { - const { page, limit, q } = Meteor.AppState.get('organizations'); - let selector = {}; - let option = { - limit: limit, - skip: 0, - sort: { createdAt: -1 } - }; + const {page, limit, q} = Meteor.AppState.get('organizations'); + let selector = {}; + let option = { + limit: limit, + skip: 0, + sort: {createdAt: -1} + }; - // filter by keyword - if(!_.isEmpty(q)) { - selector['$or'] = [ - { name: {$regex: q, $options: 'i'} } - ]; - } + // filter by keyword + if (!_.isEmpty(q)) { + selector['$or'] = [ + {name: {$regex: q, $options: 'i'}} + ]; + } - const sub = Meteor.subscribe('organizations.list', { page, q }); - const isLoading = !sub.ready(); - const total = OrganizationCollection.find(selector).count(); - const organizations = OrganizationCollection.find(selector, option).fetch(); - - return { - isLoading, - organizations, - total, - hasMore: (total > limit), - }; + const sub = Meteor.subscribe('organizations.list', {page, q}); + const isLoading = !sub.ready(); + const total = OrganizationCollection.find(selector).count(); + const organizations = OrganizationCollection.find(selector, option).fetch(); + + return { + isLoading, + organizations, + total, + hasMore: (total > limit), + }; } export default createContainer(mapMeteorToProps, Organizations); From eb02070507f27fd4df964e2f0ee559b893de784e Mon Sep 17 00:00:00 2001 From: Tan Khuu Date: Tue, 13 Sep 2016 12:27:06 +0700 Subject: [PATCH 08/10] fix bugs: 4, 8 4) put a link on employee page for users to download a template 8 ) if it is easy to put back the GA please do it UA-66639731-1 --- .meteor/packages | 1 + .meteor/versions | 1 + imports/ui/containers/PublicProfile.js | 6 ++++-- imports/ui/containers/organizations/_Employees.js | 10 ++++++++-- imports/utils/defaults.js | 2 ++ public/templates/employees.csv | 2 ++ 6 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 public/templates/employees.csv diff --git a/.meteor/packages b/.meteor/packages index c87c077..4fb7e8e 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -54,3 +54,4 @@ aldeed:moment-timezone nimble:restivus shell-server lepozepo:accounting +okgrow:analytics diff --git a/.meteor/versions b/.meteor/versions index 2c99d96..6117367 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -73,6 +73,7 @@ nimble:restivus@0.8.11 npm-bcrypt@0.9.1 npm-mongo@1.5.48 observe-sequence@1.0.12 +okgrow:analytics@2.0.0 ordered-dict@1.0.8 percolate:migrations@0.9.8 promise@0.8.4 diff --git a/imports/ui/containers/PublicProfile.js b/imports/ui/containers/PublicProfile.js index ff4f04d..e53b142 100644 --- a/imports/ui/containers/PublicProfile.js +++ b/imports/ui/containers/PublicProfile.js @@ -89,7 +89,9 @@ export default class PublicProfile extends Component { organizations, metrics, chart - } = publicInfo; + } = publicInfo, + isPresent = (organizations.length > 0) ? organizations[0].isPresent : false + ; return ( @@ -140,7 +142,7 @@ export default class PublicProfile extends Component {
    -
    - +
      {scheduler && scheduler.metrics && scheduler.metrics.map((metricKey, key) => ( - ))}
    From e3a059c5d2d1b01de8bf419a1c916ae7773c22e4 Mon Sep 17 00:00:00 2001 From: Tan Khuu Date: Wed, 14 Sep 2016 10:02:15 +0700 Subject: [PATCH 10/10] fix customs public profile, confirmation email address --- imports/api/users/methods.js | 2 +- .../CustomizePublicProfileContainer.js | 34 ++++++++++--------- .../containers/scheduler/SchedulerQuarter.js | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/imports/api/users/methods.js b/imports/api/users/methods.js index f32241b..31f1cad 100644 --- a/imports/api/users/methods.js +++ b/imports/api/users/methods.js @@ -169,7 +169,7 @@ export const confirm = new ValidatedMethod({ "emails.$.verified": true } }); - ProfileActions.setStatus.call({userId, status: STATUS_ACTIVE}); + ProfileActions.setStatus.call({userId: _id, status: STATUS_ACTIVE}); } } else { throw new Meteor.Error('invalid-token', 'User token is invalid or has been used.'); diff --git a/imports/ui/containers/profile/CustomizePublicProfileContainer.js b/imports/ui/containers/profile/CustomizePublicProfileContainer.js index 0733e5f..9e0fdab 100644 --- a/imports/ui/containers/profile/CustomizePublicProfileContainer.js +++ b/imports/ui/containers/profile/CustomizePublicProfileContainer.js @@ -60,7 +60,7 @@ class ProfilePreferences extends Component { }); } } - + onSave() { const @@ -87,20 +87,22 @@ class ProfilePreferences extends Component { const loading = (this.props.loading | this.state.loading); if (!loading) { - const {preferences} = this.state; - const { - basic, - headline, - contact, - summary, - picture, - about, - organizations, - metrics, - chart - } = this.state.publicInfo; - - const ulStyle = {margin: 0, paddingLeft: 15}; + const + {preferences} = this.state, + { + basic, + headline, + contact, + summary, + picture, + about, + organizations, + metrics, + chart + } = this.state.publicInfo, + isPresent = (organizations.length > 0) ? organizations[0].isPresent : false, + ulStyle = {margin: 0, paddingLeft: 15} + ; return (
    @@ -115,7 +117,7 @@ class ProfilePreferences extends Component {
    { + getLeaderPlans.call({}, (error, planList) => { if (!error) { if (_.isEmpty(planList)) { if (isActive) {