From 1f31a152d1faccf8cc9c78d873b38e7bef4b1ac4 Mon Sep 17 00:00:00 2001 From: Lee_D Date: Tue, 27 Aug 2024 11:31:09 +0300 Subject: [PATCH 1/4] firebasesrc --- .firebasesrc | 9 +++++++++ src/controllers/db/configKey.ts | 3 +-- 2 files changed, 10 insertions(+), 2 deletions(-) create mode 100644 .firebasesrc diff --git a/.firebasesrc b/.firebasesrc new file mode 100644 index 000000000..005161658 --- /dev/null +++ b/.firebasesrc @@ -0,0 +1,9 @@ +{ + "projects": { + "default": "delib-v3-dev", + "dev": "delib-v3-dev", + "prod": "synthesistalyaron" + }, + "targets": {}, + "etags": {} +} diff --git a/src/controllers/db/configKey.ts b/src/controllers/db/configKey.ts index 290d71d86..737413286 100644 --- a/src/controllers/db/configKey.ts +++ b/src/controllers/db/configKey.ts @@ -1,6 +1,6 @@ const mode = import.meta.env.VITE_APP_ENV as "development" | "production"; - +console.log("mode", mode); const firebaseConfig = { development: { apiKey: import.meta.env.VITE_FIREBASE_API_KEY_DEV, @@ -24,7 +24,6 @@ const firebaseConfig = { }, }; - const vapidKeys = { development: import.meta.env.VITE_FIREBASE_VAPID_KEY_DEV, production: import.meta.env.VITE_FIREBASE_VAPID_KEY_PROD, From 203fb29d059eba0af1c71e02b0818802729c72a7 Mon Sep 17 00:00:00 2001 From: Lee_D Date: Fri, 30 Aug 2024 15:52:56 +0300 Subject: [PATCH 2/4] non-voters-list --- .../settings/components/GetVoters.tsx | 60 ++- .../StatementSettingsForm.tsx | 30 +- .../settings/statementSettingsCont.ts | 510 +++++++++--------- 3 files changed, 336 insertions(+), 264 deletions(-) diff --git a/src/view/pages/statement/components/settings/components/GetVoters.tsx b/src/view/pages/statement/components/settings/components/GetVoters.tsx index 061be4ed0..8f1338700 100644 --- a/src/view/pages/statement/components/settings/components/GetVoters.tsx +++ b/src/view/pages/statement/components/settings/components/GetVoters.tsx @@ -1,28 +1,39 @@ +import { useLanguage } from "@/controllers/hooks/useLanguages"; import { User, Vote } from "delib-npm"; import React, { FC } from "react"; import { handleGetVoters } from "../statementSettingsCont"; -import { useLanguage } from "@/controllers/hooks/useLanguages"; import MembersChipsList from "./membership/membersChipsList/MembersChipList"; interface GetVotersProps { - statementId: string; + statementId: string; + joinedMembers: User[]; } -const GetVoters: FC = ({ statementId }) => { +const GetVoters: FC = ({ statementId, joinedMembers }) => { const { t } = useLanguage(); const [voters, setVoters] = React.useState([]); - const [clicked, setClicked] = React.useState(false); + const [nonVoters, setNonVoters] = React.useState([]); + const [clickedVoters, setClickedVoters] = React.useState(false); + const [clickedNonVoters, setClickedNonVoters] = React.useState(false); const getVoters = () => { - if (!clicked) { - handleGetVoters(statementId, setVoters, setClicked); + if (!clickedVoters) { + handleGetVoters(statementId, setVoters, setClickedVoters); } else { - setClicked(false); + setClickedVoters(false); } }; - const members = voters.flatMap((voter) => voter.voter as User); + React.useEffect(() => { + if (voters.length > 0) { + const voterIds = new Set(voters.map((voter) => voter.voter?.uid)); + const nonVotersList = joinedMembers.filter( + (member) => !voterIds.has(member.uid) + ); + setNonVoters(nonVotersList); + } + }, [voters, joinedMembers]); return ( <> @@ -35,17 +46,42 @@ const GetVoters: FC = ({ statementId }) => { {t("Get Voters")} - {clicked && ( + {clickedVoters && ( <> - {members.length > 0 && ( + {voters.length > 0 ? ( <> {voters.length} {t("Voted")} - + v.voter as User)} /> + + ) : ( +
{t("No voters found")}
+ )} + + )} + + + + {clickedNonVoters && ( + <> + {nonVoters.length > 0 ? ( + <> + + {nonVoters.length} {t("Did Not Vote")} + + + ) : ( +
{t("No non-voters found")}
)} - {members.length === 0 &&
{t("No voters found")}
} )} diff --git a/src/view/pages/statement/components/settings/components/statementSettingsForm/StatementSettingsForm.tsx b/src/view/pages/statement/components/settings/components/statementSettingsForm/StatementSettingsForm.tsx index c161582a8..a7f740559 100644 --- a/src/view/pages/statement/components/settings/components/statementSettingsForm/StatementSettingsForm.tsx +++ b/src/view/pages/statement/components/settings/components/statementSettingsForm/StatementSettingsForm.tsx @@ -2,7 +2,7 @@ import { Dispatch, FC } from 'react'; // Third party imports import { useNavigate, useParams } from 'react-router-dom'; -import { Statement } from 'delib-npm'; +import { Role, Statement, StatementSubscription } from 'delib-npm'; // Firestore functions @@ -26,6 +26,9 @@ import './StatementSettingsForm.scss'; // icons import SaveIcon from '@/assets/icons/save.svg?react'; import QuestionSettings from '../QuestionSettings/QuestionSettings'; +import { useAppSelector } from '@/controllers/hooks/reduxHooks'; +import { createSelector } from '@reduxjs/toolkit'; +import { RootState } from '@/model/store'; interface StatementSettingsFormProps { setIsLoading: (isLoading: boolean) => void; @@ -46,6 +49,24 @@ const StatementSettingsForm: FC = ({ const { statementId } = useParams(); const { t } = useLanguage(); + // Selector to get the statement memberships + const statementMembershipSelector = (statementId: string | undefined) => + createSelector( + (state: RootState) => state.statements.statementMembership, + (memberships) => + memberships.filter( + (membership: StatementSubscription) => + membership.statementId === statementId + ) + ); + + const members: StatementSubscription[] = useAppSelector( + statementMembershipSelector(statementId) + ); + + const joinedMembers = members.filter((member) => member.role !== Role.banned).map(m => m.user); + + // * Functions * // const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); @@ -77,7 +98,6 @@ const StatementSettingsForm: FC = ({
@@ -92,12 +112,12 @@ const StatementSettingsForm: FC = ({ - +
- +
- +
)} diff --git a/src/view/pages/statement/components/settings/statementSettingsCont.ts b/src/view/pages/statement/components/settings/statementSettingsCont.ts index 3e8d072b9..19832e51c 100644 --- a/src/view/pages/statement/components/settings/statementSettingsCont.ts +++ b/src/view/pages/statement/components/settings/statementSettingsCont.ts @@ -1,298 +1,314 @@ import { - Statement, - NavObject, - Vote, - Evaluation, - StatementType, - Screen, -} from 'delib-npm'; + Statement, + NavObject, + Vote, + Evaluation, + StatementType, + Screen, +} from "delib-npm"; // Helpers -import { getVoters } from '@/controllers/db/vote/getVotes'; -import { getEvaluations } from '@/controllers/db/evaluation/getEvaluation'; -import { navigateToStatementTab } from '@/controllers/general/helpers'; +import { getVoters } from "@/controllers/db/vote/getVotes"; +import { getEvaluations } from "@/controllers/db/evaluation/getEvaluation"; +import { navigateToStatementTab } from "@/controllers/general/helpers"; import { - createStatement, - setStatementToDB, - updateStatement, -} from '@/controllers/db/statements/setStatements'; + createStatement, + setStatementToDB, + updateStatement, +} from "@/controllers/db/statements/setStatements"; import { - defaultResultsSettings, - defaultStatementSettings, -} from './emptyStatementModel'; -import { NavigateFunction } from 'react-router-dom'; -import { store } from '@/model/store'; -import { setTempStatementsForPresentation } from '@/model/statements/statementsSlice'; + defaultResultsSettings, + defaultStatementSettings, +} from "./emptyStatementModel"; +import { NavigateFunction } from "react-router-dom"; +import { store } from "@/model/store"; +import { setTempStatementsForPresentation } from "@/model/statements/statementsSlice"; // Get users that voted on options in this statement export async function handleGetVoters( - parentId: string | undefined, - setVoters: React.Dispatch>, - setClicked: React.Dispatch> + parentId: string | undefined, + setVoters: React.Dispatch>, + setClicked: React.Dispatch> ) { - if (!parentId) return; - const voters = await getVoters(parentId); - setVoters(voters); - setClicked(true); + if (!parentId) return; + const voters = await getVoters(parentId); + setVoters(voters); + setClicked(true); +} + +//Get users that did not vote on options in this statement +export async function handleGetNonVoters( + parentId: string | undefined, + setNonVoters: React.Dispatch>, + setClicked: React.Dispatch> +) { + if (!parentId) return; + + try { + const voters = await getVoters(parentId); + + // Filter out users who haven't voted (those with no voter information) + const nonVoters = voters.filter((voter) => !voter.voter); + + setNonVoters(nonVoters); + + setClicked(true); + } catch (error) { + console.error("Error fetching non-voters:", error); + } } // Get users that evaluated on options in this statement export async function handleGetEvaluators( - parentId: string | undefined, - setEvaluators: React.Dispatch>, - setClicked: React.Dispatch> + parentId: string | undefined, + setEvaluators: React.Dispatch>, + setClicked: React.Dispatch> ) { - if (!parentId) return; - const evaluators = await getEvaluations(parentId); - setEvaluators(evaluators); - setClicked(true); + if (!parentId) return; + const evaluators = await getEvaluations(parentId); + setEvaluators(evaluators); + setClicked(true); } // Check if sub-page is checked in stored statement export function isSubPageChecked( - statement: Statement | undefined, - navObj: NavObject + statement: Statement | undefined, + navObj: NavObject ): boolean { - try { - //in case of a new statement - if (!statement) { - if (navObj.default === false) return false; - else return true; - } - - //in case of an existing statement - const { subScreens } = statement; - if (!subScreens) return true; - if (subScreens.includes(navObj.link)) return true; - - return false; - } catch (error) { - console.error(error); - - return true; - } + try { + //in case of a new statement + if (!statement) { + if (navObj.default === false) return false; + else return true; + } + + //in case of an existing statement + const { subScreens } = statement; + if (!subScreens) return true; + if (subScreens.includes(navObj.link)) return true; + + return false; + } catch (error) { + console.error(error); + + return true; + } } interface HandleSetStatementParams { - navigate: NavigateFunction; - statementId: string | undefined; - statement: Statement; - parentStatement?: Statement | 'top'; + navigate: NavigateFunction; + statementId: string | undefined; + statement: Statement; + parentStatement?: Statement | "top"; } export async function handleSetStatement({ - navigate, - statementId, - statement, - parentStatement, + navigate, + statementId, + statement, + parentStatement, }: HandleSetStatementParams) { - try { - - - - - // If statement title is empty, don't save - if(!statement.statement) return; - - const { - hasChildren, - resultsBy, - numberOfResults, - enableAddEvaluationOption, - enableAddVotingOption, - enhancedEvaluation, - showEvaluation, - subScreens, - membership, - } = getSetStatementData(statement); - - // If no statementId, user is on AddStatement page - if (!statementId) { - const newStatement = createStatement({ - text: statement.statement, - description: statement.description, - subScreens, - statementType: StatementType.question, - parentStatement: 'top', - resultsBy, - numberOfResults, - hasChildren, - enableAddEvaluationOption, - enableAddVotingOption, - enhancedEvaluation, - showEvaluation, - membership, - }); - if (!newStatement) throw new Error('newStatement had error in creating'); - - await setStatementToDB({ - parentStatement: 'top', - statement: newStatement, - addSubscription: true, - }); - navigateToStatementTab(newStatement, navigate); - - return; - } - - // If statementId, user is on Settings tab in statement page - else { - // update statement - if (!statement) throw new Error('statement is undefined'); - - const newStatement = updateStatement({ - statement, - text: statement.statement, - description: statement.description||'', - subScreens: subScreens, - statementType: StatementType.question, - resultsBy, - numberOfResults, - hasChildren, - enableAddEvaluationOption, - enableAddVotingOption, - enhancedEvaluation, - showEvaluation, - membership, - }); - if (!newStatement) throw new Error('newStatement had not been updated'); - - await setStatementToDB({ - parentStatement, - statement: newStatement, - addSubscription: true, - }); - navigateToStatementTab(newStatement, navigate); - - return; - } - } catch (error) { - console.error(error); - } + try { + // If statement title is empty, don't save + if (!statement.statement) return; + + const { + hasChildren, + resultsBy, + numberOfResults, + enableAddEvaluationOption, + enableAddVotingOption, + enhancedEvaluation, + showEvaluation, + subScreens, + membership, + } = getSetStatementData(statement); + + // If no statementId, user is on AddStatement page + if (!statementId) { + const newStatement = createStatement({ + text: statement.statement, + description: statement.description, + subScreens, + statementType: StatementType.question, + parentStatement: "top", + resultsBy, + numberOfResults, + hasChildren, + enableAddEvaluationOption, + enableAddVotingOption, + enhancedEvaluation, + showEvaluation, + membership, + }); + if (!newStatement) throw new Error("newStatement had error in creating"); + + await setStatementToDB({ + parentStatement: "top", + statement: newStatement, + addSubscription: true, + }); + navigateToStatementTab(newStatement, navigate); + + return; + } + + // If statementId, user is on Settings tab in statement page + else { + // update statement + if (!statement) throw new Error("statement is undefined"); + + const newStatement = updateStatement({ + statement, + text: statement.statement, + description: statement.description || "", + subScreens: subScreens, + statementType: StatementType.question, + resultsBy, + numberOfResults, + hasChildren, + enableAddEvaluationOption, + enableAddVotingOption, + enhancedEvaluation, + showEvaluation, + membership, + }); + if (!newStatement) throw new Error("newStatement had not been updated"); + + await setStatementToDB({ + parentStatement, + statement: newStatement, + addSubscription: true, + }); + navigateToStatementTab(newStatement, navigate); + + return; + } + } catch (error) { + console.error(error); + } } - - - - export const getStatementSettings = (statement: Statement) => { - const statementSettings = - statement.statementSettings ?? defaultStatementSettings; - - return { - enableAddEvaluationOption: Boolean( - statementSettings.enableAddEvaluationOption - ), - enableAddVotingOption: Boolean(statementSettings.enableAddVotingOption), - enhancedEvaluation: Boolean(statementSettings.enhancedEvaluation), - showEvaluation: Boolean(statementSettings.showEvaluation), - subScreens: statementSettings.subScreens ?? [], - inVotingGetOnlyResults: Boolean(statementSettings.inVotingGetOnlyResults), - enableSimilaritiesSearch: Boolean(statementSettings.enableSimilaritiesSearch), - enableNavigationalElements: Boolean(statementSettings.enableNavigationalElements), - }; + const statementSettings = + statement.statementSettings ?? defaultStatementSettings; + + return { + enableAddEvaluationOption: Boolean( + statementSettings.enableAddEvaluationOption + ), + enableAddVotingOption: Boolean(statementSettings.enableAddVotingOption), + enhancedEvaluation: Boolean(statementSettings.enhancedEvaluation), + showEvaluation: Boolean(statementSettings.showEvaluation), + subScreens: statementSettings.subScreens ?? [], + inVotingGetOnlyResults: Boolean(statementSettings.inVotingGetOnlyResults), + enableSimilaritiesSearch: Boolean( + statementSettings.enableSimilaritiesSearch + ), + enableNavigationalElements: Boolean( + statementSettings.enableNavigationalElements + ), + }; }; const getStatementSubScreens = (statement: Statement) => { - const defaultSubScreens = [Screen.CHAT, Screen.OPTIONS]; - const subScreens = statement.subScreens ?? defaultSubScreens; + const defaultSubScreens = [Screen.CHAT, Screen.OPTIONS]; + const subScreens = statement.subScreens ?? defaultSubScreens; - // don't allow setting sub-screens as an empty array - return subScreens.length === 0 ? defaultSubScreens : subScreens; + // don't allow setting sub-screens as an empty array + return subScreens.length === 0 ? defaultSubScreens : subScreens; }; const getSetStatementData = (statement: Statement) => { - const { resultsBy, numberOfResults } = - statement.resultsSettings ?? defaultResultsSettings; - const { - enableAddEvaluationOption, - enableAddVotingOption, - enhancedEvaluation, - showEvaluation, - } = getStatementSettings(statement); - - return { - hasChildren: Boolean(statement.hasChildren), - subScreens: getStatementSubScreens(statement), - resultsBy, - numberOfResults, - enableAddEvaluationOption, - enableAddVotingOption, - enhancedEvaluation, - showEvaluation, - membership: statement.membership, - }; + const { resultsBy, numberOfResults } = + statement.resultsSettings ?? defaultResultsSettings; + const { + enableAddEvaluationOption, + enableAddVotingOption, + enhancedEvaluation, + showEvaluation, + } = getStatementSettings(statement); + + return { + hasChildren: Boolean(statement.hasChildren), + subScreens: getStatementSubScreens(statement), + resultsBy, + numberOfResults, + enableAddEvaluationOption, + enableAddVotingOption, + enhancedEvaluation, + showEvaluation, + membership: statement.membership, + }; }; interface ToggleSubScreenParams { - subScreens: Screen[]; - screenLink: Screen; - statement: Statement; + subScreens: Screen[]; + screenLink: Screen; + statement: Statement; } export const toggleSubScreen = ({ - subScreens, - screenLink, - statement, + subScreens, + screenLink, + statement, }: ToggleSubScreenParams): Statement => { - const checked = subScreens.includes(screenLink) ?? false; - const newSubScreens = checked - ? subScreens.filter((subScreen) => subScreen !== screenLink) - : [...subScreens, screenLink]; - - return { - ...statement, - subScreens: newSubScreens, - }; + const checked = subScreens.includes(screenLink) ?? false; + const newSubScreens = checked + ? subScreens.filter((subScreen) => subScreen !== screenLink) + : [...subScreens, screenLink]; + + return { + ...statement, + subScreens: newSubScreens, + }; }; interface CreateStatementFromModalParams { - title: string; - description: string; - isOptionSelected: boolean; - parentStatement: Statement | 'top'; - toggleAskNotifications?: VoidFunction; - isSendToStoreTemp?: boolean; + title: string; + description: string; + isOptionSelected: boolean; + parentStatement: Statement | "top"; + toggleAskNotifications?: VoidFunction; + isSendToStoreTemp?: boolean; } export async function createStatementFromModal({ - title, - description, - isOptionSelected, - toggleAskNotifications, - parentStatement, - isSendToStoreTemp, + title, + description, + isOptionSelected, + toggleAskNotifications, + parentStatement, + isSendToStoreTemp, }: CreateStatementFromModalParams) { - try { - if (!title) throw new Error('title is undefined'); - - - - const newStatement = createStatement({ - ...defaultStatementSettings, - hasChildren: true, - toggleAskNotifications, - text:title, - description, - parentStatement, - statementType: isOptionSelected - ? StatementType.option - : StatementType.question, - }); - - if (!newStatement) throw new Error('newStatement was not created'); - - await setStatementToDB({ - statement: newStatement, - parentStatement: parentStatement === 'top' ? undefined : parentStatement, - addSubscription: true, - }); - - if (isSendToStoreTemp) { - //dispatch to the store - store.dispatch(setTempStatementsForPresentation([newStatement])); - } - } catch (error) { - console.error(error); - } + try { + if (!title) throw new Error("title is undefined"); + + const newStatement = createStatement({ + ...defaultStatementSettings, + hasChildren: true, + toggleAskNotifications, + text: title, + description, + parentStatement, + statementType: isOptionSelected + ? StatementType.option + : StatementType.question, + }); + + if (!newStatement) throw new Error("newStatement was not created"); + + await setStatementToDB({ + statement: newStatement, + parentStatement: parentStatement === "top" ? undefined : parentStatement, + addSubscription: true, + }); + + if (isSendToStoreTemp) { + //dispatch to the store + store.dispatch(setTempStatementsForPresentation([newStatement])); + } + } catch (error) { + console.error(error); + } } From 57c1ba8aefb1e3979f315310030ec9d4bfa8b8db Mon Sep 17 00:00:00 2001 From: Lee_D Date: Fri, 30 Aug 2024 15:58:48 +0300 Subject: [PATCH 3/4] code-refinement --- .../statement/components/settings/components/GetVoters.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/view/pages/statement/components/settings/components/GetVoters.tsx b/src/view/pages/statement/components/settings/components/GetVoters.tsx index 8f1338700..3c2a7dac5 100644 --- a/src/view/pages/statement/components/settings/components/GetVoters.tsx +++ b/src/view/pages/statement/components/settings/components/GetVoters.tsx @@ -1,6 +1,6 @@ import { useLanguage } from "@/controllers/hooks/useLanguages"; import { User, Vote } from "delib-npm"; -import React, { FC } from "react"; +import React, { FC, useEffect } from "react"; import { handleGetVoters } from "../statementSettingsCont"; import MembersChipsList from "./membership/membersChipsList/MembersChipList"; @@ -25,7 +25,8 @@ const GetVoters: FC = ({ statementId, joinedMembers }) => { } }; - React.useEffect(() => { + //filter out users who haven't vote/those with no voter information + useEffect(() => { if (voters.length > 0) { const voterIds = new Set(voters.map((voter) => voter.voter?.uid)); const nonVotersList = joinedMembers.filter( From 6504e9682c429d83ced01e318db6a7a73f6ddeee Mon Sep 17 00:00:00 2001 From: Lee_D Date: Tue, 3 Sep 2024 21:55:09 +0300 Subject: [PATCH 4/4] He-translation --- src/assets/Languages/he.json | 337 ++++++++++++++-------------- src/controllers/db/vote/getVotes.ts | 86 ++++--- 2 files changed, 211 insertions(+), 212 deletions(-) diff --git a/src/assets/Languages/he.json b/src/assets/Languages/he.json index 0362ceeec..ff4227c63 100644 --- a/src/assets/Languages/he.json +++ b/src/assets/Languages/he.json @@ -1,168 +1,171 @@ { - "Add": "הוספה", - "Add New Group": "הוספת קבוצה חדשה", - "Add Option": "הוספת פתרון", - "Add a solution": "הוספת פתרון", - "Add Question": "הוספת שאלה", - "Admin": "מנהל", - "Advanced": "מתקדם", - "Agree": "אני מסכים/ה", - "Agreement": "הסכמה", - "Agreement Description": "אנא אשר/י שאת/ה יודע/ת שזאת תוכנת ניסוי, וכל מידע שתכניס/י למערכת עלול להיות ציבורי וחשוף לקהל רחב. אנא המנע/י מהכנסת מידע רגיש. כל הכנסת מידע נמצא באחריותך בלבד, ואין לך תביעה מבעלי המערכת", - "Agreements": "הסכמות", - "All": "הכל", - "Allow participants to contribute options to the evaluation page": "לאפשר למשתתפים לתרום אפשרויות לדף ההערכות", - "Allow participants to contribute options to the voting page": "לאפשר למשתתפים לתרום אפשרויות לדף ההצבעה", - "Answer": "תשובה", - "Blocked": "חסום", - "Couldn't find the invitation. Please check the PIN and try again.": "לא נמצאה ההזמנה. אנא בדקו את הקוד ונסו שוב.", - "Cancel": "ביטול", - "Cancellation of division": "ביטול חלוקה", - "Chat": "שיחה", - "Close": "סגירה", - "Sign up with": "הרשם עם", - "Conversations": "שיחות", - "Creating Agreements": "יוצרים הסכמות", - "Delib": "המועצה", - "Delib: We create agreements together": "דליב: אנחנו יוצרים הסכמות ביחד", - "Description": "תיאור", - "Disconnect": "התנתקות", - "Display Results": "הצגת תוצאות", - "Display Results According To": "הצגת תוצאות לפי", - "Discussion Results": "תוצאות הדיון", - "Discussion Topic": "נושא הדיון", - "Divide into rooms": "חלק/י לחדרים", - "Division into rooms": "חלוקה לחדרים", - "Dont agree": "אני לא מסכים/ה", - "Edit Text": "עריכת טקסט", - "Enable Sub-Conversations": "לאפשר תת-שיחות", - "Evaluated": "העריכו", - "Enhanced Evaluation": "הערכה מגוונת", - "Evaluations": "פתרונות", - "Explain how to open the notifications": "הסבר כיצד לפתוח את ההתראות", - "Favorite Option": "אופציה מועדפת", - "Follow Me": "עקוב אחרי", - "Follow Mode Active": "מצב עקיבה פעיל", - "Follow Instructor": "עקוב אחרי המדריך/ה", - "Fostering Collaborations": "מקדמים שיתופי פעולה", - "From the Institute for Deliberative Democracy": "מבית המכון לדמוקרטיה דיונית", - "General": "כללי", - "Get Voters": "הבא מצביעים/ות", - "Get Evaluators": "הבא מעריכים/ות", - "Got it": "הבנתי", - "Guest": "אורח", - "Group": "קבוצה", - "Group Description": "תיאור הקבוצה", - "Group Title": "כותרת הקבוצה", - "Join with PIN number": "הצטרפות עם מספר קוד", - "Join": "הצטרף/י", - "Invite with PIN number": "הזמנה עם מספר קוד", - "Install the App": "התקנת האפליקציה", - "Info": "מידע", - "In conversation:": "בשיחה:", - "In Voting page, show only the results of the top options": "בדף ההצבעה, הצג רק את תוצאות האופציות המובילות", - "In Zoom": "בזום", - "Invited:": "מוזמנים:", - "It is necessary to receive notifications": "יש צורך לקבל התראות", - "Login with a temporary name": "התחברות עם שם זמני", - "Map": "מפה", - "Main": "ראשי", - "Main Page": "דף ראשי", - "Mass Questions": "שאלות המונים", - "Member": "חבר", - "Members in Group": "חברים בקבוצה", - "Management board": "לוח ניהול", - "Maximum number of participants in the room": "מספר מקסימלי של משתתפים בחדר", - "New": "חדש", - "New message": "הודעה חדשה", - "New Messages": "הודעות חדשות", - "Nickname": "כינוי", - "No": "לא", - "No Options Selected Yet": "לא נבחרו עדיין אפשרויות", - "No Topic Chosen by You": "לא נבחר נושא על ידך", - "No evaluators found": "לא נמצאו הערכות של משתתפים", - "No voters found": "לא נמצאו מצביעים", - "Number of Results to Display": "כמה תוצאות להציג", - "Number of Solutions in Each Level": "כמות פתרונות בכל רמה", - "Please suggest a solution to the question": "אנא הצע/י פתרון לשאלה", - "Option": "אפשרות", - "Options": "אפשרויות", - "Parent Admin": "מנהל על", - "Participants": "משתתפים", - "Participants choose rooms": "המשתתפים בוחרים חדרים", - "Please confirm alerts for Delib": "אנא אשרו התראות עבור דליב", - "Please confirm notifications to receive updates on new comments\nYou can disable notifications at any time": "אנא אשר/י התראות, כדי לקבל עדכונים על תגובות חדשות\nתוכל/י לבטל את ההתראות בכל זמן", - "Please evaluate each solution in the next set of solutions. For each solution, indicate your rating using the smiley (positive) or frown (negative) icons": "אנא העריכו כל פתרון בסט הפתרונות הבא. עבור כל פתרון, ציינו את הדירוג שלכם באמצעות האייקונים של החיוך (חיובי) או הפרצוף העצוב (שלילי)", - "Please evaluate the top solutions": "אנא העריכו את הפתרונות המובילים", - "Please chose your preferred solution": "אנא בחר/י את הפתרון המועדף עליך", - "Question": "שאלה", - "Questions": "שאלות", - "Random": "אקראי", - "Remove Option": "הסרת אפשרות", - "Results": "תוצאות", - "Results By": "תוצאות לפי", - "Room": "חדר", - "Rooms": "חדרים", - "Selected": "נבחר", - "Room Allocation": "חלוקה לחדרים", - "Room's Topic": "נושא החדר", - "Send a link to anonymous users": "שליחת קישור למשתמשים אנונימיים", - "Settings": "הגדרות", - "Share": "שתף/י", - "Show division into rooms": "הצג/י חלוקה לחדרים", - "Show Evaluations results": "הצגת תוצאות הערכות", - "Show": "הצג ", - "So you can communicate": "כדי שתוכלו לתקשר", - "Solutions": "פתרונות", - "Start": "התחלה", - "Sorry, Page not found": "מצטערים, הדף לא נמצא", - "Take me home": "הביאו אותי הביתה", - "Tabs to display": "לשוניות", - "General Settings": "הגדרות כלליות", - "Members": "חברים", - "Joined members": "חברים שהצטרפו", - "terms of use": "תנאי שימוש", - "Title": "כותרת", - "Turn off": "כיבוי התראות", - "Turn on": "הפעלת התראות", - "Update": "עדכון", - "Updating": "מעדכן", - "Voted": "הצביעו", - "Votes": "הצבעות", - "Voting": "הצבעה", - "Voting Results": "תוצאות ההצבעה", - "Vote": "הצבעה", - "Welcome to Room Number": "מוזמן/ת לחדר מספר", - "Yes": "כן", - "Would you like to receive notifications in this group?": "האם תרצה לקבל הודעות בקבוצה הזאת?", - "Save": "שמירה", - "description": "תיאור", - "Unmark as a Solution": "ביטול סימון כפתרון", - "Mark as a Solution": "סימון כפתרון", - "Mark as a Question": "סימון כשאלה", - "Unmark as a Question": "ביטול סימון כשאלה", - "Welcome to room": "ברוך/ה הבא/ה לחדר", - "Current stage": "שלב נוכחי", - "Suggestions": "הצעות", - "First Evaluation": "הערכה ראשונה", - "Second Evaluation": "הערכה שנייה", - "Finished": "סיום", - "single-step": "שלב אחד", - "multiple-steps": "מספר שלבים", - "There are no rooms yet": "אין עדיין חדרים", - "Enter your 4-digit passcode to unlock group access": "הזן את קוד הסיסמה בן 4 הספרות שלך כדי לבטל את נעילת הגישה לקבוצה", - "Bravo! Your passcode is correct. Welcome aboard!": "בראבו! קוד הגישה שלך נכון. ברוכים הבאים!", - "Something went wrong. Please try again!": "משהו השתבש. בבקשה נסה שוב!", - "Submit": "שלח", - "Click on": "תלחץ על", - "Add suggestion button": "הוסף פתרון", - "to add your suggestion": "כדי להוסיף את הפתרון שלך", - "Add suggestion":"הוסף פתרון", - "Add question button": "הוסף שאלה", - "to add your question": "כדי להוסיף את השאלה שלך", - "Add question":"הוסף שאלה", - "Sort questions": "מיין שאלות", - "Sort suggestions": "מיין פתרונות", - "Allow similarity search": "אפשר חיפוש דמיון", - "Allow removal of navigational elements": "אפשר הסרת רכיבי ניווט" -} \ No newline at end of file + "Add": "הוספה", + "Add New Group": "הוספת קבוצה חדשה", + "Add Option": "הוספת פתרון", + "Add a solution": "הוספת פתרון", + "Add Question": "הוספת שאלה", + "Admin": "מנהל", + "Advanced": "מתקדם", + "Agree": "אני מסכים/ה", + "Agreement": "הסכמה", + "Agreement Description": "אנא אשר/י שאת/ה יודע/ת שזאת תוכנת ניסוי, וכל מידע שתכניס/י למערכת עלול להיות ציבורי וחשוף לקהל רחב. אנא המנע/י מהכנסת מידע רגיש. כל הכנסת מידע נמצא באחריותך בלבד, ואין לך תביעה מבעלי המערכת", + "Agreements": "הסכמות", + "All": "הכל", + "Allow participants to contribute options to the evaluation page": "לאפשר למשתתפים לתרום אפשרויות לדף ההערכות", + "Allow participants to contribute options to the voting page": "לאפשר למשתתפים לתרום אפשרויות לדף ההצבעה", + "Answer": "תשובה", + "Blocked": "חסום", + "Couldn't find the invitation. Please check the PIN and try again.": "לא נמצאה ההזמנה. אנא בדקו את הקוד ונסו שוב.", + "Cancel": "ביטול", + "Cancellation of division": "ביטול חלוקה", + "Chat": "שיחה", + "Close": "סגירה", + "Sign up with": "הרשם עם", + "Conversations": "שיחות", + "Creating Agreements": "יוצרים הסכמות", + "Delib": "המועצה", + "Delib: We create agreements together": "דליב: אנחנו יוצרים הסכמות ביחד", + "Description": "תיאור", + "Disconnect": "התנתקות", + "Display Results": "הצגת תוצאות", + "Display Results According To": "הצגת תוצאות לפי", + "Discussion Results": "תוצאות הדיון", + "Discussion Topic": "נושא הדיון", + "Divide into rooms": "חלק/י לחדרים", + "Division into rooms": "חלוקה לחדרים", + "Dont agree": "אני לא מסכים/ה", + "Edit Text": "עריכת טקסט", + "Enable Sub-Conversations": "לאפשר תת-שיחות", + "Evaluated": "העריכו", + "Enhanced Evaluation": "הערכה מגוונת", + "Evaluations": "פתרונות", + "Explain how to open the notifications": "הסבר כיצד לפתוח את ההתראות", + "Favorite Option": "אופציה מועדפת", + "Follow Me": "עקוב אחרי", + "Follow Mode Active": "מצב עקיבה פעיל", + "Follow Instructor": "עקוב אחרי המדריך/ה", + "Fostering Collaborations": "מקדמים שיתופי פעולה", + "From the Institute for Deliberative Democracy": "מבית המכון לדמוקרטיה דיונית", + "General": "כללי", + "Get Voters": "הבא מצביעים/ות", + "Get Non Voters": "הבא משתתפים/ות שלא הצביעו", + "Get Evaluators": "הבא מעריכים/ות", + "Got it": "הבנתי", + "Guest": "אורח", + "Group": "קבוצה", + "Group Description": "תיאור הקבוצה", + "Group Title": "כותרת הקבוצה", + "Join with PIN number": "הצטרפות עם מספר קוד", + "Join": "הצטרף/י", + "Invite with PIN number": "הזמנה עם מספר קוד", + "Install the App": "התקנת האפליקציה", + "Info": "מידע", + "In conversation:": "בשיחה:", + "In Voting page, show only the results of the top options": "בדף ההצבעה, הצג רק את תוצאות האופציות המובילות", + "In Zoom": "בזום", + "Invited:": "מוזמנים:", + "It is necessary to receive notifications": "יש צורך לקבל התראות", + "Login with a temporary name": "התחברות עם שם זמני", + "Map": "מפה", + "Main": "ראשי", + "Main Page": "דף ראשי", + "Mass Questions": "שאלות המונים", + "Member": "חבר", + "Members in Group": "חברים בקבוצה", + "Management board": "לוח ניהול", + "Maximum number of participants in the room": "מספר מקסימלי של משתתפים בחדר", + "New": "חדש", + "New message": "הודעה חדשה", + "New Messages": "הודעות חדשות", + "Nickname": "כינוי", + "No": "לא", + "No Options Selected Yet": "לא נבחרו עדיין אפשרויות", + "No Topic Chosen by You": "לא נבחר נושא על ידך", + "No evaluators found": "לא נמצאו הערכות של משתתפים", + "No voters found": "לא נמצאו מצביעים", + "No non-voters found": "לא נמצאו משתתפים/ות שלא הצביעו", + "Number of Results to Display": "כמה תוצאות להציג", + "Number of Solutions in Each Level": "כמות פתרונות בכל רמה", + "Please suggest a solution to the question": "אנא הצע/י פתרון לשאלה", + "Option": "אפשרות", + "Options": "אפשרויות", + "Parent Admin": "מנהל על", + "Participants": "משתתפים", + "Participants choose rooms": "המשתתפים בוחרים חדרים", + "Please confirm alerts for Delib": "אנא אשרו התראות עבור דליב", + "Please confirm notifications to receive updates on new comments\nYou can disable notifications at any time": "אנא אשר/י התראות, כדי לקבל עדכונים על תגובות חדשות\nתוכל/י לבטל את ההתראות בכל זמן", + "Please evaluate each solution in the next set of solutions. For each solution, indicate your rating using the smiley (positive) or frown (negative) icons": "אנא העריכו כל פתרון בסט הפתרונות הבא. עבור כל פתרון, ציינו את הדירוג שלכם באמצעות האייקונים של החיוך (חיובי) או הפרצוף העצוב (שלילי)", + "Please evaluate the top solutions": "אנא העריכו את הפתרונות המובילים", + "Please chose your preferred solution": "אנא בחר/י את הפתרון המועדף עליך", + "Question": "שאלה", + "Questions": "שאלות", + "Random": "אקראי", + "Remove Option": "הסרת אפשרות", + "Results": "תוצאות", + "Results By": "תוצאות לפי", + "Room": "חדר", + "Rooms": "חדרים", + "Selected": "נבחר", + "Room Allocation": "חלוקה לחדרים", + "Room's Topic": "נושא החדר", + "Send a link to anonymous users": "שליחת קישור למשתמשים אנונימיים", + "Settings": "הגדרות", + "Share": "שתף/י", + "Show division into rooms": "הצג/י חלוקה לחדרים", + "Show Evaluations results": "הצגת תוצאות הערכות", + "Show": "הצג ", + "So you can communicate": "כדי שתוכלו לתקשר", + "Solutions": "פתרונות", + "Start": "התחלה", + "Sorry, Page not found": "מצטערים, הדף לא נמצא", + "Take me home": "הביאו אותי הביתה", + "Tabs to display": "לשוניות", + "General Settings": "הגדרות כלליות", + "Members": "חברים", + "Joined members": "חברים שהצטרפו", + "terms of use": "תנאי שימוש", + "Title": "כותרת", + "Turn off": "כיבוי התראות", + "Turn on": "הפעלת התראות", + "Update": "עדכון", + "Updating": "מעדכן", + "Voted": "הצביעו", + "Votes": "הצבעות", + "Voting": "הצבעה", + "Did Not Vote": "לא הצביעו", + "Voting Results": "תוצאות ההצבעה", + "Vote": "הצבעה", + "Welcome to Room Number": "מוזמן/ת לחדר מספר", + "Yes": "כן", + "Would you like to receive notifications in this group?": "האם תרצה לקבל הודעות בקבוצה הזאת?", + "Save": "שמירה", + "description": "תיאור", + "Unmark as a Solution": "ביטול סימון כפתרון", + "Mark as a Solution": "סימון כפתרון", + "Mark as a Question": "סימון כשאלה", + "Unmark as a Question": "ביטול סימון כשאלה", + "Welcome to room": "ברוך/ה הבא/ה לחדר", + "Current stage": "שלב נוכחי", + "Suggestions": "הצעות", + "First Evaluation": "הערכה ראשונה", + "Second Evaluation": "הערכה שנייה", + "Finished": "סיום", + "single-step": "שלב אחד", + "multiple-steps": "מספר שלבים", + "There are no rooms yet": "אין עדיין חדרים", + "Enter your 4-digit passcode to unlock group access": "הזן את קוד הסיסמה בן 4 הספרות שלך כדי לבטל את נעילת הגישה לקבוצה", + "Bravo! Your passcode is correct. Welcome aboard!": "בראבו! קוד הגישה שלך נכון. ברוכים הבאים!", + "Something went wrong. Please try again!": "משהו השתבש. בבקשה נסה שוב!", + "Submit": "שלח", + "Click on": "תלחץ על", + "Add suggestion button": "הוסף פתרון", + "to add your suggestion": "כדי להוסיף את הפתרון שלך", + "Add suggestion": "הוסף פתרון", + "Add question button": "הוסף שאלה", + "to add your question": "כדי להוסיף את השאלה שלך", + "Add question": "הוסף שאלה", + "Sort questions": "מיין שאלות", + "Sort suggestions": "מיין פתרונות", + "Allow similarity search": "אפשר חיפוש דמיון", + "Allow removal of navigational elements": "אפשר הסרת רכיבי ניווט" +} diff --git a/src/controllers/db/vote/getVotes.ts b/src/controllers/db/vote/getVotes.ts index 376efeeae..164211eec 100644 --- a/src/controllers/db/vote/getVotes.ts +++ b/src/controllers/db/vote/getVotes.ts @@ -1,10 +1,10 @@ import { - collection, - doc, - getDoc, - getDocs, - query, - where, + collection, + doc, + getDoc, + getDocs, + query, + where, } from "firebase/firestore"; import { Collections, Statement, StatementSchema, Vote } from "delib-npm"; import { DB } from "../config"; @@ -14,56 +14,52 @@ import { store } from "@/model/store"; // Why get user from firebase when we can pass it as a parameter? export async function getToVoteOnParent( - parentId: string, - updateStoreWithVoteCB: (statement: Statement) => void, + parentId: string, + updateStoreWithVoteCB: (statement: Statement) => void ): Promise { - try { - const user = getUserFromFirebase(); - if (!user) throw new Error("User not logged in"); - if(!parentId) throw new Error("ParentId not provided"); - const voteId = getVoteId(user.uid, parentId); - if (!voteId) throw new Error("VoteId not found"); + try { + const user = getUserFromFirebase(); + if (!user) throw new Error("User not logged in"); + if (!parentId) throw new Error("ParentId not provided"); + const voteId = getVoteId(user.uid, parentId); + if (!voteId) throw new Error("VoteId not found"); - const parentVoteRef = doc( - DB, - Collections.votes, - voteId - ); + const parentVoteRef = doc(DB, Collections.votes, voteId); - const voteDB = await getDoc(parentVoteRef); + const voteDB = await getDoc(parentVoteRef); - const vote = voteDB.data(); - if (!vote) return; // the user has not voted on this statement - VoteSchema.parse(vote); + const vote = voteDB.data(); + if (!vote) return; + VoteSchema.parse(vote); - //get statemtn to update to store - const statementRef = doc(DB, Collections.statements, vote.statementId); - const statementDB = await getDoc(statementRef); + //get statemtn to update to store + const statementRef = doc(DB, Collections.statements, vote.statementId); + const statementDB = await getDoc(statementRef); - const statement = statementDB.data() as Statement; - if (!statement) throw new Error("Parent not found"); - StatementSchema.parse(statement); + const statement = statementDB.data() as Statement; + if (!statement) throw new Error("Parent not found"); + StatementSchema.parse(statement); - updateStoreWithVoteCB(statement); - } catch (error) { - console.error(error); - } + updateStoreWithVoteCB(statement); + } catch (error) { + console.error(error); + } } export async function getVoters(parentId: string): Promise { - try { - const user = store.getState().user.user; - if (!user) throw new Error("User not logged in"); - const votesRef = collection(DB, Collections.votes); - const q = query(votesRef, where("parentId", "==", parentId)); + try { + const user = store.getState().user.user; + if (!user) throw new Error("User not logged in"); + const votesRef = collection(DB, Collections.votes); + const q = query(votesRef, where("parentId", "==", parentId)); - const votersDB = await getDocs(q); - const voters = votersDB.docs.map((vote) => vote.data()) as Vote[]; + const votersDB = await getDocs(q); + const voters = votersDB.docs.map((vote) => vote.data()) as Vote[]; - return voters; - } catch (error) { - console.error(error); + return voters; + } catch (error) { + console.error(error); - return [] as Vote[]; - } + return [] as Vote[]; + } }