mirror of
https://github.com/wassname/talk.git
synced 2026-09-12 13:01:11 +08:00
Q&A Beta (#2845)
* [CORL-863] Allow streams to be converted/configured to Q&A (#2809) * Create preliminary schema changes for Q&A Adds a mode and expert User onto the StorySettings. Adds a mode selection drop down on a story's Configure tab. CORL-863 * Allow multiple experts, remove form elements from search Makes the previous expert user on a Q&A story now an array of users who can be assigned. Converts the previous form based search that was pulled from the admin community area into a set of events built on callbacks. CORL-863 * Create addExpertToStory mutation CORL-863 * Create removeExpertFromStory mutation CORL-863 * Conditionally show the the expert selection options CORL-863 * Create a dropdown search control for Q&A experts CORL-863 * Fixing up tests to match new QA stream options Adds a few localization fixes to make sure tests pass. Updates existing snapshots. CORL-863 * Add load more button to expert search list CORL-863 * Update experts query to match react upgrades CORL-863 * Move the Q&A config to its own section under stream config Create enable and disable Q&A mutations/button toggle. CORL-863 * Fix alignment and layout of expert list items CORL-863 * Define translations and update tests CORL-863 * Use official copy for Q&A config CORL-863 * [CORL-856] Show expert badge on comments (#2829) * Create preliminary schema changes for Q&A Adds a mode and expert User onto the StorySettings. Adds a mode selection drop down on a story's Configure tab. CORL-863 * Allow multiple experts, remove form elements from search Makes the previous expert user on a Q&A story now an array of users who can be assigned. Converts the previous form based search that was pulled from the admin community area into a set of events built on callbacks. CORL-863 * Create addExpertToStory mutation CORL-863 * Create removeExpertFromStory mutation CORL-863 * Conditionally show the the expert selection options CORL-863 * Create a dropdown search control for Q&A experts CORL-863 * Fixing up tests to match new QA stream options Adds a few localization fixes to make sure tests pass. Updates existing snapshots. CORL-863 * Add load more button to expert search list CORL-863 * Update experts query to match react upgrades CORL-863 * Move the Q&A config to its own section under stream config Create enable and disable Q&A mutations/button toggle. CORL-863 * Fix alignment and layout of expert list items CORL-863 * Define translations and update tests CORL-863 * Use official copy for Q&A config CORL-863 * Show expert badges on comments when Q&A is enabled CORL-856 * Update mutation responses and tests due to added expert fields CORL-856 * Use EXPERT user tags to denote expert users Removes the need for viewerIsExpert and authorIsExpert loader/resolvers on Stories and Comments respectively. CORL-856 * [CORL-879] Add an unanswered tab to stream when in Q&A mode (#2838) * Create preliminary schema changes for Q&A Adds a mode and expert User onto the StorySettings. Adds a mode selection drop down on a story's Configure tab. CORL-863 * Allow multiple experts, remove form elements from search Makes the previous expert user on a Q&A story now an array of users who can be assigned. Converts the previous form based search that was pulled from the admin community area into a set of events built on callbacks. CORL-863 * Create addExpertToStory mutation CORL-863 * Create removeExpertFromStory mutation CORL-863 * Conditionally show the the expert selection options CORL-863 * Create a dropdown search control for Q&A experts CORL-863 * Fixing up tests to match new QA stream options Adds a few localization fixes to make sure tests pass. Updates existing snapshots. CORL-863 * Add load more button to expert search list CORL-863 * Update experts query to match react upgrades CORL-863 * Move the Q&A config to its own section under stream config Create enable and disable Q&A mutations/button toggle. CORL-863 * Fix alignment and layout of expert list items CORL-863 * Define translations and update tests CORL-863 * Use official copy for Q&A config CORL-863 * Show expert badges on comments when Q&A is enabled CORL-856 * Update mutation responses and tests due to added expert fields CORL-856 * Use EXPERT user tags to denote expert users Removes the need for viewerIsExpert and authorIsExpert loader/resolvers on Stories and Comments respectively. CORL-856 * Show an unanswered comment stream when Q&A is enabled CORL-879 * Do not visually show the unanswered tag CORL-879 * [CORL-859] Convert Featured stream into Answered for Q&A (#2842) * Create preliminary schema changes for Q&A Adds a mode and expert User onto the StorySettings. Adds a mode selection drop down on a story's Configure tab. CORL-863 * Allow multiple experts, remove form elements from search Makes the previous expert user on a Q&A story now an array of users who can be assigned. Converts the previous form based search that was pulled from the admin community area into a set of events built on callbacks. CORL-863 * Create addExpertToStory mutation CORL-863 * Create removeExpertFromStory mutation CORL-863 * Conditionally show the the expert selection options CORL-863 * Create a dropdown search control for Q&A experts CORL-863 * Fixing up tests to match new QA stream options Adds a few localization fixes to make sure tests pass. Updates existing snapshots. CORL-863 * Add load more button to expert search list CORL-863 * Update experts query to match react upgrades CORL-863 * Move the Q&A config to its own section under stream config Create enable and disable Q&A mutations/button toggle. CORL-863 * Fix alignment and layout of expert list items CORL-863 * Define translations and update tests CORL-863 * Use official copy for Q&A config CORL-863 * Show expert badges on comments when Q&A is enabled CORL-856 * Update mutation responses and tests due to added expert fields CORL-856 * Use EXPERT user tags to denote expert users Removes the need for viewerIsExpert and authorIsExpert loader/resolvers on Stories and Comments respectively. CORL-856 * Show an unanswered comment stream when Q&A is enabled CORL-879 * Create preliminary schema changes for Q&A Adds a mode and expert User onto the StorySettings. Adds a mode selection drop down on a story's Configure tab. CORL-863 * Do not visually show the unanswered tag CORL-879 * Allow multiple experts, remove form elements from search Makes the previous expert user on a Q&A story now an array of users who can be assigned. Converts the previous form based search that was pulled from the admin community area into a set of events built on callbacks. CORL-863 * Create addExpertToStory mutation CORL-863 * Create removeExpertFromStory mutation CORL-863 * Create a dropdown search control for Q&A experts CORL-863 * Fixing up tests to match new QA stream options Adds a few localization fixes to make sure tests pass. Updates existing snapshots. CORL-863 * Add load more button to expert search list CORL-863 * Update experts query to match react upgrades CORL-863 * Move the Q&A config to its own section under stream config Create enable and disable Q&A mutations/button toggle. CORL-863 * Fix alignment and layout of expert list items CORL-863 * Define translations and update tests CORL-863 * Show expert badges on comments when Q&A is enabled CORL-856 * Use official copy for Q&A config CORL-863 * Update mutation responses and tests due to added expert fields CORL-856 * Use EXPERT user tags to denote expert users Removes the need for viewerIsExpert and authorIsExpert loader/resolvers on Stories and Comments respectively. CORL-856 * Create the answered stream for Q&A CORL-859 * Sort the Q&A on Most Voted by default CORL-859 * Fix type mismatch between post comment form and fragments CORL-859 * Adding localizations for Q&A tags * Hide feature flags in Q&A streams * Allow experts to clear answered questions Can click a button that shows up in the unanswered tab under answered questions to refresh the stream, clearing the answered questions from that tab. * Show arrow upvote icon when in Q&A mode Also localized the upvote text so it can be translated. * Hide mod/report buttons on answered questions * Remove unnecessary fragment container * Remove errant debug console log * Make story mode required on story settings * Make remove button outlined, not filled * Further schema changes around Q&A and experts Rename add/remove story expert to removeStoryExpert and addStoryExpert naming. Replace enableQA and disableQA mutators with single updateStoryMode mutator. * Remove story mode from UpdateStorySettings * Replace inline string val's with enum * add dependencies to useEffect * docs cleanup around tags.type index check * Approve a question when it is answered in Q&A Approves using the author's id as the moderator * Add comment around use of TAG on comments edge * Use tagFilter instead of $elemMatch to filter by tags * Improve responsive styles for expert list items * Update copy to "Done" from "Remove answered questions" * Text styling for no users found text Styles the expert search list to have proper text styling when no users are found for the search keyword. * Remove duplicate checks around story experts Not necessary as Mongo does this for us. * Fix a missed "sort imports" during rebase * Refactor Q&A moderation phases for clarity Simplify logic and update comments. Rename: "answered" -> "tagExpertAnswers" Rename: "unanswered" -> "tagUnansweredQuestions" * Remove username & email from add expert mutation * Format expert list emails with Localized * Break out no comments logic into fragment * Remove ref handling from expert search field Use value assignment on TextField instead. * Replace Box with Flex and CSS * Show Q&A tooltip on Answered tab Co-authored-by: Kim Gardner <kgardnr@gmail.com>
This commit is contained in:
@@ -926,12 +926,9 @@ export async function retrieveStoryCommentTagCounts(
|
||||
// Build up the $match query.
|
||||
const $match: FilterQuery<Comment> = {
|
||||
tenantID,
|
||||
// We're filtering only for featured comments for now because that's all
|
||||
// that is returned by the tag counts at the moment. If we ever extend this
|
||||
// we should switch this out to something like
|
||||
// `"tags.type": { $exists: true }` to ensure that we are using the
|
||||
// specified index.
|
||||
"tags.type": GQLTAG.FEATURED,
|
||||
// ensure we are using the tags.type index, this
|
||||
// currently includes FEATURED and UNANSWERED tags
|
||||
"tags.type": { $exists: true },
|
||||
// Only show published comment's tag counts.
|
||||
status: { $in: PUBLISHED_STATUSES },
|
||||
};
|
||||
@@ -986,6 +983,7 @@ export async function retrieveStoryCommentTagCounts(
|
||||
// missing/extra tags here.
|
||||
{
|
||||
[GQLTAG.FEATURED]: 0,
|
||||
[GQLTAG.UNANSWERED]: 0,
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ import { dotize } from "coral-common/utils/dotize";
|
||||
import {
|
||||
DuplicateStoryIDError,
|
||||
DuplicateStoryURLError,
|
||||
StoryNotFoundError,
|
||||
} from "coral-server/errors";
|
||||
import {
|
||||
Connection,
|
||||
@@ -18,6 +19,7 @@ import { TenantResource } from "coral-server/models/tenant";
|
||||
import { stories as collection } from "coral-server/services/mongodb/collections";
|
||||
|
||||
import {
|
||||
GQLSTORY_MODE,
|
||||
GQLStoryMetadata,
|
||||
GQLStorySettings,
|
||||
} from "coral-server/graph/schema/__generated__/types";
|
||||
@@ -30,8 +32,26 @@ import {
|
||||
|
||||
export * from "./helpers";
|
||||
|
||||
export interface StreamModeSettings {
|
||||
/**
|
||||
* mode is whether the story stream is in commenting or Q&A mode.
|
||||
* This will determine the appearance of the stream and how it functions.
|
||||
* This is an optional parameter and if unset, defaults to commenting.
|
||||
*/
|
||||
mode?: GQLSTORY_MODE;
|
||||
|
||||
/**
|
||||
* experts are used during Q&A mode to assign users to answer questions
|
||||
* on a Q&A stream. It is an optional parameter and is only used when
|
||||
* the story stream is in Q&A mode.
|
||||
*/
|
||||
expertIDs?: string[];
|
||||
}
|
||||
|
||||
export type StorySettings = DeepPartial<
|
||||
Pick<GQLStorySettings, "messageBox"> & GlobalModerationSettings
|
||||
StreamModeSettings &
|
||||
GlobalModerationSettings &
|
||||
Pick<GQLStorySettings, "messageBox" | "mode" | "experts">
|
||||
>;
|
||||
|
||||
export type StoryMetadata = GQLStoryMetadata;
|
||||
@@ -544,3 +564,102 @@ export const updateStoryCounts = (
|
||||
id: string,
|
||||
commentCounts: FirstDeepPartial<RelatedCommentCounts>
|
||||
) => updateRelatedCommentCounts(collection(mongo), tenantID, id, commentCounts);
|
||||
|
||||
export async function addExpert(
|
||||
mongo: Db,
|
||||
tenantID: string,
|
||||
storyID: string,
|
||||
userID: string
|
||||
) {
|
||||
const story = await collection(mongo).findOne({ tenantID, id: storyID });
|
||||
if (!story) {
|
||||
throw new StoryNotFoundError(storyID);
|
||||
}
|
||||
|
||||
const result = await collection(mongo).findOneAndUpdate(
|
||||
{
|
||||
tenantID,
|
||||
id: storyID,
|
||||
},
|
||||
{
|
||||
$addToSet: {
|
||||
"settings.expertIDs": userID,
|
||||
},
|
||||
},
|
||||
{
|
||||
returnOriginal: false,
|
||||
}
|
||||
);
|
||||
|
||||
if (!result.ok) {
|
||||
throw new Error("unable to add expert to story");
|
||||
}
|
||||
|
||||
return result.value || null;
|
||||
}
|
||||
|
||||
export async function removeExpert(
|
||||
mongo: Db,
|
||||
tenantID: string,
|
||||
storyID: string,
|
||||
userID: string
|
||||
) {
|
||||
const story = await collection(mongo).findOne({ tenantID, id: storyID });
|
||||
if (!story) {
|
||||
throw new StoryNotFoundError(storyID);
|
||||
}
|
||||
|
||||
const result = await collection(mongo).findOneAndUpdate(
|
||||
{
|
||||
tenantID,
|
||||
id: storyID,
|
||||
},
|
||||
{
|
||||
$pull: {
|
||||
"settings.expertIDs": userID,
|
||||
},
|
||||
},
|
||||
{
|
||||
returnOriginal: false,
|
||||
}
|
||||
);
|
||||
|
||||
if (!result.ok) {
|
||||
throw new Error("unable to remove expert from story");
|
||||
}
|
||||
|
||||
return result.value || null;
|
||||
}
|
||||
|
||||
export async function setStoryMode(
|
||||
mongo: Db,
|
||||
tenantID: string,
|
||||
storyID: string,
|
||||
mode: GQLSTORY_MODE
|
||||
) {
|
||||
const story = await collection(mongo).findOne({ tenantID, id: storyID });
|
||||
if (!story) {
|
||||
throw new StoryNotFoundError(storyID);
|
||||
}
|
||||
|
||||
const result = await collection(mongo).findOneAndUpdate(
|
||||
{
|
||||
tenantID,
|
||||
id: storyID,
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
"settings.mode": mode,
|
||||
},
|
||||
},
|
||||
{
|
||||
returnOriginal: false,
|
||||
}
|
||||
);
|
||||
|
||||
if (!result.ok) {
|
||||
throw new Error("unable to enable Q&A on story");
|
||||
}
|
||||
|
||||
return result.value || null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user