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 22 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
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
name: build/deploy training.plone.org
name: Build / deploy staging.training.plone.org

on:
push:
branches:
- "main"
- "nuclia"
workflow_dispatch:

jobs:
build_deploy:
runs-on: ubuntu-latest
environment:
name: training.plone.org
url: https://training.plone.org
environment:
name: staging.training.plone.org
url: https://staging.training.plone.org
steps:
- uses: actions/checkout@v4

Expand Down
35 changes: 35 additions & 0 deletions .github/workflows/nuclia_sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
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: Commit changes
run: |
git config --global user.name github-actions
git config --global user.email [email protected]
git add .
git commit -m "Nuclia Sync: Updated docs" --allow-empty
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.

156 changes: 156 additions & 0 deletions docs/_static/searchtester.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
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(Container) {

// Container hash gets the md5 value of resource but i am unable to find resource by passing that hash
// let ContainerHash = Container.querySelector(
// "div > div.sw-field-metadata > div > div:nth-child(2) > span.title-xxs"
// ).innerText;

let ContainerHeading = Container.querySelector("div");

// One of The hash that works 79e4d894189842acb0902b5d879c2fe6
try {
nuclia.db
.getKnowledgeBox()
.pipe(
switchMap((knowledgeBox) =>
knowledgeBox.getResource("79e4d894189842acb0902b5d879c2fe6", [
"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 (e.g., '>')
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("result-title-container") &&
element.classList.length === 2
);
}

// Function to process added nodes within the shadow DOM
function processAddedNodes(addedNodes) {
addedNodes.forEach((addedNode) => {
if (isMatch(addedNode)) {
createBreadcrumbs(addedNode);
}
});
}

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 = `

/* Breadcrumb container */
.breadcrumbs {
font-size: 16px;
margin: 10px 0;
}

/* Breadcrumb links */
.breadcrumbs a {
text-decoration: none;
color: #007bff;
transition: color 0.2s;
}

/* Style for the last breadcrumb */
.breadcrumbs span:last-child {
color: #555;
}

/* Separator between breadcrumbs */
.breadcrumbs .separator {
margin: 0 5px;
color: #777;
}

/* Hover effect for breadcrumb links */
.breadcrumbs a:hover {
color: #0056b3;
}

`;
// Append the style element to the shadow DOM
shadowRoot.appendChild(style);
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>
120 changes: 80 additions & 40 deletions docs/_templates/search.html
Original file line number Diff line number Diff line change
@@ -1,42 +1,82 @@
{%- extends "page.html" %}
{# Over-ride the body to be custom search structure we want #}
{% block docs_body %}
<div class="bd-search-container">
<h1>{{ _("Search") }}</h1>
<noscript>
<div class="admonition error">
<p class="admonition-title">{% trans %}Error{% endtrans %}</p>
<p>{% trans %}Please activate JavaScript to enable the search functionality.{% endtrans %}</p>
</div>
</noscript>
{% block searchtext %}
<div>
{% trans %}Searching for multiple words only shows matches that contain
all words.{% endtrans %}
</div>
{% endblock %}
{% include "components/search-field.html" %}
<div id="search-results"></div>
{%- extends "page.html" %} {# Over-ride the body to be custom search structure
we want #} {% block docs_body %}
<div class="bd-search-container">
<h1>{{ _("Search") }}</h1>
<noscript>
<div class="admonition error">
<p class="admonition-title">{% trans %}Error{% endtrans %}</p>
<p>
{% trans %}Please activate JavaScript to enable the search
functionality.{% endtrans %}
</p>
</div>
</noscript>
{% block searchtext %}
<div>
{% trans %}Searching for multiple words only shows matches that contain all
words.{% endtrans %}
</div>
justdaksh marked this conversation as resolved.
Show resolved Hide resolved
<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 #}
{%- block htmltitle -%}
<title>{{ _("Search") }} - {{ title or docstitle }}</title>
{%- endblock htmltitle -%}
{# Manually include the search JS that Sphinx includes #}
{% block scripts -%}
{{ super() }}
<script src="{{ pathto('_static/searchtools.js', 1) }}"></script>
<script src="{{ pathto('_static/language_data.js', 1) }}"></script>
<script src="{{ pathto('searchindex.js', 1) }}"></script>
{% endblock %}
</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>

<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,displayMetadata" ></nuclia-search-bar>

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

<!-- Optional script -->
<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>
<!-- I Dont think below code is required anymore as it is related to sphinx-->
justdaksh marked this conversation as resolved.
Show resolved Hide resolved

{% endblock docs_body %} {# Below sections just re-create the behavior of Sphinx
default search #} {# Page metadata #} {%- block htmltitle -%}
<title>{{ _("Search") }} - {{ title or docstitle }}</title>
{%- endblock htmltitle -%} {# Manually include the search JS that Sphinx
includes #} {% block scripts -%} {{ super() }}
<script src="{{ pathto('_static/searchtools.js', 1) }}"></script>
<script src="{{ pathto('_static/language_data.js', 1) }}"></script>
<script src="{{ pathto('searchindex.js', 1) }}"></script>
{%- endblock scripts %}
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ sphinx-sitemap
sphinx-togglebutton
sphinxcontrib-spelling
sphinxext-opengraph
nuclia
nucliadb-sdk
justdaksh marked this conversation as resolved.
Show resolved Hide resolved
Loading