From 7e17efbeb5e4713c58b4603f8d96b351dd2d0272 Mon Sep 17 00:00:00 2001 From: Akiva Berger Date: Tue, 25 Jul 2023 12:41:44 +0300 Subject: [PATCH 001/548] feat(editor): add button on hover --- static/css/s2.css | 1 + static/js/Editor.jsx | 10 ++++++++-- static/test/linker_test.html | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 1f147ac52c..0d48648d9a 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -9500,6 +9500,7 @@ span.purim-emoji img{ position: relative; pointer-events:none; background-color: transparent; + margin-left: 50px; } .editorAddInterface:before { content: ""; diff --git a/static/js/Editor.jsx b/static/js/Editor.jsx index f5cba6c6a8..344ec63835 100644 --- a/static/js/Editor.jsx +++ b/static/js/Editor.jsx @@ -1062,12 +1062,14 @@ const AddInterface = ({ attributes, children, element }) => { const Element = (props) => { const { attributes, children, element } = props; + const [isHovering, setIsHovering] = useState(false); const sheetItemClasses = { sheetItem: 1, empty: !(Node.string(element)), highlight: (useSlate().highlightedNode === (element.node ? element.node.toString() : null)) }; + switch (element.type) { case 'spacer': const spacerSelected = useSelected(); @@ -1077,8 +1079,12 @@ const Element = (props) => { empty: 1 } return ( -
- {spacerSelected && document.getSelection().isCollapsed ? : <>{children}} +
setIsHovering(true)} + onMouseLeave={() => setIsHovering(false)} + {...attributes}> + {isHovering && } + {children}
); case 'SheetSource': diff --git a/static/test/linker_test.html b/static/test/linker_test.html index 0b318e8040..49f49e0515 100644 --- a/static/test/linker_test.html +++ b/static/test/linker_test.html @@ -96,7 +96,7 @@

השתדרות ד פועל

Hebrew Ranges

שמות, כ"ד, יג - יד

-

שמות, כ"ד, יג-יד


 +

שמות, כ"ד, יג-יד

במדבר, כ"ז, טו - כג

בראשית א לא - ב ו

(en dash) בראשית א לא – ב ו

From 7bdef7e0effc52b3cbe0073808471662b7b63de7 Mon Sep 17 00:00:00 2001 From: Skyler Cohen Date: Thu, 14 Mar 2024 14:34:19 -0400 Subject: [PATCH 002/548] feat(unbounce): Add embed code for Unbounce --- templates/base.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/base.html b/templates/base.html index 71a90be76e..e5884b31f0 100644 --- a/templates/base.html +++ b/templates/base.html @@ -150,6 +150,8 @@ {% endif %} + + From 39a70745edd09a5381438eda3eb8e7afd3c97fa7 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 21 Mar 2024 20:45:10 +0200 Subject: [PATCH 003/548] feat(Products): Initial FE wiring --- sites/sefaria/urls.py | 1 + static/js/ReaderApp.jsx | 2 ++ static/js/StaticPages.jsx | 63 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/sites/sefaria/urls.py b/sites/sefaria/urls.py index dd5998eded..92a850de42 100644 --- a/sites/sefaria/urls.py +++ b/sites/sefaria/urls.py @@ -49,6 +49,7 @@ "cloudflare_site_is_down_en", "cloudflare_site_is_down_he", "team", + "products" ] static_pages_by_lang = [ diff --git a/static/js/ReaderApp.jsx b/static/js/ReaderApp.jsx index e7579638f8..1608afe6f7 100644 --- a/static/js/ReaderApp.jsx +++ b/static/js/ReaderApp.jsx @@ -24,6 +24,7 @@ import { WordByWordPage, JobsPage, TeamMembersPage, + ProductsPage } from './StaticPages'; import { SignUpModal, @@ -2318,4 +2319,5 @@ export { WordByWordPage, JobsPage, TeamMembersPage, + ProductsPage, }; diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index fbf3959898..156ba02cff 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3128,6 +3128,68 @@ const JobsPage = memo(() => { ); }); + +/* +* Products Page +*/ + + +const product = ({ job }) => { + return ( + + ); +}; + + + +const ProductsPage = memo(() => { + const [products, setProducts] = useState({}); + const [error, setError] = useState(null); + + const loadProducts = async () => { + const dummy_data = { + "title": "My Sefaria Product", + "url": "www.sefaria.org", + "cta_labels": [ + { + "he": "הורידו עכשיו", + "en": "Install now!", + "url": "www.example.com" + }, + { + "he": "חנות אפליקציות", + "en": "App store", + "url": "www.example.com", + "icon": "https://storage.googleapis.com/img.sefaria.org/topics/rosh-hashanah.jpeg", + } + ], + "type": "Experiment", + "rectanglionURL": "https://storage.googleapis.com/img.sefaria.org/topics/rosh-hashanah.jpeg", + "desc": { + "he": "אהגכלחדךגכחךדסכצד", + "en": "Abcdefghijklmno" + } + }; + setProducts(dummy_data) + }; + + useEffect(() => { + loadProducts(); + }, []); + + return ( +
+

{products.title}

+

{products.desc.en}

+

{products.cta_labels[0].en}

+
+ ); +}); + export { RemoteLearningPage, SheetsLandingPage, @@ -3142,4 +3204,5 @@ export { WordByWordPage, JobsPage, TeamMembersPage, + ProductsPage, }; From 8eff60392743c02268bc588eaee0b8601041f51c Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 27 Mar 2024 12:23:46 +0200 Subject: [PATCH 004/548] feat(Products Page): Render components on products page --- static/js/StaticPages.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 156ba02cff..a62353263a 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3184,8 +3184,8 @@ const ProductsPage = memo(() => { return (

{products.title}

-

{products.desc.en}

-

{products.cta_labels[0].en}

+ {/*

{products.desc}

+

{products.cta_labels}

*/}
); }); From 25a4113e2cdee7e1ed370654296216c759fb5969 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 27 Mar 2024 12:34:49 +0200 Subject: [PATCH 005/548] feat(Products Page): Static html --- templates/static/products.html | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 templates/static/products.html diff --git a/templates/static/products.html b/templates/static/products.html new file mode 100644 index 0000000000..061e987a13 --- /dev/null +++ b/templates/static/products.html @@ -0,0 +1,36 @@ + +{% extends "base.html" %} +{% load i18n static %} + +{% block title %}{% trans "Products" %}{% endblock %} + +{% block description %}{% trans "A catalogue of Sefaria's products and experiments" %}{% endblock %} + +{% block js %} + +{% endblock %} + +{% block content %} + +
+
+
+

+ Products + צוות ספריא +

+
+
+
+ Blahblah +
+
+
+
+ +{% endblock %} From 6554f79faedf1f26452cae3847472a489e06e3f9 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 2 Apr 2024 22:09:28 +0300 Subject: [PATCH 006/548] feat(Products Page): Wiring up basic FE elems, first pass --- static/css/s2.css | 21 +++++++++++++++++++++ static/js/StaticPages.jsx | 20 ++++++++++++++++---- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 557c3117b1..ca1b59572a 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12755,6 +12755,27 @@ span.ref-link-color-3 {color: blue} width: 67%; } } + +.productsInner { + border: 2px solid red; + display: flex; + align-items: right; +} + +.productsInner img { + width: 30%; + max-width: 100%; + border: 2px solid purple; + padding-right: 10%; +} + +.productsInner .productsDesc { + border: 2px solid aquamarine; + font: 'Roboto', sans-serif; + color: #666666; + font-size: 16px; +} + .image-in-text-title { margin: auto; /* English System Small */ margin-top: 15px; diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index a62353263a..825ea1fd65 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3171,7 +3171,7 @@ const ProductsPage = memo(() => { "rectanglionURL": "https://storage.googleapis.com/img.sefaria.org/topics/rosh-hashanah.jpeg", "desc": { "he": "אהגכלחדךגכחךדסכצד", - "en": "Abcdefghijklmno" + "en": "Vivamus dictum rutrum mi, ut varius odio viverra sit amet. Quisque vitae pharetra ipsum. Integer nec dui malesuada, maximus nisi vitae, ullamcorper enim. Aenean ultrices ullamcorper malesuada. Fusce et leo justo. Etiam quis mattis enim. " } }; setProducts(dummy_data) @@ -3181,11 +3181,23 @@ const ProductsPage = memo(() => { loadProducts(); }, []); + console.log("products: ", products.desc) + // TODO - Will need to use InterfaceText for language switching!! return (
-

{products.title}

- {/*

{products.desc}

-

{products.cta_labels}

*/} +
+

{products.title}

+ {products?.type} + {/* Will need some kind of mapping here */} + {products?.cta_labels?.map(item => ( + {item.en} + ))} +
+ +
+ +
{products?.desc?.en}
+
); }); From 5083f4368664f5a54ddc7271cd8d833c84cac652 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 3 Apr 2024 13:59:59 +0300 Subject: [PATCH 007/548] feat(Products Page): Spec out some more basic css --- static/css/s2.css | 32 ++++++++++++++++++++++++++++++++ static/js/StaticPages.jsx | 14 ++++++++------ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index ca1b59572a..f65b93b448 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12776,6 +12776,38 @@ span.ref-link-color-3 {color: blue} font-size: 16px; } +.productsHeader { + display: flex; + justify-content: space-evenly; +} + +.productsHeader .productsTitle { + font: 'Roboto', sans-serif; + color: #666666; + font-size: 22px; + font-weight: 500px; +} + +.productsHeader .productsTypeLabel { + font: 'Roboto', sans-serif; + font-size: 14px; + font-weight: 400; + line-height: 18px; + background-color: #EDEDEC; + border-radius: 6px; + padding: 5px 10px; + color: #666666; +} + +.productsHeader .productsCTA { + color: #4B71B7; +} + +.productsHeader .productsCTAIcon { + width: 1%; + height: 1%; +} + .image-in-text-title { margin: auto; /* English System Small */ margin-top: 15px; diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 825ea1fd65..66f0e6d2cd 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3186,14 +3186,16 @@ const ProductsPage = memo(() => { return (
-

{products.title}

- {products?.type} - {/* Will need some kind of mapping here */} - {products?.cta_labels?.map(item => ( - {item.en} - ))} + {products.title} + {products?.type} + {/* Will need some kind of mapping here, conditional on icon image*/} + {products?.cta_labels?.map(item => ( + {item.en} + ))}
+
+
{products?.desc?.en}
From 4b9427a5155d73014791a82311fc9aa0cebad5b3 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 3 Apr 2024 22:08:35 +0300 Subject: [PATCH 008/548] feat(Products Page): First pass at GraphQL, WIP --- static/js/StaticPages.jsx | 199 +++++++++++++++++++++++++++++++++----- 1 file changed, 176 insertions(+), 23 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 66f0e6d2cd..b8183d3c58 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3149,33 +3149,186 @@ const product = ({ job }) => { const ProductsPage = memo(() => { const [products, setProducts] = useState({}); const [error, setError] = useState(null); + + const fetchProductsJSON = async () => { + const query = ` + query { + products ( + pagination: { limit: -1 } + ) + { + data { + id + attributes { + title + url + type + description + rectanglion { + data { + attributes { + url + alternativeText + } + } + } + createdAt + updatedAt + locale + cta_labels { + data { + id + attributes { + text + url + icon { + data { + id + attributes { + url + alternativeText + } + } + } + locale + localizations { + data { + id + attributes { + text + } + } + } + } + } + } + localizations { + data { + attributes { + locale + title + type + description + } + } + } + } + } + } + } + + `; - const loadProducts = async () => { - const dummy_data = { - "title": "My Sefaria Product", - "url": "www.sefaria.org", - "cta_labels": [ - { - "he": "הורידו עכשיו", - "en": "Install now!", - "url": "www.example.com" + try { + const response = await fetch(STRAPI_INSTANCE + "/graphql", { + method: "POST", + mode: "cors", + cache: "no-cache", + credentials: "omit", + headers: { + "Content-Type": "application/json", }, - { - "he": "חנות אפליקציות", - "en": "App store", - "url": "www.example.com", - "icon": "https://storage.googleapis.com/img.sefaria.org/topics/rosh-hashanah.jpeg", - } - ], - "type": "Experiment", - "rectanglionURL": "https://storage.googleapis.com/img.sefaria.org/topics/rosh-hashanah.jpeg", - "desc": { - "he": "אהגכלחדךגכחךדסכצד", - "en": "Vivamus dictum rutrum mi, ut varius odio viverra sit amet. Quisque vitae pharetra ipsum. Integer nec dui malesuada, maximus nisi vitae, ullamcorper enim. Aenean ultrices ullamcorper malesuada. Fusce et leo justo. Etiam quis mattis enim. " + redirect: "follow", + referrerPolicy: "no-referrer", + body: JSON.stringify({ query }), + }); + if (!response.ok) { + throw new Error(`HTTP Error: ${response.statusText}`); } - }; - setProducts(dummy_data) + const data = await response.json(); + return data; + } catch (error) { + throw error; + } }; + + const loadProducts = async () => { + if (typeof STRAPI_INSTANCE !== "undefined" && STRAPI_INSTANCE) { + try { + const productsData = await fetchProductsJSON(); + console.log(productsData); + const heLocalization = productsData.attributes.localizations.data[0].attributes; + const ctaLabels = productsData.attributes.ctaLabels.data.attributes; + + console.log(productsData); + + const productsFromStrapi = productsData.data?.products?.data?.map((productsData) => { + + const ctaLabelsLocalized = ctaLabels.map((cta) => { + return { + text: { + en: cta.text, + he: cta.localizations.data[0].attributes.text + }, + url: cta.url, + icon: { + url: cta.icon.data.attributes.url, + altText: cta.icon.data.attributes.alternativeText + } + }; + }); + + return { + id: productsData.id, + titles: { + en: productsData.attributes.title, + he: heLocalization.title + }, + type: { + en: productsData.attributes.type, + he: productsData.attributes.localizations.data[0].attributes.type, + }, + url: productsData.attributes.url, + desc: + { + en: productsData.attributes.description, + he: heLocalization.description + }, + rectanglion: { + url: productsData.attributes.rectanglion.data.attributes.url, + alt: productsData.attributes.rectanglion.data.attributes.alternativeText, + }, + ctaLabels: ctaLabelsLocalized, + + }; + }, {}); + console.log('Products from STRAPI', productsFromStrapi); + setProducts(productsFromStrapi); + } catch (error) { + console.error("Fetch error:", error); + setError("Error: Sefaria's CMS cannot be reached"); + } + } else { + setError("Error: Sefaria's CMS cannot be reached"); + } + }; + + // const loadProducts = async () => { + // const dummy_data = { + // "title": "My Sefaria Product", + // "url": "www.sefaria.org", + // "cta_labels": [ + // { + // "he": "הורידו עכשיו", + // "en": "Install now!", + // "url": "www.example.com" + // }, + // { + // "he": "חנות אפליקציות", + // "en": "App store", + // "url": "www.example.com", + // "icon": "https://storage.googleapis.com/img.sefaria.org/topics/rosh-hashanah.jpeg", + // } + // ], + // "type": "Experiment", + // "rectanglionURL": "https://storage.googleapis.com/img.sefaria.org/topics/rosh-hashanah.jpeg", + // "desc": { + // "he": "אהגכלחדךגכחךדסכצד", + // "en": "Vivamus dictum rutrum mi, ut varius odio viverra sit amet. Quisque vitae pharetra ipsum. Integer nec dui malesuada, maximus nisi vitae, ullamcorper enim. Aenean ultrices ullamcorper malesuada. Fusce et leo justo. Etiam quis mattis enim. " + // } + // }; + // setProducts(dummy_data) + // }; useEffect(() => { loadProducts(); From 6b4e9b5264eea1a2c7c208d7175b92d059941e84 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 4 Apr 2024 10:36:01 +0300 Subject: [PATCH 009/548] feat(Products Page): Tighten up data and code for first pass --- static/js/StaticPages.jsx | 63 +++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index b8183d3c58..1f102064d5 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3246,24 +3246,27 @@ const ProductsPage = memo(() => { if (typeof STRAPI_INSTANCE !== "undefined" && STRAPI_INSTANCE) { try { const productsData = await fetchProductsJSON(); - console.log(productsData); - const heLocalization = productsData.attributes.localizations.data[0].attributes; - const ctaLabels = productsData.attributes.ctaLabels.data.attributes; + // const productsData = productsDataFull.data.products.data; + // console.log(productsData); + console.log(productsData); const productsFromStrapi = productsData.data?.products?.data?.map((productsData) => { + const heLocalization = productsData.attributes.localizations.data[0].attributes; + const ctaLabels = productsData.attributes.cta_labels.data; + const ctaLabelsLocalized = ctaLabels.map((cta) => { return { text: { - en: cta.text, - he: cta.localizations.data[0].attributes.text + en: cta.attributes.text, + he: cta.attributes.localizations.data[0].attributes.text }, - url: cta.url, + url: cta.attributes.url, icon: { - url: cta.icon.data.attributes.url, - altText: cta.icon.data.attributes.alternativeText + url: cta.attributes.icon.data.attributes.url, + // altText: cta.attributes.icon.data.attributes.alternativeText } }; }); @@ -3286,7 +3289,7 @@ const ProductsPage = memo(() => { }, rectanglion: { url: productsData.attributes.rectanglion.data.attributes.url, - alt: productsData.attributes.rectanglion.data.attributes.alternativeText, + // alt: productsData.attributes.rectanglion.data.attributes.alternativeText, }, ctaLabels: ctaLabelsLocalized, @@ -3330,33 +3333,43 @@ const ProductsPage = memo(() => { // setProducts(dummy_data) // }; + debugger; + useEffect(() => { loadProducts(); }, []); - console.log("products: ", products.desc) + console.log("products: ", products) // TODO - Will need to use InterfaceText for language switching!! + + return (
-
- {products.title} - {products?.type} - {/* Will need some kind of mapping here, conditional on icon image*/} - {products?.cta_labels?.map(item => ( - {item.en} - ))} -
- -
- -
- -
{products?.desc?.en}
-
+ {products?.map((product) => ( +
+
+ {product.title} + {product.type} + {/* Will need some kind of mapping here, conditional on icon image*/} + {product.cta_labels?.map(item => ( + + {item.en} + {item.en} + + ))} +
+
+
+ Product Image +
{product.desc?.en}
+
+
+ ))}
); }); + export { RemoteLearningPage, SheetsLandingPage, From d52d29df338a65d0d6a14e496e25c82d4c610ca6 Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 15 Apr 2024 21:41:33 +0300 Subject: [PATCH 010/548] feat(Products page): Working firstpass at FE with Strapi --- static/js/StaticPages.jsx | 75 ++++++++++++++------------------------- 1 file changed, 26 insertions(+), 49 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 1f102064d5..bf80853e1d 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3147,7 +3147,7 @@ const product = ({ job }) => { const ProductsPage = memo(() => { - const [products, setProducts] = useState({}); + const [products, setProducts] = useState([]); const [error, setError] = useState(null); const fetchProductsJSON = async () => { @@ -3306,65 +3306,42 @@ const ProductsPage = memo(() => { } }; - // const loadProducts = async () => { - // const dummy_data = { - // "title": "My Sefaria Product", - // "url": "www.sefaria.org", - // "cta_labels": [ - // { - // "he": "הורידו עכשיו", - // "en": "Install now!", - // "url": "www.example.com" - // }, - // { - // "he": "חנות אפליקציות", - // "en": "App store", - // "url": "www.example.com", - // "icon": "https://storage.googleapis.com/img.sefaria.org/topics/rosh-hashanah.jpeg", - // } - // ], - // "type": "Experiment", - // "rectanglionURL": "https://storage.googleapis.com/img.sefaria.org/topics/rosh-hashanah.jpeg", - // "desc": { - // "he": "אהגכלחדךגכחךדסכצד", - // "en": "Vivamus dictum rutrum mi, ut varius odio viverra sit amet. Quisque vitae pharetra ipsum. Integer nec dui malesuada, maximus nisi vitae, ullamcorper enim. Aenean ultrices ullamcorper malesuada. Fusce et leo justo. Etiam quis mattis enim. " - // } - // }; - // setProducts(dummy_data) - // }; - - debugger; useEffect(() => { + console.log("UseEffect triggered"); loadProducts(); }, []); console.log("products: ", products) // TODO - Will need to use InterfaceText for language switching!! - + return (
- {products?.map((product) => ( -
-
- {product.title} - {product.type} - {/* Will need some kind of mapping here, conditional on icon image*/} - {product.cta_labels?.map(item => ( - - {item.en} - {item.en} - - ))} + {products ? ( + products.map((product) => ( +
+
+ {product.titles.en} + {product.type.en} + {/* Will need some kind of mapping here, conditional on icon image*/} + {product.cta_labels?.map(cta => ( + + Click icon + {cta.text.en} + + ))} +
+
+
+ Product Image +
{product.desc?.en}
+
-
-
- Product Image -
{product.desc?.en}
-
-
- ))} + )) + ) : ( +
Loading...
+ )}
); }); From be2433d76a5c58a93f9cbb44acf6dab926242607 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 16 Apr 2024 19:16:26 +0300 Subject: [PATCH 011/548] feat(Products Page): Confirm data first pass, minor CSS tweaks --- static/css/s2.css | 3 ++- static/js/StaticPages.jsx | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index f65b93b448..cf0e8ed4ef 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12763,7 +12763,7 @@ span.ref-link-color-3 {color: blue} } .productsInner img { - width: 30%; + width: 200px; max-width: 100%; border: 2px solid purple; padding-right: 10%; @@ -12779,6 +12779,7 @@ span.ref-link-color-3 {color: blue} .productsHeader { display: flex; justify-content: space-evenly; + margin-top: 10%; } .productsHeader .productsTitle { diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index bf80853e1d..6b5660a27d 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3250,7 +3250,8 @@ const ProductsPage = memo(() => { // console.log(productsData); - console.log(productsData); + console.log('datadata', productsData); + debugger; const productsFromStrapi = productsData.data?.products?.data?.map((productsData) => { @@ -3265,7 +3266,7 @@ const ProductsPage = memo(() => { }, url: cta.attributes.url, icon: { - url: cta.attributes.icon.data.attributes.url, + url: cta.attributes.icon.data?.attributes.url, // altText: cta.attributes.icon.data.attributes.alternativeText } }; @@ -3327,7 +3328,7 @@ const ProductsPage = memo(() => { {/* Will need some kind of mapping here, conditional on icon image*/} {product.cta_labels?.map(cta => ( - Click icon + {cta.icon.url && Click icon} {cta.text.en} ))} From 4803e887b0ba9468b80a7018096e4850b5813450 Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 6 May 2024 20:34:13 +0300 Subject: [PATCH 012/548] feat(Products Page): Polishing FE --- static/css/s2.css | 19 ++++++++++++------- static/js/StaticPages.jsx | 6 ++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index cf0e8ed4ef..9ae3c96b6c 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12757,7 +12757,7 @@ span.ref-link-color-3 {color: blue} } .productsInner { - border: 2px solid red; + /* border: 2px solid red; */ display: flex; align-items: right; } @@ -12765,12 +12765,12 @@ span.ref-link-color-3 {color: blue} .productsInner img { width: 200px; max-width: 100%; - border: 2px solid purple; - padding-right: 10%; + border: 2px solid gray; + margin-right: 3%; } .productsInner .productsDesc { - border: 2px solid aquamarine; + /* border: 2px solid aquamarine; */ font: 'Roboto', sans-serif; color: #666666; font-size: 16px; @@ -12778,7 +12778,7 @@ span.ref-link-color-3 {color: blue} .productsHeader { display: flex; - justify-content: space-evenly; + justify-content: left; margin-top: 10%; } @@ -12798,15 +12798,20 @@ span.ref-link-color-3 {color: blue} border-radius: 6px; padding: 5px 10px; color: #666666; + margin-left: 3%; } .productsHeader .productsCTA { color: #4B71B7; + border-width: 10px; + border-color: #0cd200; } .productsHeader .productsCTAIcon { - width: 1%; - height: 1%; + width: 10px; + height: 10px; + /* border-width: 10px; + border-color: #0cd200; */ } .image-in-text-title { diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 6b5660a27d..1828fae11e 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -9,6 +9,7 @@ import {NewsletterSignUpForm} from "./NewsletterSignUpForm"; import palette from './sefaria/palette'; import classNames from 'classnames'; import Cookies from 'js-cookie'; +import ReactMarkdown from 'react-markdown'; @@ -3328,7 +3329,8 @@ const ProductsPage = memo(() => { {/* Will need some kind of mapping here, conditional on icon image*/} {product.cta_labels?.map(cta => ( - {cta.icon.url && Click icon} + {console.log('cta', cta)} + {/* {cta.icon.url && Click icon} */} {cta.text.en} ))} @@ -3336,7 +3338,7 @@ const ProductsPage = memo(() => {
Product Image -
{product.desc?.en}
+ {product.desc?.en}
)) From e7fb04d59a25bac99790ca597d472b5a5b05a74f Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 7 May 2024 13:49:53 +0300 Subject: [PATCH 013/548] chore(Products Page): Render CTA Labels --- static/css/s2.css | 2 ++ static/js/StaticPages.jsx | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/static/css/s2.css b/static/css/s2.css index 9ae3c96b6c..041d3bbd7b 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12805,6 +12805,8 @@ span.ref-link-color-3 {color: blue} color: #4B71B7; border-width: 10px; border-color: #0cd200; + margin-left: 4%; + justify-content: right; } .productsHeader .productsCTAIcon { diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 1828fae11e..6ef5561f8e 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3327,7 +3327,8 @@ const ProductsPage = memo(() => { {product.titles.en} {product.type.en} {/* Will need some kind of mapping here, conditional on icon image*/} - {product.cta_labels?.map(cta => ( + {console.log('ctaTEST', product.ctaLabels)} + {product.ctaLabels?.map(cta => ( {console.log('cta', cta)} {/* {cta.icon.url && Click icon} */} From dc637f73a63194a062403b088ed86ab538d8dfbc Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 7 May 2024 13:55:24 +0300 Subject: [PATCH 014/548] chore(Products Page): Local img render fix, title fix --- static/js/StaticPages.jsx | 5 ++--- templates/static/products.html | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 6ef5561f8e..32bf257554 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3327,18 +3327,17 @@ const ProductsPage = memo(() => { {product.titles.en} {product.type.en} {/* Will need some kind of mapping here, conditional on icon image*/} - {console.log('ctaTEST', product.ctaLabels)} {product.ctaLabels?.map(cta => ( {console.log('cta', cta)} - {/* {cta.icon.url && Click icon} */} + {cta.icon.url && Click icon} {cta.text.en} ))}

- Product Image + Product Image {product.desc?.en}
diff --git a/templates/static/products.html b/templates/static/products.html index 061e987a13..74ba2f477f 100644 --- a/templates/static/products.html +++ b/templates/static/products.html @@ -21,7 +21,7 @@

- Products + Sefaria's Products צוות ספריא

From e105c61791e954b50364830a72209491fca06cb3 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 7 May 2024 22:16:46 +0300 Subject: [PATCH 015/548] feat(Products Page): Hebrew text --- static/css/s2.css | 23 +++++++++++++++---- static/js/StaticPages.jsx | 42 ++++++++++++++++++++++++++-------- templates/static/products.html | 4 ++-- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 041d3bbd7b..019993ec81 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12765,7 +12765,6 @@ span.ref-link-color-3 {color: blue} .productsInner img { width: 200px; max-width: 100%; - border: 2px solid gray; margin-right: 3%; } @@ -12801,21 +12800,35 @@ span.ref-link-color-3 {color: blue} margin-left: 3%; } -.productsHeader .productsCTA { +.productsHeader .cta { + display: flex; + align-items: center; +} + +.productsHeader .cta .productsCTA { color: #4B71B7; border-width: 10px; border-color: #0cd200; - margin-left: 4%; - justify-content: right; + margin-right: 10px; } -.productsHeader .productsCTAIcon { +.productsHeader .cta .productsCTAIcon { width: 10px; height: 10px; + margin-left: 10px; /* border-width: 10px; border-color: #0cd200; */ } +.productsTitle { + font-family: Roboto; + font-size: 22px; + font-weight: 500; + line-height: 25.78px; + text-align: left; + color: #666666; +} + .image-in-text-title { margin: auto; /* English System Small */ margin-top: 15px; diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 32bf257554..00528757be 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3324,21 +3324,43 @@ const ProductsPage = memo(() => { products.map((product) => (
- {product.titles.en} - {product.type.en} + + {product.titles.en} + {product.titles.he} + + + {product.type.en} + {product.type.he} + {/* Will need some kind of mapping here, conditional on icon image*/} - {product.ctaLabels?.map(cta => ( - - {console.log('cta', cta)} - {cta.icon.url && Click icon} - {cta.text.en} - - ))} + + {product.ctaLabels?.map(cta => ( + + {console.log('cta', cta)} + {cta.icon.url && Click icon} + + {cta.text.en} + {cta.text.he} + + + + ))} +

Product Image - {product.desc?.en} + + + {product.desc?.en} + + + + + {product.desc?.he} + + +
)) diff --git a/templates/static/products.html b/templates/static/products.html index 74ba2f477f..794c0e41d2 100644 --- a/templates/static/products.html +++ b/templates/static/products.html @@ -21,8 +21,8 @@

- Sefaria's Products - צוות ספריא + Sefaria's Products + המוצרים שלנו

From 226adf764a1e13d954921db9ddc125c860684aef Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 9 May 2024 12:15:45 +0300 Subject: [PATCH 016/548] feat(Products Page): CSS tweaks --- static/css/s2.css | 11 ++++++++++- static/js/StaticPages.jsx | 24 +++++++++++++----------- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 019993ec81..e2331a0902 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12777,10 +12777,14 @@ span.ref-link-color-3 {color: blue} .productsHeader { display: flex; - justify-content: left; + justify-content: space-between; margin-top: 10%; } +.productsTitleAndLabel { + flex:auto; +} + .productsHeader .productsTitle { font: 'Roboto', sans-serif; color: #666666; @@ -12829,6 +12833,11 @@ span.ref-link-color-3 {color: blue} color: #666666; } +.productsChevron path { + fill: #4B71B7; /* Change to the desired color */ + stroke-width: 0.5px; /* Adjust the thickness as needed */ +} + .image-in-text-title { margin: auto; /* English System Small */ margin-top: 15px; diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 00528757be..c7586d5ff3 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3324,16 +3324,18 @@ const ProductsPage = memo(() => { products.map((product) => (
- - {product.titles.en} - {product.titles.he} - - - {product.type.en} - {product.type.he} - +
+ + {product.titles.en} + {product.titles.he} + + + {product.type.en} + {product.type.he} + +
{/* Will need some kind of mapping here, conditional on icon image*/} - +

From 72f0e8c5e2d9080c478e3827d3896c105c752f32 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 9 May 2024 12:24:06 +0300 Subject: [PATCH 017/548] feat(Products Page): CSS for icon --- static/css/s2.css | 17 +++++++++-------- static/js/StaticPages.jsx | 2 -- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index e2331a0902..67b737565d 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12817,11 +12817,12 @@ span.ref-link-color-3 {color: blue} } .productsHeader .cta .productsCTAIcon { - width: 10px; - height: 10px; - margin-left: 10px; - /* border-width: 10px; - border-color: #0cd200; */ + width: 13.33px; + height: 16px; + top: 646px; + left: 610px; + fill: #4B71B7; + margin: 0 5px; } .productsTitle { @@ -12833,9 +12834,9 @@ span.ref-link-color-3 {color: blue} color: #666666; } -.productsChevron path { - fill: #4B71B7; /* Change to the desired color */ - stroke-width: 0.5px; /* Adjust the thickness as needed */ +.productsCTA::after{ + content: " >"; + color: #4B71B7; } .image-in-text-title { diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index c7586d5ff3..f5c34faff2 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3338,13 +3338,11 @@ const ProductsPage = memo(() => { From 3bccb1d947dea3b76b83f02aa29ab4bf0398bc55 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 9 May 2024 13:24:23 +0300 Subject: [PATCH 018/548] feat(Products Page): Icon recolor --- static/css/s2.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/css/s2.css b/static/css/s2.css index 67b737565d..ec2ec9df95 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12821,8 +12821,8 @@ span.ref-link-color-3 {color: blue} height: 16px; top: 646px; left: 610px; - fill: #4B71B7; margin: 0 5px; + filter: invert(45%) sepia(17%) saturate(1643%) hue-rotate(180deg) brightness(90%) contrast(90%); } .productsTitle { From d56b54c2e05c7f9b1c767f55a13b790545be1002 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 16 May 2024 09:58:55 +0300 Subject: [PATCH 019/548] feat(Products Page): CSS tweaks --- static/css/s2.css | 7 ++++++- static/js/StaticPages.jsx | 6 +++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index ec2ec9df95..463dead7bd 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12822,7 +12822,12 @@ span.ref-link-color-3 {color: blue} top: 646px; left: 610px; margin: 0 5px; - filter: invert(45%) sepia(17%) saturate(1643%) hue-rotate(180deg) brightness(90%) contrast(90%); + /* filter: invert(45%) sepia(17%) saturate(1643%) hue-rotate(180deg) brightness(90%) contrast(90%); */ + --image-path: attr(data-image-path); + mask: url(--image-path) no-repeat; + background-color: #4B71B7; + border: #0cd200; + ; } .productsTitle { diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index f5c34faff2..7d5282994b 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3338,7 +3338,11 @@ const ProductsPage = memo(() => { {/* Will need some kind of mapping here, conditional on icon image*/}
From b793eeedafff30a979046b4989a40d1a27bcaa4d Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 21 May 2024 13:22:59 +0300 Subject: [PATCH 021/548] feat(Products Page): Image fixed height --- static/css/s2.css | 1 + 1 file changed, 1 insertion(+) diff --git a/static/css/s2.css b/static/css/s2.css index 463dead7bd..430860f9d7 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12766,6 +12766,7 @@ span.ref-link-color-3 {color: blue} width: 200px; max-width: 100%; margin-right: 3%; + max-height: 116px; } .productsInner .productsDesc { From 5a1c87de14c38d1d6e6794f071009e4165799d7d Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 21 May 2024 13:41:31 +0300 Subject: [PATCH 022/548] feat(Products Page): Use margin-inline-start/end to improve Hebrew margin spacing --- static/css/s2.css | 13 ++++++------- static/js/StaticPages.jsx | 1 - 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 430860f9d7..ae14da53bf 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12765,7 +12765,7 @@ span.ref-link-color-3 {color: blue} .productsInner img { width: 200px; max-width: 100%; - margin-right: 3%; + margin-inline-end: 3%; max-height: 116px; } @@ -12802,7 +12802,7 @@ span.ref-link-color-3 {color: blue} border-radius: 6px; padding: 5px 10px; color: #666666; - margin-left: 3%; + margin-inline-start: 3%; } .productsHeader .cta { @@ -12814,7 +12814,7 @@ span.ref-link-color-3 {color: blue} color: #4B71B7; border-width: 10px; border-color: #0cd200; - margin-right: 10px; + margin-inline-end: 10px; } .productsHeader .cta .productsCTAIcon { @@ -12823,12 +12823,11 @@ span.ref-link-color-3 {color: blue} top: 646px; left: 610px; margin: 0 5px; - /* filter: invert(45%) sepia(17%) saturate(1643%) hue-rotate(180deg) brightness(90%) contrast(90%); */ - --image-path: attr(data-image-path); + filter: brightness(0) saturate(100%) invert(52%) sepia(17%) saturate(6763%) hue-rotate(200deg) brightness(78%) contrast(77%);; + /* --image-path: attr(data-image-path); mask: url(--image-path) no-repeat; background-color: #4B71B7; - border: #0cd200; - ; + border: #0cd200; */ } .productsTitle { diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 9116c83d60..41e5957634 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3334,7 +3334,6 @@ const ProductsPage = memo(() => { {product.type.he} ) : ''}
- {/* Will need some kind of mapping here, conditional on icon image*/}
{product.ctaLabels?.map(cta => ( From 6883b3fa2951dd08d06296372bfd5b678f67a25a Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 22 May 2024 11:10:54 +0300 Subject: [PATCH 023/548] feat(Products Page): Add reorderability --- static/js/StaticPages.jsx | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 41e5957634..2a9fd7db4d 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3135,15 +3135,15 @@ const JobsPage = memo(() => { */ -const product = ({ job }) => { - return ( - - ); -}; +// const product = ({ job }) => { +// return ( +// +// ); +// }; @@ -3162,6 +3162,7 @@ const ProductsPage = memo(() => { id attributes { title + rank url type description @@ -3217,7 +3218,6 @@ const ProductsPage = memo(() => { } } } - `; try { @@ -3279,6 +3279,7 @@ const ProductsPage = memo(() => { en: productsData.attributes.title, he: heLocalization.title }, + rank: productsData.attributes.rank, type: { en: productsData.attributes.type, he: productsData.attributes.localizations.data[0].attributes.type, @@ -3297,8 +3298,10 @@ const ProductsPage = memo(() => { }; }, {}); - console.log('Products from STRAPI', productsFromStrapi); - setProducts(productsFromStrapi); + + const orderedProducts = productsFromStrapi.sort((a, b) => a.rank - b.rank); + console.log('Products from STRAPI', orderedProducts); + setProducts(orderedProducts); } catch (error) { console.error("Fetch error:", error); setError("Error: Sefaria's CMS cannot be reached"); From 16ac39b4261ad5a1c52b19ae0cbed5d3256ef7b0 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 22 May 2024 11:16:10 +0300 Subject: [PATCH 024/548] fix(Products Page): Revert from test to loading --- templates/static/products.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/static/products.html b/templates/static/products.html index 794c0e41d2..004c7244ee 100644 --- a/templates/static/products.html +++ b/templates/static/products.html @@ -27,7 +27,7 @@

- Blahblah +

Loading...

From 765ac0a2dcb74b3bdfecaa6c5f6f16d9599f2c17 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 22 May 2024 11:41:40 +0300 Subject: [PATCH 025/548] feat(Products Page): First pass gray dev box --- static/css/s2.css | 35 ++++++++++++++++++++++++++++++++++- static/js/StaticPages.jsx | 12 +++++++++++- 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index ae14da53bf..34661b09c9 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12839,11 +12839,44 @@ span.ref-link-color-3 {color: blue} color: #666666; } -.productsCTA::after{ +.productsCTA::after { content: " >"; color: #4B71B7; } +.productsDevBox { + background: #EDEDEC; + color: #666666; + border: red; + font-family: Roboto; + font-size: 16px; + font-weight: 400; + line-height: 18.75px; + text-align: left; + padding: 3%; +} + +.productsDevBox .productsDevHeader { + font-family: Roboto; + font-size: 22px; + font-weight: 500; + line-height: 25.78px; + text-align: left; + padding-bottom: 2%; + +} + +.productsDevBox a { + color: #4B71B7 !important; + +} + +.productsDevBox a::after { + content: " >"; + color: #4B71B7; +} + + .image-in-text-title { margin: auto; /* English System Small */ margin-top: 15px; diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 2a9fd7db4d..fd0961d641 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3318,11 +3318,21 @@ const ProductsPage = memo(() => { }, []); console.log("products: ", products) - // TODO - Will need to use InterfaceText for language switching!! + + + const DevBox = () => { + return ( +
+

Sefaria Developers

+

Check out the products our developer friends from around the world have been building for you! Explore

+
+ ); + }; return (
+ {products ? ( products.map((product) => (
From a6910c8355c7304d9d66a1298902f08ef152c645 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 22 May 2024 11:47:42 +0300 Subject: [PATCH 026/548] feat(Products Page): Add template Hebrew for devbox, adjust styling --- static/css/s2.css | 5 +++-- static/js/StaticPages.jsx | 13 +++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 34661b09c9..5aef3b942a 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12852,7 +12852,9 @@ span.ref-link-color-3 {color: blue} font-size: 16px; font-weight: 400; line-height: 18.75px; - text-align: left; + display: flex; + align-items: flex-start; + flex-direction: column; padding: 3%; } @@ -12861,7 +12863,6 @@ span.ref-link-color-3 {color: blue} font-size: 22px; font-weight: 500; line-height: 25.78px; - text-align: left; padding-bottom: 2%; } diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index fd0961d641..bf40147c7b 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3323,8 +3323,17 @@ const ProductsPage = memo(() => { const DevBox = () => { return (
-

Sefaria Developers

-

Check out the products our developer friends from around the world have been building for you! Explore

+

+ Sefaria Developers + עברית פה +

+

+ + Check out the products our developer friends from around the world have been building for you! Explore + + עברית פה + +

); }; From f4237efe772578c17925c4ecb7329749dcd6ad43 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 23 May 2024 11:59:17 +0300 Subject: [PATCH 027/548] feat(Products Page): Separate into smaller JSX components --- static/js/StaticPages.jsx | 107 +++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 42 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index bf40147c7b..7679f3f589 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3247,12 +3247,6 @@ const ProductsPage = memo(() => { if (typeof STRAPI_INSTANCE !== "undefined" && STRAPI_INSTANCE) { try { const productsData = await fetchProductsJSON(); - // const productsData = productsDataFull.data.products.data; - // console.log(productsData); - - - console.log('datadata', productsData); - debugger; const productsFromStrapi = productsData.data?.products?.data?.map((productsData) => { @@ -3338,42 +3332,44 @@ const ProductsPage = memo(() => { ); }; + const ProductTitle = ({product}) => { + return ( +
+ + {product.titles.en} + {product.titles.he} + + {product.type.en ? ( + {product.type.en} + {product.type.he} + ) : ''} +
+ ); + }; - return ( -
- - {products ? ( - products.map((product) => ( -
-
-
- - {product.titles.en} - {product.titles.he} - - {product.type.en ? ( - {product.type.en} - {product.type.he} - ) : ''} -
-
- {product.ctaLabels?.map(cta => ( - - {cta.icon.url && Click icon} - - - {cta.text.en} - {cta.text.he} - - - ))} -
-
-
-
+ const ProductCTA = ({product}) => { + return ( +
+ {product.ctaLabels?.map(cta => ( + + {cta.icon.url && Click icon} + + + {cta.text.en} + {cta.text.he} + + + ))} +
+ ); + }; + + const ProductDesc = ({product}) => { + return ( +
Product Image @@ -3387,7 +3383,34 @@ const ProductsPage = memo(() => {
-
+ ); + }; + + const Product = ({key, product}) => { + return ( +
+
+ + +
+
+ +
+ ); + }; + + // Map to a component, create an array of components, insert dev box to that array, map + // Pull out each div, own simple functional comp -- there's master product functional that maps the data and calls each of them + // [product, product, devbox, product ] + // leave the position as a variable so can change, even if in code. (n is a var) + // render as children? array of react components. {array[:n]} {dev} {array[n:]} + + return ( +
+ {/* */} + {products ? ( + products.map((product) => ( + )) ) : (
Loading...
From 7ad691ea1151db88371d186df4228e7fc0374d8b Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 23 May 2024 15:08:32 +0300 Subject: [PATCH 028/548] feat(Products Page): Injection of DevBox, updating copy, margin --- static/css/s2.css | 1 + static/js/StaticPages.jsx | 46 ++++++++++++++++++++------------------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 5aef3b942a..3dee9df2be 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12856,6 +12856,7 @@ span.ref-link-color-3 {color: blue} align-items: flex-start; flex-direction: column; padding: 3%; + margin-top: 10%; } .productsDevBox .productsDevHeader { diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 7679f3f589..07b63a1dc1 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3135,17 +3135,6 @@ const JobsPage = memo(() => { */ -// const product = ({ job }) => { -// return ( -// -// ); -// }; - - const ProductsPage = memo(() => { const [products, setProducts] = useState([]); @@ -3262,7 +3251,6 @@ const ProductsPage = memo(() => { url: cta.attributes.url, icon: { url: cta.attributes.icon.data?.attributes.url, - // altText: cta.attributes.icon.data.attributes.alternativeText } }; }); @@ -3286,7 +3274,6 @@ const ProductsPage = memo(() => { }, rectanglion: { url: productsData.attributes.rectanglion.data.attributes.url, - // alt: productsData.attributes.rectanglion.data.attributes.alternativeText, }, ctaLabels: ctaLabelsLocalized, @@ -3294,7 +3281,7 @@ const ProductsPage = memo(() => { }, {}); const orderedProducts = productsFromStrapi.sort((a, b) => a.rank - b.rank); - console.log('Products from STRAPI', orderedProducts); + console.log('Products from Strapi', orderedProducts); setProducts(orderedProducts); } catch (error) { console.error("Fetch error:", error); @@ -3318,12 +3305,12 @@ const ProductsPage = memo(() => { return (

- Sefaria Developers + Powered by Sefaria עברית פה

- Check out the products our developer friends from around the world have been building for you! Explore + Check out the products our software developer friends from around the world have been building for you! Explore עברית פה @@ -3398,20 +3385,35 @@ const ProductsPage = memo(() => {

); }; - + + const ProductList = []; + if (products) { + for (const product of products) { + ProductList.push() + } + } + + // Map to a component, create an array of components, insert dev box to that array, map // Pull out each div, own simple functional comp -- there's master product functional that maps the data and calls each of them // [product, product, devbox, product ] // leave the position as a variable so can change, even if in code. (n is a var) // render as children? array of react components. {array[:n]} {dev} {array[n:]} + // Possible issue, state not set yet until return called? Bc of useEffect? + + const devBoxPosition = 2; + const initialProducts = ProductList.slice(0, devBoxPosition); + const remainingProducts = ProductList.slice(devBoxPosition); + return (
- {/* */} - {products ? ( - products.map((product) => ( - - )) + {products && products.length > 0 ? ( + <> + {initialProducts} + + {remainingProducts} + ) : (
Loading...
)} From a1de610704bdca09c37beeedcb623a4f73a6897b Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 23 May 2024 15:11:47 +0300 Subject: [PATCH 029/548] chore(Products Page): Clean up comments, console.log --- static/js/StaticPages.jsx | 66 +++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 07b63a1dc1..47c5e90d06 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3281,7 +3281,6 @@ const ProductsPage = memo(() => { }, {}); const orderedProducts = productsFromStrapi.sort((a, b) => a.rank - b.rank); - console.log('Products from Strapi', orderedProducts); setProducts(orderedProducts); } catch (error) { console.error("Fetch error:", error); @@ -3294,7 +3293,6 @@ const ProductsPage = memo(() => { useEffect(() => { - console.log("UseEffect triggered"); loadProducts(); }, []); @@ -3337,39 +3335,38 @@ const ProductsPage = memo(() => { const ProductCTA = ({product}) => { return (
- {product.ctaLabels?.map(cta => ( - - {cta.icon.url && Click icon} - - - {cta.text.en} - {cta.text.he} - - - ))} -
+ {product.ctaLabels?.map(cta => ( + + {cta.icon.url && Click icon} + + + {cta.text.en} + {cta.text.he} + + + ))} +
); }; const ProductDesc = ({product}) => { return (
- Product Image - - - {product.desc?.en} - - - - - {product.desc?.he} - - - -
+ Product Image + + + {product.desc?.en} + + + + + {product.desc?.he} + + +
); }; @@ -3380,7 +3377,9 @@ const ProductsPage = memo(() => {
+
+
); @@ -3393,15 +3392,6 @@ const ProductsPage = memo(() => { } } - - // Map to a component, create an array of components, insert dev box to that array, map - // Pull out each div, own simple functional comp -- there's master product functional that maps the data and calls each of them - // [product, product, devbox, product ] - // leave the position as a variable so can change, even if in code. (n is a var) - // render as children? array of react components. {array[:n]} {dev} {array[n:]} - - // Possible issue, state not set yet until return called? Bc of useEffect? - const devBoxPosition = 2; const initialProducts = ProductList.slice(0, devBoxPosition); const remainingProducts = ProductList.slice(devBoxPosition); From 6f39d757d3c4ec150c268627e5117fdfb5dde689 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 23 May 2024 15:22:57 +0300 Subject: [PATCH 030/548] fix(Products Page): HR styling under product headers --- static/css/s2.css | 7 ++++++- static/js/StaticPages.jsx | 4 +--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 3dee9df2be..30b06cff83 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12756,6 +12756,10 @@ span.ref-link-color-3 {color: blue} } } +.product hr { + border: 1px solid var(--light-grey); +} + .productsInner { /* border: 2px solid red; */ display: flex; @@ -12783,9 +12787,10 @@ span.ref-link-color-3 {color: blue} } .productsTitleAndLabel { - flex:auto; + flex: auto; } + .productsHeader .productsTitle { font: 'Roboto', sans-serif; color: #666666; diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 47c5e90d06..7341bae193 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3372,14 +3372,12 @@ const ProductsPage = memo(() => { const Product = ({key, product}) => { return ( -
+
-
-
); From a92286dc4ecc76cf98c8e6ed3d60676764f26482 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 23 May 2024 15:30:08 +0300 Subject: [PATCH 031/548] chore(Products Page): Comments --- static/js/StaticPages.jsx | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 7341bae193..99b2f3e0aa 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3140,6 +3140,7 @@ const ProductsPage = memo(() => { const [products, setProducts] = useState([]); const [error, setError] = useState(null); + // GraphQL query to Strapi const fetchProductsJSON = async () => { const query = ` query { @@ -3232,6 +3233,7 @@ const ProductsPage = memo(() => { } }; + // Loading Products data, and setting the state ordering the products by their `rank` const loadProducts = async () => { if (typeof STRAPI_INSTANCE !== "undefined" && STRAPI_INSTANCE) { try { @@ -3299,6 +3301,7 @@ const ProductsPage = memo(() => { console.log("products: ", products) + // The static content on the page inviting users to browse our "powered-by" products const DevBox = () => { return (
@@ -3317,6 +3320,11 @@ const ProductsPage = memo(() => { ); }; + /** + * The following are the building block components of an individual product. + */ + + // The title and gray background label for each product const ProductTitle = ({product}) => { return (
@@ -3332,6 +3340,7 @@ const ProductsPage = memo(() => { ); }; + // The call-to-action (link) in the heading of each product const ProductCTA = ({product}) => { return (
@@ -3352,6 +3361,7 @@ const ProductsPage = memo(() => { ); }; + // The main body of each product entry, containing an image and description const ProductDesc = ({product}) => { return (
@@ -3370,6 +3380,7 @@ const ProductsPage = memo(() => { ); }; + // The main product component, comprised of the building block sub-components const Product = ({key, product}) => { return (
@@ -3383,6 +3394,10 @@ const ProductsPage = memo(() => { ); }; + // In order to inject the static 'DevBox' in a fixed position on the page, we + // create an array of components, and then slice the list into two sub-lists at the + // desired insertion position for the 'DevBox'. When rendering, we render the + // first sub-list, the , and finally the second sub-list. const ProductList = []; if (products) { for (const product of products) { From b7e553dc2eeb0b6e5f1f54c1678c51747761a79d Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 27 May 2024 11:49:51 +0300 Subject: [PATCH 032/548] feat(Products Page): Hebrew devbox text --- static/js/StaticPages.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 99b2f3e0aa..5e5369d0db 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3307,13 +3307,13 @@ const ProductsPage = memo(() => {

Powered by Sefaria - עברית פה + פרויקטים מכח ספריא

Check out the products our software developer friends from around the world have been building for you! Explore - עברית פה + נסו את המוצרים שמפתחי תוכנה וידידי ספריא מרחבי העולם בנו עבורכם! גלו את הפרויקטים

@@ -3323,7 +3323,7 @@ const ProductsPage = memo(() => { /** * The following are the building block components of an individual product. */ - + // The title and gray background label for each product const ProductTitle = ({product}) => { return ( From e2a43e6edba5c84e6739d023492aabcdf7cd01cf Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 28 May 2024 11:30:14 +0300 Subject: [PATCH 033/548] chore(Products Page): Sort on backend --- static/js/StaticPages.jsx | 113 +++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 56 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 5e5369d0db..0a194a3e45 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3141,73 +3141,75 @@ const ProductsPage = memo(() => { const [error, setError] = useState(null); // GraphQL query to Strapi + // TODO - add publicationState:PREVIEW, to query for draft feature for admin const fetchProductsJSON = async () => { const query = ` query { - products ( - pagination: { limit: -1 } - ) - { - data { - id - attributes { - title - rank - url - type - description - rectanglion { - data { - attributes { - url - alternativeText - } - } - } - createdAt - updatedAt - locale - cta_labels { - data { - id - attributes { - text - url - icon { - data { - id - attributes { - url - alternativeText - } + products ( + pagination: { limit: -1 }, + sort: "rank:asc" + ) + { + data { + id + attributes { + title + rank + url + type + description + rectanglion { + data { + attributes { + url + alternativeText } } - locale - localizations { - data { - id - attributes { - text + } + createdAt + updatedAt + locale + cta_labels { + data { + id + attributes { + text + url + icon { + data { + id + attributes { + url + alternativeText + } + } + } + locale + localizations { + data { + id + attributes { + text + } + } } } } } - } - } - localizations { - data { - attributes { - locale - title - type - description + localizations { + data { + attributes { + locale + title + type + description + } + } } } } } - } } - } `; try { @@ -3227,6 +3229,7 @@ const ProductsPage = memo(() => { throw new Error(`HTTP Error: ${response.statusText}`); } const data = await response.json(); + console.log(data); return data; } catch (error) { throw error; @@ -3281,9 +3284,7 @@ const ProductsPage = memo(() => { }; }, {}); - - const orderedProducts = productsFromStrapi.sort((a, b) => a.rank - b.rank); - setProducts(orderedProducts); + setProducts(productsFromStrapi); } catch (error) { console.error("Fetch error:", error); setError("Error: Sefaria's CMS cannot be reached"); From d67e0b83a876144605f45ca7e072c1bdb357c02f Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 29 May 2024 12:14:43 +0300 Subject: [PATCH 034/548] feat(Products Page): Display drafts to admin --- static/js/StaticPages.jsx | 41 +++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 0a194a3e45..fb2711fde4 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -10,6 +10,7 @@ import palette from './sefaria/palette'; import classNames from 'classnames'; import Cookies from 'js-cookie'; import ReactMarkdown from 'react-markdown'; +import Sefaria from './sefaria/sefaria'; @@ -3141,12 +3142,18 @@ const ProductsPage = memo(() => { const [error, setError] = useState(null); // GraphQL query to Strapi - // TODO - add publicationState:PREVIEW, to query for draft feature for admin const fetchProductsJSON = async () => { + + // If the viewer is an admin, edit the query to retrieve the drafts as well + var includeDrafts = ''; + if (Sefaria.is_moderator){ + includeDrafts = 'publicationState:PREVIEW,'; + } const query = ` query { products ( pagination: { limit: -1 }, + ${includeDrafts} sort: "rank:asc" ) { @@ -3211,7 +3218,7 @@ const ProductsPage = memo(() => { } } `; - + try { const response = await fetch(STRAPI_INSTANCE + "/graphql", { method: "POST", @@ -3244,18 +3251,18 @@ const ProductsPage = memo(() => { const productsFromStrapi = productsData.data?.products?.data?.map((productsData) => { - const heLocalization = productsData.attributes.localizations.data[0].attributes; - const ctaLabels = productsData.attributes.cta_labels.data; + const heLocalization = productsData.attributes?.localizations?.data[0]?.attributes; + const ctaLabels = productsData.attributes?.cta_labels?.data; const ctaLabelsLocalized = ctaLabels.map((cta) => { return { text: { - en: cta.attributes.text, - he: cta.attributes.localizations.data[0].attributes.text + en: cta.attributes?.text, + he: cta.attributes?.localizations?.data[0]?.attributes.text }, - url: cta.attributes.url, + url: cta.attributes?.url, icon: { - url: cta.attributes.icon.data?.attributes.url, + url: cta.attributes?.icon?.data?.attributes?.url, } }; }); @@ -3263,22 +3270,22 @@ const ProductsPage = memo(() => { return { id: productsData.id, titles: { - en: productsData.attributes.title, - he: heLocalization.title + en: productsData.attributes?.title, + he: heLocalization?.title }, - rank: productsData.attributes.rank, + rank: productsData.attributes?.rank, type: { - en: productsData.attributes.type, - he: productsData.attributes.localizations.data[0].attributes.type, + en: productsData.attributes?.type, + he: productsData.attributes?.localizations?.data[0]?.attributes?.type, }, - url: productsData.attributes.url, + url: productsData.attributes?.url, desc: { - en: productsData.attributes.description, - he: heLocalization.description + en: productsData.attributes?.description, + he: heLocalization?.description }, rectanglion: { - url: productsData.attributes.rectanglion.data.attributes.url, + url: productsData.attributes?.rectanglion?.data?.attributes?.url, }, ctaLabels: ctaLabelsLocalized, From 58426876d2de61df1fff4eb937351f32cf1bc630 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 30 May 2024 10:15:21 +0300 Subject: [PATCH 035/548] feat(Products Page): Weave into SuperAbout page --- static/css/s2.css | 6 ++++++ templates/_sidebar.html | 3 +++ templates/static/products.html | 24 +++++++++--------------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 6ca8b787b4..0b1504e69b 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12984,6 +12984,10 @@ span.ref-link-color-3 {color: blue} } } +.product { + max-width: 600px; +} + .product hr { border: 1px solid var(--light-grey); } @@ -13006,6 +13010,7 @@ span.ref-link-color-3 {color: blue} font: 'Roboto', sans-serif; color: #666666; font-size: 16px; + margin-top: 0; } .productsHeader { @@ -13090,6 +13095,7 @@ span.ref-link-color-3 {color: blue} flex-direction: column; padding: 3%; margin-top: 10%; + max-width: 600px; } .productsDevBox .productsDevHeader { diff --git a/templates/_sidebar.html b/templates/_sidebar.html index 6d6c02785d..0a57475b67 100644 --- a/templates/_sidebar.html +++ b/templates/_sidebar.html @@ -13,6 +13,9 @@

{{heTitle}}

  • Jobs at Sefaria משרות פנויות בספריא
  • +
  • + Sefaria's Products + מוצרים של בספריא
  • Our Supporters התומכים שלנו
  • diff --git a/templates/static/products.html b/templates/static/products.html index 004c7244ee..060a84f716 100644 --- a/templates/static/products.html +++ b/templates/static/products.html @@ -16,21 +16,15 @@ {% endblock %} {% block content %} - -
    -
    -
    -

    - Sefaria's Products - המוצרים שלנו -

    -
    -
    -
    -

    Loading...

    -
    -
    +
    + {% if not request.user_agent.is_mobile %} + {% include '_sidebar.html' with whichPage='products' title="Products" heTitle="מוצרים" %} + {% endif %} +
    +
    +

    Loading...

    - +
    {% endblock %} +{% block footer %} {% endblock %} From 28821274d2ef21475c6dd6b36d965281d6c974e6 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 30 May 2024 11:23:37 +0300 Subject: [PATCH 036/548] chore(Products Page): Streamline CSS --- static/css/s2.css | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/static/css/s2.css b/static/css/s2.css index 0b1504e69b..0277c20655 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12988,6 +12988,11 @@ span.ref-link-color-3 {color: blue} max-width: 600px; } +#productsPageContent { + margin-top: 225px; + margin-inline-start: 68px; +} + .product hr { border: 1px solid var(--light-grey); } @@ -13010,6 +13015,9 @@ span.ref-link-color-3 {color: blue} font: 'Roboto', sans-serif; color: #666666; font-size: 16px; +} + +.productsDesc p { margin-top: 0; } @@ -13112,6 +13120,10 @@ span.ref-link-color-3 {color: blue} } +.productsDevBox p { + margin-top: 0; +} + .productsDevBox a::after { content: " >"; color: #4B71B7; From 3daf4ff0d306263737997ffb2b5dcda3303433c9 Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 30 May 2024 11:33:17 +0300 Subject: [PATCH 037/548] chore(Products Page): Remove localhost preface for local image rendering --- static/js/StaticPages.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 443c6ae8c8..efec7931a6 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3353,8 +3353,8 @@ const ProductsPage = memo(() => { {product.ctaLabels?.map(cta => ( {cta.icon.url && Click icon} @@ -3371,7 +3371,7 @@ const ProductsPage = memo(() => { const ProductDesc = ({product}) => { return (
    - Product Image + Product Image {product.desc?.en} From 5de199913eb4b0cab2803ed282fa5473d3780bc0 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Sun, 2 Jun 2024 12:58:39 +0300 Subject: [PATCH 038/548] feat(Sheets Home Page): hero banner first pass --- static/css/static.css | 1 - static/js/ReaderApp.jsx | 6 +++--- static/js/SheetsHomePage.jsx | 17 +++++++++++++++++ templates/static/sheets.html | 2 +- 4 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 static/js/SheetsHomePage.jsx diff --git a/static/css/static.css b/static/css/static.css index 3ba84ceb05..3408c52dd6 100644 --- a/static/css/static.css +++ b/static/css/static.css @@ -728,7 +728,6 @@ p.registration-links a:hover{ } #aboutCover { height: 440px; - margin-left: 250px; padding: 180px 0; background-color: #ADA99B; box-sizing: border-box; diff --git a/static/js/ReaderApp.jsx b/static/js/ReaderApp.jsx index b1ee4e29aa..ad53ab5d24 100644 --- a/static/js/ReaderApp.jsx +++ b/static/js/ReaderApp.jsx @@ -13,7 +13,6 @@ import {ContentLanguageContext, AdContext, StrapiDataProvider, ExampleComponent, import { ContestLandingPage, RemoteLearningPage, - SheetsLandingPage, PBSC2020LandingPage, PBSC2021LandingPage, PoweredByPage, @@ -37,6 +36,7 @@ import { Promotions } from './Promotions'; import Component from 'react-class'; import { io } from 'socket.io-client'; import { SignUpModalKind } from './sefaria/signupModalContent'; +import SheetsHomePage from "./SheetsHomePage"; class ReaderApp extends Component { constructor(props) { @@ -2316,7 +2316,6 @@ export { loadServerData, EditCollectionPage, RemoteLearningPage, - SheetsLandingPage, ContestLandingPage, PBSC2020LandingPage, PBSC2021LandingPage, @@ -2328,5 +2327,6 @@ export { WordByWordPage, JobsPage, TeamMembersPage, - UpdatesPanel + UpdatesPanel, + SheetsHomePage }; diff --git a/static/js/SheetsHomePage.jsx b/static/js/SheetsHomePage.jsx new file mode 100644 index 0000000000..24fcd196e9 --- /dev/null +++ b/static/js/SheetsHomePage.jsx @@ -0,0 +1,17 @@ +import React from 'react'; +const SheetsHeroBanner = () => { + return
    + +
    ; +} + +const SheetsHomePage = () => { + return
    + +
    +} +export default SheetsHomePage; \ No newline at end of file diff --git a/templates/static/sheets.html b/templates/static/sheets.html index 43fac8a6d0..74b1b041e9 100644 --- a/templates/static/sheets.html +++ b/templates/static/sheets.html @@ -13,7 +13,7 @@ {% endblock %} From 1d54258759fe26e9e10bbf8f655c550639991c6f Mon Sep 17 00:00:00 2001 From: saengel Date: Sun, 2 Jun 2024 14:27:03 +0300 Subject: [PATCH 039/548] chore(Products Page): Media queries for responsiveness --- static/css/s2.css | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/static/css/s2.css b/static/css/s2.css index 0277c20655..5e396cd0ff 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13142,6 +13142,34 @@ span.ref-link-color-3 {color: blue} color: #666666; } +@media (max-width: 768px) { + .productsInner { + flex-direction: column; + align-items: flex-start; + } + + .productsInner img { + width: 100%; + } + + .product { + margin-right: 5%; + } + + .productsDesc { + margin-top: 5%; + } + + .productsDevBox { + margin-right: 5%; + } + + #productsPageContent { + margin-inline-start: 10px; + margin-top: 100px; +} +} + @-webkit-keyframes load5 { 0%,100%{box-shadow:0 -2.6em 0 0 #ffffff,1.8em -1.8em 0 0 rgba(0,0,0,0.2),2.5em 0 0 0 rgba(0,0,0,0.2),1.75em 1.75em 0 0 rgba(0,0,0,0.2),0 2.5em 0 0 rgba(0,0,0,0.2),-1.8em 1.8em 0 0 rgba(0,0,0,0.2),-2.6em 0 0 0 rgba(0,0,0,0.5),-1.8em -1.8em 0 0 rgba(0,0,0,0.7)} 12.5%{box-shadow:0 -2.6em 0 0 rgba(0,0,0,0.7),1.8em -1.8em 0 0 #ffffff,2.5em 0 0 0 rgba(0,0,0,0.2),1.75em 1.75em 0 0 rgba(0,0,0,0.2),0 2.5em 0 0 rgba(0,0,0,0.2),-1.8em 1.8em 0 0 rgba(0,0,0,0.2),-2.6em 0 0 0 rgba(0,0,0,0.2),-1.8em -1.8em 0 0 rgba(0,0,0,0.5)} From a5e68c986bb57830942ed77106dec37475204cec Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Sun, 2 Jun 2024 14:35:06 +0300 Subject: [PATCH 040/548] chore: started SheetsTopics --- static/css/static.css | 4 ++++ static/js/SheetsHomePage.jsx | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/static/css/static.css b/static/css/static.css index 3408c52dd6..9d0355d263 100644 --- a/static/css/static.css +++ b/static/css/static.css @@ -5,6 +5,10 @@ display: flex; flex-direction: row; } +#sheetsHomePage { + display: flex; + flex-direction: row; +} .inApp #staticContentWrapper { display: none; } diff --git a/static/js/SheetsHomePage.jsx b/static/js/SheetsHomePage.jsx index 24fcd196e9..46094eaf56 100644 --- a/static/js/SheetsHomePage.jsx +++ b/static/js/SheetsHomePage.jsx @@ -9,9 +9,27 @@ const SheetsHeroBanner = () => {
    ; } +const SheetsTopicsTOC = () => { + return "TOC placeholder" +} + +const SheetsTopicsCalendar = () => { + return "Calendar Placeholder" +} + +const SheetsTopics = () => { + return
    +} +const SheetsSidebar = () => { + return "Sidebar Placeholder" +} const SheetsHomePage = () => { return
    +
    + + +
    } export default SheetsHomePage; \ No newline at end of file From 3ce2844b655b7033d6a0be73bfca93c4ad50dd09 Mon Sep 17 00:00:00 2001 From: saengel Date: Sun, 2 Jun 2024 15:47:30 +0300 Subject: [PATCH 041/548] chore(Products Page): Responsive image resizing fix --- static/css/s2.css | 2 -- 1 file changed, 2 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 5e396cd0ff..43c4861bb8 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13004,10 +13004,8 @@ span.ref-link-color-3 {color: blue} } .productsInner img { - width: 200px; max-width: 100%; margin-inline-end: 3%; - max-height: 116px; } .productsInner .productsDesc { From 43f712b8f57604cb920f288dd45dee7f6a6370c2 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Sun, 2 Jun 2024 16:56:25 +0300 Subject: [PATCH 042/548] chore: first pass at SheetsTopicTOC --- static/js/SheetsHomePage.jsx | 12 +----------- static/js/SheetsTopics.jsx | 24 ++++++++++++++++++++++++ static/js/TopicsPage.jsx | 14 +++++++++----- 3 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 static/js/SheetsTopics.jsx diff --git a/static/js/SheetsHomePage.jsx b/static/js/SheetsHomePage.jsx index 46094eaf56..0e45458806 100644 --- a/static/js/SheetsHomePage.jsx +++ b/static/js/SheetsHomePage.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import SheetsTopics from "./SheetsTopics"; const SheetsHeroBanner = () => { return
    ; } -const SheetsTopicsTOC = () => { - return "TOC placeholder" -} - -const SheetsTopicsCalendar = () => { - return "Calendar Placeholder" -} - -const SheetsTopics = () => { - return
    -} const SheetsSidebar = () => { return "Sidebar Placeholder" } diff --git a/static/js/SheetsTopics.jsx b/static/js/SheetsTopics.jsx new file mode 100644 index 0000000000..e2f6d65608 --- /dev/null +++ b/static/js/SheetsTopics.jsx @@ -0,0 +1,24 @@ +import { ResponsiveNBox } from "./Misc"; +import React from "react"; +import { getTopicTOCListings } from "./TopicsPage"; + +const SheetsTopicsTOC = () => { + const openCat = () => {alert("Open")} + const categoryListings = getTopicTOCListings(openCat); + return ( +
    +
    Browse by Topic
    + +
    + ); +} + +const SheetsTopicsCalendar = () => { + return "Calendar Placeholder" +} + +const SheetsTopics = () => { + return
    +} + +export default SheetsTopics; \ No newline at end of file diff --git a/static/js/TopicsPage.jsx b/static/js/TopicsPage.jsx index b79ab2c52c..b4b7e598a4 100644 --- a/static/js/TopicsPage.jsx +++ b/static/js/TopicsPage.jsx @@ -12,10 +12,8 @@ import Footer from './Footer'; import {CategoryHeader} from "./Misc"; import Component from 'react-class'; -// The root topics page listing topic categories to browse -const TopicsPage = ({setNavTopic, multiPanel, initialWidth}) => { - let categoryListings = Sefaria.topic_toc.map(cat => { - const openCat = e => {e.preventDefault(); setNavTopic(cat.slug, {en: cat.en, he: cat.he})}; +const getTopicTOCListings = (openCat) => { + return Sefaria.topic_toc.map(cat => { return (
    ); }); +} + +// The root topics page listing topic categories to browse +const TopicsPage = ({setNavTopic, multiPanel, initialWidth}) => { + const openCat = e => {e.preventDefault(); setNavTopic(cat.slug, {en: cat.en, he: cat.he})}; + let categoryListings = getTopicTOCListings(openCat); const letter = Sefaria.interfaceLang === "hebrew" ? "א" : "a"; categoryListings.push(
    @@ -78,4 +82,4 @@ const TopicsPage = ({setNavTopic, multiPanel, initialWidth}) => { }; -export default TopicsPage; \ No newline at end of file +export { TopicsPage, getTopicTOCListings }; \ No newline at end of file From fa52c50667b8dca0840b48ee002e563eb8d42340 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Sun, 2 Jun 2024 17:39:24 +0300 Subject: [PATCH 043/548] chore: first pass for SheetsSidebar --- static/css/static.css | 6 ++++++ static/js/Misc.jsx | 13 +++++++++++-- static/js/NavSidebar.jsx | 33 +++++++++++++++++++++++++++++++-- static/js/SheetsHomePage.jsx | 12 ++++++++++++ templates/static/sheets.html | 2 +- 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/static/css/static.css b/static/css/static.css index 3408c52dd6..eaf1425702 100644 --- a/static/css/static.css +++ b/static/css/static.css @@ -5,6 +5,12 @@ display: flex; flex-direction: row; } +#sheetsButton { + display: none; +} +#sheetsLandingPage #sheetsButton { + display: inline; +} .inApp #staticContentWrapper { display: none; } diff --git a/static/js/Misc.jsx b/static/js/Misc.jsx index 409e0f4558..74f3102beb 100644 --- a/static/js/Misc.jsx +++ b/static/js/Misc.jsx @@ -1114,7 +1114,15 @@ const AllAdminButtons = ({ buttonOptions, buttonIDs, adminClasses }) => { ); }; -const CategoryHeader = ({children, type, data = [], toggleButtonIDs = ["subcategory", "edit"], actionButtons = {}}) => { + +const CreateSheetsButton = () => { + return + make a sheet icon + Create + +} + +const CategoryHeader = ({children, type, data = [], toggleButtonIDs = ["subcategory", "edit"], actionButtons = {}}) => { /* Provides an interface for using admin tools. `type` is 'sources', 'cats', 'books' or 'topics' @@ -3382,5 +3390,6 @@ export { requestWithCallBack, OnInView, TopicPictureUploader, - ImageWithCaption + ImageWithCaption, + CreateSheetsButton }; diff --git a/static/js/NavSidebar.jsx b/static/js/NavSidebar.jsx index 1aaadeaee4..61b6c03adf 100644 --- a/static/js/NavSidebar.jsx +++ b/static/js/NavSidebar.jsx @@ -1,7 +1,7 @@ import React, { useState, useEffect } from 'react'; import classNames from 'classnames'; import Sefaria from './sefaria/sefaria'; -import {AppStoreButton, DonateLink, EnglishText, HebrewText, ImageWithCaption} from './Misc' +import {AppStoreButton, CreateSheetsButton, DonateLink, EnglishText, HebrewText, ImageWithCaption} from './Misc' import {NewsletterSignUpForm} from "./NewsletterSignUpForm"; import {InterfaceText, ProfileListing, Dropdown} from './Misc'; import { Promotions } from './Promotions' @@ -44,6 +44,8 @@ const Modules = ({type, props}) => { "GetTheApp": GetTheApp, "StayConnected": StayConnected, "AboutLearningSchedules": AboutLearningSchedules, + "CreateASheet": CreateASheet, + "WhatIsASourceSheet": WhatIsASourceSheet, "AboutTranslatedText": AboutTranslatedText, "AboutCollections": AboutCollections, "ExploreCollections": ExploreCollections, @@ -691,7 +693,34 @@ const StayConnected = () => { // TODO: remove? looks like we are not using this ); }; - +const WhatIsASourceSheet = () => ( + + What is a Source Sheet? + + + Lorem ipsum + Get Started + + + Lorem ipsum + Get Started + + + +); +const CreateASheet = () => ( + + Create A Sheet + + + Mix and match sources along with outside sources, comments, images, and videos. + + + + + + +); const AboutLearningSchedules = () => ( Learning Schedules diff --git a/static/js/SheetsHomePage.jsx b/static/js/SheetsHomePage.jsx index 24fcd196e9..a84996eb53 100644 --- a/static/js/SheetsHomePage.jsx +++ b/static/js/SheetsHomePage.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import {NavSidebar} from "./NavSidebar"; const SheetsHeroBanner = () => { return
    ; } +const SheetsSidebar = () => { + const sidebarModules = [ + {type: "CreateASheet"}, + {type: "WhatIsASourceSheet"}, + ]; + return +} + + + const SheetsHomePage = () => { return
    +
    } export default SheetsHomePage; \ No newline at end of file diff --git a/templates/static/sheets.html b/templates/static/sheets.html index 74b1b041e9..4271a1990f 100644 --- a/templates/static/sheets.html +++ b/templates/static/sheets.html @@ -19,7 +19,7 @@ {% endblock %} {% block content %} -
    +

    Loading...

    From 4a98e94ddef081f94f7d9c8e34a9ce07a6e67f43 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Mon, 3 Jun 2024 09:34:11 +0300 Subject: [PATCH 044/548] chore: sheetsLandingPage resourcesLink button CSS --- static/css/static.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/static/css/static.css b/static/css/static.css index eaf1425702..ae090216da 100644 --- a/static/css/static.css +++ b/static/css/static.css @@ -11,6 +11,11 @@ #sheetsLandingPage #sheetsButton { display: inline; } +#sheetsLandingPage .resourcesLink { + display: block; + width: 30%; + margin-top: 15px; +} .inApp #staticContentWrapper { display: none; } From 4a5f8ea9d3c6293c1a05f3308364e6de7e2f154a Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 3 Jun 2024 12:03:52 +0300 Subject: [PATCH 045/548] chore(Products Page): Fix CSS --- static/css/s2.css | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 43c4861bb8..51d32799c2 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13029,7 +13029,6 @@ span.ref-link-color-3 {color: blue} flex: auto; } - .productsHeader .productsTitle { font: 'Roboto', sans-serif; color: #666666; @@ -13147,8 +13146,12 @@ span.ref-link-color-3 {color: blue} } .productsInner img { - width: 100%; - } + display: block; + width: 100%; + height: 100%; + max-width: 700px; + max-height: 350px; + } .product { margin-right: 5%; @@ -13165,7 +13168,7 @@ span.ref-link-color-3 {color: blue} #productsPageContent { margin-inline-start: 10px; margin-top: 100px; -} + } } @-webkit-keyframes load5 { From 441c49336ebab7f909395d939f6cd088ae0d67b0 Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 3 Jun 2024 12:07:31 +0300 Subject: [PATCH 046/548] chore(Products Page): Remove double loading --- static/js/StaticPages.jsx | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index efec7931a6..2617601515 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3346,6 +3346,19 @@ const ProductsPage = memo(() => { ); }; + // onClickQuestion = (p, i) => { + // gtag("event", "products_${specific_cta}_clicked", { + // panel_type: "static", + // panel_number: 0, // + // panel_name: "Products Page", + // position: rank, + // experiment: experiment, + // feature_name: "Products", + // engagement_type: "static", + // engagement_value: 0, + // }); + // } + // The call-to-action (link) in the heading of each product const ProductCTA = ({product}) => { return ( @@ -3369,9 +3382,10 @@ const ProductsPage = memo(() => { // The main body of each product entry, containing an image and description const ProductDesc = ({product}) => { + console.log(`http://localhost:1337${product.rectanglion.url}`); return (
    - Product Image + Product Image {product.desc?.en} @@ -3417,14 +3431,12 @@ const ProductsPage = memo(() => { return (
    - {products && products.length > 0 ? ( + {products && products.length > 0 && ( <> {initialProducts} - + {/* */} {remainingProducts} - ) : ( -
    Loading...
    )}
    ); From db6c2cd7df57e339fb7688d39952722dcd6407d1 Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 3 Jun 2024 12:07:54 +0300 Subject: [PATCH 047/548] fix(Products Page): Shift loading into a div from h1 --- templates/static/products.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/static/products.html b/templates/static/products.html index 060a84f716..29828f2839 100644 --- a/templates/static/products.html +++ b/templates/static/products.html @@ -22,7 +22,7 @@ {% endif %}
    -

    Loading...

    +
    Loading...
    From bb6024fc9fe33a80260cc5bb1dc1f8aa361caab8 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Mon, 3 Jun 2024 12:44:27 +0300 Subject: [PATCH 048/548] chore: added title to hero banner --- static/css/static.css | 21 +++++++++++++++++++++ static/js/SheetsHomePage.jsx | 4 ++++ 2 files changed, 25 insertions(+) diff --git a/static/css/static.css b/static/css/static.css index 3408c52dd6..1255803974 100644 --- a/static/css/static.css +++ b/static/css/static.css @@ -3662,4 +3662,25 @@ form.globalUpdateForm + div.notificationsList { } .about.section { padding-top: 40px; +} +#sheetsLandingPage .overlayTextOnSheetsHero { + color: white; + text-shadow: 0 0 10px rgba(0, 0, 0, 0.7); + font-family: Source Serif Pro, serif; + font-weight: 400; +} +.overlayTextOnSheetsHero #title { + position: absolute; + left: 72px; + font-size: 50px; + top: 145px; + line-height: 62.65px; +} +.overlayTextOnSheetsHero #message { + position: absolute; + left: 72px; + font-family: Source Sans Pro, serif; + font-size: 24px; + line-height: 18px; + top: 227px; } \ No newline at end of file diff --git a/static/js/SheetsHomePage.jsx b/static/js/SheetsHomePage.jsx index 24fcd196e9..bc99f3b7dc 100644 --- a/static/js/SheetsHomePage.jsx +++ b/static/js/SheetsHomePage.jsx @@ -6,6 +6,10 @@ const SheetsHeroBanner = () => { Video of sofer writing letters of the Torah +
    +
    Join the Torah Conversation
    +
    Create, share, and discover source sheets.
    +
    ; } From d7284415f6238ddf5a9195ce63f68955b6ec981c Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Mon, 3 Jun 2024 13:32:03 +0300 Subject: [PATCH 049/548] chore: sheets should be a menu_open URL --- sefaria/urls.py | 1 + sites/sefaria/urls.py | 1 - sourcesheets/views.py | 7 ++++++ static/css/s2.css | 48 +++++++++++++++++++++++++++++++++++- static/css/static.css | 45 --------------------------------- static/js/ReaderApp.jsx | 5 ++++ static/js/ReaderPanel.jsx | 21 +++++++++------- static/js/SheetsHomePage.jsx | 2 +- 8 files changed, 73 insertions(+), 57 deletions(-) diff --git a/sefaria/urls.py b/sefaria/urls.py index b782760b87..23e5cc0e49 100644 --- a/sefaria/urls.py +++ b/sefaria/urls.py @@ -73,6 +73,7 @@ # Source Sheet Builder urlpatterns += [ + url(r'^sheets$', sheets_views.sheets_home_page), url(r'^sheets/new/?$', sheets_views.new_sheet), url(r'^sheets/(?P\d+)$', sheets_views.view_sheet), url(r'^sheets/visual/(?P\d+)$', sheets_views.view_visual_sheet), diff --git a/sites/sefaria/urls.py b/sites/sefaria/urls.py index 4753abb7fb..8e04bd1720 100644 --- a/sites/sefaria/urls.py +++ b/sites/sefaria/urls.py @@ -37,7 +37,6 @@ "dicta-thanks", "daf-yomi", "remote-learning", - "sheets", "powered-by-sefaria-contest-2020", "powered-by-sefaria-contest-2021", "ramban-sponsorships", diff --git a/sourcesheets/views.py b/sourcesheets/views.py index 1340dc9111..6a103a9eea 100644 --- a/sourcesheets/views.py +++ b/sourcesheets/views.py @@ -58,6 +58,13 @@ def annotate_user_links(sources): return sources +from django.utils.translation import ugettext as _ +from reader.views import menu_page +def sheets_home_page(request): + title = _("Sheets on Sefaria") + desc = _("Mix and match sources from Sefaria’s library of Jewish texts, and add your comments, images and videos.") + return menu_page(request, page="sheets", title=title, desc=desc) + @login_required @ensure_csrf_cookie def new_sheet(request): diff --git a/static/css/s2.css b/static/css/s2.css index 0875e35aa2..832e49436f 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -10010,7 +10010,53 @@ span.purim-emoji img{ border-bottom: 4px solid var(--lighter-grey); } - +#aboutCover { + height: 440px; + padding: 180px 0; + background-color: #ADA99B; + box-sizing: border-box; + text-align: center; + overflow: hidden; + position: relative; +} +#aboutVideo { + position: absolute; + top: -90px; + left: 0; + min-width: 1200px; + z-index: 0; + width: 100%; +} +@media (max-width: 450px) { + #aboutCover { + height: 270px; + padding: 180px 0; + } + #aboutVideo { + min-width: 900px; + } +} +.overlayTextOnSheetsHero { + color: white; + text-shadow: 0 0 10px rgba(0, 0, 0, 0.7); + font-family: Source Serif Pro, serif; + font-weight: 400; +} +.overlayTextOnSheetsHero #title { + position: absolute; + left: 72px; + font-size: 50px; + top: 145px; + line-height: 62.65px; +} +.overlayTextOnSheetsHero #message { + position: absolute; + left: 72px; + font-family: Source Sans Pro, serif; + font-size: 24px; + line-height: 18px; + top: 227px; +} .readerPanel.hebrew .sheetContent .sheetItem.segment .sourceContentText.outsideBiText.en { display: none; } diff --git a/static/css/static.css b/static/css/static.css index 1255803974..8ada0d6573 100644 --- a/static/css/static.css +++ b/static/css/static.css @@ -726,35 +726,11 @@ p.registration-links a:hover{ margin: 0; width: 100%; } -#aboutCover { - height: 440px; - padding: 180px 0; - background-color: #ADA99B; - box-sizing: border-box; - text-align: center; - overflow: hidden; - position: relative; -} -#aboutVideo { - position: absolute; - top: -90px; - left: 0; - min-width: 1200px; - z-index: 0; - width: 100%; -} @media (max-width: 450px) { #aboutPage #aboutHeader { margin-bottom: 130px; } - #aboutPage #aboutCover { - height: 270px; - padding: 180px 0; - } - #aboutPage #aboutVideo { - min-width: 900px; - } } #donatePage pre{ all: initial; @@ -3663,24 +3639,3 @@ form.globalUpdateForm + div.notificationsList { .about.section { padding-top: 40px; } -#sheetsLandingPage .overlayTextOnSheetsHero { - color: white; - text-shadow: 0 0 10px rgba(0, 0, 0, 0.7); - font-family: Source Serif Pro, serif; - font-weight: 400; -} -.overlayTextOnSheetsHero #title { - position: absolute; - left: 72px; - font-size: 50px; - top: 145px; - line-height: 62.65px; -} -.overlayTextOnSheetsHero #message { - position: absolute; - left: 72px; - font-family: Source Sans Pro, serif; - font-size: 24px; - line-height: 18px; - top: 227px; -} \ No newline at end of file diff --git a/static/js/ReaderApp.jsx b/static/js/ReaderApp.jsx index ad53ab5d24..35252857bd 100644 --- a/static/js/ReaderApp.jsx +++ b/static/js/ReaderApp.jsx @@ -542,6 +542,11 @@ class ReaderApp extends Component { hist.url = "calendars"; hist.mode = "calendars"; break; + case "sheets": + hist.url = "sheets"; + hist.mode = "sheets"; + hist.title = Sefaria._("Sheets on Sefaria"); + break; case "updates": hist.title = Sefaria._("New Additions to the " + siteName + " Library"); hist.url = "updates"; diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index 151ab5a193..de4573714b 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -41,6 +41,7 @@ import { ToggleSet, InterfaceText, EnglishText, HebrewText, SignUpModal, } from './Misc'; import {ContentText} from "./ContentText"; +import SheetsHomePage from "./SheetsHomePage"; class ReaderPanel extends Component { @@ -1031,17 +1032,19 @@ class ReaderPanel extends Component { } else if (this.state.menuOpen === "saved" || this.state.menuOpen === "history") { menu = ( - + ); + } else if (this.state.menuOpen === "sheets") { + menu = (); } else if (this.state.menuOpen === "profile") { menu = ( { } const SheetsHomePage = () => { - return
    + return
    } From 2f7ac644aeaf539f9ed0a71150ab2357b1b233d7 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Mon, 3 Jun 2024 13:51:09 +0300 Subject: [PATCH 050/548] chore: flexbox for sheets page --- static/css/s2.css | 4 ++++ static/js/SheetsHomePage.jsx | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/static/css/s2.css b/static/css/s2.css index 832e49436f..1cbb7ec5a2 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -10057,6 +10057,10 @@ span.purim-emoji img{ line-height: 18px; top: 227px; } +#sheetsFlexbox { + display: flex; + justify-content: space-around; +} .readerPanel.hebrew .sheetContent .sheetItem.segment .sourceContentText.outsideBiText.en { display: none; } diff --git a/static/js/SheetsHomePage.jsx b/static/js/SheetsHomePage.jsx index b50567e380..7296e7887f 100644 --- a/static/js/SheetsHomePage.jsx +++ b/static/js/SheetsHomePage.jsx @@ -20,7 +20,7 @@ const SheetsSidebar = () => { const SheetsHomePage = () => { return
    -
    +
    From 19e86b1fe1b0eaa41fc40fb8ea404acba2cb10dc Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Mon, 3 Jun 2024 14:16:11 +0300 Subject: [PATCH 051/548] fix(Sheets Home Page): allow scroll --- static/css/s2.css | 1 + static/js/SheetsHomePage.jsx | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 1cbb7ec5a2..18198b18a1 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -10011,6 +10011,7 @@ span.purim-emoji img{ } #aboutCover { + margin-top: -90px height: 440px; padding: 180px 0; background-color: #ADA99B; diff --git a/static/js/SheetsHomePage.jsx b/static/js/SheetsHomePage.jsx index 7296e7887f..97b1df1469 100644 --- a/static/js/SheetsHomePage.jsx +++ b/static/js/SheetsHomePage.jsx @@ -1,5 +1,8 @@ import React from 'react'; import SheetsTopics from "./SheetsTopics"; +import Footer from "./Footer"; +import {InterfaceText, ResponsiveNBox} from "./Misc"; +import {NavSidebar} from "./NavSidebar"; const SheetsHeroBanner = () => { return
    From 0f8f045dbec2da14b6c9f90ba1f40ee407ec3134 Mon Sep 17 00:00:00 2001 From: Skyler C Date: Fri, 14 Jun 2024 05:03:48 -0400 Subject: [PATCH 109/548] Update Hebrew about.html for 2023 updates --- templates/static/he/about.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/templates/static/he/about.html b/templates/static/he/about.html index a48e15d850..e9137c626f 100644 --- a/templates/static/he/about.html +++ b/templates/static/he/about.html @@ -279,6 +279,18 @@

    ספריא מוסיפה את התלמוד הירושלמי בצרפתית לאוסף המקורות המתורגמים, הכולל תרגום של התלמוד הבבלי לגרמנית. +
    +

    2023

    +
    + בשבועות הקשות שלאחר השבת השחורה של ה-7 באוקטובר, יהודים בכל העולם פונים לספריא. כמות המשתמשים באתר וביישומון עולה ל-889,295, מספר המעיד על כוחם של מקורות היהדות לחזק ולשמש עוגן ליהודים בכל רחבי תבל. +
    +
    + מחלקת המחקר והפיתוח של ספריא משיקה שותפות פורצת דרך עם AppliedAI והאוניברסיטה הטכנית של מינכן (TUM). מטרת השותפות היא בחינת האפשרויות הטמונות במינוף של אינטליגנציה מלאכותית ככלי להרחבה משמעותית של גישה ציבורית לתורה. +
    +
    + ספריא יוצרת שותפות עם מרכז שטיינזלץ וה-Aleph Society כדי להשיק אוסף דיגיטלי של כל הפרשנויות שכתב הרב עדין שטיינזלץ, ובכך להנגיש את כלל כתביו של הרב הנודע לכל לומד או לומדת באשר יהיו. +
    +

    From 77d16be563a7050723ef5b4cb76af765087cad91 Mon Sep 17 00:00:00 2001 From: Skyler C Date: Fri, 14 Jun 2024 05:13:06 -0400 Subject: [PATCH 110/548] chore: Fix link to annual impact report --- templates/static/link-to-annual-report.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/static/link-to-annual-report.html b/templates/static/link-to-annual-report.html index fb4e72013a..111388ad80 100644 --- a/templates/static/link-to-annual-report.html +++ b/templates/static/link-to-annual-report.html @@ -15,7 +15,7 @@

    Annual Report דו"ח שנתי

    {% endif %} - +
    From c5e81ed951c5c15300a6ecfc7cd5ec0b1fd3bcdc Mon Sep 17 00:00:00 2001 From: Skyler C Date: Fri, 14 Jun 2024 06:11:52 -0400 Subject: [PATCH 111/548] chore: Fix teams page view on mobile devices --- static/css/static.css | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/static/css/static.css b/static/css/static.css index 3ba84ceb05..5dc57ffe1f 100644 --- a/static/css/static.css +++ b/static/css/static.css @@ -814,6 +814,17 @@ p.registration-links a:hover{ width: 200px; content: ""; } + +@media (max-width: 450px) { + #teamPage .team-members { + justify-content: center; + } + + #teamPage .team-members::after { + width: auto !important; + } +} + #teamPage .teamMember { flex: 0 0 30%; } @@ -3663,4 +3674,4 @@ form.globalUpdateForm + div.notificationsList { } .about.section { padding-top: 40px; -} \ No newline at end of file +} From c76d56d14d44aa62f92845b1b63e6f8eaa0103a8 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Sun, 16 Jun 2024 14:19:36 +0300 Subject: [PATCH 112/548] fix(Sheets Home Page): position of hero banner title and message --- static/css/s2.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index dac6d0d7de..3a9db9b5bf 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -10050,14 +10050,14 @@ span.purim-emoji img{ } .overlayTextOnSheetsHero #title { position: absolute; - left: 10%; + left: 6%; font-size: 50px; top: 145px; line-height: 62.65px; } .overlayTextOnSheetsHero #message { position: absolute; - left: 10%; + left: 6%; font-family: Source Sans Pro, serif; font-size: 24px; line-height: 18px; From 85ac4ed6734810d1ccab893e119c777352a9ffdb Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 17 Jun 2024 21:24:40 +0300 Subject: [PATCH 113/548] feat(Module switcher): Styling progress --- static/css/s2.css | 18 +++++++++++++++++- static/js/common/DropdownMenu.jsx | 2 +- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 985e859518..656ef6bfdb 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -850,7 +850,8 @@ div:has(#bannerMessage) + .readerApp.singlePanel .mobileNavMenu { .interfaceLinks-options { display: flex; flex-direction: column; - padding: 4px 0; + padding: 4px; + max-width: 220px; } .header .interfaceLinks .interfaceLinks-option { /* display: flex; */ @@ -13147,6 +13148,21 @@ span.ref-link-color-3 {color: blue} .dropdownHeader { margin-bottom: 1rem; + font-family: Roboto; + font-size: 16px; + font-weight: 400; + line-height: 18.75px; + text-align: left; + +} + +.dropdownDesc { + font-family: Roboto; + font-size: 14px; + font-weight: 400; + line-height: 18px; + text-align: left; + } .image-in-text-title { diff --git a/static/js/common/DropdownMenu.jsx b/static/js/common/DropdownMenu.jsx index 8c93241e3b..cf3c7855a7 100644 --- a/static/js/common/DropdownMenu.jsx +++ b/static/js/common/DropdownMenu.jsx @@ -52,7 +52,7 @@ const DropdownMenu = ({header, bodyItems}) => {
    {item.text}
    -
    Description goes here
    +
    Lorem ipsum dolor sit amet, lorem dolor.
    ) } {/* עברית From 1f8d8af5cb46987bf843cd3de4733c189291f264 Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 17 Jun 2024 21:59:29 +0300 Subject: [PATCH 114/548] chore(Products Page): Addressing code review feedback --- static/css/s2.css | 3 + static/js/StaticPages.jsx | 250 +++++++++++++++++++------------------- 2 files changed, 127 insertions(+), 126 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 2c29c36b0e..c3097db15e 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13024,6 +13024,9 @@ span.ref-link-color-3 {color: blue} display: flex; justify-content: space-between; margin-top: 10%; + margin-bottom: 3%; + padding-bottom: 3%; + border-bottom: 1px solid #CCCCCC; } .productsTitleAndLabel { diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 30ef58fdc3..9e0ff6aa0f 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3134,12 +3134,121 @@ const JobsPage = memo(() => { * Products Page */ +// The static content on the page inviting users to browse our "powered-by" products +const DevBox = () => { + return ( +
    +

    + Powered by Sefaria + פרויקטים מכח ספריא +

    +

    + + Check out the products our software developer friends from around the world have been building for you! Explore + + נסו את המוצרים שמפתחי תוכנה וידידי ספריא מרחבי העולם בנו עבורכם! גלו את הפרויקטים + +

    +
    + ); + }; + +/** + * The following are the building block components of an individual product. + */ + +// The title and gray background label for each product +const ProductTitle = ({product}) => { + return ( +
    + + {product.titles.en} + {product.titles.he} + + {product.type.en ? ( + {product.type.en} + {product.type.he} + ) : ''} +
    + ); +}; + + + +// The call-to-action (link) in the heading of each product +// TODO - uncomment once analytics is confirmed +const ProductCTA = ({cta}) => { + return ( + + // productsAnalytics(product?.rank, `${product?.titles.en}_${cta.text.en}`, product?.type.en, "viewed")}> + + // TODO - once analytics finalized, add onClick={productsAnalytics(product?.rank, `${product?.titles.en}_${cta.text.en}`, product?.type.en, "clicked")} + + {cta.icon.url && Click icon} + + + {cta.text.en} + {cta.text.he} + + + + // + + + ); +}; + +// The main body of each product entry, containing an image and description +const ProductDesc = ({product}) => { + return ( +
    + {`Image + + + {product.desc?.en} + + + + + {product.desc?.he} + + +
    + ); +}; + +// The main product component, comprised of the building block sub-components +const Product = ({key, product}) => { + return ( +
    +
    + +
    + {product.ctaLabels?.map(cta => ( + + ))} +
    +
    + +
    + ); +}; + + const ProductsPage = memo(() => { const [products, setProducts] = useState([]); const [error, setError] = useState(null); + useEffect(() => { + loadProducts(); + }, []); + // GraphQL query to Strapi const fetchProductsJSON = async () => { @@ -3234,7 +3343,6 @@ const ProductsPage = memo(() => { throw new Error(`HTTP Error: ${response.statusText}`); } const data = await response.json(); - console.log(data); return data; } catch (error) { throw error; @@ -3246,7 +3354,6 @@ const ProductsPage = memo(() => { if (typeof STRAPI_INSTANCE !== "undefined" && STRAPI_INSTANCE) { try { const productsData = await fetchProductsJSON(); - console.log(productsData); const productsFromStrapi = productsData.data?.products?.data?.map((productsData) => { @@ -3299,131 +3406,22 @@ const ProductsPage = memo(() => { setError("Error: Sefaria's CMS cannot be reached"); } }; - - useEffect(() => { - loadProducts(); - }, []); - - console.log("products: ", products) - - // Generalized function for catching products page analytics - const productsAnalytics = (rank, product_cta, label, event) => { - gtag("event", `${product_cta}_${event}`, { - panel_type: "strapi-static", - panel_number: 0, - panel_name: "Products Page", - position: rank, - experiment: 1, - feature_name: label, - engagement_type: "static", - engagement_value: 0, - }); - } + // Generalized function for catching products page analytics - to be revisited + // const productsAnalytics = (rank, product_cta, label, event) => { + // gtag("event", `${product_cta}_${event}`, { + // panel_type: "strapi-static", + // panel_number: 0, + // panel_name: "Products Page", + // position: rank, + // experiment: 1, + // feature_name: label, + // engagement_type: "static", + // engagement_value: 0, + // }); + // } - // The static content on the page inviting users to browse our "powered-by" products - const DevBox = () => { - return ( -
    -

    - Powered by Sefaria - פרויקטים מכח ספריא -

    -

    - - Check out the products our software developer friends from around the world have been building for you! Explore - - נסו את המוצרים שמפתחי תוכנה וידידי ספריא מרחבי העולם בנו עבורכם! גלו את הפרויקטים - -

    -
    - ); - }; - - /** - * The following are the building block components of an individual product. - */ - - // The title and gray background label for each product - const ProductTitle = ({product}) => { - return ( -
    - - {product.titles.en} - {product.titles.he} - - {product.type.en ? ( - {product.type.en} - {product.type.he} - ) : ''} -
    - ); - }; - - - - // The call-to-action (link) in the heading of each product - const ProductCTA = ({product}) => { - return ( -
    - {product.ctaLabels?.map(cta => ( - productsAnalytics(product?.rank, `${product?.titles.en}_${cta.text.en}`, product?.type.en, "viewed")}> - - - {cta.icon.url && Click icon} - - - {cta.text.en} - {cta.text.he} - - - - - ))} - -
    - ); - }; - - // The main body of each product entry, containing an image and description - const ProductDesc = ({product}) => { - return ( -
    - {`Image - - - {product.desc?.en} - - - - - {product.desc?.he} - - -
    - ); - }; - - // The main product component, comprised of the building block sub-components - const Product = ({key, product}) => { - return ( -
    -
    - - -
    -
    - -
    - ); - }; - // In order to inject the static 'DevBox' in a fixed position on the page, we // create an array of components, and then slice the list into two sub-lists at the // desired insertion position for the 'DevBox'. When rendering, we render the @@ -3441,13 +3439,13 @@ const ProductsPage = memo(() => { return (
    - {products && products.length > 0 && ( + {products && products.length > 0 ? ( <> {initialProducts} {/* */} {remainingProducts} - )} + ) : null}
    ); }); From 7d09c10cadb03e9022834fc7dda5bd628532ffaf Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 18 Jun 2024 11:49:49 +0300 Subject: [PATCH 115/548] chore(Products Page): Use InterfaceText as per docs --- static/js/StaticPages.jsx | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 9e0ff6aa0f..bbaaf11762 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3139,15 +3139,17 @@ const DevBox = () => { return (

    - Powered by Sefaria - פרויקטים מכח ספריא +

    - - Check out the products our software developer friends from around the world have been building for you! Explore - - נסו את המוצרים שמפתחי תוכנה וידידי ספריא מרחבי העולם בנו עבורכם! גלו את הפרויקטים - + + + נסו את המוצרים שמפתחי תוכנה וידידי ספריא מרחבי העולם בנו עבורכם! גלו את הפרויקטים + + + Check out the products our software developer friends from around the world have been building for you! Explore + +

    ); @@ -3162,8 +3164,9 @@ const ProductTitle = ({product}) => { return (
    - {product.titles.en} - {product.titles.he} + + {} + {} {product.type.en ? ( {product.type.en} From 42d39036fdca6752cf03b79a14308c97dd03674c Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 18 Jun 2024 11:54:28 +0300 Subject: [PATCH 116/548] chore(Products Page): Use InterfaceText as per docs, add to markdown section --- static/js/StaticPages.jsx | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index bbaaf11762..b40e6a6332 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3165,12 +3165,9 @@ const ProductTitle = ({product}) => {
    - {} - {} - {product.type.en ? ( - {product.type.en} - {product.type.he} + {product.type.en ? ( + ) : ''}
    ); @@ -3194,8 +3191,7 @@ const ProductCTA = ({cta}) => { alt="Click icon" />} - {cta.text.en} - {cta.text.he} + @@ -3207,19 +3203,23 @@ const ProductCTA = ({cta}) => { // The main body of each product entry, containing an image and description const ProductDesc = ({product}) => { + console.log(product); return (
    {`Image - - - {product.desc?.en} - - - - - {product.desc?.he} - - + + + + + {product.desc?.he} + + + + + {product.desc?.en} + + +
    ); }; From 14990f6fe2446c2ddf31006be07623dad4c52d01 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 18 Jun 2024 12:10:30 +0300 Subject: [PATCH 117/548] chore(Products Page): Improve CSS to use vars --- static/css/s2.css | 45 +++++++++++++++++---------------------- static/js/StaticPages.jsx | 7 +++++- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index c3097db15e..d1028f77e7 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12993,10 +12993,6 @@ span.ref-link-color-3 {color: blue} margin-inline-start: 68px; } -.product hr { - border: 1px solid var(--light-grey); -} - .productsInner { display: flex; align-items: right; @@ -13011,8 +13007,8 @@ span.ref-link-color-3 {color: blue} } .productsInner .productsDesc { - font: 'Roboto', sans-serif; - color: #666666; + font: var(--english-sans-serif-font-family); + color: var(--dark-grey); font-size: 16px; } @@ -13026,7 +13022,7 @@ span.ref-link-color-3 {color: blue} margin-top: 10%; margin-bottom: 3%; padding-bottom: 3%; - border-bottom: 1px solid #CCCCCC; + border-bottom: 1px solid var(--light-grey); } .productsTitleAndLabel { @@ -13034,21 +13030,21 @@ span.ref-link-color-3 {color: blue} } .productsHeader .productsTitle { - font: 'Roboto', sans-serif; - color: #666666; + font: var(--english-sans-serif-font-family); + color: var(--dark-grey); font-size: 22px; font-weight: 500px; } .productsHeader .productsTypeLabel { - font: 'Roboto', sans-serif; + font: var(--english-sans-serif-font-family); font-size: 14px; font-weight: 400; line-height: 18px; - background-color: #EDEDEC; + background-color: var(--lighter-grey); border-radius: 6px; padding: 0.01px 5px; - color: #666666; + color: var(--dark-grey); margin-inline-start: 3%; } @@ -13058,9 +13054,8 @@ span.ref-link-color-3 {color: blue} } .productsHeader .cta .productsCTA { - color: #4B71B7; + color: var(--commentary-blue); border-width: 10px; - border-color: #0cd200; margin-inline-end: 10px; } @@ -13073,29 +13068,27 @@ span.ref-link-color-3 {color: blue} filter: brightness(0) saturate(100%) invert(52%) sepia(17%) saturate(6763%) hue-rotate(200deg) brightness(78%) contrast(77%);; /* --image-path: attr(data-image-path); mask: url(--image-path) no-repeat; - background-color: #4B71B7; - border: #0cd200; */ + background-color: #4B71B7; */ } .productsTitle { - font-family: Roboto; + font-family: var(--english-sans-serif-font-family); font-size: 22px; font-weight: 500; line-height: 25.78px; text-align: left; - color: #666666; + color: var(--dark-grey); } .productsCTA::after { content: " >"; - color: #4B71B7; + color: var(--commentary-blue); } .productsDevBox { - background: #EDEDEC; - color: #666666; - border: red; - font-family: Roboto; + background: var(--lighter-grey); + color: var(--dark-grey); + font-family: var(--english-sans-serif-font-family); font-size: 16px; font-weight: 400; line-height: 18.75px; @@ -13108,7 +13101,7 @@ span.ref-link-color-3 {color: blue} } .productsDevBox .productsDevHeader { - font-family: Roboto; + font-family: var(--english-sans-serif-font-family); font-size: 22px; font-weight: 500; line-height: 25.78px; @@ -13117,7 +13110,7 @@ span.ref-link-color-3 {color: blue} } .productsDevBox a { - color: #4B71B7 !important; + color: var(--commentary-blue) !important; } @@ -13127,7 +13120,7 @@ span.ref-link-color-3 {color: blue} .productsDevBox a::after { content: " >"; - color: #4B71B7; + color: var(--commentary-blue); } diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index b40e6a6332..cf680fcb21 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3,7 +3,10 @@ import { SimpleInterfaceBlock, TwoOrThreeBox, ResponsiveNBox, - NBox, InterfaceText, + NBox, + InterfaceText, + HebrewText, + EnglishText } from './Misc'; import {NewsletterSignUpForm} from "./NewsletterSignUpForm"; import palette from './sefaria/palette'; @@ -3252,6 +3255,8 @@ const ProductsPage = memo(() => { loadProducts(); }, []); + console.log(products); + // GraphQL query to Strapi const fetchProductsJSON = async () => { From 45b0e259a500291a469808c85c012bed620796b4 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 18 Jun 2024 12:34:50 +0300 Subject: [PATCH 118/548] chore(Products Page): Resolve key errors --- static/js/StaticPages.jsx | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index cf680fcb21..21c709466d 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3186,8 +3186,7 @@ const ProductCTA = ({cta}) => { // productsAnalytics(product?.rank, `${product?.titles.en}_${cta.text.en}`, product?.type.en, "viewed")}> // TODO - once analytics finalized, add onClick={productsAnalytics(product?.rank, `${product?.titles.en}_${cta.text.en}`, product?.type.en, "clicked")} - + {cta.icon.url && { // The main body of each product entry, containing an image and description const ProductDesc = ({product}) => { - console.log(product); return (
    {`Image @@ -3228,14 +3226,14 @@ const ProductDesc = ({product}) => { }; // The main product component, comprised of the building block sub-components -const Product = ({key, product}) => { +const Product = ({id, product}) => { return ( -
    +
    {product.ctaLabels?.map(cta => ( - + ))}
    @@ -3255,8 +3253,6 @@ const ProductsPage = memo(() => { loadProducts(); }, []); - console.log(products); - // GraphQL query to Strapi const fetchProductsJSON = async () => { @@ -3377,7 +3373,8 @@ const ProductsPage = memo(() => { url: cta.attributes?.url, icon: { url: cta.attributes?.icon?.data?.attributes?.url, - } + }, + id: cta.id }; }); From 857c4ae6e330e446735aab3a8937542890117926 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Tue, 18 Jun 2024 14:59:55 +0300 Subject: [PATCH 119/548] fix(Search Results): refactor SearchResultList so that it can only have one type of query not both sheet and text --- static/js/SearchResultList.jsx | 165 +++++++++++++++------------------ 1 file changed, 76 insertions(+), 89 deletions(-) diff --git a/static/js/SearchResultList.jsx b/static/js/SearchResultList.jsx index d2b6f65aaa..f400bd3cac 100644 --- a/static/js/SearchResultList.jsx +++ b/static/js/SearchResultList.jsx @@ -79,39 +79,37 @@ const SearchTopic = (props) => { class SearchResultList extends Component { constructor(props) { super(props); - this.types = this.props.types || ['text', 'sheet']; this.querySize = {"text": 50, "sheet": 20}; this.state = { - runningQueries: this._typeObjDefault(null), - isQueryRunning: this._typeObjDefault(false), - moreToLoad: this._typeObjDefault(true), - totals: this._typeObjDefault(new SearchTotal()), - pagesLoaded: this._typeObjDefault(0), - hits: this._typeObjDefault([]), + runningQueries: null, + isQueryRunning: false, + moreToLoad: true, + totals: new SearchTotal(), + pagesLoaded: 0, + hits: [], error: false, topics: [] } // Load search results from cache so they are available for immediate render - this.types.map(t => { - const args = this._getQueryArgs(props, t); - let cachedQuery = Sefaria.search.getCachedQuery(args); - while (cachedQuery) { + + const args = this._getQueryArgs(props); + let cachedQuery = Sefaria.search.getCachedQuery(args); + while (cachedQuery) { // Load all pages of results that are available in cache, so if page X was // previously loaded it will be returned. //console.log("Loaded cached query for") //console.log(args); - this.state.hits[t] = this.state.hits[t].concat(cachedQuery.hits.hits); - this.state.totals[t] = cachedQuery.hits.total; - this.state.pagesLoaded[t] += 1; - args.start = this.state.pagesLoaded[t] * this.querySize[t]; - if (t === "text") { + this.state.hits = this.state.hits.concat(cachedQuery.hits.hits); + this.state.totals = cachedQuery.hits.total; + this.state.pagesLoaded += 1; + args.start = this.state.pagesLoaded * this.querySize; + if (this.props.tab === "text") { // Since texts only have one filter type, aggregations are only requested once on first page args.aggregationsToUpdate = []; } cachedQuery = Sefaria.search.getCachedQuery(args); - } - }); + } this.updateTotalResults(); } componentDidMount() { @@ -125,23 +123,19 @@ class SearchResultList extends Component { componentWillReceiveProps(newProps) { if(this.props.query !== newProps.query) { this.setState({ - totals: this._typeObjDefault(new SearchTotal()), - hits: this._typeObjDefault([]), - moreToLoad: this._typeObjDefault(true), + totals: new SearchTotal(), + hits: [], + moreToLoad: true, }); this._executeAllQueries(newProps); - } else { - this.types.forEach(t => { - if (this._shouldUpdateQuery(this.props, newProps, t)) { - let state = { - hits: extend(this.state.hits, {[t]: []}), - pagesLoaded: extend(this.state.pagesLoaded, {[t]: 0}), - moreToLoad: extend(this.state.moreToLoad, {[t]: true}) - }; - this.setState(state); - this._executeQuery(newProps, t); - } - }); + } else if (this._shouldUpdateQuery(this.props, newProps, this.props.tab)) { + let state = { + hits: [], + pagesLoaded: 0, + moreToLoad: true + }; + this.setState(state); + this._executeQuery(newProps, this.props.tab); } } async addRefTopic(topic) { @@ -237,45 +231,38 @@ class SearchResultList extends Component { })); this.setState({topics: searchTopics}); } - updateRunningQuery(type, ajax) { - this.state.runningQueries[type] = ajax; - this.state.isQueryRunning[type] = !!ajax; + updateRunningQuery(ajax) { + this.state.runningQueries = ajax; + this.state.isQueryRunning = !!ajax; this.setState(this.state); } totalResults() { - return this.types.reduce((accum, type) => (this.state.totals[type].combine(accum)), new SearchTotal()); + return this.state.totals; } updateTotalResults() { this.props.updateTotalResults(this.totalResults()); } - _typeObjDefault(defaultValue) { - // es6 version of dict comprehension... - return this.types.reduce((obj, k) => { obj[k] = defaultValue; return obj; }, {}); - } - _abortRunningQueries() { - this.types.forEach(t => this._abortRunningQuery(t)); - } - _abortRunningQuery(type) { - if(this.state.runningQueries[type]) { - this.state.runningQueries[type].abort(); //todo: make work with promises + _abortRunningQuery() { + if(this.state.runningQueries) { + this.state.runningQueries.abort(); //todo: make work with promises } - this.updateRunningQuery(type, null); + this.updateRunningQuery(null); } handleScroll() { var tab = this.props.tab; - if (!this.state.moreToLoad[tab]) { return; } - if (this.state.runningQueries[tab]) { return; } + if (!this.state.moreToLoad) { return; } + if (this.state.runningQueries) { return; } var $scrollable = $(ReactDOM.findDOMNode(this)).closest(".content"); var margin = 300; if($scrollable.scrollTop() + $scrollable.innerHeight() + margin >= $scrollable[0].scrollHeight) { - this._loadNextPage(tab); + this._loadNextPage(); } } - _shouldUpdateQuery(oldProps, newProps, type) { - const oldSearchState = this._getSearchState(type, oldProps); - const newSearchState = this._getSearchState(type, newProps); + _shouldUpdateQuery(oldProps, newProps) { + const oldSearchState = this._getSearchState(this.props.tab, oldProps); + const newSearchState = this._getSearchState(this.props.tab, newProps); return !oldSearchState.isEqual({ other: newSearchState, fields: ['appliedFilters', 'field', 'sortType'] }) || ((oldSearchState.filtersValid !== newSearchState.filtersValid) && oldSearchState.appliedFilters.length > 0); // Execute a second query to apply filters after an initial query which got available filters } @@ -288,7 +275,7 @@ class SearchResultList extends Component { } _executeAllQueries(props) { this._executeTopicQuery(); - this.types.forEach(t => this._executeQuery(props, t)); + this._executeQuery(props, this.props.tab); } _getAggsToUpdate(filtersValid, aggregation_field_array, aggregation_field_lang_suffix_array, appliedFilterAggTypes, type) { // Returns a list of aggregations type which we should request from the server. @@ -300,34 +287,34 @@ class SearchResultList extends Component { .zip(aggregation_field_array, aggregation_field_lang_suffix_array) .map(([agg, suffix_map]) => `${agg}${suffix_map ? suffix_map[Sefaria.interfaceLang] : ''}`); // add suffix based on interfaceLang to filter, if present in suffix_map } - _executeQuery(props, type) { + _executeQuery(props) { //This takes a props object, so as to be able to handle being called from componentWillReceiveProps with newProps props = props || this.props; if (!props.query) { return; } - this._abortRunningQuery(type); + this._abortRunningQuery(); - let args = this._getQueryArgs(props, type); + let args = this._getQueryArgs(props); // If there are no available filters yet, don't apply filters. Split into two queries: // 1) Get all potential filters and counts // 2) Apply filters (Triggered from componentWillReceiveProps) const request_applied = args.applied_filters; - const searchState = this._getSearchState(type, props); + const searchState = this._getSearchState(this.props.tab, props); const { appliedFilters, appliedFilterAggTypes } = searchState; - const { aggregation_field_array, build_and_apply_filters } = SearchState.metadataByType[type]; + const { aggregation_field_array, build_and_apply_filters } = SearchState.metadataByType[this.props.tab]; args.success = data => { - this.updateRunningQuery(type, null); - if (this.state.pagesLoaded[type] === 0) { // Skip if pages have already been loaded from cache, but let aggregation processing below occur + this.updateRunningQuery(null); + if (this.state.pagesLoaded === 0) { // Skip if pages have already been loaded from cache, but let aggregation processing below occur const currTotal = data.hits.total; let state = { - hits: extend(this.state.hits, {[type]: data.hits.hits}), - totals: extend(this.state.totals, {[type]: currTotal}), - pagesLoaded: extend(this.state.pagesLoaded, {[type]: 1}), - moreToLoad: extend(this.state.moreToLoad, {[type]: currTotal.getValue() > this.querySize[type]}) + hits: data.hits.hits, + totals: currTotal, + pagesLoaded: 1, + moreToLoad: currTotal.getValue() > this.querySize[type] }; this.setState(state, () => { this.updateTotalResults(); @@ -335,7 +322,7 @@ class SearchResultList extends Component { }); const filter_label = (request_applied && request_applied.length > 0) ? (' - ' + request_applied.join('|')) : ''; const query_label = props.query + filter_label; - Sefaria.track.event("Search", `${this.props.searchInBook? "SidebarSearch ": ""}Query: ${type}`, query_label, data.hits.total.getValue()); + Sefaria.track.event("Search", `${this.props.searchInBook? "SidebarSearch ": ""}Query: ${this.props.tab}`, query_label, data.hits.total.getValue()); } if (data.aggregations) { @@ -355,26 +342,26 @@ class SearchResultList extends Component { orphans.push(...tempOrphans); } } - this.props.registerAvailableFilters(type, availableFilters, registry, orphans, args.aggregationsToUpdate); + this.props.registerAvailableFilters(this.props.tab, availableFilters, registry, orphans, args.aggregationsToUpdate); } }; args.error = this._handleError; const runningQuery = Sefaria.search.execute_query(args); - this.updateRunningQuery(type, runningQuery); + this.updateRunningQuery(runningQuery); } - _getQueryArgs(props, type) { + _getQueryArgs(props) { props = props || this.props; - const searchState = this._getSearchState(type, props); + const searchState = this._getSearchState(this.props.tab, props); const { field, fieldExact, sortType, filtersValid, appliedFilters, appliedFilterAggTypes } = searchState; const request_applied = filtersValid && appliedFilters; - const { aggregation_field_array, aggregation_field_lang_suffix_array } = SearchState.metadataByType[type]; - const aggregationsToUpdate = this._getAggsToUpdate(filtersValid, aggregation_field_array, aggregation_field_lang_suffix_array, appliedFilterAggTypes, type); + const { aggregation_field_array, aggregation_field_lang_suffix_array } = SearchState.metadataByType[this.props.tab]; + const aggregationsToUpdate = this._getAggsToUpdate(filtersValid, aggregation_field_array, aggregation_field_lang_suffix_array, appliedFilterAggTypes, this.props.tab); return { query: props.query, - type, + type: this.props.tab, applied_filters: request_applied, appliedFilterAggTypes, aggregationsToUpdate, @@ -384,26 +371,26 @@ class SearchResultList extends Component { exact: fieldExact === field, }; } - _loadNextPage(type) { + _loadNextPage() { console.log("load next page") - const args = this._getQueryArgs(this.props, type); - args.start = this.state.pagesLoaded[type] * this.querySize[type]; + const args = this._getQueryArgs(this.props); + args.start = this.state.pagesLoaded * this.querySize[this.props.tab]; args.error = () => console.log("Failure in SearchResultList._loadNextPage"); args.success = data => { - var nextHits = this.state.hits[type].concat(data.hits.hits); + let nextHits = this.state.hits.concat(data.hits.hits); - this.state.hits[type] = nextHits; - this.state.pagesLoaded[type] += 1; - if (this.state.pagesLoaded[type] * this.querySize[type] >= this.state.totals[type].getValue() ) { - this.state.moreToLoad[type] = false; + this.state.hits = nextHits; + this.state.pagesLoaded += 1; + if (this.state.pagesLoaded * this.querySize[this.props.tab] >= this.state.totals.getValue() ) { + this.state.moreToLoad = false; } this.setState(this.state); - this.updateRunningQuery(type, null); + this.updateRunningQuery(null); }; const runningNextPageQuery = Sefaria.search.execute_query(args); - this.updateRunningQuery(type, runningNextPageQuery, false); + this.updateRunningQuery(runningNextPageQuery, false); } _handleError(jqXHR, textStatus, errorThrown) { if (textStatus == "abort") { @@ -412,7 +399,7 @@ class SearchResultList extends Component { return; } this.setState({error: true}); - this.updateRunningQuery(null, null); + this.updateRunningQuery(null); } showSheets() { this.props.updateTab('sheet'); @@ -430,7 +417,7 @@ class SearchResultList extends Component { let results = []; if (tab == "text") { - results = Sefaria.search.mergeTextResultsVersions(this.state.hits.text); + results = Sefaria.search.mergeTextResultsVersions(this.state.hits); results = results.filter(result => !!result._source.version).map(result => + results = this.state.hits.map(result => ); const noResultsMessage = (); - const queryFullyLoaded = !this.state.moreToLoad[tab] && !this.state.isQueryRunning[tab]; + const queryFullyLoaded = !this.state.moreToLoad && !this.state.isQueryRunning; const haveResults = !!results.length; results = haveResults ? results : noResultsMessage; @@ -494,7 +481,7 @@ class SearchResultList extends Component {
    { queryFullyLoaded || haveResults ? results : null } - { this.state.isQueryRunning[tab] ? loadingMessage : null } + { this.state.isQueryRunning ? loadingMessage : null }
    ); From 2269f08909cb6358814ed22bc1a41390dad54ca6 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Tue, 18 Jun 2024 16:57:11 +0300 Subject: [PATCH 120/548] chore: remove SearchTabs --- static/js/SearchPage.jsx | 1 - static/js/SearchResultList.jsx | 49 +++++----------------------------- 2 files changed, 6 insertions(+), 44 deletions(-) diff --git a/static/js/SearchPage.jsx b/static/js/SearchPage.jsx index 438b2bc3c9..2cb603ccfc 100644 --- a/static/js/SearchPage.jsx +++ b/static/js/SearchPage.jsx @@ -61,7 +61,6 @@ class SearchPage extends Component { textSearchState={this.props.textSearchState} sheetSearchState={this.props.sheetSearchState} onResultClick={this.props.onResultClick} - updateTab={this.props.updateTab} updateAppliedOptionSort={this.props.updateAppliedOptionSort} registerAvailableFilters={this.props.registerAvailableFilters} updateTotalResults={n => this.setState({totalResults: n})} diff --git a/static/js/SearchResultList.jsx b/static/js/SearchResultList.jsx index f400bd3cac..bb00079b18 100644 --- a/static/js/SearchResultList.jsx +++ b/static/js/SearchResultList.jsx @@ -103,7 +103,7 @@ class SearchResultList extends Component { this.state.hits = this.state.hits.concat(cachedQuery.hits.hits); this.state.totals = cachedQuery.hits.total; this.state.pagesLoaded += 1; - args.start = this.state.pagesLoaded * this.querySize; + args.start = this.state.pagesLoaded * this.querySize[this.props.tab]; if (this.props.tab === "text") { // Since texts only have one filter type, aggregations are only requested once on first page args.aggregationsToUpdate = []; @@ -134,8 +134,9 @@ class SearchResultList extends Component { pagesLoaded: 0, moreToLoad: true }; - this.setState(state); - this._executeQuery(newProps, this.props.tab); + this.setState(state, () => { + this._executeQuery(newProps, this.props.tab); + }) } } async addRefTopic(topic) { @@ -314,7 +315,7 @@ class SearchResultList extends Component { hits: data.hits.hits, totals: currTotal, pagesLoaded: 1, - moreToLoad: currTotal.getValue() > this.querySize[type] + moreToLoad: currTotal.getValue() > this.querySize[this.props.tab] }; this.setState(state, () => { this.updateTotalResults(); @@ -365,7 +366,7 @@ class SearchResultList extends Component { applied_filters: request_applied, appliedFilterAggTypes, aggregationsToUpdate, - size: this.querySize[type], + size: this.querySize[this.props.tab], field, sort_type: sortType, exact: fieldExact === field, @@ -401,12 +402,6 @@ class SearchResultList extends Component { this.setState({error: true}); this.updateRunningQuery(null); } - showSheets() { - this.props.updateTab('sheet'); - } - showTexts() { - this.props.updateTab('text'); - } render () { if (!(this.props.query)) { // Push this up? Thought is to choose on the SearchPage level whether to show a ResultList or an EmptySearchMessage. return null; @@ -461,14 +456,6 @@ class SearchResultList extends Component { return (
    - {!this.props.searchInBook ? - : null - } {Sefaria.multiPanel && !this.props.compare ? ( -
    - - -
    -); - - -const SearchTab = ({label, total, onClick, active}) => { - const classes = classNames({"search-dropdown-button": 1, active}); - - return ( -
    {e.charCode === 13 ? onClick(e) : null}} role="button" tabIndex="0"> -
    - {label}  - {`(${total.asString()})`} -
    -
    - ); -}; - - const SearchSortBox = ({type, updateAppliedOptionSort, sortType}) => { const [isOpen, setIsOpen] = useState(false); From f683e4ffcf9363ac91e8f855c77c219806176790 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 19 Jun 2024 13:06:45 +0300 Subject: [PATCH 121/548] chore(Products Page): Code review, svg color fix --- static/css/s2.css | 18 +++++++++++++----- static/js/StaticPages.jsx | 12 ++++++------ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index d1028f77e7..d21cef315b 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12984,6 +12984,11 @@ span.ref-link-color-3 {color: blue} } } +.productsFlexWrapper { + display: flex; + flex-direction: column; +} + .product { max-width: 600px; } @@ -13059,16 +13064,19 @@ span.ref-link-color-3 {color: blue} margin-inline-end: 10px; } + +.productsHeader .cta .productsCTAIcon::before { + -webkit-mask: url("--image-url") no-repeat; + mask: url("--image-url") no-repeat; + background-color: var(--commentary-blue); +} + .productsHeader .cta .productsCTAIcon { - width: 13.33px; height: 16px; top: 646px; left: 610px; margin: 0 5px; - filter: brightness(0) saturate(100%) invert(52%) sepia(17%) saturate(6763%) hue-rotate(200deg) brightness(78%) contrast(77%);; - /* --image-path: attr(data-image-path); - mask: url(--image-path) no-repeat; - background-color: #4B71B7; */ + vertical-align: middle; } .productsTitle { diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index 21c709466d..d3c518d3ca 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3188,9 +3188,9 @@ const ProductCTA = ({cta}) => { // TODO - once analytics finalized, add onClick={productsAnalytics(product?.rank, `${product?.titles.en}_${cta.text.en}`, product?.type.en, "clicked")}
    {cta.icon.url && Click icon} + style={{"--image-url": cta.icon.url}} + src={cta.icon.url} + alt="Click icon" />} @@ -3226,9 +3226,9 @@ const ProductDesc = ({product}) => { }; // The main product component, comprised of the building block sub-components -const Product = ({id, product}) => { +const Product = ({product}) => { return ( -
    +
    @@ -3443,7 +3443,7 @@ const ProductsPage = memo(() => { const remainingProducts = ProductList.slice(devBoxPosition); return ( -
    +
    {products && products.length > 0 ? ( <> {initialProducts} From 39893c04c757df246a57e0c2244e1ec2fed2839a Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Wed, 19 Jun 2024 15:22:31 +0300 Subject: [PATCH 122/548] chore: change searchTab to searchType --- reader/views.py | 2 +- static/js/ReaderApp.jsx | 7 +---- static/js/ReaderPanel.jsx | 4 +-- static/js/SearchPage.jsx | 3 +- static/js/SearchResultList.jsx | 52 ++++++++++++++++------------------ static/js/SidebarSearch.jsx | 3 +- 6 files changed, 30 insertions(+), 41 deletions(-) diff --git a/reader/views.py b/reader/views.py index 45580457ec..5822a56fd5 100644 --- a/reader/views.py +++ b/reader/views.py @@ -429,7 +429,7 @@ def make_search_panel_dict(get_dict, i, **kwargs): panel = { "menuOpen": "search", "searchQuery": search_params["query"], - "searchTab": search_params["tab"], + "searchType": search_params["tab"], } panelDisplayLanguage = kwargs.get("panelDisplayLanguage") if panelDisplayLanguage: diff --git a/static/js/ReaderApp.jsx b/static/js/ReaderApp.jsx index b1ee4e29aa..1706d1b899 100644 --- a/static/js/ReaderApp.jsx +++ b/static/js/ReaderApp.jsx @@ -52,7 +52,7 @@ class ReaderApp extends Component { mode: "Menu", menuOpen: props.initialMenu, searchQuery: props.initialQuery, - searchTab: props.initialSearchTab, + searchTab: props.initialSearchType, tab: props.initialTab, topicSort: props.initialTopicSort, textSearchState: new SearchState({ @@ -1181,9 +1181,6 @@ toggleSignUpModal(modalContentKind = SignUpModalKind.Default) { }; this.setPanelState(n, updates); } - updateSearchTab(n, searchTab) { - this.setPanelState(n, { searchTab }); - } updateAvailableFilters(n, type, availableFilters, filterRegistry, orphanFilters, aggregationsToUpdate) { const state = this.state.panels[n]; const searchState = this._getSearchState(state, type); @@ -2125,7 +2122,6 @@ toggleSignUpModal(modalContentKind = SignUpModalKind.Default) { var onSidebarSearchClick = this.handleSidebarSearchClick.bind(null, i); var unsetTextHighlight = this.unsetTextHighlight.bind(null, i); var updateQuery = this.updateQuery.bind(null, i); - var updateSearchTab = this.updateSearchTab.bind(null, i); var updateAvailableFilters = this.updateAvailableFilters.bind(null, i); var updateSearchFilter = this.updateSearchFilter.bind(null, i); var updateSearchOptionField = this.updateSearchOptionField.bind(null, i); @@ -2183,7 +2179,6 @@ toggleSignUpModal(modalContentKind = SignUpModalKind.Default) { setDefaultOption={this.setDefaultOption} unsetTextHighlight={unsetTextHighlight} onQueryChange={updateQuery} - updateSearchTab={updateSearchTab} updateSearchFilter={updateSearchFilter} updateSearchOptionField={updateSearchOptionField} updateSearchOptionSort={updateSearchOptionSort} diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index 151ab5a193..59c1e4f430 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -887,7 +887,7 @@ class ReaderPanel extends Component { key={"searchPage"} interfaceLang={this.props.interfaceLang} query={this.state.searchQuery} - tab={this.state.searchTab} + type={this.state.searchTab} textSearchState={this.state.textSearchState} sheetSearchState={this.state.sheetSearchState} settings={Sefaria.util.clone(this.state.settings)} @@ -897,7 +897,6 @@ class ReaderPanel extends Component { toggleLanguage={this.toggleLanguage} close={this.props.closePanel} onQueryChange={this.props.onQueryChange} - updateTab={this.props.updateSearchTab} updateAppliedFilter={this.props.updateSearchFilter} updateAppliedOptionField={this.props.updateSearchOptionField} updateAppliedOptionSort={this.props.updateSearchOptionSort} @@ -1168,7 +1167,6 @@ ReaderPanel.propTypes = { backFromExtendedNotes: PropTypes.func, unsetTextHighlight: PropTypes.func, onQueryChange: PropTypes.func, - updateSearchTab: PropTypes.func, updateSearchFilter: PropTypes.func, updateSearchOptionField: PropTypes.func, updateSearchOptionSort: PropTypes.func, diff --git a/static/js/SearchPage.jsx b/static/js/SearchPage.jsx index 2cb603ccfc..1b6b5a3d6b 100644 --- a/static/js/SearchPage.jsx +++ b/static/js/SearchPage.jsx @@ -56,7 +56,7 @@ class SearchPage extends Component { { - this._executeQuery(newProps, this.props.tab); + this._executeQuery(newProps, this.props.type); }) } } @@ -250,8 +250,6 @@ class SearchResultList extends Component { this.updateRunningQuery(null); } handleScroll() { - var tab = this.props.tab; - if (!this.state.moreToLoad) { return; } if (this.state.runningQueries) { return; } @@ -262,8 +260,8 @@ class SearchResultList extends Component { } } _shouldUpdateQuery(oldProps, newProps) { - const oldSearchState = this._getSearchState(this.props.tab, oldProps); - const newSearchState = this._getSearchState(this.props.tab, newProps); + const oldSearchState = this._getSearchState(this.props.type, oldProps); + const newSearchState = this._getSearchState(this.props.type, newProps); return !oldSearchState.isEqual({ other: newSearchState, fields: ['appliedFilters', 'field', 'sortType'] }) || ((oldSearchState.filtersValid !== newSearchState.filtersValid) && oldSearchState.appliedFilters.length > 0); // Execute a second query to apply filters after an initial query which got available filters } @@ -276,7 +274,7 @@ class SearchResultList extends Component { } _executeAllQueries(props) { this._executeTopicQuery(); - this._executeQuery(props, this.props.tab); + this._executeQuery(props, this.props.type); } _getAggsToUpdate(filtersValid, aggregation_field_array, aggregation_field_lang_suffix_array, appliedFilterAggTypes, type) { // Returns a list of aggregations type which we should request from the server. @@ -303,9 +301,9 @@ class SearchResultList extends Component { // 2) Apply filters (Triggered from componentWillReceiveProps) const request_applied = args.applied_filters; - const searchState = this._getSearchState(this.props.tab, props); + const searchState = this._getSearchState(this.props.type, props); const { appliedFilters, appliedFilterAggTypes } = searchState; - const { aggregation_field_array, build_and_apply_filters } = SearchState.metadataByType[this.props.tab]; + const { aggregation_field_array, build_and_apply_filters } = SearchState.metadataByType[this.props.type]; args.success = data => { this.updateRunningQuery(null); @@ -315,7 +313,7 @@ class SearchResultList extends Component { hits: data.hits.hits, totals: currTotal, pagesLoaded: 1, - moreToLoad: currTotal.getValue() > this.querySize[this.props.tab] + moreToLoad: currTotal.getValue() > this.querySize[this.props.type] }; this.setState(state, () => { this.updateTotalResults(); @@ -323,7 +321,7 @@ class SearchResultList extends Component { }); const filter_label = (request_applied && request_applied.length > 0) ? (' - ' + request_applied.join('|')) : ''; const query_label = props.query + filter_label; - Sefaria.track.event("Search", `${this.props.searchInBook? "SidebarSearch ": ""}Query: ${this.props.tab}`, query_label, data.hits.total.getValue()); + Sefaria.track.event("Search", `${this.props.searchInBook? "SidebarSearch ": ""}Query: ${this.props.type}`, query_label, data.hits.total.getValue()); } if (data.aggregations) { @@ -343,7 +341,7 @@ class SearchResultList extends Component { orphans.push(...tempOrphans); } } - this.props.registerAvailableFilters(this.props.tab, availableFilters, registry, orphans, args.aggregationsToUpdate); + this.props.registerAvailableFilters(this.props.type, availableFilters, registry, orphans, args.aggregationsToUpdate); } }; args.error = this._handleError; @@ -354,19 +352,19 @@ class SearchResultList extends Component { _getQueryArgs(props) { props = props || this.props; - const searchState = this._getSearchState(this.props.tab, props); + const searchState = this._getSearchState(this.props.type, props); const { field, fieldExact, sortType, filtersValid, appliedFilters, appliedFilterAggTypes } = searchState; const request_applied = filtersValid && appliedFilters; - const { aggregation_field_array, aggregation_field_lang_suffix_array } = SearchState.metadataByType[this.props.tab]; - const aggregationsToUpdate = this._getAggsToUpdate(filtersValid, aggregation_field_array, aggregation_field_lang_suffix_array, appliedFilterAggTypes, this.props.tab); + const { aggregation_field_array, aggregation_field_lang_suffix_array } = SearchState.metadataByType[this.props.type]; + const aggregationsToUpdate = this._getAggsToUpdate(filtersValid, aggregation_field_array, aggregation_field_lang_suffix_array, appliedFilterAggTypes, this.props.type); return { query: props.query, - type: this.props.tab, + type: this.props.type, applied_filters: request_applied, appliedFilterAggTypes, aggregationsToUpdate, - size: this.querySize[this.props.tab], + size: this.querySize[this.props.type], field, sort_type: sortType, exact: fieldExact === field, @@ -375,14 +373,14 @@ class SearchResultList extends Component { _loadNextPage() { console.log("load next page") const args = this._getQueryArgs(this.props); - args.start = this.state.pagesLoaded * this.querySize[this.props.tab]; + args.start = this.state.pagesLoaded * this.querySize[this.props.type]; args.error = () => console.log("Failure in SearchResultList._loadNextPage"); args.success = data => { let nextHits = this.state.hits.concat(data.hits.hits); this.state.hits = nextHits; this.state.pagesLoaded += 1; - if (this.state.pagesLoaded * this.querySize[this.props.tab] >= this.state.totals.getValue() ) { + if (this.state.pagesLoaded * this.querySize[this.props.type] >= this.state.totals.getValue() ) { this.state.moreToLoad = false; } @@ -407,11 +405,11 @@ class SearchResultList extends Component { return null; } - const { tab } = this.props; - const searchState = this._getSearchState(tab); + const { type } = this.props; + const searchState = this._getSearchState(type); let results = []; - if (tab == "text") { + if (type == "text") { results = Sefaria.search.mergeTextResultsVersions(this.state.hits); results = results.filter(result => !!result._source.version).map(result => {Sefaria.multiPanel && !this.props.compare ? : @@ -476,7 +474,7 @@ class SearchResultList extends Component { } SearchResultList.propTypes = { query: PropTypes.string, - tab: PropTypes.oneOf(["text", "sheet"]), + type: PropTypes.oneOf(["text", "sheet"]), textSearchState: PropTypes.object, sheetSearchState: PropTypes.object, onResultClick: PropTypes.func, diff --git a/static/js/SidebarSearch.jsx b/static/js/SidebarSearch.jsx index 3d1962f71c..b22507ea14 100644 --- a/static/js/SidebarSearch.jsx +++ b/static/js/SidebarSearch.jsx @@ -116,8 +116,7 @@ const SidebarSearch = ({ title, updateAppliedOptionSort, navigatePanel, sidebarS query={query} compare={false} searchInBook={true} - tab="text" - types={["text"]} + type={"text"} textSearchState={searchState} updateTotalResults={n => console.log(n)} registerAvailableFilters={n => console.log(n)} From 2a825666738ba6d74710e279ae10505c4312a80b Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Wed, 19 Jun 2024 15:38:30 +0300 Subject: [PATCH 123/548] chore: change remaining searchTab to searchType --- reader/views.py | 2 +- static/js/ReaderApp.jsx | 14 +++++++------- static/js/ReaderPanel.jsx | 2 +- static/js/SearchPage.jsx | 14 +++++++------- static/js/SearchResultList.jsx | 6 +++--- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/reader/views.py b/reader/views.py index 5822a56fd5..2cf0856dab 100644 --- a/reader/views.py +++ b/reader/views.py @@ -839,7 +839,7 @@ def search(request): props={ "initialMenu": "search", "initialQuery": search_params["query"], - "initialSearchTab": search_params["tab"], + "initialSearchType": search_params["tab"], "initialTextSearchFilters": search_params["textFilters"], "initialTextSearchFilterAggTypes": search_params["textFilterAggTypes"], "initialTextSearchField": search_params["textField"], diff --git a/static/js/ReaderApp.jsx b/static/js/ReaderApp.jsx index 1706d1b899..4f61140d81 100644 --- a/static/js/ReaderApp.jsx +++ b/static/js/ReaderApp.jsx @@ -52,7 +52,7 @@ class ReaderApp extends Component { mode: "Menu", menuOpen: props.initialMenu, searchQuery: props.initialQuery, - searchTab: props.initialSearchType, + searchType: props.initialSearchType, tab: props.initialTab, topicSort: props.initialTopicSort, textSearchState: new SearchState({ @@ -154,7 +154,7 @@ class ReaderApp extends Component { collectionTag: state.collectionTag || null, translationsSlug: state.translationsSlug || null, searchQuery: state.searchQuery || null, - searchTab: state.searchTab || 'text', + searchType: state.searchType || 'text', showHighlight: state.showHighlight || null, textSearchState: state.textSearchState || new SearchState({ type: 'text' }), sheetSearchState: state.sheetSearchState || new SearchState({ type: 'sheet' }), @@ -390,7 +390,7 @@ class ReaderApp extends Component { (prev.currVersions.en !== next.currVersions.en) || (prev.currVersions.he !== next.currVersions.he) || (prev.searchQuery != next.searchQuery) || - (prev.searchTab != next.searchTab) || + (prev.searchType != next.searchType) || (prev.tab !== next.tab) || (prev.topicSort !== next.topicSort) || (prev.collectionName !== next.collectionName) || @@ -478,7 +478,7 @@ class ReaderApp extends Component { const query = state.searchQuery ? encodeURIComponent(state.searchQuery) : ""; hist.title = state.searchQuery ? state.searchQuery.stripHtml() + " | " : ""; hist.title += Sefaria._(siteName + " Search"); - hist.url = "search" + (state.searchQuery ? (`&q=${query}&tab=${state.searchTab}` + + hist.url = "search" + (state.searchQuery ? (`&q=${query}&tab=${state.searchType}` + state.textSearchState.makeURL({ prefix: 't', isStart: false }) + state.sheetSearchState.makeURL({ prefix: 's', isStart: false })) : ""); hist.mode = "search"; @@ -1710,15 +1710,15 @@ toggleSignUpModal(modalContentKind = SignUpModalKind.Default) { const textSearchState = (!!this.state.panels && this.state.panels.length && !!this.state.panels[0].textSearchState) ? this.state.panels[0].textSearchState.update({ filtersValid: false }) : new SearchState({ type: 'text' }); const sheetSearchState = (!!this.state.panels && this.state.panels.length && !!this.state.panels[0].sheetSearchState) ? this.state.panels[0].sheetSearchState.update({ filtersValid: false }) : new SearchState({ type: 'sheet' }); - const searchTab = !!this.state.panels && this.state.panels.length ? this.state.panels[0].searchTab : "text"; - this.setSinglePanelState({mode: "Menu", menuOpen: "search", searchQuery, searchTab, textSearchState, sheetSearchState }); + const searchType = !!this.state.panels && this.state.panels.length ? this.state.panels[0].searchType : "text"; + this.setSinglePanelState({mode: "Menu", menuOpen: "search", searchQuery, searchType, textSearchState, sheetSearchState }); } searchInCollection(searchQuery, collection) { let panel; const textSearchState = new SearchState({ type: 'text' }); const sheetSearchState = new SearchState({ type: 'sheet', appliedFilters: [collection], appliedFilterAggTypes: ['collections']}); - this.setSinglePanelState({mode: "Menu", menuOpen: "search", "searchTab": "sheet", searchQuery, textSearchState, sheetSearchState }); + this.setSinglePanelState({mode: "Menu", menuOpen: "search", "searchType": "sheet", searchQuery, textSearchState, sheetSearchState }); } showCommunity() { this.setSinglePanelState({menuOpen: "community"}); diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index 59c1e4f430..db166efe56 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -887,7 +887,7 @@ class ReaderPanel extends Component { key={"searchPage"} interfaceLang={this.props.interfaceLang} query={this.state.searchQuery} - type={this.state.searchTab} + type={this.state.searchType} textSearchState={this.state.textSearchState} sheetSearchState={this.state.sheetSearchState} settings={Sefaria.util.clone(this.state.settings)} diff --git a/static/js/SearchPage.jsx b/static/js/SearchPage.jsx index 1b6b5a3d6b..8dbe44b311 100644 --- a/static/js/SearchPage.jsx +++ b/static/js/SearchPage.jsx @@ -56,7 +56,7 @@ class SearchPage extends Component { 0 ? this.setState({mobileFiltersOpen: false})} compare={this.props.compare} - type={this.props.tab} /> + type={this.props.type} /> : null }
    : null } @@ -93,7 +93,7 @@ class SearchPage extends Component { SearchPage.propTypes = { interfaceLang: PropTypes.oneOf(["english", "hebrew"]), query: PropTypes.string, - tab: PropTypes.oneOf(["text", "sheet"]), + type: PropTypes.oneOf(["text", "sheet"]), textSearchState: PropTypes.object, sheetSearchState: PropTypes.object, settings: PropTypes.object, diff --git a/static/js/SearchResultList.jsx b/static/js/SearchResultList.jsx index c51a5be636..bb2d0f08d8 100644 --- a/static/js/SearchResultList.jsx +++ b/static/js/SearchResultList.jsx @@ -409,7 +409,7 @@ class SearchResultList extends Component { const searchState = this._getSearchState(type); let results = []; - if (type == "text") { + if (type === "text") { results = Sefaria.search.mergeTextResultsVersions(this.state.hits); results = results.filter(result => !!result._source.version).map(result => {Sefaria.multiPanel && !this.props.compare ? : From 72701789cb3b9bccdbb5bb5f65f274e51d3e7b93 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Wed, 19 Jun 2024 15:41:17 +0300 Subject: [PATCH 124/548] chore: abortRunningQueries should be abortRunningQuery --- static/js/SearchResultList.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/js/SearchResultList.jsx b/static/js/SearchResultList.jsx index bb2d0f08d8..3be45cfaee 100644 --- a/static/js/SearchResultList.jsx +++ b/static/js/SearchResultList.jsx @@ -117,7 +117,7 @@ class SearchResultList extends Component { $(ReactDOM.findDOMNode(this)).closest(".content").on("scroll.infiteScroll", this.handleScroll); } componentWillUnmount() { - this._abortRunningQueries(); // todo: make this work w/ promises + this._abortRunningQuery(); // todo: make this work w/ promises $(ReactDOM.findDOMNode(this)).closest(".content").off("scroll.infiniteScroll", this.handleScroll); } componentWillReceiveProps(newProps) { From b908e75fb24f12c3d135aabe2aacbe6ef3366e79 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 19 Jun 2024 19:18:50 +0300 Subject: [PATCH 125/548] feat(Module switcher): Improved css --- static/css/s2.css | 4 ++++ static/js/common/DropdownMenu.jsx | 16 ++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 656ef6bfdb..bd71d02b46 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13153,6 +13153,7 @@ span.ref-link-color-3 {color: blue} font-weight: 400; line-height: 18.75px; text-align: left; + color: var(--selected-option); } @@ -13162,7 +13163,10 @@ span.ref-link-color-3 {color: blue} font-weight: 400; line-height: 18px; text-align: left; +} +.dropdownItem { + border-bottom: 1px solid var(--light-grey); } .image-in-text-title { diff --git a/static/js/common/DropdownMenu.jsx b/static/js/common/DropdownMenu.jsx index cf3c7855a7..e4e73a2c8c 100644 --- a/static/js/common/DropdownMenu.jsx +++ b/static/js/common/DropdownMenu.jsx @@ -47,14 +47,14 @@ const DropdownMenu = ({header, bodyItems}) => { : null}
    From 5bdb9a6718cff9c0d725a38d981180c7247bc882 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 19 Jun 2024 19:39:09 +0300 Subject: [PATCH 126/548] feat(Module switcher): Adjust padding in CSS --- static/css/s2.css | 9 ++++++++- static/js/Header.jsx | 10 +++++----- static/js/common/DropdownMenu.jsx | 3 ++- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index bd71d02b46..2f2d7df99a 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13147,7 +13147,7 @@ span.ref-link-color-3 {color: blue} } .dropdownHeader { - margin-bottom: 1rem; + margin-bottom: 10px; font-family: Roboto; font-size: 16px; font-weight: 400; @@ -13157,16 +13157,23 @@ span.ref-link-color-3 {color: blue} } +.dropdownHeaderText { + /* border: 5px solid red; */ + padding-left: 10px; +} + .dropdownDesc { font-family: Roboto; font-size: 14px; font-weight: 400; line-height: 18px; text-align: left; + padding-left: 30px; } .dropdownItem { border-bottom: 1px solid var(--light-grey); + padding: 0px 0px 5px 10px !important; } .image-in-text-title { diff --git a/static/js/Header.jsx b/static/js/Header.jsx index 5e97821308..c2ebba5f04 100644 --- a/static/js/Header.jsx +++ b/static/js/Header.jsx @@ -46,11 +46,6 @@ class Header extends Component { // const sampleHeader = "Sefaria Links"; const sampleBody = [ - { - 'url': '//developers.sefaria.org', - 'text': 'Developer Portal', - 'icon': '/static/icons/developers_icon.svg' - }, { 'url': '/', 'text': 'Library', @@ -60,6 +55,11 @@ class Header extends Component { 'url': '//sheets.sefaria.org', 'text': 'Sheets', 'icon': '/static/icons/sheets_icon.svg' + }, + { + 'url': '//developers.sefaria.org', + 'text': 'Developer Portal', + 'icon': '/static/icons/developers_icon.svg' } ]; diff --git a/static/js/common/DropdownMenu.jsx b/static/js/common/DropdownMenu.jsx index e4e73a2c8c..55a49d3633 100644 --- a/static/js/common/DropdownMenu.jsx +++ b/static/js/common/DropdownMenu.jsx @@ -50,7 +50,8 @@ const DropdownMenu = ({header, bodyItems}) => { {bodyItems.map(item =>
    - {item.text} + + {item.text}
    Lorem ipsum dolor sit amet, lorem dolor.
    ) From 43c3cc774adcbb9de846bc1748b09a9b6dabe82a Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 19 Jun 2024 19:40:47 +0300 Subject: [PATCH 127/548] feat(Module switcher): Fix css to avoid redundant last border --- static/css/s2.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 2f2d7df99a..b674db4b71 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13158,7 +13158,6 @@ span.ref-link-color-3 {color: blue} } .dropdownHeaderText { - /* border: 5px solid red; */ padding-left: 10px; } @@ -13172,10 +13171,13 @@ span.ref-link-color-3 {color: blue} } .dropdownItem { - border-bottom: 1px solid var(--light-grey); padding: 0px 0px 5px 10px !important; } +.dropdownItem:not(:last-child){ + border-bottom: 1px solid var(--light-grey); +} + .image-in-text-title { margin: auto; /* English System Small */ margin-top: 15px; From 277702d484fd8067c4e0b2a8b009b9d12c8e881d Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 19 Jun 2024 19:45:01 +0300 Subject: [PATCH 128/548] feat(Module switcher): padding fixes --- static/css/s2.css | 1 + 1 file changed, 1 insertion(+) diff --git a/static/css/s2.css b/static/css/s2.css index b674db4b71..4be8d92f84 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13168,6 +13168,7 @@ span.ref-link-color-3 {color: blue} line-height: 18px; text-align: left; padding-left: 30px; + padding-bottom: 10px; } .dropdownItem { From 6b46aef441f82b3b830f3579c8bbd54c1a5a08d5 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 19 Jun 2024 19:47:15 +0300 Subject: [PATCH 129/548] chore(Module switcher): Code clean up --- static/js/common/DropdownMenu.jsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/static/js/common/DropdownMenu.jsx b/static/js/common/DropdownMenu.jsx index 55a49d3633..602df0334b 100644 --- a/static/js/common/DropdownMenu.jsx +++ b/static/js/common/DropdownMenu.jsx @@ -4,9 +4,6 @@ const DropdownMenu = ({header, bodyItems}) => { const [isOpen, setIsOpen] = useState(false); const wrapperRef = useRef(null); - const getCurrentPage = () => { - return isOpen ? (encodeURIComponent(Sefaria.util.currentPath())) : "/"; - } const handleClick = (e) => { e.stopPropagation(); setIsOpen(isOpen => !isOpen); @@ -36,11 +33,12 @@ const DropdownMenu = ({header, bodyItems}) => { return (
    - {Sefaria._('Toggle + {Sefaria._('Toggle
    { header ? (
    + {/* TODO: Deal with Hebrew text, use */} {header}
    ) From 32fdf268dd61a3f4797b3f0ea0ae90198e907cbb Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 19 Jun 2024 19:52:29 +0300 Subject: [PATCH 130/548] chore(Module switcher): Right padding adjustment --- static/css/s2.css | 1 + 1 file changed, 1 insertion(+) diff --git a/static/css/s2.css b/static/css/s2.css index 4be8d92f84..d450029eec 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13169,6 +13169,7 @@ span.ref-link-color-3 {color: blue} text-align: left; padding-left: 30px; padding-bottom: 10px; + padding-right: 10px; } .dropdownItem { From ea6a9cc0e82e0912fd0e45006b2ae69e4bfb200c Mon Sep 17 00:00:00 2001 From: saengel Date: Thu, 20 Jun 2024 12:57:36 +0300 Subject: [PATCH 131/548] feat(Module switcher): Composable component --- static/css/s2.css | 6 ++- static/icons/module_switcher_icon.svg | 3 ++ static/js/Header.jsx | 19 +++++++- static/js/common/DropdownMenu.jsx | 65 +++++++++++++++++---------- 4 files changed, 66 insertions(+), 27 deletions(-) create mode 100644 static/icons/module_switcher_icon.svg diff --git a/static/css/s2.css b/static/css/s2.css index d450029eec..14af76f2fb 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13174,10 +13174,12 @@ span.ref-link-color-3 {color: blue} .dropdownItem { padding: 0px 0px 5px 10px !important; + text-align: left; + padding-left: 10px; } -.dropdownItem:not(:last-child){ - border-bottom: 1px solid var(--light-grey); +.dropdownSeparator { + border: 1px solid var(--light-grey); } .image-in-text-title { diff --git a/static/icons/module_switcher_icon.svg b/static/icons/module_switcher_icon.svg new file mode 100644 index 0000000000..e5e02252fc --- /dev/null +++ b/static/icons/module_switcher_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/js/Header.jsx b/static/js/Header.jsx index c2ebba5f04..6cc3c3c5d5 100644 --- a/static/js/Header.jsx +++ b/static/js/Header.jsx @@ -15,7 +15,7 @@ import { DonateLink } from './Misc'; import {Autocomplete} from './Autocomplete' -import { DropdownMenu } from './common/DropdownMenu'; +import { DropdownMenu, DropdownMenuSeparator, DropdownMenuItem, DropdownMenuItemWithIcon } from './common/DropdownMenu'; class Header extends Component { constructor(props) { @@ -89,7 +89,22 @@ class Header extends Component { : } { !Sefaria._uid && Sefaria._siteSettings.TORAH_SPECIFIC ? - : null} + + item 1 + item 2 + + + + + + + + + + + + + : null}
    ); diff --git a/static/js/common/DropdownMenu.jsx b/static/js/common/DropdownMenu.jsx index 602df0334b..d50c149289 100644 --- a/static/js/common/DropdownMenu.jsx +++ b/static/js/common/DropdownMenu.jsx @@ -1,6 +1,41 @@ import React, {useContext, useEffect, useRef, useState} from 'react'; -const DropdownMenu = ({header, bodyItems}) => { + +// Todo +// Fix the styling on the 'dropdown item' (regular one) +// Restore the header to also show the globe icon + +const DropdownMenuSeparator = () => { + + return ( +
    + ); + +} + +const DropdownMenuItem = ({url, children}) => { + return ( + + + {children} + + + ); +} + +const DropdownMenuItemWithIcon = ({icon, text}) => { + return ( + <> +
    + + {text} +
    +
    Lorem ipsum dolor sit amet, lorem dolor.
    + + ); +} + +const DropdownMenu = ({children}) => { const [isOpen, setIsOpen] = useState(false); const wrapperRef = useRef(null); @@ -33,29 +68,10 @@ const DropdownMenu = ({header, bodyItems}) => { return (
    - {Sefaria._('Toggle + {Sefaria._('Toggle
    - { header ? - ( -
    - {/* TODO: Deal with Hebrew text, use */} - {header} -
    - ) - : null} -
    - {bodyItems.map(item => - -
    - - {item.text} -
    -
    Lorem ipsum dolor sit amet, lorem dolor.
    -
    ) - } - {/* עברית - English */} + {children}
    @@ -64,5 +80,8 @@ const DropdownMenu = ({header, bodyItems}) => { export { - DropdownMenu + DropdownMenu, + DropdownMenuSeparator, + DropdownMenuItem, + DropdownMenuItemWithIcon }; \ No newline at end of file From 04b9b2aad6608b0215a70c27e0192d3c1ed82e0a Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 20 Jun 2024 13:09:07 +0300 Subject: [PATCH 132/548] chore: add collections to sheet_data in get_sheets_for_ref --- sefaria/sheets.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sefaria/sheets.py b/sefaria/sheets.py index 7005b5924a..721a1a199a 100755 --- a/sefaria/sheets.py +++ b/sefaria/sheets.py @@ -847,6 +847,7 @@ def get_sheets_for_ref(tref, uid=None, in_collection=None): for anchor_ref, anchor_ref_expanded in zip(anchor_ref_list, anchor_ref_expanded_list): sheet_data = { "owner": sheet["owner"], + "collections": [{'name': c.name, 'slug': c.slug} for c in CollectionSet({"sheets": sheet['id']}).array()], "_id": str(sheet["_id"]), "id": str(sheet["id"]), "public": sheet["status"] == "public", From 51ed1a25c4621ce11dd2299227611316b796a111 Mon Sep 17 00:00:00 2001 From: saengel Date: Sun, 23 Jun 2024 09:31:44 +0300 Subject: [PATCH 133/548] feat(Module switcher): Open in new tab --- static/js/common/DropdownMenu.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/js/common/DropdownMenu.jsx b/static/js/common/DropdownMenu.jsx index d50c149289..fceefd5db4 100644 --- a/static/js/common/DropdownMenu.jsx +++ b/static/js/common/DropdownMenu.jsx @@ -16,7 +16,7 @@ const DropdownMenuSeparator = () => { const DropdownMenuItem = ({url, children}) => { return ( - + {children} From 4787623d568202b6994b69ecf85d5b9767c933fd Mon Sep 17 00:00:00 2001 From: saengel Date: Sun, 23 Jun 2024 13:23:59 +0300 Subject: [PATCH 134/548] chore(Module switcher): Tighten css --- static/css/s2.css | 5 +++-- static/js/Header.jsx | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 14af76f2fb..7575767b33 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13174,12 +13174,12 @@ span.ref-link-color-3 {color: blue} .dropdownItem { padding: 0px 0px 5px 10px !important; - text-align: left; - padding-left: 10px; + text-align: left !important; } .dropdownSeparator { border: 1px solid var(--light-grey); + margin: 5px; } .image-in-text-title { @@ -13192,6 +13192,7 @@ span.ref-link-color-3 {color: blue} font-size: 14px; line-height: 18px; color: #666666; +} @-webkit-keyframes load5 { 0%,100%{box-shadow:0 -2.6em 0 0 #ffffff,1.8em -1.8em 0 0 rgba(0,0,0,0.2),2.5em 0 0 0 rgba(0,0,0,0.2),1.75em 1.75em 0 0 rgba(0,0,0,0.2),0 2.5em 0 0 rgba(0,0,0,0.2),-1.8em 1.8em 0 0 rgba(0,0,0,0.2),-2.6em 0 0 0 rgba(0,0,0,0.5),-1.8em -1.8em 0 0 rgba(0,0,0,0.7)} diff --git a/static/js/Header.jsx b/static/js/Header.jsx index 6cc3c3c5d5..61b0c0482a 100644 --- a/static/js/Header.jsx +++ b/static/js/Header.jsx @@ -88,11 +88,9 @@ class Header extends Component { : } + { !Sefaria._uid && Sefaria._siteSettings.TORAH_SPECIFIC ? - item 1 - item 2 - @@ -104,7 +102,19 @@ class Header extends Component { + + + {'More of our products >'} + + : null} + + { !Sefaria._uid && Sefaria._siteSettings.TORAH_SPECIFIC ? + : null} +
    ); From b0fe02c02702686efd069611537e6c430951f270 Mon Sep 17 00:00:00 2001 From: Yosef Kaner Date: Sun, 23 Jun 2024 14:26:21 +0300 Subject: [PATCH 135/548] Update popup.js Fix - title in Hebrew was showing in English. When ctrl+click is triggered open in new tab. --- static/js/linker.v3/popup.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/static/js/linker.v3/popup.js b/static/js/linker.v3/popup.js index fe80d935cb..aaeeb01614 100644 --- a/static/js/linker.v3/popup.js +++ b/static/js/linker.v3/popup.js @@ -289,7 +289,7 @@ export class PopupManager { this.linkerHeader.style["border-top-color"] = this.category_colors[primaryCategory]; // TODO is this right? - if (this.contentLang !== "he") { + if (this.contentLang.slice(0, 2) !== "he") { // [].forEach.call(heElems, function(e) {e.style.display = "None"}); this.heTitle.style.display = "None"; [].forEach.call(this.enElems, function(e) {e.style.display = "Block"}); @@ -413,6 +413,9 @@ export class PopupManager { elem.addEventListener('mouseout', this.hidePopup, false); } else if (this.mode === "popup-click") { elem.addEventListener('click', (event) => { + if (event.ctrlKey) { + return; + } event.preventDefault(); event.stopPropagation(); this.showPopup(elem, source); @@ -420,4 +423,4 @@ export class PopupManager { }, false); } } -} \ No newline at end of file +} From 834f955aaf82ac21a5d3a2a09a1760a6c5abaf25 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Mon, 24 Jun 2024 10:50:08 +0300 Subject: [PATCH 136/548] chore: pass SearchResultList in as prop to SearchPage --- static/js/ReaderPanel.jsx | 2 ++ static/js/SearchPage.jsx | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index db166efe56..b4975a0a0c 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -9,6 +9,7 @@ import {ContentLanguageContext} from './context'; import $ from './sefaria/sefariaJquery'; import TextColumn from './TextColumn'; import TextsPage from './TextsPage'; +import SearchResultList from "./SearchResultList"; import { ConnectionsPanel, ConnectionsPanelHeader, @@ -885,6 +886,7 @@ class ReaderPanel extends Component { } else if (this.state.menuOpen === "search" && this.state.searchQuery) { menu = ( {this.props.compare ? @@ -54,7 +54,7 @@ class SearchPage extends Component { : null }
    - Date: Mon, 24 Jun 2024 12:55:40 +0300 Subject: [PATCH 137/548] chore: remove TextSearchState and SheetSearchState distinction from SearchPage --- static/js/ReaderPanel.jsx | 3 +-- static/js/SearchPage.jsx | 10 ++++------ static/js/SearchResultList.jsx | 17 ++++++++--------- static/js/SidebarSearch.jsx | 2 +- 4 files changed, 14 insertions(+), 18 deletions(-) diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index db166efe56..ba06d47801 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -888,8 +888,7 @@ class ReaderPanel extends Component { interfaceLang={this.props.interfaceLang} query={this.state.searchQuery} type={this.state.searchType} - textSearchState={this.state.textSearchState} - sheetSearchState={this.state.sheetSearchState} + searchState={this.state[`${this.state.searchType}SearchState`]} settings={Sefaria.util.clone(this.state.settings)} panelsOpen={this.props.panelsOpen} onResultClick={this.props.onSearchResultClick} diff --git a/static/js/SearchPage.jsx b/static/js/SearchPage.jsx index 8dbe44b311..42c6ce7088 100644 --- a/static/js/SearchPage.jsx +++ b/static/js/SearchPage.jsx @@ -58,8 +58,7 @@ class SearchPage extends Component { query={this.props.query} type={this.props.type} compare={this.props.compare} - textSearchState={this.props.textSearchState} - sheetSearchState={this.props.sheetSearchState} + searchState={this.props.searchState} onResultClick={this.props.onResultClick} updateAppliedOptionSort={this.props.updateAppliedOptionSort} registerAvailableFilters={this.props.registerAvailableFilters} @@ -73,8 +72,8 @@ class SearchPage extends Component { {this.state.totalResults?.getValue() > 0 ? this.setState({mobileFiltersOpen: false})} @@ -94,8 +93,7 @@ SearchPage.propTypes = { interfaceLang: PropTypes.oneOf(["english", "hebrew"]), query: PropTypes.string, type: PropTypes.oneOf(["text", "sheet"]), - textSearchState: PropTypes.object, - sheetSearchState: PropTypes.object, + searchState: PropTypes.object, settings: PropTypes.object, panelsOpen: PropTypes.number, close: PropTypes.func, diff --git a/static/js/SearchResultList.jsx b/static/js/SearchResultList.jsx index 3be45cfaee..57b3190149 100644 --- a/static/js/SearchResultList.jsx +++ b/static/js/SearchResultList.jsx @@ -260,17 +260,17 @@ class SearchResultList extends Component { } } _shouldUpdateQuery(oldProps, newProps) { - const oldSearchState = this._getSearchState(this.props.type, oldProps); - const newSearchState = this._getSearchState(this.props.type, newProps); + const oldSearchState = this._getSearchState(oldProps); + const newSearchState = this._getSearchState(newProps); return !oldSearchState.isEqual({ other: newSearchState, fields: ['appliedFilters', 'field', 'sortType'] }) || ((oldSearchState.filtersValid !== newSearchState.filtersValid) && oldSearchState.appliedFilters.length > 0); // Execute a second query to apply filters after an initial query which got available filters } - _getSearchState(type, props) { + _getSearchState(props) { props = props || this.props; if (!props.query) { return; } - return props[`${type}SearchState`]; + return props['searchState']; } _executeAllQueries(props) { this._executeTopicQuery(); @@ -301,7 +301,7 @@ class SearchResultList extends Component { // 2) Apply filters (Triggered from componentWillReceiveProps) const request_applied = args.applied_filters; - const searchState = this._getSearchState(this.props.type, props); + const searchState = this._getSearchState(props); const { appliedFilters, appliedFilterAggTypes } = searchState; const { aggregation_field_array, build_and_apply_filters } = SearchState.metadataByType[this.props.type]; @@ -352,7 +352,7 @@ class SearchResultList extends Component { _getQueryArgs(props) { props = props || this.props; - const searchState = this._getSearchState(this.props.type, props); + const searchState = this._getSearchState(props); const { field, fieldExact, sortType, filtersValid, appliedFilters, appliedFilterAggTypes } = searchState; const request_applied = filtersValid && appliedFilters; const { aggregation_field_array, aggregation_field_lang_suffix_array } = SearchState.metadataByType[this.props.type]; @@ -406,7 +406,7 @@ class SearchResultList extends Component { } const { type } = this.props; - const searchState = this._getSearchState(type); + const searchState = this._getSearchState(); let results = []; if (type === "text") { @@ -475,8 +475,7 @@ class SearchResultList extends Component { SearchResultList.propTypes = { query: PropTypes.string, type: PropTypes.oneOf(["text", "sheet"]), - textSearchState: PropTypes.object, - sheetSearchState: PropTypes.object, + searchState: PropTypes.object, onResultClick: PropTypes.func, updateAppliedOptionSort: PropTypes.func, registerAvailableFilters: PropTypes.func, diff --git a/static/js/SidebarSearch.jsx b/static/js/SidebarSearch.jsx index b22507ea14..00e0509f50 100644 --- a/static/js/SidebarSearch.jsx +++ b/static/js/SidebarSearch.jsx @@ -117,7 +117,7 @@ const SidebarSearch = ({ title, updateAppliedOptionSort, navigatePanel, sidebarS compare={false} searchInBook={true} type={"text"} - textSearchState={searchState} + searchState={searchState} updateTotalResults={n => console.log(n)} registerAvailableFilters={n => console.log(n)} updateAppliedOptionSort={updateAppliedOptionSort} From 3b41088915e25c02a3190981cb3914e37d414b00 Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 24 Jun 2024 13:08:16 +0300 Subject: [PATCH 138/548] chore(Module switcher): Fix CSS, reintegrate language toggle --- static/css/s2.css | 9 +++++---- static/js/Header.jsx | 23 ++--------------------- 2 files changed, 7 insertions(+), 25 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 7575767b33..ce273e1fcb 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -844,9 +844,10 @@ div:has(#bannerMessage) + .readerApp.singlePanel .mobileNavMenu { .interface-english .header .interfaceLinks .interfaceLinks-menu .interfaceLinks-header { font-family: "Roboto", "Helvetica Neue", Helvetica, sans-serif; } -.interface-hebrew .header .interfaceLinks .interfaceLinks-menu .interfaceLinks-header { +.interface-hebrew .header .interfaceLinks .interfaceLinks-menu .interfaceLinks-header {∫ font-family: "Heebo", sans-serif; } + .interfaceLinks-options { display: flex; flex-direction: column; @@ -854,7 +855,7 @@ div:has(#bannerMessage) + .readerApp.singlePanel .mobileNavMenu { max-width: 220px; } .header .interfaceLinks .interfaceLinks-option { - /* display: flex; */ + display: flex; text-decoration: none; font-style: normal; font-weight: normal; @@ -13173,13 +13174,13 @@ span.ref-link-color-3 {color: blue} } .dropdownItem { - padding: 0px 0px 5px 10px !important; + padding: 10px 0px 5px 10px !important; text-align: left !important; + flex-direction: column; } .dropdownSeparator { border: 1px solid var(--light-grey); - margin: 5px; } .image-in-text-title { diff --git a/static/js/Header.jsx b/static/js/Header.jsx index 61b0c0482a..4ad2efc45d 100644 --- a/static/js/Header.jsx +++ b/static/js/Header.jsx @@ -44,25 +44,6 @@ class Header extends Component { Sefaria Logo : Sefaria Logo; - // const sampleHeader = "Sefaria Links"; - const sampleBody = [ - { - 'url': '/', - 'text': 'Library', - 'icon': '/static/icons/library_icon.svg' - }, - { - 'url': '//sheets.sefaria.org', - 'text': 'Sheets', - 'icon': '/static/icons/sheets_icon.svg' - }, - { - 'url': '//developers.sefaria.org', - 'text': 'Developer Portal', - 'icon': '/static/icons/developers_icon.svg' - } - ]; - const headerContent = ( <> @@ -103,8 +84,8 @@ class Header extends Component { - - {'More of our products >'} + + {'See all products >'} : null} From fea94b8c1529fab70d9544fde48bb55dc9db88a9 Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 24 Jun 2024 13:28:33 +0300 Subject: [PATCH 139/548] feat(Module switcher): Add Hebrew rendering, fix style to render both --- static/css/s2.css | 4 ---- static/js/Header.jsx | 8 ++++---- static/js/common/DropdownMenu.jsx | 11 ++++++++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index ce273e1fcb..430c008450 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -861,7 +861,6 @@ div:has(#bannerMessage) + .readerApp.singlePanel .mobileNavMenu { font-weight: normal; font-size: 16px; line-height: 23px; - text-align: right; color: #666666; padding: 5px; direction: ltr; @@ -13153,7 +13152,6 @@ span.ref-link-color-3 {color: blue} font-size: 16px; font-weight: 400; line-height: 18.75px; - text-align: left; color: var(--selected-option); } @@ -13167,7 +13165,6 @@ span.ref-link-color-3 {color: blue} font-size: 14px; font-weight: 400; line-height: 18px; - text-align: left; padding-left: 30px; padding-bottom: 10px; padding-right: 10px; @@ -13175,7 +13172,6 @@ span.ref-link-color-3 {color: blue} .dropdownItem { padding: 10px 0px 5px 10px !important; - text-align: left !important; flex-direction: column; } diff --git a/static/js/Header.jsx b/static/js/Header.jsx index 4ad2efc45d..6133f7f79c 100644 --- a/static/js/Header.jsx +++ b/static/js/Header.jsx @@ -73,19 +73,19 @@ class Header extends Component { { !Sefaria._uid && Sefaria._siteSettings.TORAH_SPECIFIC ? - + - + - + - {'See all products >'} + '}} /> : null} diff --git a/static/js/common/DropdownMenu.jsx b/static/js/common/DropdownMenu.jsx index fceefd5db4..ec52b635e7 100644 --- a/static/js/common/DropdownMenu.jsx +++ b/static/js/common/DropdownMenu.jsx @@ -1,4 +1,5 @@ import React, {useContext, useEffect, useRef, useState} from 'react'; +import { InterfaceText } from '../Misc'; // Todo @@ -23,14 +24,18 @@ const DropdownMenuItem = ({url, children}) => { ); } -const DropdownMenuItemWithIcon = ({icon, text}) => { +const DropdownMenuItemWithIcon = ({icon, textEn, textHe}) => { return ( <>
    - {text} + + + +
    +
    +
    -
    Lorem ipsum dolor sit amet, lorem dolor.
    ); } From 92af1a63c39788499d44538976fa6c0347d8eee4 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Mon, 24 Jun 2024 16:20:50 +0300 Subject: [PATCH 140/548] chore: start creating FilterNodes for SheetsWithRef --- static/js/ConnectionsPanel.jsx | 24 ++++++++++++++++++++++++ static/js/ReaderPanel.jsx | 1 - static/js/SearchPage.jsx | 1 - 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/static/js/ConnectionsPanel.jsx b/static/js/ConnectionsPanel.jsx index b874731285..20dd99cf65 100644 --- a/static/js/ConnectionsPanel.jsx +++ b/static/js/ConnectionsPanel.jsx @@ -41,6 +41,7 @@ import { event } from 'jquery'; import TopicSearch from "./TopicSearch"; import WebPage from './WebPage' import { SignUpModalKind } from './sefaria/signupModalContent'; +import SearchState from "./sefaria/searchState"; class ConnectionsPanel extends Component { @@ -458,6 +459,29 @@ class ConnectionsPanel extends Component { />); } else if (this.props.mode === "Sheets") { + /* + Write a function that takes a list of sheets and generates the available filters. Should create two types of filters, collection filters and topic filters. + How to create a FilterNode: + + For collections, determine lang of title and put it in the right field (either title or heTitle) + docCount is how many times this collection of topic comes up in the list of sheets + aggKey is a unique ID for the collection or topic (slug in both cases) + aggType is either topic or collection (look at code for exact spelling) + children and parent is undefined + selected is 0 + */ + const sheets = Sefaria.sheets.sheetsByRef(this.props.srefs); + const filters = {}; + sheets.forEach(sheet => { + sheet.topics.forEach(topic => { + let filter = topic.slug in filters ? filters[topic.slug] : {[topic.slug]: + {title: topic.en, heTitle: topic.he, + docCount: 0, aggKey: topic.slug, + selected: 0, aggType: 'topics_en'}}; + filter.docCount += 1; + }) + }) + const sheetsWithRefState = new SearchState({ type: 'sheet', availableFilters: filters }); const connectedSheet = this.props.nodeRef ? this.props.nodeRef.split(".")[0] : null; content = (
    {this.props.srefs[0].indexOf("Sheet") === -1 ? diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index f6ec4a5333..7042935f87 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -887,7 +887,6 @@ class ReaderPanel extends Component { menu = ( Date: Mon, 24 Jun 2024 16:48:56 +0300 Subject: [PATCH 141/548] chore: use sheetsWithRefSearchState to generate Search State for SheetsWithRef --- static/js/ConnectionsPanel.jsx | 13 +------------ static/js/Misc.jsx | 2 ++ static/js/sefaria/sefaria.js | 26 ++++++++++++++++++++++++++ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/static/js/ConnectionsPanel.jsx b/static/js/ConnectionsPanel.jsx index 20dd99cf65..5e7a880246 100644 --- a/static/js/ConnectionsPanel.jsx +++ b/static/js/ConnectionsPanel.jsx @@ -470,18 +470,7 @@ class ConnectionsPanel extends Component { children and parent is undefined selected is 0 */ - const sheets = Sefaria.sheets.sheetsByRef(this.props.srefs); - const filters = {}; - sheets.forEach(sheet => { - sheet.topics.forEach(topic => { - let filter = topic.slug in filters ? filters[topic.slug] : {[topic.slug]: - {title: topic.en, heTitle: topic.he, - docCount: 0, aggKey: topic.slug, - selected: 0, aggType: 'topics_en'}}; - filter.docCount += 1; - }) - }) - const sheetsWithRefState = new SearchState({ type: 'sheet', availableFilters: filters }); + const sheetsWithRefSearchState = Sefaria.sheets.sheetsWithRefSearchState(this.props.srefs); const connectedSheet = this.props.nodeRef ? this.props.nodeRef.split(".")[0] : null; content = (
    {this.props.srefs[0].indexOf("Sheet") === -1 ? diff --git a/static/js/Misc.jsx b/static/js/Misc.jsx index f5645ee130..4f0853f665 100644 --- a/static/js/Misc.jsx +++ b/static/js/Misc.jsx @@ -1047,6 +1047,8 @@ class ToggleOption extends Component { //style={this.props.style} + + const requestWithCallBack = ({url, setSavingStatus, redirect, type="POST", data={}, redirect_params}) => { let ajaxPayload = {url, type}; if (type === "POST") { diff --git a/static/js/sefaria/sefaria.js b/static/js/sefaria/sefaria.js index ecffc50cd5..c249c1d23c 100644 --- a/static/js/sefaria/sefaria.js +++ b/static/js/sefaria/sefaria.js @@ -10,6 +10,7 @@ import Hebrew from './hebrew'; import Util from './util'; import $ from './sefariaJquery'; import Cookies from 'js-cookie'; +import SearchState from "./searchState"; let Sefaria = Sefaria || { @@ -2754,6 +2755,31 @@ _media: {}, return Sefaria.topic_toc.filter(x => x.slug == slug).length > 0; }, sheets: { + sheetsWithRefSearchState(sref) { + /* + This function is used to generate the SearchState with its relevant FilterNodes to be used by SheetsWithRef for filtering sheets by topic and collection + */ + const sheets = this.sheetsByRef(sref); + let filters = {}; // object where keys are slugs of filters and values are the data for filternodes + sheets.forEach(sheet => { + sheet?.topics.forEach(topic => { + let filter = topic.slug in filters ? filters[topic.slug] : {title: topic.en, heTitle: topic.he, + docCount: 0, aggKey: topic.slug, + selected: 0, aggType: 'topics_en'}; + filter.docCount += 1; + filters[topic.slug] = filter; + }) + sheet?.collections.forEach(collection => { + let filter = collection.slug in filters ? filters[collection.slug] : {title: collection.name, heTitle: collection.name, + docCount: 0, aggKey: collection.slug, + selected: 0, aggType: 'collections'}; + filter.docCount += 1; + filters[collection.slug] = filter; + }) + }) + filters = Object.values(filters); + return new SearchState({ type: 'sheet', availableFilters: filters }); + }, _loadSheetByID: {}, loadSheetByID: function(id, callback, reset) { if (reset) { From 57ab9902596386c8a28bbb556519a43abf0c8b4b Mon Sep 17 00:00:00 2001 From: YishaiGlasner Date: Mon, 24 Jun 2024 20:04:21 +0300 Subject: [PATCH 142/548] feat(Lexicon): class for new lexicon - Kovetz Yesodot VaChakirot. --- sefaria/model/lexicon.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/sefaria/model/lexicon.py b/sefaria/model/lexicon.py index e8d6595150..2623437dfe 100644 --- a/sefaria/model/lexicon.py +++ b/sefaria/model/lexicon.py @@ -357,6 +357,23 @@ def as_strings(self, with_headword=True): return ['
    '.join(strings)] +class KovetzYesodotEntry(DictionaryEntry): + required_attrs = DictionaryEntry.required_attrs + ["content", "rid"] + + def headword_string(self): + return f'{self.headword}' + + def as_strings(self, with_headword=True): + strings = [] + if with_headword: + strings.append(self.headword_string()) + for key, value in self.content.items(): + if key != 'reference': + strings.append(f'{key}') + strings += value + return ['
    '.join(strings)] + + class LexiconEntrySubClassMapping(object): lexicon_class_map = { 'BDB Augmented Strong': StrongsDictionaryEntry, @@ -367,7 +384,8 @@ class LexiconEntrySubClassMapping(object): 'Sefer HaShorashim': HebrewDictionaryEntry, 'Animadversions by Elias Levita on Sefer HaShorashim': HebrewDictionaryEntry, 'BDB Dictionary': BDBEntry, - 'BDB Aramaic Dictionary': BDBEntry + 'BDB Aramaic Dictionary': BDBEntry, + 'Kovetz Yesodot VaChakirot': KovetzYesodotEntry, } @classmethod From 6fd326ad2784b549c133a6fa7f00b67cdc8be323 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 25 Jun 2024 10:41:12 +0300 Subject: [PATCH 143/548] feat(Remove Community Menu Items): Remove links to community/collections on home page --- static/js/CommunityPage.jsx | 2 -- static/js/Footer.jsx | 1 - static/js/Header.jsx | 5 ----- static/js/NavSidebar.jsx | 2 -- static/js/TextsPage.jsx | 1 - static/js/TopicPageAll.jsx | 1 - static/js/TopicsPage.jsx | 1 - 7 files changed, 13 deletions(-) diff --git a/static/js/CommunityPage.jsx b/static/js/CommunityPage.jsx index 8510b13093..6f6127b150 100644 --- a/static/js/CommunityPage.jsx +++ b/static/js/CommunityPage.jsx @@ -20,10 +20,8 @@ const CommunityPage = ({multiPanel, toggleSignUpModal, initialWidth}) => { const [dataLoaded, setDataLoaded] = useState(!!Sefaria.community); const sidebarModules = [ - {type: "JoinTheConversation"}, {type: dataLoaded ? "WhoToFollow" : null, props: {toggleSignUpModal}}, {type: "Promo"}, - {type: "ExploreCollections"}, {type: "SupportSefaria", props: {blue: true}}, {type: "StayConnected"}, ]; diff --git a/static/js/Footer.jsx b/static/js/Footer.jsx index e95cbf6bf8..63a5518f1f 100644 --- a/static/js/Footer.jsx +++ b/static/js/Footer.jsx @@ -55,7 +55,6 @@ class Footer extends Component {
    - diff --git a/static/js/Header.jsx b/static/js/Header.jsx index cef41de821..8795d9bd8e 100644 --- a/static/js/Header.jsx +++ b/static/js/Header.jsx @@ -51,7 +51,6 @@ class Header extends Component { {logo} : null } Texts Topics - Community Donate
    @@ -215,10 +214,6 @@ const MobileNavMenu = ({onRefClick, showSearch, openTopic, openURL, close, visib Topics - - - Community - Learning Schedules diff --git a/static/js/NavSidebar.jsx b/static/js/NavSidebar.jsx index 1aaadeaee4..4daf5487cc 100644 --- a/static/js/NavSidebar.jsx +++ b/static/js/NavSidebar.jsx @@ -241,8 +241,6 @@ const Resources = () => (

    Resources

    - - diff --git a/static/js/TextsPage.jsx b/static/js/TextsPage.jsx index 53ef228dfb..cd948c2961 100644 --- a/static/js/TextsPage.jsx +++ b/static/js/TextsPage.jsx @@ -93,7 +93,6 @@ const TextsPage = ({categories, settings, setCategories, onCompareBack, openSear multiPanel ? {type: "RecentlyViewed", props: {toggleSignUpModal}} : {type: null}, {type: "Translations"}, {type: "LearningSchedules"}, - {type: "JoinTheCommunity"}, {type: "Resources"}, ]; diff --git a/static/js/TopicPageAll.jsx b/static/js/TopicPageAll.jsx index d732d7c0cd..c7addcd444 100644 --- a/static/js/TopicPageAll.jsx +++ b/static/js/TopicPageAll.jsx @@ -45,7 +45,6 @@ class TopicPageAll extends Component { const sidebarModules = [ {type: "Promo"}, {type: "TrendingTopics"}, - {type: "JoinTheConversation"}, {type: "GetTheApp"}, {type: "SupportSefaria"}, ]; diff --git a/static/js/TopicsPage.jsx b/static/js/TopicsPage.jsx index b79ab2c52c..6d61844374 100644 --- a/static/js/TopicsPage.jsx +++ b/static/js/TopicsPage.jsx @@ -50,7 +50,6 @@ const TopicsPage = ({setNavTopic, multiPanel, initialWidth}) => { const sidebarModules = [ multiPanel ? {type: "AboutTopics"} : {type: null}, {type: "TrendingTopics"}, - {type: "JoinTheConversation"}, {type: "GetTheApp"}, {type: "SupportSefaria"}, ]; From b157623792a02a4746ad428d10b9c39ca48247c9 Mon Sep 17 00:00:00 2001 From: YishaiGlasner Date: Tue, 25 Jun 2024 11:33:21 +0300 Subject: [PATCH 144/548] feat(Lexicon): change of building Kovetz Yesodot VaChakirot entry. --- sefaria/model/lexicon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sefaria/model/lexicon.py b/sefaria/model/lexicon.py index 2623437dfe..3b5dd363d6 100644 --- a/sefaria/model/lexicon.py +++ b/sefaria/model/lexicon.py @@ -369,7 +369,7 @@ def as_strings(self, with_headword=True): strings.append(self.headword_string()) for key, value in self.content.items(): if key != 'reference': - strings.append(f'{key}') + strings.append(f'
    {key}') strings += value return ['
    '.join(strings)] From b206cf4b418d75e62e3748c755bb45c0deb92f3f Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Tue, 25 Jun 2024 12:08:24 +0300 Subject: [PATCH 145/548] chore: extract out SearchTopMatter from SearchResultList in order to create SheetsWithRefResultList --- static/js/ConnectionsPanel.jsx | 54 +++++++++----------- static/js/ReaderPanel.jsx | 2 +- static/js/SearchPage.jsx | 1 + static/js/SearchResultList.jsx | 54 +++++++++++--------- static/js/Sheets/SheetsWithRefResultList.jsx | 13 +++++ static/js/SidebarSearch.jsx | 2 +- static/js/sefaria/sefaria.js | 38 +++++++++++--- 7 files changed, 99 insertions(+), 65 deletions(-) create mode 100644 static/js/Sheets/SheetsWithRefResultList.jsx diff --git a/static/js/ConnectionsPanel.jsx b/static/js/ConnectionsPanel.jsx index 5e7a880246..dfea493b47 100644 --- a/static/js/ConnectionsPanel.jsx +++ b/static/js/ConnectionsPanel.jsx @@ -459,38 +459,30 @@ class ConnectionsPanel extends Component { />); } else if (this.props.mode === "Sheets") { - /* - Write a function that takes a list of sheets and generates the available filters. Should create two types of filters, collection filters and topic filters. - How to create a FilterNode: - - For collections, determine lang of title and put it in the right field (either title or heTitle) - docCount is how many times this collection of topic comes up in the list of sheets - aggKey is a unique ID for the collection or topic (slug in both cases) - aggType is either topic or collection (look at code for exact spelling) - children and parent is undefined - selected is 0 - */ - const sheetsWithRefSearchState = Sefaria.sheets.sheetsWithRefSearchState(this.props.srefs); const connectedSheet = this.props.nodeRef ? this.props.nodeRef.split(".")[0] : null; - content = (
    - {this.props.srefs[0].indexOf("Sheet") === -1 ? - - : null - } - {this.props.srefs[0].indexOf("Sheet") === -1 ? - : null - } -
    ); + let sheets = Sefaria.sheets.sheetsTotal(this.props.srefs); + sheets = Sefaria.sheets.sortSheetsByInterfaceLang(sheets); + sheets = Sefaria.sheets.filterSheetsForDisplay(sheets, connectedSheet); + const sheetsWithRefSearchState = Sefaria.sheets.sheetsWithRefSearchState(sheets); + // content = (
    + // {this.props.srefs[0].indexOf("Sheet") === -1 ? + // + // : null + // } + // {this.props.srefs[0].indexOf("Sheet") === -1 ? + // : null + // } + //
    ); } else if (this.props.mode === "Add To Sheet") { let refForSheet, versionsForSheet, selectedWordsForSheet, nodeRef; // add source from connections diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index 7042935f87..12d58800ac 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -9,7 +9,7 @@ import {ContentLanguageContext} from './context'; import $ from './sefaria/sefariaJquery'; import TextColumn from './TextColumn'; import TextsPage from './TextsPage'; -import SearchResultList from "./SearchResultList"; +import {SearchResultList} from "./SearchResultList"; import { ConnectionsPanel, ConnectionsPanelHeader, diff --git a/static/js/SearchPage.jsx b/static/js/SearchPage.jsx index 2d12fb232c..066177c7a7 100644 --- a/static/js/SearchPage.jsx +++ b/static/js/SearchPage.jsx @@ -57,6 +57,7 @@ class SearchPage extends Component { -
    - {Sefaria.multiPanel && !this.props.compare ? - - : - } -
    +
    { queryFullyLoaded || haveResults ? results : null } { this.state.isQueryRunning ? loadingMessage : null } @@ -481,21 +472,36 @@ SearchResultList.propTypes = { registerAvailableFilters: PropTypes.func, }; +const SearchTopMatter = ({type, compare, updateAppliedOptionSort, searchState, openMobileFilters}) => { + return
    + {Sefaria.multiPanel && !compare ? + + : + } +
    +} const SearchSortBox = ({type, updateAppliedOptionSort, sortType}) => { - const [isOpen, setIsOpen] = useState(false); + const [isOpen, setIsOpen] = useState(false); - const handleClick = (newSortType) => { - if (sortType === newSortType) { - return; + const handleClick = (newSortType) => { + if (sortType === newSortType) { + return; + } + updateAppliedOptionSort(type, newSortType); + setIsOpen(false); } - updateAppliedOptionSort(type, newSortType); - setIsOpen(false); - } - const filterTextClasses = classNames({ searchFilterToggle: 1, active: isOpen }); - return ( - {setIsOpen(false)}} isOpen={isOpen}> - { + setIsOpen(false) + }} isOpen={isOpen}> + {setIsOpen(!isOpen)}} enText={"Sort"} heText={"מיון"} @@ -525,4 +531,4 @@ const SearchFilterButton = ({openMobileFilters, nFilters}) => ( ); -export default SearchResultList; +export { SearchResultList, SearchTopMatter }; diff --git a/static/js/Sheets/SheetsWithRefResultList.jsx b/static/js/Sheets/SheetsWithRefResultList.jsx new file mode 100644 index 0000000000..67cbce2f77 --- /dev/null +++ b/static/js/Sheets/SheetsWithRefResultList.jsx @@ -0,0 +1,13 @@ +import {SearchTopMatter} from "../SearchResultList"; +import React from "react"; + +const SheetsWithRefResultList = ({query, type, listItems, compare, searchState, onResultClick, updateAppliedOptionSort, + registerAvailableFilters, updateTotalResults, openMobileFilters}) => { + return
    + +
    + {listItems} +
    +
    +} diff --git a/static/js/SidebarSearch.jsx b/static/js/SidebarSearch.jsx index 00e0509f50..b24737541d 100644 --- a/static/js/SidebarSearch.jsx +++ b/static/js/SidebarSearch.jsx @@ -2,7 +2,7 @@ import { useState, useEffect } from "react"; import {InterfaceText, EnglishText, HebrewText} from "./Misc"; import Sefaria from "./sefaria/sefaria"; import SearchState from './sefaria/searchState'; -import SearchResultList from './SearchResultList'; +import {SearchResultList} from './SearchResultList'; import DictionarySearch from './DictionarySearch'; import classNames from 'classnames'; diff --git a/static/js/sefaria/sefaria.js b/static/js/sefaria/sefaria.js index c249c1d23c..89a06302aa 100644 --- a/static/js/sefaria/sefaria.js +++ b/static/js/sefaria/sefaria.js @@ -2755,11 +2755,30 @@ _media: {}, return Sefaria.topic_toc.filter(x => x.slug == slug).length > 0; }, sheets: { - sheetsWithRefSearchState(sref) { + sortSheetsByInterfaceLang(sheets) { + return sheets.sort((a, b) => { + // First sort by language / interface language + let aHe, bHe; + [aHe, bHe] = [a.title, b.title].map(Sefaria.hebrew.isHebrew); + if (aHe !== bHe) { return (bHe ? -1 : 1) * (Sefaria.interfaceLang === "hebrew" ? -1 : 1); } + // Then by number of views + return b.views - a.views; + }) + }, + filterSheetsForDisplay(sheets, connectedSheet) { + // filters out duplicate sheets by sheet ID number and filters so that we don't show sheets as connections to themselves + return sheets.filter( + (sheet, index, self) => + index === self.findIndex((s) => ( + s.id === sheet.id + ))).filter(sheet => { + return sheet.id !== connectedSheet;}); + }, + sheetsWithRefSearchState(sheets) { /* This function is used to generate the SearchState with its relevant FilterNodes to be used by SheetsWithRef for filtering sheets by topic and collection */ - const sheets = this.sheetsByRef(sref); + let filters = {}; // object where keys are slugs of filters and values are the data for filternodes sheets.forEach(sheet => { sheet?.topics.forEach(topic => { @@ -2942,14 +2961,17 @@ _media: {}, this._userSheetsByRef[ref] = data; return Sefaria._saveItemsByRef(data, this._userSheetsByRef); }, - sheetsTotalCount: function(refs) { - // Returns the total number of private and public sheets on `refs` without double counting my public sheets. - var sheets = Sefaria.sheets.sheetsByRef(refs) || []; + sheetsTotal: function(refs) { + // Returns the combination of private and public sheets on `refs` without double counting my public sheets. + let sheets = Sefaria.sheets.sheetsByRef(refs) || []; if (Sefaria._uid) { - var mySheets = Sefaria.sheets.userSheetsByRef(refs) || []; - sheets = sheets.filter(function(sheet) { return sheet.owner !== Sefaria._uid }).concat(mySheets); + const mySheets = Sefaria.sheets.userSheetsByRef(refs) || []; + sheets = mySheets.concat(sheets.filter(function(sheet) { return sheet.owner !== Sefaria._uid })); } - return sheets.length; + return sheets; + }, + sheetsTotalCount: function(refs) { + return Sefaria.sheets.sheetsTotal(refs).length; }, extractIdFromSheetRef: function (ref) { return typeof ref === "string" ? parseInt(ref.split(" ")[1]) : parseInt(ref[0].split(" ")[1]); From 7b7634f9bbd6619fe8ec400a949a43b4f79dd5b1 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Tue, 25 Jun 2024 17:06:00 +0300 Subject: [PATCH 146/548] chore: extract SheetResult from SearchSheetResult --- static/js/ConnectionsPanel.jsx | 25 +----------- static/js/SearchSheetResult.jsx | 40 ++------------------ static/js/Sheets/SheetResult.jsx | 39 +++++++++++++++++++ static/js/Sheets/SheetsWithRefList.jsx | 23 +++++++++++ static/js/Sheets/SheetsWithRefPage.jsx | 29 ++++++++++++++ static/js/Sheets/SheetsWithRefResultList.jsx | 13 ------- 6 files changed, 96 insertions(+), 73 deletions(-) create mode 100644 static/js/Sheets/SheetResult.jsx create mode 100644 static/js/Sheets/SheetsWithRefList.jsx create mode 100644 static/js/Sheets/SheetsWithRefPage.jsx delete mode 100644 static/js/Sheets/SheetsWithRefResultList.jsx diff --git a/static/js/ConnectionsPanel.jsx b/static/js/ConnectionsPanel.jsx index dfea493b47..bd0f8bdeec 100644 --- a/static/js/ConnectionsPanel.jsx +++ b/static/js/ConnectionsPanel.jsx @@ -42,6 +42,7 @@ import TopicSearch from "./TopicSearch"; import WebPage from './WebPage' import { SignUpModalKind } from './sefaria/signupModalContent'; import SearchState from "./sefaria/searchState"; +import SheetsWithRefPage from "./Sheets/SheetsWithRefPage"; class ConnectionsPanel extends Component { @@ -460,29 +461,7 @@ class ConnectionsPanel extends Component { } else if (this.props.mode === "Sheets") { const connectedSheet = this.props.nodeRef ? this.props.nodeRef.split(".")[0] : null; - let sheets = Sefaria.sheets.sheetsTotal(this.props.srefs); - sheets = Sefaria.sheets.sortSheetsByInterfaceLang(sheets); - sheets = Sefaria.sheets.filterSheetsForDisplay(sheets, connectedSheet); - const sheetsWithRefSearchState = Sefaria.sheets.sheetsWithRefSearchState(sheets); - // content = (
    - // {this.props.srefs[0].indexOf("Sheet") === -1 ? - // - // : null - // } - // {this.props.srefs[0].indexOf("Sheet") === -1 ? - // : null - // } - //
    ); + return ; } else if (this.props.mode === "Add To Sheet") { let refForSheet, versionsForSheet, selectedWordsForSheet, nodeRef; // add source from connections diff --git a/static/js/SearchSheetResult.jsx b/static/js/SearchSheetResult.jsx index 821dc3fd94..53e61f86ed 100644 --- a/static/js/SearchSheetResult.jsx +++ b/static/js/SearchSheetResult.jsx @@ -8,6 +8,7 @@ import { ColorBarBox, InterfaceText, ProfilePic, } from './Misc'; +import SheetResult from "./Sheets/SheetResult"; class SearchSheetResult extends Component { @@ -35,43 +36,8 @@ class SearchSheetResult extends Component { var clean_title = $("" + s.title + "").text(); var href = "/sheets/" + s.sheetId; const snippetMarkup = this.get_snippet_markup(data); - const snippetClasses = classNames({snippet: 1, en: snippetMarkup.lang == "en", he: snippetMarkup.lang == "he"}); - const ownerIsHe = Sefaria.hebrew.isHebrew(s.owner_name); - const titleIsHe = Sefaria.hebrew.isHebrew(clean_title); - const tags = s.tags && s.tags.length ? Sefaria.util.zip(s.tags, s.topic_slugs, s.topics_he) : []; - return ( -
    - -
    - {clean_title} -
    - -
    - -
    -
    -
    -
    - - - {s.owner_name} - - - {tags.map((topic, i) => { - return ( - - - - ); - })} - -
    -
    - ); + return ; } } SearchSheetResult.propTypes = { diff --git a/static/js/Sheets/SheetResult.jsx b/static/js/Sheets/SheetResult.jsx new file mode 100644 index 0000000000..3539647319 --- /dev/null +++ b/static/js/Sheets/SheetResult.jsx @@ -0,0 +1,39 @@ +import Sefaria from "../sefaria/sefaria"; +import classNames from "classnames"; +import {ColorBarBox, ProfilePic} from "../Misc"; +import React from "react"; + +const SheetResult = ({href, handleSheetClick, clean_title, snippetMarkup, profile_url, + handleProfileClick, owner_name, owner_image}) => { + const ownerIsHe = Sefaria.hebrew.isHebrew(owner_name); + const titleIsHe = Sefaria.hebrew.isHebrew(clean_title); + const snippetClasses = classNames({snippet: 1, en: snippetMarkup.lang === "en", he: snippetMarkup.lang === "he"}); + return +} +export default SheetResult; \ No newline at end of file diff --git a/static/js/Sheets/SheetsWithRefList.jsx b/static/js/Sheets/SheetsWithRefList.jsx new file mode 100644 index 0000000000..48bf28d5aa --- /dev/null +++ b/static/js/Sheets/SheetsWithRefList.jsx @@ -0,0 +1,23 @@ +import {SearchTopMatter} from "../SearchResultList"; +import React from "react"; +import SheetResult from "./SheetResult"; + +const SheetsWithRefList = ({type, listItems, query, compare, searchState, onResultClick, updateAppliedOptionSort, openMobileFilters}) => { + return
    + +
    + {listItems.map(item => + // + + )} +
    +
    +} + +export default SheetsWithRefList; diff --git a/static/js/Sheets/SheetsWithRefPage.jsx b/static/js/Sheets/SheetsWithRefPage.jsx new file mode 100644 index 0000000000..8bbef48d72 --- /dev/null +++ b/static/js/Sheets/SheetsWithRefPage.jsx @@ -0,0 +1,29 @@ +import SearchPage from "../SearchPage"; +import SheetsWithRefList from "./SheetsWithRefList"; +import Sefaria from "../sefaria/sefaria"; +const SheetsWithRefPage = ({srefs, connectedSheet}) => { + let sheets = Sefaria.sheets.sheetsTotal(srefs); + sheets = Sefaria.sheets.sortSheetsByInterfaceLang(sheets); + sheets = Sefaria.sheets.filterSheetsForDisplay(sheets, connectedSheet); + const searchState = Sefaria.sheets.sheetsWithRefSearchState(sheets); + const onSearchResultClick = () => {alert('resultClick')} + const updateSearchFilter = () => {alert('filter')} + const updateSearchOptionField = () => {alert("field")} + const updateSearchOptionSort = () => {alert("sort")} + const registerAvailableFilters = () => {alert("register")} + return +} +export default SheetsWithRefPage; \ No newline at end of file diff --git a/static/js/Sheets/SheetsWithRefResultList.jsx b/static/js/Sheets/SheetsWithRefResultList.jsx deleted file mode 100644 index 67cbce2f77..0000000000 --- a/static/js/Sheets/SheetsWithRefResultList.jsx +++ /dev/null @@ -1,13 +0,0 @@ -import {SearchTopMatter} from "../SearchResultList"; -import React from "react"; - -const SheetsWithRefResultList = ({query, type, listItems, compare, searchState, onResultClick, updateAppliedOptionSort, - registerAvailableFilters, updateTotalResults, openMobileFilters}) => { - return
    - -
    - {listItems} -
    -
    -} From 0b8ae828d55a52b103e3c1d03c9d2bd04443572d Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Wed, 26 Jun 2024 11:38:25 +0300 Subject: [PATCH 147/548] chore: fix hero banner css --- static/css/s2.css | 7 +------ static/js/Sheets/SheetsHomePage.jsx | 1 + 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index e36183a453..833508e125 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -10042,21 +10042,16 @@ span.purim-emoji img{ text-shadow: 0 0 10px rgba(0, 0, 0, 0.7); font-family: Source Serif Pro, serif; font-weight: 400; -} -.interface-hebrew .overlayTextOnSheetsHero #title, .interface-hebrew .overlayTextOnSheetsHero #message { - right: 10%; - left: revert; + margin-inline-start: 10%; } .overlayTextOnSheetsHero #title { position: absolute; - left: 10%; font-size: 50px; top: 145px; line-height: 62.65px; } .overlayTextOnSheetsHero #message { position: absolute; - left: 10%; font-family: Source Sans Pro, serif; font-size: 24px; line-height: 18px; diff --git a/static/js/Sheets/SheetsHomePage.jsx b/static/js/Sheets/SheetsHomePage.jsx index 14a88c2b1e..75afb3a02f 100644 --- a/static/js/Sheets/SheetsHomePage.jsx +++ b/static/js/Sheets/SheetsHomePage.jsx @@ -2,6 +2,7 @@ import React from 'react'; import {InterfaceText, ResponsiveNBox} from "../Misc"; import {NavSidebar} from "../NavSidebar"; import Footer from "../Footer"; + const SheetsHeroBanner = ({title, message, videoOptions, posterImg}) => { /* `title` and `message` are shown on top of the video. `posterImg` is shown while video is downloaded, From 101a3a79a9e9773fe030f513725917815a3baca1 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Wed, 26 Jun 2024 13:36:21 +0300 Subject: [PATCH 148/548] chore: searchTopMsg for SearchPage --- static/js/SearchPage.jsx | 3 ++- static/js/Sheets/SheetsWithRefList.jsx | 8 +------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/static/js/SearchPage.jsx b/static/js/SearchPage.jsx index 066177c7a7..c7dc0b8e48 100644 --- a/static/js/SearchPage.jsx +++ b/static/js/SearchPage.jsx @@ -26,6 +26,7 @@ class SearchPage extends Component { const classes = classNames({readerNavMenu: 1, compare: this.props.compare}); const isQueryHebrew = Sefaria.hebrew.isHebrew(this.props.query); const { list: ListComponent } = this.props; + const searchTopMsg = this.props.key === "searchPage" ? "Results for" : "Sheets with"; return (
    {this.props.compare ? @@ -41,7 +42,7 @@ class SearchPage extends Component {

    - Results for  + {searchTopMsg}  { this.props.query } diff --git a/static/js/Sheets/SheetsWithRefList.jsx b/static/js/Sheets/SheetsWithRefList.jsx index 48bf28d5aa..2db173bf87 100644 --- a/static/js/Sheets/SheetsWithRefList.jsx +++ b/static/js/Sheets/SheetsWithRefList.jsx @@ -1,18 +1,12 @@ import {SearchTopMatter} from "../SearchResultList"; import React from "react"; import SheetResult from "./SheetResult"; - -const SheetsWithRefList = ({type, listItems, query, compare, searchState, onResultClick, updateAppliedOptionSort, openMobileFilters}) => { +const SheetsWithRefList = ({type, listItems, compare, searchState, onResultClick, updateAppliedOptionSort, openMobileFilters}) => { return
    {listItems.map(item => - // )} From af0a6b7a53da83f01ffeae74c2325fe69b40eee5 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Wed, 26 Jun 2024 14:01:07 +0300 Subject: [PATCH 149/548] chore: remove GenericComponents --- static/js/Sheets/GenericComponents.jsx | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 static/js/Sheets/GenericComponents.jsx diff --git a/static/js/Sheets/GenericComponents.jsx b/static/js/Sheets/GenericComponents.jsx deleted file mode 100644 index 6c7b12f305..0000000000 --- a/static/js/Sheets/GenericComponents.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import {InterfaceText} from "../Misc"; -import classNames from "classnames"; -import React from "react"; -const Button = ({img, href, children, classes={}}) => { - classes = {button: 1, ...classes}; - return - {img} - {children} - -} - -const Card = ({cardTitle, cardTitleHref, oncardTitleClick, cardText}) => { - return
    - - - -
    - -
    -
    -} - -export { Button, Card } From 238f7c7a9be72d94fd8921e73c50d2aa83b6cae8 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Wed, 26 Jun 2024 15:54:52 +0300 Subject: [PATCH 150/548] feat(Sheets Search): modify SearchSheetResult to handle both search and "sheets with" case --- static/css/s2.css | 27 ++++++++++- static/js/SearchResultList.jsx | 3 +- static/js/SearchSheetResult.jsx | 79 ++++++++++++++++++--------------- 3 files changed, 70 insertions(+), 39 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 42c41ea739..397de9c8ad 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -4574,6 +4574,20 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus font-size: 24px; margin-bottom: 15px; } +.sheetResult .result-title { + --english-font: var(--english-sans-serif-font-family); + font-size: 16px; + font-weight: 600; + line-height: 18.75px; + color: #000000; +} +.sheetResult .snippet.en { + color: #666666; + --english-font: var(--english-sans-serif-font-family); + font-size: 14px; + font-weight: 400; + line-height: 18px; +} .searchContent .result-title .int-he { font-family: "Taamey Frank", "adobe-garamond-pro", "Crimson Text", Georgia, "Times New Roman", serif; font-size: 22px; @@ -4593,7 +4607,18 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus font-size: 13px; } .searchContent .sheetResult .ownerName { - color: #000; + color: var(--midrash-green); + margin-inline-start: 10px; +} +.searchContent .sheetResult .date { + color: #999999; + --english-font: var(--english-sans-serif-font-family); + font-size: 14px; + font-weight: 400; + line-height: 18px; + margin-inline-start: 10px; +} +.searchContent .sheetResult .bullet { margin-inline-start: 10px; } .searchContent .sheetResult .sheetData .tagsViews a:not(:last-of-type):after{ diff --git a/static/js/SearchResultList.jsx b/static/js/SearchResultList.jsx index d2b6f65aaa..4cbe62aa0b 100644 --- a/static/js/SearchResultList.jsx +++ b/static/js/SearchResultList.jsx @@ -457,7 +457,8 @@ class SearchResultList extends Component { } else if (tab == "sheet") { results = this.state.hits.sheet.map(result => diff --git a/static/js/SearchSheetResult.jsx b/static/js/SearchSheetResult.jsx index 821dc3fd94..b5061b2302 100644 --- a/static/js/SearchSheetResult.jsx +++ b/static/js/SearchSheetResult.jsx @@ -12,7 +12,7 @@ import { class SearchSheetResult extends Component { handleSheetClick(e) { - var s = this.props.data._source; + const s = this.props.metadata; if (this.props.onResultClick) { e.preventDefault() this.props.onResultClick("Sheet " + s.sheetId); @@ -20,64 +20,69 @@ class SearchSheetResult extends Component { Sefaria.track.event("Search", "Search Result Sheet Click", `${this.props.query} - ${s.sheetId}`); } handleProfileClick(e) { - const s = this.props.data._source; + const s = this.props.metadata; Sefaria.track.event("Search", "Search Result Sheet Owner Click", `${this.props.query} - ${s.sheetId} - ${s.owner_name}`); } - get_snippet_markup(data) { - let snippet = data.highlight.content.join("..."); // data.highlight ? data.highlight.content.join("...") : s.content; - snippet = snippet.replace(/^[ .,;:!-)\]]+/, ""); + get_snippet_markup() { + const snippet = this.props.snippet.replace(/^[ .,;:!-)\]]+/, ""); const lang = Sefaria.hebrew.isHebrew(snippet) ? "he" : "en"; return { markup: {__html: snippet}, lang }; } + formatDate(dateString) { + const date = new Date(dateString); + // Define options for Intl.DateTimeFormat + const options = { year: 'numeric', month: 'long', day: 'numeric' }; + // Use Intl.DateTimeFormat to format the date + return new Intl.DateTimeFormat('en-US', options).format(date); + } render() { - const data = this.props.data; - const s = data._source; + const s = this.props.metadata; var clean_title = $("" + s.title + "").text(); var href = "/sheets/" + s.sheetId; - const snippetMarkup = this.get_snippet_markup(data); - const snippetClasses = classNames({snippet: 1, en: snippetMarkup.lang == "en", he: snippetMarkup.lang == "he"}); + const snippetMarkup = this.get_snippet_markup(); + const snippetClasses = classNames({snippet: 1, en: snippetMarkup.lang === "en", he: snippetMarkup.lang === "he"}); const ownerIsHe = Sefaria.hebrew.isHebrew(s.owner_name); const titleIsHe = Sefaria.hebrew.isHebrew(clean_title); - const tags = s.tags && s.tags.length ? Sefaria.util.zip(s.tags, s.topic_slugs, s.topics_he) : []; + const date = this.formatDate(this.props.metadata.dateCreated); return (
    +
    {clean_title}
    - -
    - -
    -
    +
    + +
    -
    - - - {s.owner_name} - - - {tags.map((topic, i) => { - return ( - - - - ); - })} - -
    ); } } + SearchSheetResult.propTypes = { - query: PropTypes.string, - data: PropTypes.object, - onResultClick: PropTypes.func + query: PropTypes.string, + metadata: PropTypes.object, + snippet: PropTypes.string, + onResultClick: PropTypes.func }; From f62955f9e11ec419f8a9cb7ece44d8ee60d17319 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Wed, 26 Jun 2024 15:57:35 +0300 Subject: [PATCH 151/548] chore: css adjustment for sheet search --- static/css/s2.css | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 397de9c8ad..bf9907b998 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -4609,6 +4609,8 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus .searchContent .sheetResult .ownerName { color: var(--midrash-green); margin-inline-start: 10px; + --english-font: var(--english-sans-serif-font-family); + font-size: 14px; } .searchContent .sheetResult .date { color: #999999; @@ -4616,10 +4618,10 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus font-size: 14px; font-weight: 400; line-height: 18px; - margin-inline-start: 10px; + margin-inline-start: 5px; } .searchContent .sheetResult .bullet { - margin-inline-start: 10px; + margin-inline-start: 5px; } .searchContent .sheetResult .sheetData .tagsViews a:not(:last-of-type):after{ content: ","; From 922badd1ff67f527e7bf847cdd7cadd6ece9b352 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Wed, 26 Jun 2024 16:12:14 +0300 Subject: [PATCH 152/548] chore: remove SheetResult.jsx --- static/js/SearchSheetResult.jsx | 1 - static/js/Sheets/SheetResult.jsx | 39 -------------------------- static/js/Sheets/SheetsWithRefList.jsx | 22 +++++++++++---- 3 files changed, 17 insertions(+), 45 deletions(-) delete mode 100644 static/js/Sheets/SheetResult.jsx diff --git a/static/js/SearchSheetResult.jsx b/static/js/SearchSheetResult.jsx index 8df200e9d5..b5061b2302 100644 --- a/static/js/SearchSheetResult.jsx +++ b/static/js/SearchSheetResult.jsx @@ -8,7 +8,6 @@ import { ColorBarBox, InterfaceText, ProfilePic, } from './Misc'; -import SheetResult from "./Sheets/SheetResult"; class SearchSheetResult extends Component { diff --git a/static/js/Sheets/SheetResult.jsx b/static/js/Sheets/SheetResult.jsx deleted file mode 100644 index 3539647319..0000000000 --- a/static/js/Sheets/SheetResult.jsx +++ /dev/null @@ -1,39 +0,0 @@ -import Sefaria from "../sefaria/sefaria"; -import classNames from "classnames"; -import {ColorBarBox, ProfilePic} from "../Misc"; -import React from "react"; - -const SheetResult = ({href, handleSheetClick, clean_title, snippetMarkup, profile_url, - handleProfileClick, owner_name, owner_image}) => { - const ownerIsHe = Sefaria.hebrew.isHebrew(owner_name); - const titleIsHe = Sefaria.hebrew.isHebrew(clean_title); - const snippetClasses = classNames({snippet: 1, en: snippetMarkup.lang === "en", he: snippetMarkup.lang === "he"}); - return -} -export default SheetResult; \ No newline at end of file diff --git a/static/js/Sheets/SheetsWithRefList.jsx b/static/js/Sheets/SheetsWithRefList.jsx index 2db173bf87..063a2af6d2 100644 --- a/static/js/Sheets/SheetsWithRefList.jsx +++ b/static/js/Sheets/SheetsWithRefList.jsx @@ -1,14 +1,26 @@ import {SearchTopMatter} from "../SearchResultList"; import React from "react"; -import SheetResult from "./SheetResult"; -const SheetsWithRefList = ({type, listItems, compare, searchState, onResultClick, updateAppliedOptionSort, openMobileFilters}) => { +import SearchSheetResult from "../SearchSheetResult"; +const SheetsWithRefList = ({type, listItems, query, compare, searchState, onResultClick, updateAppliedOptionSort, openMobileFilters}) => { return
    - {listItems.map(item => - + {listItems.map(item => { + const metadata = { + sheetId: item.id, + title: item.title, + owner_name: item.ownerName, + owner_image: item.ownerImageUrl, + profile_url: item.ownerProfileUrl, + }; + return + } )}
    From c94ce253f0727beaf717ff108b8f1134876430f0 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 27 Jun 2024 09:35:15 +0300 Subject: [PATCH 153/548] feat(Sheets API): for /api/sheets/ref added get_collections_with_sheets to return collections --- sefaria/sheets.py | 21 +++++++++++++++++++-- sourcesheets/views.py | 2 +- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/sefaria/sheets.py b/sefaria/sheets.py index 721a1a199a..62106ff727 100755 --- a/sefaria/sheets.py +++ b/sefaria/sheets.py @@ -784,13 +784,24 @@ def get_top_sheets(limit=3): query = {"status": "public", "views": {"$gte": 100}} return sheet_list(query=query, limit=limit) +def get_collections_with_sheets(sheet_ids): + """ + Return every public collection that has a sheet in `sheet_ids` + """ + collections = CollectionSet({'sheets': {'$in': sheet_ids }, 'listed': True}, hint="sheets_listed") + sheet_id_to_collections = defaultdict(list) + for collection in collections: + for sheet_id in collection.sheets: + sheet_id_to_collections[sheet_id].append({'name': collection.name, 'slug': collection.slug}) + return sheet_id_to_collections -def get_sheets_for_ref(tref, uid=None, in_collection=None): +def get_sheets_for_ref(tref, uid=None, in_collection=None, include_collections=None): """ Returns a list of sheets that include ref, formating as need for the Client Sidebar. If `uid` is present return user sheets, otherwise return public sheets. If `in_collection` (list of slugs) is present, only return sheets in one of the listed collections. + If `include_collections` is present, given the list of sheets that include tref, return all public collections that have at least one of those sheets """ oref = model.Ref(tref) # perform initial search with context to catch ranges that include a segment ref @@ -827,6 +838,10 @@ def get_sheets_for_ref(tref, uid=None, in_collection=None): user_profiles[profile]["profile_pic_url_small"] = "" results = [] + sheet_id_to_collection = {} + if include_collections: + sheet_id_to_collection = get_collections_with_sheets([s['id'] for s in sheets]) + for sheet in sheets: anchor_ref_list, anchor_ref_expanded_list = oref.get_all_anchor_refs(segment_refs, sheet.get("includedRefs", []), sheet.get("expandedRefs", [])) ownerData = user_profiles.get(sheet["owner"], {'first_name': 'Ploni', 'last_name': 'Almoni', 'email': 'test@sefaria.org', 'slug': 'Ploni-Almoni', 'id': None, 'profile_pic_url_small': ''}) @@ -847,7 +862,6 @@ def get_sheets_for_ref(tref, uid=None, in_collection=None): for anchor_ref, anchor_ref_expanded in zip(anchor_ref_list, anchor_ref_expanded_list): sheet_data = { "owner": sheet["owner"], - "collections": [{'name': c.name, 'slug': c.slug} for c in CollectionSet({"sheets": sheet['id']}).array()], "_id": str(sheet["_id"]), "id": str(sheet["id"]), "public": sheet["status"] == "public", @@ -874,7 +888,10 @@ def get_sheets_for_ref(tref, uid=None, in_collection=None): "is_featured": sheet.get("is_featured", False), "category": "Sheets", # ditto "type": "sheet", # ditto + "dateCreated": sheet["dateCreated"] } + if include_collections: + sheet_data["collections"] = sheet_id_to_collection[sheet["id"]] results.append(sheet_data) return results diff --git a/sourcesheets/views.py b/sourcesheets/views.py index 1340dc9111..65cce41136 100644 --- a/sourcesheets/views.py +++ b/sourcesheets/views.py @@ -1020,7 +1020,7 @@ def sheets_by_ref_api(request, ref): """ API to get public sheets by ref. """ - return jsonResponse(get_sheets_for_ref(ref)) + return jsonResponse(get_sheets_for_ref(ref, include_collections=True)) def get_aliyot_by_parasha_api(request, parasha): From 0a932a3dddd962d6e99191853e4f7d5f4f8c64fb Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 27 Jun 2024 09:38:26 +0300 Subject: [PATCH 154/548] chore: remove GenericComponents --- static/js/Sheets/GenericComponents.jsx | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 static/js/Sheets/GenericComponents.jsx diff --git a/static/js/Sheets/GenericComponents.jsx b/static/js/Sheets/GenericComponents.jsx deleted file mode 100644 index 6c7b12f305..0000000000 --- a/static/js/Sheets/GenericComponents.jsx +++ /dev/null @@ -1,23 +0,0 @@ -import {InterfaceText} from "../Misc"; -import classNames from "classnames"; -import React from "react"; -const Button = ({img, href, children, classes={}}) => { - classes = {button: 1, ...classes}; - return - {img} - {children} - -} - -const Card = ({cardTitle, cardTitleHref, oncardTitleClick, cardText}) => { - return
    - - - -
    - -
    -
    -} - -export { Button, Card } From b007ab50caff0bf7ae0f5e6ff2c8fb2b7c6d09f3 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 27 Jun 2024 09:42:32 +0300 Subject: [PATCH 155/548] chore: only return dateCreated if include_collections is True --- sefaria/sheets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sefaria/sheets.py b/sefaria/sheets.py index 62106ff727..f68afd20ea 100755 --- a/sefaria/sheets.py +++ b/sefaria/sheets.py @@ -888,10 +888,10 @@ def get_sheets_for_ref(tref, uid=None, in_collection=None, include_collections=N "is_featured": sheet.get("is_featured", False), "category": "Sheets", # ditto "type": "sheet", # ditto - "dateCreated": sheet["dateCreated"] } if include_collections: sheet_data["collections"] = sheet_id_to_collection[sheet["id"]] + sheet_data["dateCreated"] = sheet["dateCreated"] results.append(sheet_data) return results From fca50f1237820a886b64bc3a1997a939e50c9ef5 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 27 Jun 2024 12:04:56 +0300 Subject: [PATCH 156/548] chore: use /api/sheets/ref instead of related API --- static/js/Sheets/SheetsWithRefList.jsx | 3 ++- static/js/Sheets/SheetsWithRefPage.jsx | 32 ++++++++++++++++++-------- static/js/sefaria/sefaria.js | 16 ++++++++----- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/static/js/Sheets/SheetsWithRefList.jsx b/static/js/Sheets/SheetsWithRefList.jsx index 063a2af6d2..bacc27fc47 100644 --- a/static/js/Sheets/SheetsWithRefList.jsx +++ b/static/js/Sheets/SheetsWithRefList.jsx @@ -13,10 +13,11 @@ const SheetsWithRefList = ({type, listItems, query, compare, searchState, onResu owner_name: item.ownerName, owner_image: item.ownerImageUrl, profile_url: item.ownerProfileUrl, + dateCreated: item.dateCreated }; return diff --git a/static/js/Sheets/SheetsWithRefPage.jsx b/static/js/Sheets/SheetsWithRefPage.jsx index 8bbef48d72..6d49361b72 100644 --- a/static/js/Sheets/SheetsWithRefPage.jsx +++ b/static/js/Sheets/SheetsWithRefPage.jsx @@ -1,16 +1,30 @@ import SearchPage from "../SearchPage"; import SheetsWithRefList from "./SheetsWithRefList"; import Sefaria from "../sefaria/sefaria"; +import {useEffect, useState} from "react"; const SheetsWithRefPage = ({srefs, connectedSheet}) => { - let sheets = Sefaria.sheets.sheetsTotal(srefs); - sheets = Sefaria.sheets.sortSheetsByInterfaceLang(sheets); - sheets = Sefaria.sheets.filterSheetsForDisplay(sheets, connectedSheet); - const searchState = Sefaria.sheets.sheetsWithRefSearchState(sheets); - const onSearchResultClick = () => {alert('resultClick')} - const updateSearchFilter = () => {alert('filter')} - const updateSearchOptionField = () => {alert("field")} - const updateSearchOptionSort = () => {alert("sort")} - const registerAvailableFilters = () => {alert("register")} + const [sheets, setSheets] = useState([]); + const [searchState, setSearchState] = useState(null); + const [loading, setLoading] = useState(true); + useEffect(() => { + delete Sefaria.sheets._sheetsByRef[srefs]; + Sefaria.sheets.getSheetsByRef(srefs).then(sheets => { + sheets = Sefaria.sheets.sortSheetsByInterfaceLang(sheets); + sheets = Sefaria.sheets.filterSheetsForDisplay(sheets, connectedSheet); + const searchState = Sefaria.sheets.sheetsWithRefSearchState(sheets); + setSheets(sheets); + setSearchState(searchState); + setLoading(false); + }) + }, []); + const onSearchResultClick = (props) => {console.log(props)} + const updateSearchFilter = (props) => {console.log(props)} + const updateSearchOptionField = (props) => {console.log(props)} + const updateSearchOptionSort = (props) => {console.log(props)} + const registerAvailableFilters = (props) => {console.log(props)} + if (loading) { + return
    Loading...
    ; + } return x.slug == slug).length > 0; }, sheets: { + getSheetsByRef: function(srefs) { + return Sefaria._cachedApiPromise({ + url: `${Sefaria.apiHost}/api/sheets/ref/${srefs}`, + key: srefs, + store: Sefaria.sheets._sheetsByRef + }); + }, sortSheetsByInterfaceLang(sheets) { return sheets.sort((a, b) => { // First sort by language / interface language @@ -2986,17 +2993,14 @@ _media: {}, this._userSheetsByRef[ref] = data; return Sefaria._saveItemsByRef(data, this._userSheetsByRef); }, - sheetsTotal: function(refs) { - // Returns the combination of private and public sheets on `refs` without double counting my public sheets. + sheetsTotalCount: function(refs) { + // Returns the total number of private and public sheets on `refs` without double counting my public sheets. let sheets = Sefaria.sheets.sheetsByRef(refs) || []; if (Sefaria._uid) { const mySheets = Sefaria.sheets.userSheetsByRef(refs) || []; sheets = mySheets.concat(sheets.filter(function(sheet) { return sheet.owner !== Sefaria._uid })); } - return sheets; - }, - sheetsTotalCount: function(refs) { - return Sefaria.sheets.sheetsTotal(refs).length; + return sheets.length; }, extractIdFromSheetRef: function (ref) { return typeof ref === "string" ? parseInt(ref.split(" ")[1]) : parseInt(ref[0].split(" ")[1]); From 2b97f2e21158a177be502c837ccca9f981501797 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 27 Jun 2024 13:09:34 +0300 Subject: [PATCH 157/548] chore: update SearchTotal from SheetsWithRefList --- static/js/Sheets/SheetsWithRefList.jsx | 8 ++++++-- static/js/Sheets/SheetsWithRefPage.jsx | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/static/js/Sheets/SheetsWithRefList.jsx b/static/js/Sheets/SheetsWithRefList.jsx index bacc27fc47..eaa8660888 100644 --- a/static/js/Sheets/SheetsWithRefList.jsx +++ b/static/js/Sheets/SheetsWithRefList.jsx @@ -1,7 +1,11 @@ import {SearchTopMatter} from "../SearchResultList"; -import React from "react"; +import React, {useState, useEffect} from "react"; import SearchSheetResult from "../SearchSheetResult"; -const SheetsWithRefList = ({type, listItems, query, compare, searchState, onResultClick, updateAppliedOptionSort, openMobileFilters}) => { +import {SearchTotal} from "../sefaria/searchTotal"; +const SheetsWithRefList = ({type, listItems, query, compare, updateTotalResults, searchState, onResultClick, updateAppliedOptionSort, openMobileFilters}) => { + useEffect(() => { + updateTotalResults(new SearchTotal(listItems)); + }, []); return
    diff --git a/static/js/Sheets/SheetsWithRefPage.jsx b/static/js/Sheets/SheetsWithRefPage.jsx index 6d49361b72..797eb1014a 100644 --- a/static/js/Sheets/SheetsWithRefPage.jsx +++ b/static/js/Sheets/SheetsWithRefPage.jsx @@ -17,11 +17,21 @@ const SheetsWithRefPage = ({srefs, connectedSheet}) => { setLoading(false); }) }, []); - const onSearchResultClick = (props) => {console.log(props)} - const updateSearchFilter = (props) => {console.log(props)} - const updateSearchOptionField = (props) => {console.log(props)} - const updateSearchOptionSort = (props) => {console.log(props)} - const registerAvailableFilters = (props) => {console.log(props)} + const onSearchResultClick = (...args) => { + args.forEach(arg => console.log(arg)); + } + const updateSearchFilter = (...args) => { + args.forEach(arg => console.log(arg)); + } + const updateSearchOptionField = (...args) => { + args.forEach(arg => console.log(arg)); + } + const updateSearchOptionSort = (...args) => { + args.forEach(arg => console.log(arg)); + } + const registerAvailableFilters = (...args) => { + args.forEach(arg => console.log(arg)); + } if (loading) { return
    Loading...
    ; } From 91e4c50612e9e92bc0b21c154c824b1aa545b341 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 27 Jun 2024 13:17:19 +0300 Subject: [PATCH 158/548] chore: removed nested a tag --- static/js/SearchSheetResult.jsx | 40 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/static/js/SearchSheetResult.jsx b/static/js/SearchSheetResult.jsx index b5061b2302..3de7ed4f45 100644 --- a/static/js/SearchSheetResult.jsx +++ b/static/js/SearchSheetResult.jsx @@ -30,9 +30,7 @@ class SearchSheetResult extends Component { } formatDate(dateString) { const date = new Date(dateString); - // Define options for Intl.DateTimeFormat const options = { year: 'numeric', month: 'long', day: 'numeric' }; - // Use Intl.DateTimeFormat to format the date return new Intl.DateTimeFormat('en-US', options).format(date); } render() { @@ -43,28 +41,28 @@ class SearchSheetResult extends Component { const snippetClasses = classNames({snippet: 1, en: snippetMarkup.lang === "en", he: snippetMarkup.lang === "he"}); const ownerIsHe = Sefaria.hebrew.isHebrew(s.owner_name); const titleIsHe = Sefaria.hebrew.isHebrew(clean_title); - const date = this.formatDate(this.props.metadata.dateCreated); + const dateString = this.formatDate(this.props.metadata.dateCreated); return (
    - - +
    {clean_title}
    From 76b309b2fa430c0baf2172854e1662268fa8b795 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 27 Jun 2024 13:27:47 +0300 Subject: [PATCH 159/548] chore: /api/sheets/ref takes include_collections as param --- sourcesheets/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sourcesheets/views.py b/sourcesheets/views.py index 65cce41136..194cb5ecf4 100644 --- a/sourcesheets/views.py +++ b/sourcesheets/views.py @@ -1020,7 +1020,8 @@ def sheets_by_ref_api(request, ref): """ API to get public sheets by ref. """ - return jsonResponse(get_sheets_for_ref(ref, include_collections=True)) + include_collections = bool(int(request.GET.get("include_collections", 0))) + return jsonResponse(get_sheets_for_ref(ref, include_collections=include_collections)) def get_aliyot_by_parasha_api(request, parasha): From c68fe758bffb0beaf01ab440e517b25b7488e6af Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 27 Jun 2024 14:41:52 +0300 Subject: [PATCH 160/548] chore: make searchTopMsg a prop Results for vs Sheets with --- static/js/ReaderPanel.jsx | 1 + static/js/SearchPage.jsx | 3 +-- static/js/Sheets/SheetsWithRefList.jsx | 2 +- static/js/Sheets/SheetsWithRefPage.jsx | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index 12d58800ac..f3be5c9df6 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -886,6 +886,7 @@ class ReaderPanel extends Component { } else if (this.state.menuOpen === "search" && this.state.searchQuery) { menu = ( {this.props.compare ? @@ -42,7 +41,7 @@ class SearchPage extends Component {

    - {searchTopMsg}  + {this.props.searchTopMsg}  { this.props.query } diff --git a/static/js/Sheets/SheetsWithRefList.jsx b/static/js/Sheets/SheetsWithRefList.jsx index eaa8660888..918bc360a9 100644 --- a/static/js/Sheets/SheetsWithRefList.jsx +++ b/static/js/Sheets/SheetsWithRefList.jsx @@ -4,7 +4,7 @@ import SearchSheetResult from "../SearchSheetResult"; import {SearchTotal} from "../sefaria/searchTotal"; const SheetsWithRefList = ({type, listItems, query, compare, updateTotalResults, searchState, onResultClick, updateAppliedOptionSort, openMobileFilters}) => { useEffect(() => { - updateTotalResults(new SearchTotal(listItems)); + updateTotalResults(new SearchTotal({value: listItems.length})); }, []); return
    { } return Date: Thu, 27 Jun 2024 15:09:16 +0300 Subject: [PATCH 161/548] chore: create sheetsWithRef route --- sefaria/urls.py | 3 +++ sourcesheets/views.py | 3 ++- static/js/ConnectionsPanel.jsx | 10 +++------- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sefaria/urls.py b/sefaria/urls.py index b782760b87..c3ec49ccaf 100644 --- a/sefaria/urls.py +++ b/sefaria/urls.py @@ -6,6 +6,8 @@ from django.contrib import admin from django.http import HttpResponseRedirect import django.contrib.auth.views as django_auth_views + +import sourcesheets from sefaria.forms import SefariaPasswordResetForm, SefariaSetPasswordForm, SefariaLoginForm from sefaria.settings import DOWN_FOR_MAINTENANCE, STATIC_URL @@ -32,6 +34,7 @@ url(r'^texts/recent/?$', reader_views.old_recent_redirect), url(r'^texts/(?P.+)?$', reader_views.texts_category_list), url(r'^search/?$', reader_views.search), + url(r'sheetsWithRef$', sourcesheets.views.sheets_with_ref), url(r'^search-autocomplete-redirecter/?$', reader_views.search_autocomplete_redirecter), url(r'^calendars/?$', reader_views.calendars), url(r'^collections/?$', reader_views.public_collections), diff --git a/sourcesheets/views.py b/sourcesheets/views.py index 65cce41136..14ec082015 100644 --- a/sourcesheets/views.py +++ b/sourcesheets/views.py @@ -1022,7 +1022,8 @@ def sheets_by_ref_api(request, ref): """ return jsonResponse(get_sheets_for_ref(ref, include_collections=True)) - +def sheets_with_ref(request, ref): + pass def get_aliyot_by_parasha_api(request, parasha): response = {"ref":[]}; diff --git a/static/js/ConnectionsPanel.jsx b/static/js/ConnectionsPanel.jsx index bd0f8bdeec..7559fc7c4b 100644 --- a/static/js/ConnectionsPanel.jsx +++ b/static/js/ConnectionsPanel.jsx @@ -41,8 +41,6 @@ import { event } from 'jquery'; import TopicSearch from "./TopicSearch"; import WebPage from './WebPage' import { SignUpModalKind } from './sefaria/signupModalContent'; -import SearchState from "./sefaria/searchState"; -import SheetsWithRefPage from "./Sheets/SheetsWithRefPage"; class ConnectionsPanel extends Component { @@ -387,6 +385,7 @@ class ConnectionsPanel extends Component { null } @@ -459,9 +458,6 @@ class ConnectionsPanel extends Component { filterRef={this.props.filterRef} />); - } else if (this.props.mode === "Sheets") { - const connectedSheet = this.props.nodeRef ? this.props.nodeRef.split(".")[0] : null; - return ; } else if (this.props.mode === "Add To Sheet") { let refForSheet, versionsForSheet, selectedWordsForSheet, nodeRef; // add source from connections @@ -735,11 +731,11 @@ ConnectionsPanel.propTypes = { }; -const ResourcesList = ({ masterPanelMode, setConnectionsMode, counts }) => { +const ResourcesList = ({ srefs, setConnectionsMode, counts }) => { // A list of Resources in addition to connection return (
    - setConnectionsMode("Sheets")} /> + window.open(`${Sefaria.apiHost}/sheetsWithRef?ref=${srefs}`)} /> setConnectionsMode("WebPages")} /> setConnectionsMode("Topics")} alwaysShow={Sefaria.is_moderator} /> setConnectionsMode("manuscripts")} /> From 6bf97fec9ba0df03776bedd1ce3a093ff1a774ef Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Thu, 27 Jun 2024 15:31:25 +0300 Subject: [PATCH 162/548] feat(Sheets): sheetsWithRef route works --- sefaria/urls.py | 2 +- sourcesheets/views.py | 7 +++++-- static/js/ConnectionsPanel.jsx | 2 +- static/js/ReaderPanel.jsx | 35 ++++++++++++++++++---------------- static/js/sefaria/sefaria.js | 1 + 5 files changed, 27 insertions(+), 20 deletions(-) diff --git a/sefaria/urls.py b/sefaria/urls.py index c3ec49ccaf..6f7d9ea9dd 100644 --- a/sefaria/urls.py +++ b/sefaria/urls.py @@ -34,7 +34,7 @@ url(r'^texts/recent/?$', reader_views.old_recent_redirect), url(r'^texts/(?P.+)?$', reader_views.texts_category_list), url(r'^search/?$', reader_views.search), - url(r'sheetsWithRef$', sourcesheets.views.sheets_with_ref), + url(r'sheetsWithRef/(?P.+)$', sourcesheets.views.sheets_with_ref), url(r'^search-autocomplete-redirecter/?$', reader_views.search_autocomplete_redirecter), url(r'^calendars/?$', reader_views.calendars), url(r'^collections/?$', reader_views.public_collections), diff --git a/sourcesheets/views.py b/sourcesheets/views.py index 14ec082015..cb415b1c93 100644 --- a/sourcesheets/views.py +++ b/sourcesheets/views.py @@ -17,6 +17,7 @@ from django.views.decorators.csrf import ensure_csrf_cookie, csrf_exempt, csrf_protect from django.contrib.auth.decorators import login_required +from django.utils.translation import ugettext as _ # noinspection PyUnresolvedReferences from django.contrib.auth.models import User @@ -45,6 +46,7 @@ from sefaria.gauth.decorators import gauth_required +from reader.views import menu_page def annotate_user_links(sources): """ @@ -1022,8 +1024,9 @@ def sheets_by_ref_api(request, ref): """ return jsonResponse(get_sheets_for_ref(ref, include_collections=True)) -def sheets_with_ref(request, ref): - pass +def sheets_with_ref(request, tref): + title = _(f"Sheets with {tref} on Sefaria") + return menu_page(request, page="sheetsWithRef", title=title, props={"sheetsWithRef": tref}) def get_aliyot_by_parasha_api(request, parasha): response = {"ref":[]}; diff --git a/static/js/ConnectionsPanel.jsx b/static/js/ConnectionsPanel.jsx index 7559fc7c4b..ba3304a788 100644 --- a/static/js/ConnectionsPanel.jsx +++ b/static/js/ConnectionsPanel.jsx @@ -735,7 +735,7 @@ const ResourcesList = ({ srefs, setConnectionsMode, counts }) => { // A list of Resources in addition to connection return (
    - window.open(`${Sefaria.apiHost}/sheetsWithRef?ref=${srefs}`)} /> + window.open(`${Sefaria.apiHost}/sheetsWithRef/${srefs}`)} /> setConnectionsMode("WebPages")} /> setConnectionsMode("Topics")} alwaysShow={Sefaria.is_moderator} /> setConnectionsMode("manuscripts")} /> diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index f3be5c9df6..1d0458e4d7 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -42,6 +42,7 @@ import { ToggleSet, InterfaceText, EnglishText, HebrewText, SignUpModal, } from './Misc'; import {ContentText} from "./ContentText"; +import SheetsWithRefPage from "./Sheets/SheetsWithRefPage"; class ReaderPanel extends Component { @@ -781,25 +782,27 @@ class ReaderPanel extends Component { if (this.state.menuOpen === "navigation") { - const openNav = this.state.compare ? this.props.openComparePanel : this.openMenu.bind(null, "navigation"); + const openNav = this.state.compare ? this.props.openComparePanel : this.openMenu.bind(null, "navigation"); const openTextTOC = this.state.compare ? this.openCompareTextTOC : null; menu = (); - + key={this.state.navigationCategories ? this.state.navigationCategories.join("-") : this.state.navigationTopicCategory ? this.state.navigationTopicCategory : "navHome"} + compare={this.state.compare} + multiPanel={this.props.multiPanel} + categories={this.state.navigationCategories || []} + settings={this.state.settings} + setCategories={this.setNavigationCategories} + openTextTOC={openTextTOC} + setOption={this.setOption} + toggleLanguage={this.toggleLanguage} + onCompareBack={this.props.closePanel} + openSearch={this.openSearch} + openDisplaySettings={this.openDisplaySettings} + initialWidth={this.state.width} + toggleSignUpModal={this.props.toggleSignUpModal}/>); + } else if (this.state.menuOpen === "sheetsWithRef") { + const connectedSheet = this.props.nodeRef ? this.props.nodeRef.split(".")[0] : null; + menu = (); } else if (this.state.menuOpen === "sheet meta") { menu = ( Date: Sun, 30 Jun 2024 13:15:53 +0300 Subject: [PATCH 163/548] chore(Products Page): Revert to using filter to recolor icons --- static/css/s2.css | 20 +++++++------------- static/js/StaticPages.jsx | 4 ++-- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index d21cef315b..3c643a5236 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12994,10 +12994,11 @@ span.ref-link-color-3 {color: blue} } #productsPageContent { - margin-top: 225px; - margin-inline-start: 68px; + margin-inline-start: 70px; + margin-top: 165px; } + .productsInner { display: flex; align-items: right; @@ -13065,18 +13066,16 @@ span.ref-link-color-3 {color: blue} } -.productsHeader .cta .productsCTAIcon::before { - -webkit-mask: url("--image-url") no-repeat; - mask: url("--image-url") no-repeat; - background-color: var(--commentary-blue); -} - .productsHeader .cta .productsCTAIcon { height: 16px; top: 646px; left: 610px; margin: 0 5px; vertical-align: middle; + /** This uses the filter to recolor SVGs in a single line to commentary blue. + To determine the appropriate parameters, see a filter color picker such as https://angel-rs.github.io/css-color-filter-generator/ */ + filter: brightness(0) saturate(100%) invert(52%) sepia(17%) saturate(6763%) hue-rotate(200deg) brightness(78%) contrast(77%); + } .productsTitle { @@ -13170,11 +13169,6 @@ span.ref-link-color-3 {color: blue} margin-right: 5%; } - #productsPageContent { - margin-inline-start: 10px; - margin-top: 100px; - } -} @-webkit-keyframes load5 { 0%,100%{box-shadow:0 -2.6em 0 0 #ffffff,1.8em -1.8em 0 0 rgba(0,0,0,0.2),2.5em 0 0 0 rgba(0,0,0,0.2),1.75em 1.75em 0 0 rgba(0,0,0,0.2),0 2.5em 0 0 rgba(0,0,0,0.2),-1.8em 1.8em 0 0 rgba(0,0,0,0.2),-2.6em 0 0 0 rgba(0,0,0,0.5),-1.8em -1.8em 0 0 rgba(0,0,0,0.7)} diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index d3c518d3ca..fe2dbbb628 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3189,7 +3189,7 @@ const ProductCTA = ({cta}) => { {cta.icon.url && Click icon} @@ -3207,7 +3207,7 @@ const ProductCTA = ({cta}) => { const ProductDesc = ({product}) => { return (
    - {`Image + {`Image From 1d549ff52493b5091df5074e294f6a4798b76175 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Sun, 30 Jun 2024 13:45:39 +0300 Subject: [PATCH 164/548] chore: fix tabbing for SearchPage --- static/js/ReaderPanel.jsx | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index ba06d47801..a4a989ca70 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -884,24 +884,24 @@ class ReaderPanel extends Component { } else if (this.state.menuOpen === "search" && this.state.searchQuery) { menu = (); + key={"searchPage"} + interfaceLang={this.props.interfaceLang} + query={this.state.searchQuery} + type={this.state.searchType} + searchState={this.state[`${this.state.searchType}SearchState`]} + settings={Sefaria.util.clone(this.state.settings)} + panelsOpen={this.props.panelsOpen} + onResultClick={this.props.onSearchResultClick} + openDisplaySettings={this.openDisplaySettings} + toggleLanguage={this.toggleLanguage} + close={this.props.closePanel} + onQueryChange={this.props.onQueryChange} + updateAppliedFilter={this.props.updateSearchFilter} + updateAppliedOptionField={this.props.updateSearchOptionField} + updateAppliedOptionSort={this.props.updateSearchOptionSort} + registerAvailableFilters={this.props.registerAvailableFilters} + compare={this.state.compare} + />); } else if (this.state.menuOpen === "topics") { if (this.state.navigationTopicCategory) { From c2f989947dfddbcef11e7f5e59ed4711ebb81a5b Mon Sep 17 00:00:00 2001 From: YishaiGlasner Date: Sun, 30 Jun 2024 15:56:08 +0300 Subject: [PATCH 165/548] fix(a tag): make isScrollLink to work when the link is to the same book (rather than the same node). --- static/js/TextRange.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/js/TextRange.jsx b/static/js/TextRange.jsx index 38441ac3b3..777f34ada4 100644 --- a/static/js/TextRange.jsx +++ b/static/js/TextRange.jsx @@ -506,8 +506,8 @@ class TextSegment extends Component { handleRefLinkClick(refLink, event) { event.preventDefault(); let newRef = Sefaria.humanRef(refLink.attr("data-ref")); - const newBook = Sefaria.parseRef(newRef)?.book; - const currBook = Sefaria.parseRef(this.props.sref)?.book; + const newBook = Sefaria.parseRef(newRef)?.index; + const currBook = Sefaria.parseRef(this.props.sref)?.index; const isScrollLink = refLink.attr('data-scroll-link'); // two options: in most cases, we open a new panel, but if isScrollLink is 'true', we should navigate in the same panel to the new location From c843a26405703b2f0296b6a7a627bc13a44198b7 Mon Sep 17 00:00:00 2001 From: saengel Date: Sun, 30 Jun 2024 21:23:03 +0300 Subject: [PATCH 166/548] chore(Products): Fix icon alignment, link underline --- static/css/s2.css | 31 ++++++++++++++++++++----------- static/js/StaticPages.jsx | 22 +++++++--------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 3c643a5236..778ae24170 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12984,10 +12984,10 @@ span.ref-link-color-3 {color: blue} } } -.productsFlexWrapper { +/* .productsFlexWrapper { display: flex; flex-direction: column; -} +} */ .product { max-width: 600px; @@ -12998,26 +12998,34 @@ span.ref-link-color-3 {color: blue} margin-top: 165px; } - -.productsInner { +.productInner { display: flex; align-items: right; } -.productsInner img { +.productInner img { max-width: 100%; max-height: 116px; height: auto; display: block; margin-inline-end: 3%; + padding-right: 20px; } -.productsInner .productsDesc { +.productInner .productsDesc { font: var(--english-sans-serif-font-family); color: var(--dark-grey); font-size: 16px; } +.productImgWrapper { + flex: 0 0 auto; +} + +.productDescWrapper { + flex: 1 1 auto; +} + .productsDesc p { margin-top: 0; } @@ -13067,11 +13075,11 @@ span.ref-link-color-3 {color: blue} .productsHeader .cta .productsCTAIcon { - height: 16px; + height: 12px; top: 646px; left: 610px; margin: 0 5px; - vertical-align: middle; + vertical-align: baseline; /** This uses the filter to recolor SVGs in a single line to commentary blue. To determine the appropriate parameters, see a filter color picker such as https://angel-rs.github.io/css-color-filter-generator/ */ filter: brightness(0) saturate(100%) invert(52%) sepia(17%) saturate(6763%) hue-rotate(200deg) brightness(78%) contrast(77%); @@ -13144,17 +13152,18 @@ span.ref-link-color-3 {color: blue} } @media (max-width: 768px) { - .productsInner { + .productInner { flex-direction: column; align-items: flex-start; } - .productsInner img { + .productInner img { display: block; width: 100%; height: 100%; max-width: 700px; max-height: 350px; + padding-bottom: 20px; } .product { @@ -13168,7 +13177,7 @@ span.ref-link-color-3 {color: blue} .productsDevBox { margin-right: 5%; } - +} @-webkit-keyframes load5 { 0%,100%{box-shadow:0 -2.6em 0 0 #ffffff,1.8em -1.8em 0 0 rgba(0,0,0,0.2),2.5em 0 0 0 rgba(0,0,0,0.2),1.75em 1.75em 0 0 rgba(0,0,0,0.2),0 2.5em 0 0 rgba(0,0,0,0.2),-1.8em 1.8em 0 0 rgba(0,0,0,0.2),-2.6em 0 0 0 rgba(0,0,0,0.5),-1.8em -1.8em 0 0 rgba(0,0,0,0.7)} diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index fe2dbbb628..cb3688be15 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3206,21 +3206,13 @@ const ProductCTA = ({cta}) => { // The main body of each product entry, containing an image and description const ProductDesc = ({product}) => { return ( -
    - {`Image - - - - - {product.desc?.he} - - - - - {product.desc?.en} - - - +
    +
    + {`Image +
    +
    + +
    ); }; From 09616c174f13ba4010029951af95afda86474194 Mon Sep 17 00:00:00 2001 From: saengel Date: Sun, 30 Jun 2024 21:31:03 +0300 Subject: [PATCH 167/548] chore(Products Page): Attempt to replace greater-than w caret --- static/css/s2.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/css/s2.css b/static/css/s2.css index 778ae24170..068c01b7b6 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13134,7 +13134,7 @@ span.ref-link-color-3 {color: blue} } .productsDevBox a::after { - content: " >"; + content: url("/static/icons/chevron.svg"); color: var(--commentary-blue); } From 37da4a00abe6125a3568e2be31f724317f2e1910 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Mon, 1 Jul 2024 10:58:26 +0300 Subject: [PATCH 168/548] chore: filter and sort in SheetsWithRefPage for display --- sourcesheets/views.py | 6 +++-- static/js/ReaderApp.jsx | 5 ++++ static/js/ReaderPanel.jsx | 3 +-- static/js/Sheets/SheetsWithRefPage.jsx | 32 ++++++++++++++++++++++---- static/js/sefaria/sefaria.js | 19 --------------- 5 files changed, 38 insertions(+), 27 deletions(-) diff --git a/sourcesheets/views.py b/sourcesheets/views.py index cb415b1c93..0f7f6b2c28 100644 --- a/sourcesheets/views.py +++ b/sourcesheets/views.py @@ -1025,8 +1025,10 @@ def sheets_by_ref_api(request, ref): return jsonResponse(get_sheets_for_ref(ref, include_collections=True)) def sheets_with_ref(request, tref): - title = _(f"Sheets with {tref} on Sefaria") - return menu_page(request, page="sheetsWithRef", title=title, props={"sheetsWithRef": tref}) + he_tref = Ref(tref).he_normal() + ref = tref if request.interfaceLang == "english" else he_tref + title = _(f"Sheets with ")+ref+_(" on Sefaria") + return menu_page(request, page="sheetsWithRef", title=title, props={"sheetsWithRef": {"en": tref, "he": he_tref}}) def get_aliyot_by_parasha_api(request, parasha): response = {"ref":[]}; diff --git a/static/js/ReaderApp.jsx b/static/js/ReaderApp.jsx index e1a2c90d25..fda1e853ed 100644 --- a/static/js/ReaderApp.jsx +++ b/static/js/ReaderApp.jsx @@ -454,6 +454,11 @@ class ReaderApp extends Component { hist.url = "texts" + (cats ? "/" + cats : ""); hist.mode = "navigation"; break; + case "sheetsWithRef": + hist.title = Sefaria._("Sheets with ") + Sefaria.sheetsWithRef[Sefaria.interfaceLang] + Sefaria._(" on Sefaria"); + hist.mode = "sheetsWithRef"; + hist.url = `sheetsWithRef/${Sefaria.sheetsWithRef['en']}`; + break; case "text toc": var ref = state.refs.slice(-1)[0]; var bookTitle = ref ? Sefaria.parseRef(ref).index : "404"; diff --git a/static/js/ReaderPanel.jsx b/static/js/ReaderPanel.jsx index 1d0458e4d7..35605b6530 100644 --- a/static/js/ReaderPanel.jsx +++ b/static/js/ReaderPanel.jsx @@ -801,8 +801,7 @@ class ReaderPanel extends Component { initialWidth={this.state.width} toggleSignUpModal={this.props.toggleSignUpModal}/>); } else if (this.state.menuOpen === "sheetsWithRef") { - const connectedSheet = this.props.nodeRef ? this.props.nodeRef.split(".")[0] : null; - menu = (); + menu = (); } else if (this.state.menuOpen === "sheet meta") { menu = ( { +const SheetsWithRefPage = ({srefs}) => { const [sheets, setSheets] = useState([]); const [searchState, setSearchState] = useState(null); const [loading, setLoading] = useState(true); + + const prepSheetsForDisplay = (sheets) => { + // First show my sheets + //if (a.owner === Sefaria._uid) + sheets = sheets.sort((a, b) => { + // First place user's sheet + if (a.owner === Sefaria.uid && b.owner !== Sefaria.uid) { + return -1; + } + if (a.owner !== Sefaria.uid && b.owner === Sefaria.uid) { + return 1; + } + // Then sort by language / interface language + let aHe, bHe; + [aHe, bHe] = [a.title, b.title].map(Sefaria.hebrew.isHebrew); + if (aHe !== bHe) { return (bHe ? -1 : 1) * (Sefaria.interfaceLang === "hebrew" ? -1 : 1); } + // Then by number of views + return b.views - a.views; + }) + // filters out duplicate sheets by sheet ID number and filters so that we don't show sheets as connections to themselves + return sheets.filter((sheet, index, self) => + index === self.findIndex((s) => ( + s.id === sheet.id) + )) + } useEffect(() => { delete Sefaria.sheets._sheetsByRef[srefs]; Sefaria.sheets.getSheetsByRef(srefs).then(sheets => { - sheets = Sefaria.sheets.sortSheetsByInterfaceLang(sheets); - sheets = Sefaria.sheets.filterSheetsForDisplay(sheets, connectedSheet); + sheets = prepSheetsForDisplay(sheets); const searchState = Sefaria.sheets.sheetsWithRefSearchState(sheets); setSheets(sheets); setSearchState(searchState); @@ -40,7 +64,7 @@ const SheetsWithRefPage = ({srefs, connectedSheet}) => { searchTopMsg="Sheets With" list={SheetsWithRefList} listItems={sheets} - query={srefs[0]} + query={srefs} type={'sheet'} compare={false} searchState={searchState} diff --git a/static/js/sefaria/sefaria.js b/static/js/sefaria/sefaria.js index b01cfb3b94..fce5f37149 100644 --- a/static/js/sefaria/sefaria.js +++ b/static/js/sefaria/sefaria.js @@ -2787,25 +2787,6 @@ _media: {}, store: Sefaria.sheets._sheetsByRef }); }, - sortSheetsByInterfaceLang(sheets) { - return sheets.sort((a, b) => { - // First sort by language / interface language - let aHe, bHe; - [aHe, bHe] = [a.title, b.title].map(Sefaria.hebrew.isHebrew); - if (aHe !== bHe) { return (bHe ? -1 : 1) * (Sefaria.interfaceLang === "hebrew" ? -1 : 1); } - // Then by number of views - return b.views - a.views; - }) - }, - filterSheetsForDisplay(sheets, connectedSheet) { - // filters out duplicate sheets by sheet ID number and filters so that we don't show sheets as connections to themselves - return sheets.filter( - (sheet, index, self) => - index === self.findIndex((s) => ( - s.id === sheet.id - ))).filter(sheet => { - return sheet.id !== connectedSheet;}); - }, sheetsWithRefSearchState(sheets) { /* This function is used to generate the SearchState with its relevant FilterNodes to be used by SheetsWithRef for filtering sheets by topic and collection From 55af4cd2103f25c71a2a8a61d5014524539d7774 Mon Sep 17 00:00:00 2001 From: stevekaplan123 Date: Mon, 1 Jul 2024 11:42:26 +0300 Subject: [PATCH 169/548] chore: appliedFilters works in SheetsWithRefPage but topics and collections dont get updated --- static/js/Sheets/SheetsWithRefPage.jsx | 28 +++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/static/js/Sheets/SheetsWithRefPage.jsx b/static/js/Sheets/SheetsWithRefPage.jsx index 9598677d60..bd7936691d 100644 --- a/static/js/Sheets/SheetsWithRefPage.jsx +++ b/static/js/Sheets/SheetsWithRefPage.jsx @@ -6,10 +6,19 @@ const SheetsWithRefPage = ({srefs}) => { const [sheets, setSheets] = useState([]); const [searchState, setSearchState] = useState(null); const [loading, setLoading] = useState(true); - + const applyFilters = (sheets) => { + searchState.appliedFilters.forEach((appliedFilter, i) => { + const type = searchState.appliedFilterAggTypes[i]; + sheets = sheets.filter(sheet => { + const items = type === 'topics_en' ? sheet.topics : sheet.collections; + const slugs = items.map(x => x.slug); + return slugs.includes(appliedFilter); + }); + }); + return sheets; + } const prepSheetsForDisplay = (sheets) => { - // First show my sheets - //if (a.owner === Sefaria._uid) + sheets = applyFilters(sheets); sheets = sheets.sort((a, b) => { // First place user's sheet if (a.owner === Sefaria.uid && b.owner !== Sefaria.uid) { @@ -34,7 +43,6 @@ const SheetsWithRefPage = ({srefs}) => { useEffect(() => { delete Sefaria.sheets._sheetsByRef[srefs]; Sefaria.sheets.getSheetsByRef(srefs).then(sheets => { - sheets = prepSheetsForDisplay(sheets); const searchState = Sefaria.sheets.sheetsWithRefSearchState(sheets); setSheets(sheets); setSearchState(searchState); @@ -44,8 +52,14 @@ const SheetsWithRefPage = ({srefs}) => { const onSearchResultClick = (...args) => { args.forEach(arg => console.log(arg)); } - const updateSearchFilter = (...args) => { - args.forEach(arg => console.log(arg)); + const updateSearchFilter = (type, searchState, filterNode) => { + if (filterNode.isUnselected()) { + filterNode.setSelected(true); + } else { + filterNode.setUnselected(true); + } + const update = Sefaria.search.getAppliedSearchFilters(searchState.availableFilters); + setSearchState(searchState.update(update)); } const updateSearchOptionField = (...args) => { args.forEach(arg => console.log(arg)); @@ -63,7 +77,7 @@ const SheetsWithRefPage = ({srefs}) => { key={"sheetsPage"} searchTopMsg="Sheets With" list={SheetsWithRefList} - listItems={sheets} + listItems={prepSheetsForDisplay(sheets)} query={srefs} type={'sheet'} compare={false} From 054754d34b983068c1a93f2a1d78bd963e8645f5 Mon Sep 17 00:00:00 2001 From: saengel Date: Mon, 1 Jul 2024 12:20:05 +0300 Subject: [PATCH 170/548] chore(Products Page): Remove localhost --- static/js/StaticPages.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index cb3688be15..ec31ef12c4 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3189,7 +3189,7 @@ const ProductCTA = ({cta}) => {
    {cta.icon.url && Click icon} @@ -3208,7 +3208,7 @@ const ProductDesc = ({product}) => { return (
    - {`Image + {`Image
    From eb89885484452ed01b30031398bc9b7a07c89e3e Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 2 Jul 2024 10:13:12 +0300 Subject: [PATCH 171/548] chore(Products Page): Address design feedback --- static/css/s2.css | 49 ++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 068c01b7b6..1d08dfbdbb 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -12984,10 +12984,10 @@ span.ref-link-color-3 {color: blue} } } -/* .productsFlexWrapper { +.productsFlexWrapper { display: flex; flex-direction: column; -} */ +} .product { max-width: 600px; @@ -12996,11 +12996,14 @@ span.ref-link-color-3 {color: blue} #productsPageContent { margin-inline-start: 70px; margin-top: 165px; + margin-bottom: 165px; } .productInner { display: flex; align-items: right; + flex-direction: row; + flex-wrap: wrap; } .productInner img { @@ -13010,6 +13013,7 @@ span.ref-link-color-3 {color: blue} display: block; margin-inline-end: 3%; padding-right: 20px; + padding-bottom: 20px; } .productInner .productsDesc { @@ -13151,32 +13155,37 @@ span.ref-link-color-3 {color: blue} color: #666666; } -@media (max-width: 768px) { - .productInner { - flex-direction: column; - align-items: flex-start; +@media (max-width: 900px) { + + .productImgWrapper { + display: block; + margin-left: auto; + margin-right: auto; + } + + #productsPageContent { + margin-right: 70px; } - .productInner img { - display: block; - width: 100%; - height: 100%; - max-width: 700px; - max-height: 350px; - padding-bottom: 20px; - } + .productsHeader { + flex-direction: column; + align-items: flex-start; + } - .product { - margin-right: 5%; + .productsTitleAndLabel { + display: flex; + flex-direction: column; + align-items: flex-start; } - .productsDesc { - margin-top: 5%; + .cta { + flex-direction: column; + align-items: flex-start !important; } - .productsDevBox { + /* .productsDevBox { margin-right: 5%; - } + } */ } @-webkit-keyframes load5 { From 4af1c1bcebd989d8daf42192bd4bbce29517a232 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 2 Jul 2024 12:01:43 +0300 Subject: [PATCH 172/548] chore(Products Page): Mobile web css refinements --- static/css/s2.css | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/static/css/s2.css b/static/css/s2.css index 1d08dfbdbb..caff8fe5f9 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13170,12 +13170,22 @@ span.ref-link-color-3 {color: blue} .productsHeader { flex-direction: column; align-items: flex-start; + padding-top: 5px; + padding-bottom: 5px; } .productsTitleAndLabel { display: flex; flex-direction: column; align-items: flex-start; + padding-top: 5px; + padding-bottom: 5px; + } + + .productsTypeLabel { + padding: 1px 1px !important; + margin-top: 3px; + margin-left: 0px !important; } .cta { @@ -13183,6 +13193,11 @@ span.ref-link-color-3 {color: blue} align-items: flex-start !important; } + .cta a { + padding-top: 3px; + padding-bottom: 3px; + } + /* .productsDevBox { margin-right: 5%; } */ From 908c6f7d7d5175c02eb69901aa1acec670f75396 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 2 Jul 2024 12:20:43 +0300 Subject: [PATCH 173/548] chore(Products Page): Reduce spacing around header line --- static/css/s2.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index caff8fe5f9..e144490a19 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13038,8 +13038,8 @@ span.ref-link-color-3 {color: blue} display: flex; justify-content: space-between; margin-top: 10%; - margin-bottom: 3%; - padding-bottom: 3%; + margin-bottom: 2%; + padding-bottom: 2%; border-bottom: 1px solid var(--light-grey); } From ce17d5e3a7d836da5d57a33c8aff56c8951e128d Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 2 Jul 2024 12:40:50 +0300 Subject: [PATCH 174/548] chore(Products Page): Add mobile web page title --- static/js/StaticPages.jsx | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/static/js/StaticPages.jsx b/static/js/StaticPages.jsx index ec31ef12c4..efedc96be2 100644 --- a/static/js/StaticPages.jsx +++ b/static/js/StaticPages.jsx @@ -3435,15 +3435,21 @@ const ProductsPage = memo(() => { const remainingProducts = ProductList.slice(devBoxPosition); return ( -
    - {products && products.length > 0 ? ( - <> - {initialProducts} - {/* */} - {remainingProducts} - - ) : null} -
    + <> +

    + Sefaria's Products + מוצרים של בספריא +

    +
    + {products && products.length > 0 ? ( + <> + {initialProducts} + {/* */} + {remainingProducts} + + ) : null} +
    + ); }); From 18114f78e2fdbb85eff45e1ab8f720a9432c2115 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 2 Jul 2024 13:30:24 +0300 Subject: [PATCH 175/548] chore(PR Templates): Create template for new PRs --- .github/pull_request_template.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000000..4701933c5f --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,8 @@ +## Description +_A brief description of the PR_ + +## Code Changes +_The following changes were made to the files below_ + +## Notes +_Any additional notes go here_ \ No newline at end of file From dd60a0bd21c35add78a8e136cfabaaefb394e7b9 Mon Sep 17 00:00:00 2001 From: saengel Date: Tue, 2 Jul 2024 13:48:17 +0300 Subject: [PATCH 176/548] chore(Products Page): Alignment fixes, CSS fixes --- static/css/s2.css | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index e144490a19..3704dfa056 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13003,7 +13003,6 @@ span.ref-link-color-3 {color: blue} display: flex; align-items: right; flex-direction: row; - flex-wrap: wrap; } .productInner img { @@ -13155,7 +13154,7 @@ span.ref-link-color-3 {color: blue} color: #666666; } -@media (max-width: 900px) { +@media (max-width: 480px) { .productImgWrapper { display: block; @@ -13198,9 +13197,13 @@ span.ref-link-color-3 {color: blue} padding-bottom: 3px; } - /* .productsDevBox { + .productInner { + flex-direction: column; + } + + .productsDevBox { margin-right: 5%; - } */ + } } @-webkit-keyframes load5 { From 99e9eaa301b0272f5af6a52c8f1d184a3a222f0c Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 3 Jul 2024 10:44:24 +0300 Subject: [PATCH 177/548] chore(Products Page): Switch to chevron --- static/css/s2.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 3704dfa056..0f0c6c7ac9 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13099,8 +13099,8 @@ span.ref-link-color-3 {color: blue} } .productsCTA::after { - content: " >"; - color: var(--commentary-blue); + content: " ›"; + color: var(--commentary-blue); } .productsDevBox { @@ -13137,7 +13137,7 @@ span.ref-link-color-3 {color: blue} } .productsDevBox a::after { - content: url("/static/icons/chevron.svg"); + content: " ›"; color: var(--commentary-blue); } From b725085f5cdd78b9696e6e8e2ba73ba1a0b01389 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 3 Jul 2024 10:47:15 +0300 Subject: [PATCH 178/548] chore(Products Page): Fix he/en padding issues --- static/css/s2.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/static/css/s2.css b/static/css/s2.css index 0f0c6c7ac9..1f4b129805 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13011,7 +13011,6 @@ span.ref-link-color-3 {color: blue} height: auto; display: block; margin-inline-end: 3%; - padding-right: 20px; padding-bottom: 20px; } @@ -13027,6 +13026,8 @@ span.ref-link-color-3 {color: blue} .productDescWrapper { flex: 1 1 auto; + padding-left: 20px; + padding-right: 20px; } .productsDesc p { From b341c5935888b743444c4617ca097149c700ec29 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 3 Jul 2024 10:55:17 +0300 Subject: [PATCH 179/548] fix(Products Page): Fix mobile-web margins to be like new additions --- static/css/s2.css | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/static/css/s2.css b/static/css/s2.css index 1f4b129805..595feeaf43 100644 --- a/static/css/s2.css +++ b/static/css/s2.css @@ -13164,7 +13164,7 @@ span.ref-link-color-3 {color: blue} } #productsPageContent { - margin-right: 70px; + margin: 100px 10px 0px 10px;; } .productsHeader { @@ -13183,7 +13183,7 @@ span.ref-link-color-3 {color: blue} } .productsTypeLabel { - padding: 1px 1px !important; + padding: 1px 5px !important; margin-top: 3px; margin-left: 0px !important; } @@ -13202,8 +13202,9 @@ span.ref-link-color-3 {color: blue} flex-direction: column; } - .productsDevBox { - margin-right: 5%; + .productDescWrapper{ + padding-left: 0px; + padding-right: 0px; } } From 29722e977e1ad6331580c6332d4343f72bb6c8e0 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 3 Jul 2024 11:03:52 +0300 Subject: [PATCH 180/548] fix(Products Page): Typo in hebrew sidebar --- templates/_sidebar.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/_sidebar.html b/templates/_sidebar.html index 0a57475b67..0de08cb2b1 100644 --- a/templates/_sidebar.html +++ b/templates/_sidebar.html @@ -15,7 +15,7 @@

    {{heTitle}}

    משרות פנויות בספריא
  • Sefaria's Products - מוצרים של בספריא
  • + מוצרים של ספריא
  • Our Supporters התומכים שלנו
  • From 62ec0caf8f3d2957d6b4c0809727331633fedd65 Mon Sep 17 00:00:00 2001 From: YishaiGlasner Date: Wed, 3 Jul 2024 18:14:15 +0300 Subject: [PATCH 181/548] feat(Topic): add pools to optional_attrs. --- sefaria/model/topic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sefaria/model/topic.py b/sefaria/model/topic.py index a5dfe56568..48bbfd52f2 100644 --- a/sefaria/model/topic.py +++ b/sefaria/model/topic.py @@ -49,6 +49,7 @@ class Topic(abst.SluggedAbstractMongoRecord, AbstractTitledObject): "data_source", #any topic edited manually should display automatically in the TOC and this flag ensures this 'image', "portal_slug", # slug to relevant Portal object + 'pools', # list of strings, any of them represents a pool that this topic is member of ] attr_schemas = { From 849cb8ae483724f54027834dbfc7d3d75689bd83 Mon Sep 17 00:00:00 2001 From: YishaiGlasner Date: Wed, 3 Jul 2024 18:18:32 +0300 Subject: [PATCH 182/548] feat(Topic): normalize pools - remove duplicates, sort, and set to an empty array if missing. --- sefaria/model/topic.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sefaria/model/topic.py b/sefaria/model/topic.py index 48bbfd52f2..0d796c7121 100644 --- a/sefaria/model/topic.py +++ b/sefaria/model/topic.py @@ -115,6 +115,7 @@ def _normalize(self): displays_under_link = IntraTopicLink().load({"fromTopic": slug, "linkType": "displays-under"}) if getattr(displays_under_link, "toTopic", "") == "authors": self.subclass = "author" + self.pools = sorted(set(getattr(self, 'pools', []))) def _sanitize(self): super()._sanitize() From 2c42b7680183ab3a50834b275bd3f9d50234e5bf Mon Sep 17 00:00:00 2001 From: YishaiGlasner Date: Wed, 3 Jul 2024 18:22:37 +0300 Subject: [PATCH 183/548] feat(Topic): function for adding pool. --- sefaria/model/topic.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sefaria/model/topic.py b/sefaria/model/topic.py index 0d796c7121..03868e9b95 100644 --- a/sefaria/model/topic.py +++ b/sefaria/model/topic.py @@ -427,6 +427,10 @@ def __str__(self): def __repr__(self): return "{}.init('{}')".format(self.__class__.__name__, self.slug) + def add_pool(self, pool_name): + if pool_name not in self.pools: + self.pools.append(pool_name) + self.save() class PersonTopic(Topic): """ From eec5b9ac0e67fa8e58ed253e7e83792a258d2218 Mon Sep 17 00:00:00 2001 From: YishaiGlasner Date: Wed, 3 Jul 2024 18:31:18 +0300 Subject: [PATCH 184/548] feat(Topic): add optional_pools as class attribute. validate pools are in optional_pools. --- sefaria/model/topic.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sefaria/model/topic.py b/sefaria/model/topic.py index 03868e9b95..78d06a4acf 100644 --- a/sefaria/model/topic.py +++ b/sefaria/model/topic.py @@ -52,6 +52,8 @@ class Topic(abst.SluggedAbstractMongoRecord, AbstractTitledObject): 'pools', # list of strings, any of them represents a pool that this topic is member of ] + optional_pools = {'sheets', 'textual', 'torahtab'} + attr_schemas = { "image": { "image_uri": { @@ -104,6 +106,7 @@ def _validate(self): if getattr(self, "image", False): img_url = self.image.get("image_uri") if img_url: validate_url(img_url) + assert all(pool in self.optional_pools for pool in self.pools), f'Pools {[pool for pool in self.pools if pool not in self.optional_pools]} is not an optional pool' def _normalize(self): super()._normalize() @@ -432,6 +435,8 @@ def add_pool(self, pool_name): self.pools.append(pool_name) self.save() + def update_sheets_pool(self): + class PersonTopic(Topic): """ Represents a topic which is a person. Not necessarily an author of a book. From edc246243f0b2c0d41e5f903fab13eca30661778 Mon Sep 17 00:00:00 2001 From: saengel Date: Wed, 3 Jul 2024 18:49:43 +0300 Subject: [PATCH 185/548] feat(Remove Footer): Remove footer --- static/js/BookPage.jsx | 3 --- static/js/CalendarsPage.jsx | 2 -- static/js/CollectionPage.jsx | 2 -- static/js/CommunityPage.jsx | 2 -- static/js/MyNotesPanel.jsx | 2 -- static/js/NotificationsPanel.jsx | 2 -- static/js/PublicCollectionsPage.jsx | 2 -- static/js/SearchPage.jsx | 2 -- static/js/TextCategoryPage.jsx | 3 --- static/js/TextsPage.jsx | 3 --- static/js/TopicPage.jsx | 3 --- static/js/TopicPageAll.jsx | 2 -- static/js/TopicsPage.jsx | 2 -- static/js/TranslationsPage.jsx | 2 -- static/js/UpdatesPanel.jsx | 2 -- static/js/UserHistoryPanel.jsx | 3 --- static/js/UserProfile.jsx | 2 -- 17 files changed, 39 deletions(-) diff --git a/static/js/BookPage.jsx b/static/js/BookPage.jsx index b91af7dc06..ffbf79dc42 100644 --- a/static/js/BookPage.jsx +++ b/static/js/BookPage.jsx @@ -23,7 +23,6 @@ import { NavSidebar, Modules } from './NavSidebar'; import DictionarySearch from './DictionarySearch'; import VersionBlock from './VersionBlock/VersionBlock'; import ExtendedNotes from './ExtendedNotes'; -import Footer from './Footer'; import classNames from 'classnames'; import PropTypes from 'prop-types'; import Component from 'react-class'; @@ -305,8 +304,6 @@ class BookPage extends Component { {this.isBookToc() && ! this.props.compare ? : null}
    - {this.isBookToc() && ! this.props.compare ? -
    : null}
    ); diff --git a/static/js/CalendarsPage.jsx b/static/js/CalendarsPage.jsx index c6d96a8f5f..22f1c4e9e8 100644 --- a/static/js/CalendarsPage.jsx +++ b/static/js/CalendarsPage.jsx @@ -7,7 +7,6 @@ import classNames from 'classnames'; import Sefaria from './sefaria/sefaria'; import $ from './sefaria/sefariaJquery'; import { NavSidebar, Modules }from './NavSidebar'; -import Footer from './Footer'; import Component from 'react-class'; @@ -58,7 +57,6 @@ const CalendarsPage = ({multiPanel, initialWidth}) => {
    -
    ); diff --git a/static/js/CollectionPage.jsx b/static/js/CollectionPage.jsx index 49adfa7131..692b6c8717 100644 --- a/static/js/CollectionPage.jsx +++ b/static/js/CollectionPage.jsx @@ -5,7 +5,6 @@ import classNames from 'classnames'; import $ from './sefaria/sefariaJquery'; import Sefaria from './sefaria/sefaria'; import { NavSidebar } from './NavSidebar'; -import Footer from './Footer'; import { CategoryColorLine, DropdownModal, @@ -296,7 +295,6 @@ class CollectionPage extends Component {

    -
    ); diff --git a/static/js/CommunityPage.jsx b/static/js/CommunityPage.jsx index 8510b13093..f5188eb51e 100644 --- a/static/js/CommunityPage.jsx +++ b/static/js/CommunityPage.jsx @@ -5,7 +5,6 @@ import Sefaria from './sefaria/sefaria'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { NavSidebar, Modules } from './NavSidebar'; -import Footer from'./Footer'; import { InterfaceText, LoadingMessage, @@ -64,7 +63,6 @@ const CommunityPage = ({multiPanel, toggleSignUpModal, initialWidth}) => {

    -
    ); diff --git a/static/js/MyNotesPanel.jsx b/static/js/MyNotesPanel.jsx index 9ba568836c..886ef08df5 100644 --- a/static/js/MyNotesPanel.jsx +++ b/static/js/MyNotesPanel.jsx @@ -15,7 +15,6 @@ import Sefaria from './sefaria/sefaria'; import $ from './sefaria/sefariaJquery'; import TextRange from './TextRange'; import { AddToSourceSheetWindow } from './AddToSourceSheet'; -import Footer from './Footer'; import Component from 'react-class'; @@ -85,7 +84,6 @@ class MyNotesPanel extends Component {
    -
    ); } diff --git a/static/js/NotificationsPanel.jsx b/static/js/NotificationsPanel.jsx index 27abe785d4..a522c72a86 100644 --- a/static/js/NotificationsPanel.jsx +++ b/static/js/NotificationsPanel.jsx @@ -1,7 +1,6 @@ import React, { useRef } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import Footer from './Footer'; import ReactDOM from 'react-dom'; import Sefaria from './sefaria/sefaria'; import $ from './sefaria/sefariaJquery'; @@ -92,7 +91,6 @@ class NotificationsPanel extends Component {
    -
    ); diff --git a/static/js/PublicCollectionsPage.jsx b/static/js/PublicCollectionsPage.jsx index 5d71fd7b16..3b41d26b7e 100644 --- a/static/js/PublicCollectionsPage.jsx +++ b/static/js/PublicCollectionsPage.jsx @@ -1,7 +1,6 @@ import React, { useState, useEffect, useCallback, useRef } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; -import Footer from './Footer'; import Sefaria from './sefaria/sefaria'; import Component from 'react-class'; import { NavSidebar, Modules } from './NavSidebar'; @@ -91,7 +90,6 @@ const PublicCollectionsPage = ({multiPanel, initialWidth}) => {
    -
    ); diff --git a/static/js/SearchPage.jsx b/static/js/SearchPage.jsx index 438b2bc3c9..9a1511efc7 100644 --- a/static/js/SearchPage.jsx +++ b/static/js/SearchPage.jsx @@ -4,7 +4,6 @@ import $ from './sefaria/sefariaJquery'; import Sefaria from './sefaria/sefaria'; import classNames from 'classnames'; import PropTypes from 'prop-types'; -import Footer from './Footer'; import ComparePanelHeader from './ComparePanelHeader'; import SearchResultList from './SearchResultList'; import SearchFilters from './SearchFilters'; @@ -85,7 +84,6 @@ class SearchPage extends Component {
    : null }
    - { this.props.panelsOpen === 1 ?
    : null }
    ); diff --git a/static/js/TextCategoryPage.jsx b/static/js/TextCategoryPage.jsx index c8bcb4b9bb..fbaf26c997 100644 --- a/static/js/TextCategoryPage.jsx +++ b/static/js/TextCategoryPage.jsx @@ -4,7 +4,6 @@ import PropTypes from 'prop-types'; import Sefaria from './sefaria/sefaria'; import { ContentLanguageContext } from './context'; import { NavSidebar } from './NavSidebar'; -import Footer from './Footer'; import ComparePanelHeader from './ComparePanelHeader'; import { CategoryAttribution, @@ -77,7 +76,6 @@ const TextCategoryPage = ({category, categories, setCategories, toggleLanguage, heCatTitle={heCatTitle} /> ) : null; - const footer = compare ? null :
    ; const navMenuClasses = classNames({readerNavCategoryMenu: 1, readerNavMenu: 1, noLangToggleInHebrew: 1, compare: compare}); return (
    @@ -103,7 +101,6 @@ const TextCategoryPage = ({category, categories, setCategories, toggleLanguage,
    {!compare ? : null}
    - {footer}
    ); diff --git a/static/js/TextsPage.jsx b/static/js/TextsPage.jsx index 53ef228dfb..1fcc4490c7 100644 --- a/static/js/TextsPage.jsx +++ b/static/js/TextsPage.jsx @@ -5,7 +5,6 @@ import Sefaria from './sefaria/sefaria'; import $ from './sefaria/sefariaJquery'; import { NavSidebar, Modules, RecentlyViewed } from './NavSidebar'; import TextCategoryPage from './TextCategoryPage'; -import Footer from './Footer'; import ComparePanelHeader from './ComparePanelHeader'; import { TextBlockLink, @@ -97,7 +96,6 @@ const TextsPage = ({categories, settings, setCategories, onCompareBack, openSear {type: "Resources"}, ]; - const footer = compare ? null :
    ; const classes = classNames({readerNavMenu:1, compare: compare, noLangToggleInHebrew: 1 }); return (
    @@ -114,7 +112,6 @@ const TextsPage = ({categories, settings, setCategories, onCompareBack, openSear
    {!compare ? : null}
    - {footer}
    ); diff --git a/static/js/TopicPage.jsx b/static/js/TopicPage.jsx index 0d25a0dac8..ff2c235d23 100644 --- a/static/js/TopicPage.jsx +++ b/static/js/TopicPage.jsx @@ -5,7 +5,6 @@ import Sefaria from './sefaria/sefaria'; import { useIncrementalLoad } from './Hooks'; import { Promotions } from './Promotions'; import { NavSidebar } from './NavSidebar'; -import Footer from './Footer'; import {TopicEditor} from './TopicEditor'; import {AdminEditorButton, useEditToggle} from './AdminEditor'; import { @@ -270,7 +269,6 @@ const TopicCategory = ({topic, topicTitle, setTopic, setNavTopic, compare, initi -