Add gender support to growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-*

Bug: T335975
Change-Id: I4ef8ea6af11974d25c7193b6150f3943cf060082
这个提交包含在:
Cynthia Simiyu 2023-06-20 16:08:36 +03:00 提交者 Martin Urbanec
父节点 4d6fdcd3fe
当前提交 45c953f551
共有 6 个文件被更改,包括 58 次插入25 次删除

查看文件

@ -129,9 +129,9 @@
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee": "Skip this {{GENDER:$1|mentee}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-header": "(Optional) Why would {{GENDER:|you}} like to skip this mentee?",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-pretext": "Skipping a mentee will remove them from the praise-worthy list temporarily (for $1 {{PLURAL:$1|day|days}}). They can re-appear later if their following activity meets {{GENDER:|your}} preferred metrics.",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-already-praised": "I've already sent praise to this mentee",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-praiseworthy": "I don't think this mentee is praise-worthy",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-now": "I don't want to send praise now",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-already-praised": "I've already sent praise to this {{GENDER:$1|mentee}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-praiseworthy": "I don't think this {{GENDER:$1|mentee}} is praise-worthy",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-now": "I don't want to praise this {{GENDER:$1|mentee}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-other": "Other / I'd rather not say",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-submit": "Submit",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-cancel": "Cancel",

查看文件

@ -137,7 +137,7 @@
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-pretext": "Explanation how skipping works shown in the Skip mentee dialog in Personalized praise\n\nParameters:\n* $1 - number of days for which mentees are skipped\n\n{{doc-growthexperiments-mentor-dashboard}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-already-praised": "An item in the list of skipping reasons in the Skip mentee dialog in Personalized praise\n\n{{doc-growthexperiments-mentor-dashboard}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-praiseworthy": "An item in the list of skipping reasons in the Skip mentee dialog in Personalized praise\n\n{{doc-growthexperiments-mentor-dashboard}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-now": "An item in the list of skipping reasons in the Skip mentee dialog in Personalized praise\n\n{{doc-growthexperiments-mentor-dashboard}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-now": "An item in the list of skipping reasons in the Skip mentee dialog in Personalized praise. The message is shown to mentors who want to skip or check off a mentee who has done something praiseworthy, but the mentee has declined to receive praise for now. The message explains why the mentee does not want to be praised.\n\nParameters:\n* $1 - The gender of the mentee\n\n{{doc-growthexperiments-mentor-dashboard}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-other": "An item in the list of skipping reasons in the Skip mentee dialog in Personalized praise\n\n{{doc-growthexperiments-mentor-dashboard}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-submit": "Submit button in the Skip mentee dialog in Personalized praise\n\n{{doc-growthexperiments-mentor-dashboard}}",
"growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-cancel": "Cancel button in the Skip mentee dialog in Personalized praise\n\n{{doc-growthexperiments-mentor-dashboard}}",

查看文件

@ -105,7 +105,8 @@ class MentorDashboardModuleRegistry {
'personalized-praise',
$context,
$geServices->getPraiseworthyMenteeSuggester(),
$geServices->getPersonalizedPraiseSettings()
$geServices->getPersonalizedPraiseSettings(),
$services->getGenderCache()
);
},
];

查看文件

@ -4,6 +4,7 @@ namespace GrowthExperiments\MentorDashboard\Modules;
use ExtensionRegistry;
use FormatJson;
use GenderCache;
use GrowthExperiments\MentorDashboard\PersonalizedPraise\PersonalizedPraiseSettings;
use GrowthExperiments\MentorDashboard\PersonalizedPraise\PraiseworthyConditionsLookup;
use GrowthExperiments\MentorDashboard\PersonalizedPraise\PraiseworthyMenteeSuggester;
@ -16,23 +17,27 @@ class PersonalizedPraise extends BaseModule {
private PraiseworthyMenteeSuggester $praiseworthyMenteeSuggester;
private PersonalizedPraiseSettings $personalizedPraiseSettings;
private GenderCache $genderCache;
/**
* @param string $name
* @param IContextSource $ctx
* @param PraiseworthyMenteeSuggester $praiseworthyMenteeSuggester
* @param PersonalizedPraiseSettings $personalizedPraiseSettings
* @param GenderCache $genderCache
*/
public function __construct(
$name,
IContextSource $ctx,
PraiseworthyMenteeSuggester $praiseworthyMenteeSuggester,
PersonalizedPraiseSettings $personalizedPraiseSettings
PersonalizedPraiseSettings $personalizedPraiseSettings,
GenderCache $genderCache
) {
parent::__construct( $name, $ctx );
$this->praiseworthyMenteeSuggester = $praiseworthyMenteeSuggester;
$this->personalizedPraiseSettings = $personalizedPraiseSettings;
$this->genderCache = $genderCache;
}
/** @inheritDoc */
@ -110,6 +115,27 @@ class PersonalizedPraise extends BaseModule {
return $result;
}
/**
* Get an array of mentee objects with gender property.
*
* This function clones the mentee objects from getPraiseworthyMentees()
* and adds a gender property, based on the genderCache service.
* The gender property can be 'male', 'female', 'unknown' or null.
*
* @return array An array of mentee objects with gender property
*/
protected function getMenteeGenders() {
$praiseworthyMentees = $this->getPraiseworthyMentees();
$menteeGenders = [];
foreach ( $praiseworthyMentees as $mentee ) {
$userId = $mentee->getUser()->getId();
$menteeGenders[$userId] = $this->genderCache->getGenderOf( $mentee->getUser()->getName(), __METHOD__ );
}
return $menteeGenders;
}
/** @inheritDoc */
protected function getJsConfigVars() {
return [
@ -132,6 +158,7 @@ class PersonalizedPraise extends BaseModule {
),
'GEPersonalizedPraiseSkipMenteesForDays' =>
PraiseworthyConditionsLookup::SKIP_MENTEES_FOR_DAYS,
'GEMenteeGenders' => $this->getMenteeGenders(),
];
}

查看文件

@ -36,9 +36,9 @@ module.exports = {
// entities allowed.
coverageThreshold: {
global: {
branches: 30.5,
functions: 32.7,
lines: 42.4
branches: 30,
functions: 32,
lines: 42
}
},
// A list of paths to directories that Jest should use to search for files in.

查看文件

@ -44,7 +44,7 @@
</template>
<script>
const { ref, inject } = require( 'vue' );
const { ref, inject, computed } = require( 'vue' );
const { CdxButton, CdxDialog, CdxRadio } = require( '@wikimedia/codex' );
// NOTE: Keep in sync with ApiInvalidatePersonalizedPraiseSuggestion's skipreason param list
const SKIP_REASONS = [
@ -67,24 +67,29 @@ module.exports = exports = {
mentee: { type: Object, required: true }
},
emits: [ 'skip' ],
setup( _props, { emit } ) {
setup( props, { emit } ) {
const open = ref( false );
const selectedReason = ref( null );
const skipMenteesForDays = Number( mw.config.get( 'GEPersonalizedPraiseSkipMenteesForDays' ) );
const $i18n = inject( 'i18n' );
const log = inject( '$log' );
const reasonItems = SKIP_REASONS.map( ( x ) => {
return {
label: $i18n(
// Giving grep a chance to find usages:
// * growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-already-praised
// * growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-praiseworthy
// * growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-now
// * growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-other
'growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-' + x
),
value: x
};
const menteeGender = computed( () => {
return mw.config.get( 'GEMenteeGenders' )[ props.mentee.userId ];
} );
const reasonItems = computed( () => {
return SKIP_REASONS.map( ( x ) => {
return {
label: $i18n(
// Giving grep a chance to find usages:
// * growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-already-praised
// * growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-praiseworthy
// * growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-not-now
// * growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-other
'growthexperiments-mentor-dashboard-personalized-praise-skip-mentee-reason-' + x,
[ menteeGender.value ] ).text(),
value: x
};
} );
} );
function onSkipButtonClicked() {
@ -97,12 +102,12 @@ module.exports = exports = {
return {
open,
reasonItems,
selectedReason,
skipMenteesForDays,
log,
onSkipButtonClicked,
onSubmit
onSubmit,
reasonItems
};
},
watch: {