Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrating Nuclia Widget #792

Draft
wants to merge 35 commits into
base: nuclia
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
99a154c
Integrating Nuclia Widget
justdaksh Sep 3, 2023
520b294
removing redundant searchtester script
justdaksh Sep 3, 2023
b4533ea
Merged with main
justdaksh Sep 16, 2023
26ba768
Merged with main
justdaksh Sep 16, 2023
e752db2
Revert "Merged with main"
justdaksh Sep 16, 2023
2f72d6b
Merging with main
justdaksh Sep 16, 2023
642e5e0
Resolved conflicts of widget with nuclia
justdaksh Sep 16, 2023
a6aca93
Updated nuclia_sync.yml
justdaksh Sep 16, 2023
aa591bf
Updated Environment varibles
justdaksh Sep 17, 2023
ae4d412
Merge branch 'nuclia_widget' of https://github.com/plone/training int…
justdaksh Sep 17, 2023
c20299a
Updating env varibale to upload job
justdaksh Sep 17, 2023
00dda20
Functioning breadcrumbs,Debugging CI
justdaksh Sep 18, 2023
cdb9d41
Removed breadmaker.py && heading_to_breadcrumb_mapping.json
justdaksh Sep 18, 2023
95037a4
Updated nuclia workflow
justdaksh Sep 18, 2023
69e1658
Nuclia Sync: Updated docs
invalid-email-address Sep 18, 2023
adf5cbd
remove print statements
justdaksh Sep 18, 2023
8262dda
Merge branch 'nuclia_widget' of https://github.com/plone/training int…
justdaksh Sep 18, 2023
09683d9
Rerunning jobs for debugging
justdaksh Sep 18, 2023
dfc5dfe
Updating Commit Changes Run
justdaksh Sep 18, 2023
38cd562
Nuclia Sync: Updated docs
invalid-email-address Sep 18, 2023
930ebfe
Reverting to using JSON for breadcrumbs insted of metadata
justdaksh Sep 19, 2023
323e5de
Merge branch 'nuclia_widget' of https://github.com/plone/training int…
justdaksh Sep 19, 2023
dd68adf
Nuclia Sync: Updated docs
invalid-email-address Sep 19, 2023
c0d8c37
Updated searchhtml
justdaksh Sep 19, 2023
0572655
Merge branch 'nuclia_widget' of https://github.com/plone/training int…
justdaksh Sep 19, 2023
7d30969
Nuclia Sync: Updated docs
invalid-email-address Sep 19, 2023
4e53835
Using metadata,style changes
justdaksh Sep 20, 2023
adb5743
Updating workflow
justdaksh Sep 21, 2023
b5c5647
Added field parameter to upload script
justdaksh Oct 1, 2023
28b2a20
Style Changes on results
justdaksh Oct 1, 2023
6dc5fdc
title font-size change
justdaksh Oct 1, 2023
5823c65
Merge branch 'main' into nuclia_widget
justdaksh Oct 15, 2023
731c4d9
Merge branch 'refs/heads/main' into nuclia_widget
stevepiercy May 21, 2024
1257b91
Merge remote-tracking branch 'origin/nuclia_widget' into nuclia_widget
stevepiercy May 21, 2024
3373a37
Merge branch 'nuclia' into nuclia_widget
stevepiercy May 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/nuclia_sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
name: Nuclia Sync

on: [push]
jobs:
sync:
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.10"

- name: Install requirements
run: |
pip install -q -r requirements.txt

- name: Run Nuclia Sync
env:
DEPLOY_NUCLIA_URL: ${{secrets.DEPLOY_NUCLIA_URL}}
DEPLOY_NUCLIA_TOKEN: ${{secrets.DEPLOY_NUCLIA_TOKEN}}
run: |
python3 upload.py

- name: Check for changes in nuclia_sync.json
id: check_changes
run: |
CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }})
echo "Changed files: $CHANGED_FILES"
if echo "$CHANGED_FILES" | grep -q 'nuclia_sync.json'; then
echo "::set-output name=changed::true"
else
echo "::set-output name=changed::false"
fi

- name: Commit changes
if: steps.check_changes.outputs.changed == 'true'
run: |
git config --global user.name github-actions
git config --global user.email [email protected]
git add .
git commit -m "Nuclia Sync: Updated docs"
git push
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So everytime there is a commit on main, we run the job, which makes a commit on main.
It looks like an infinite loop :)

Maybe the job should have a condition like if the last changes are only about our 2 generated json files, we stop.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ebrehault I have put the check for nuclia_sync.json only. This should work, right?

1 change: 1 addition & 0 deletions docs/_static/nuclia_sync.json

Large diffs are not rendered by default.

206 changes: 206 additions & 0 deletions docs/_static/searchtester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
const { switchMap } = rxjs;
const nucliaResult = document.querySelector("nuclia-search-results");
const shadowRoot = nucliaResult.shadowRoot;

const nuclia = new window.NucliaSDK.Nuclia({
backend: "https://nuclia.cloud/api",
zone: "europe-1",
knowledgeBox: "62407006-2711-4631-9c03-761d156de289",
});
justdaksh marked this conversation as resolved.
Show resolved Hide resolved

function createBreadcrumbs(resultTitleContainer,ContainerHash) {

let ContainerHeading = resultTitleContainer.querySelector("div:nth-child(2)");

try {
nuclia.db
.getKnowledgeBox()
.pipe(
switchMap((knowledgeBox) =>
knowledgeBox.getResource(ContainerHash, [
"extra",
])
)
)
.subscribe(
(resource) => {
insertBreadcrumbDiv(resource, ContainerHeading);
},
(error) => {
console.error("Error fetching resource:", error);
}
);
} catch (error) {
console.error("Error in createBreadcrumbs:", error);
}
}

function insertBreadcrumbDiv(resource, ContainerHeading) {
let array = resource.extra.metadata["breadcrumbs"];
if (!ContainerHeading.querySelector("div.breadcrumbs")) {
let breadcrumbContainer = document.createElement("div");
breadcrumbContainer.className = "breadcrumbs";
for (let i = 0; i < array.length; i++) {
let dict = array[i];

// Create a span element for each breadcrumb
let breadcrumbSpan = document.createElement("span");

// Create a breadcrumb link or span based on whether it's the last breadcrumb
if (i < array.length - 1) {
let breadcrumbLink = document.createElement("a");
breadcrumbLink.href = dict.url;
breadcrumbLink.textContent = dict.label;
breadcrumbLink.classList.add("breadcrumb-link");
breadcrumbSpan.appendChild(breadcrumbLink);

// Add a separator between breadcrumb links
let separator = document.createTextNode(" > ");
breadcrumbSpan.appendChild(separator);
} else {
// If it's the last breadcrumb, create a non-clickable span
breadcrumbSpan.textContent = dict.label;
breadcrumbSpan.classList.add("breadcrumb-last");
}

breadcrumbContainer.appendChild(breadcrumbSpan);
}
ContainerHeading.insertAdjacentElement(
"afterbegin",
breadcrumbContainer
);
}
}

function isMatch(element) {
return (
element &&
element.nodeName === "DIV" &&
element.classList &&
element.classList.contains("sw-result-row") &&
element.classList.length === 2
);
}

// Function to process added nodes within the shadow DOM
function processAddedNodes(addedNodes) {
addedNodes.forEach((addedNode) => {
if (isMatch(addedNode)) {
let resultTitleContainer = addedNode.querySelector('.result-title-container')
let ContainerHash = addedNode.getAttribute('data-nuclia-rid');
if (ContainerHash.length == 32) { // To be removed when Null result issue get solved
createBreadcrumbs(resultTitleContainer,ContainerHash);
}
}
});
}

function addBreadcrumbsToResults() {
if (!nucliaResult) {
console.error("Nuclia-search-result tag not found");
return;
}
let observer = new MutationObserver(callback);

observer.observe(shadowRoot, {
childList: true,
subtree: true,
});
}

const callback = function (mutationsList, observer) {
for (const mutation of mutationsList) {
if (mutation.type === "childList") {
processAddedNodes(mutation.addedNodes);
}
}
};

const style = document.createElement('style');
style.textContent = `
:host {
--pst-color-primary: #579aca;
--color-on-hover: #0056b3;
--color-of-separator: #777;
--color-of-lastbreadcrumb: #CECECE;
--size-of-title-m: 22px;
}

/* Breadcrumb container */
.breadcrumbs {
margin: 10px 0;
}

/* Breadcrumb links */
.breadcrumbs a {
font-size: var(--font-size-small);
text-decoration: none;
color: var(--pst-color-primary);
transition: color 0.2s;
}

/* Style for the last breadcrumb */
.breadcrumbs span:last-child {
font-size: var(--font-size-small);
color: var(--color-of-lastbreadcrumb);
}

/* Separator between breadcrumbs */
.breadcrumbs .separator {
font-size: var(--font-size-small);
margin: 0 5px;
color: var(--color-of-separator);
}

/* Hover effect for breadcrumb links */
.breadcrumbs a:hover {
color: var(--color-on-hover);
}

/*Heading of the results*/
h3.ellipsis.title-m{
color: var(--pst-color-primary);
font-size: var(--size-of-title-m);
}

/*Subheading of the results*/
.sw-paragraph-result {
color: var(--pst-color-primary);
}
/*Gap between results*/
.results, .search-results {
gap: var(--rhythm-7);
}
/*Gap between widget and answer generation*/
.sw-initial-answer {
margin-top: var(--rhythm-3);
}
`;
// Append the style element to the shadow DOM
shadowRoot.appendChild(style);

function handleThemeChange(mutationsList) {
mutationsList.forEach((mutation) => {
if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') {
const newMode = htmlSelector.getAttribute('data-theme');
const nucliaSearchResults = document.querySelector('nuclia-search-results');
const nucliaSearchBar = document.querySelector('nuclia-search-bar');
const currentMode = nucliaSearchResults.getAttribute('mode');

if (newMode === 'dark' && currentMode !== 'dark') {
nucliaSearchResults.setAttribute('mode', 'dark');
nucliaSearchBar.setAttribute('mode', 'dark');
} else if (newMode === 'light' && currentMode !== 'light') {
nucliaSearchResults.setAttribute('mode', 'light');
nucliaSearchBar.setAttribute('mode', 'light');
}
}
});
}

// Select the HTML element and configure the observer
const htmlSelector = document.querySelector('html');
const observer = new MutationObserver(handleThemeChange);

// Start observing changes in the data-theme attribute
observer.observe(htmlSelector, { attributes: true, attributeFilter: ['data-theme'] });
34 changes: 0 additions & 34 deletions docs/_templates/components/search-field.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,38 +16,4 @@
spellcheck="false"/>
<span class="search-button__kbd-shortcut"><kbd class="kbd-shortcut__modifier">Ctrl</kbd>+<kbd>K</kbd></span>
</div>
<div class="d-flex visually-hidden">
<label for="training">Filter by training</label>
</div>
<div class="d-flex">
<select class="form-control" name="training" id="training" onchange="this.form.submit()">
<option value="all">all trainings</option>
{% for id, title in
[
['mastering-plone', 'Mastering Plone development'],
['mastering-plone-5', 'Mastering Plone development (Plone 5)'],
['effective-volto','Effective Volto (advanced)'],
['voltoaddons','Volto add-ons'],
['volto','Volto (beginner)'],
['voltohandson','Volto Hands-On (beginner)'],
['react','ReactJS'],
['theming','Classic UI Theming'],
['testing','Testing'],
['deployment','Deployment'],
['javascript','Javascript (Plone 5)'],
['ttw','TTW (Plone 5)'],
['solr','Solr'],
['workflow','Workflow'],
['migrations','Migrating content (best practice)'],
['transmogrifier','Migrating content (Transmogrifier)'],
['wsgi','WSGI'],
['advanced-python','Advanced Python'],
['angular','Angular'],
['gatsby','Gatsby'],
['contributing', 'Contributing'],
] %}
<option value="{{id}}">{{ title }}</option>
{% endfor %}
</select>
</div>
</form>
65 changes: 53 additions & 12 deletions docs/_templates/search.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,59 @@ <h1>{{ _("Search") }}</h1>
all words.{% endtrans %}
</div>
{% endblock %}
{% include "components/search-field.html" %}
<div id="search-results"></div>
</div>
<script>
// Activate the search field on page load
let searchInput = document.querySelector("form.bd-search input");
if (searchInput) {
searchInput.focus();
searchInput.select();
console.log("[PST]: Set focus on search field.");
}
</script>
</div>
<script src="https://unpkg.com/rxjs@^7/dist/bundles/rxjs.umd.min.js"></script>
<script src="https://unpkg.com/@nuclia/core@latest/umd/index.js"></script>

<!-- Adding the widget to search result page -->
<script>
document.addEventListener("DOMContentLoaded", () => {
const queryInput = document.getElementById("search-input").value;

const script = document.createElement("script");
script.src = "https://cdn.nuclia.cloud/nuclia-video-widget.umd.js";
script.async = true; // adding this to maybe load nuclia widget faster

// Initialize the Nuclia widget once it's loaded
script.onload = () => {
const widget = document.getElementsByTagName("nuclia-search-bar")[0]; // get the widget
// Pass the query to the Nuclia Search Widget
widget.search(queryInput);

const script2 = document.createElement("script"); // Call searchtester script after we get search results
script2.src = "{{ pathto('_static/searchtester.js', 1) }}";

// On searchtester.js load call function to add breadcrumbs
script2.onload = () => {
addBreadcrumbsToResults();
};
document.head.appendChild(script2);
};

document.head.appendChild(script);
});
</script>

<!-- Nuclia Widget -->
<nuclia-search-bar mode = "dark"
knowledgebox="62407006-2711-4631-9c03-761d156de289"
zone="europe-1"
features="answers,navigateToLink,hideThumbnails"
></nuclia-search-bar>

<!-- Search results -->
<nuclia-search-results mode = "dark"></nuclia-search-results>

<!-- Optional script below-->
<script>
// Activate the search field on page load
let searchInput = document.querySelector("form.bd-search input");
if (searchInput) {
searchInput.focus();
searchInput.select();
console.log("[PST]: Set focus on search field.");
}
</script>
{% endblock docs_body %}
{# Below sections just re-create the behavior of Sphinx default search #}
{# Page metadata #}
Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
-c constraints.txt

Sphinx
jsx-lexer
lesscpy
linkify-it-py
myst-parser
nuclia
nucliadb-sdk
sphinx-autobuild
sphinx-book-theme
sphinx-copybutton
Expand Down
Loading
Loading