Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
136 changes: 78 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,55 +1,3 @@
# Development Setup

### Clone mercurial repository.
```shell
hg clone http://hg.code.sf.net/p/roundup/code roundup
```

### Make python virtual env and activate it
```shell
cd roundup
python -m venv .
```
#### For linux and mac
```shell
source bin/activate
```
#### For windows powershell
```shell
.\scripts\Activate.ps1
```

### Install roundup
```shell
python -m pip install .
```

### Clone tracker only repo.
```shell
git clone https://github.com/UMB-CS-682-Team-03/tracker.git
```

### Init the demo tracker with default ./demo
```shell
roundup-demo -b sqlite
```

### Move the files from tracker dir to demo dir
#### For linux and mac
```shell
cp -r ./tracker/**/* ./demo
cp -r ./tracker/.git ./tracker/.gitignore ./demo
```
#### For windows powershell
```shell
xcopy .\tracker .\demo /s #say yes to all
```

1. Now you are done setting up developing environment.
2. Open the roundup folder in VScode.
3. Any new changes are only to be done in demo directory.
4. git is initialized to track origin in demo directory (for windows check if .git folder is copied to the demo)

# Roundup - Classhelper
## `<roundup-classhelper>`
## Why there is need of `<roundup-classhelper>` in the issue tracker?
Expand Down Expand Up @@ -224,7 +172,81 @@ Copy the following files into your Roundup instance `html` directory:

After copying these files, you can use the `<roundup-classhelper>` component in your Roundup templates.

# Missing translations
To set up translations for the <roundup-classhelper> component, follow these steps:

1. In your Roundup instance's Demo/locale directory, create a new file if not exists with the name __.po (e.g., de.po for German).

2. After the header, add the translation entries for the <roundup-classhelper> component.
For example next and submit are not being shown for German, you can add:
msgid "submit"
msgstr "gehen"

msgid "next"
msgstr "nächste"

msgid "name"
msgstr "name"

The **msgid** here is case sensitive therefore be careful.

3. Save the __.po file.

4. Restart your Roundup instance.

This should get you the missing translations, for more details refer roundup documentation for translations.

# Development Setup

### Clone mercurial repository.
```shell
hg clone http://hg.code.sf.net/p/roundup/code roundup
```

### Make python virtual env and activate it
```shell
cd roundup
python -m venv .
```
#### For linux and mac
```shell
source bin/activate
```
#### For windows powershell
```shell
.\scripts\Activate.ps1
```

### Install roundup
```shell
python -m pip install .
```

### Clone tracker only repo.
```shell
git clone https://github.com/UMB-CS-682-Team-03/tracker.git
```

### Init the demo tracker with default ./demo
```shell
roundup-demo -b sqlite
```

### Move the files from tracker dir to demo dir
#### For linux and mac
```shell
cp -r ./tracker/**/* ./demo
cp -r ./tracker/.git ./tracker/.gitignore ./demo
```
#### For windows powershell
```shell
xcopy .\tracker .\demo /s #say yes to all
```

1. Now you are done setting up developing environment.
2. Open the roundup folder in VScode.
3. Any new changes are only to be done in demo directory.
4. git is initialized to track origin in demo directory (for windows check if .git folder is copied to the demo)

# Running the Test Suite

Expand All @@ -233,13 +255,12 @@ After copying these files, you can use the `<roundup-classhelper>` component in
- GeckoDriver (for Firefox)

### Installation Instructions
1. **Selenium Installation**:
Open your terminal or command prompt and run:
python -m pip install selenium==4.18.1

2. **GeckoDriver Installation**:
pip install geckodriver==0.0.1
Enable the python virtual environment then proceed to install the following packages

```shell
python -m pip install selenium geckodriver
```

#### To run the code in a Headless Environment:
Set "HEADLESS = TRUE " in line 12.
Expand All @@ -250,4 +271,3 @@ After copying these files, you can use the `<roundup-classhelper>` component in

### Run the test suite
python test_classhelper.py

87 changes: 48 additions & 39 deletions html/classhelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const CLASSHELPER_POPUP_URL = "about:blank";
const CLASSHELPER_POPUP_TARGET = "_blank";

const CLASSHELPER_TABLE_SELECTION_NONE = "table-selection-none";
const CLASSHELPER_TRANSLATION_KEYWORDS = ["apply", "cancel", "next", "prev", "search", "reset"];

const ALTERNATIVE_DROPDOWN_PATHNAMES = {
"roles": "/rest/roles"
Expand Down Expand Up @@ -149,12 +150,6 @@ class ClassHelper extends HTMLElement {

const initialRequestURL = ClassHelper.getRestURL(this.trackerBaseURL, this.helpurlProps);

ClassHelper.fetchTranslations()
.catch(error => {
console.warn("Classhelper failed in translating.")
console.error(error);
});

this.fetchDropdownsData()
.catch(error => {
// Top level handling for dropdowns errors.
Expand Down Expand Up @@ -280,20 +275,39 @@ class ClassHelper extends HTMLElement {
return;
}

let translations = {
"Apply": "Apply",
"Cancel": "Cancel",
"Next": "Next",
"Prev": "Prev",
"Search": "Search",
"Reset": "Reset"
};
ClassHelper.translations = translations;
const keys = new Set();

const classhelpers = document.getElementsByTagName(CLASSHELPER_TAG_NAME);
for (let classhelper of classhelpers) {
if (classhelper.dataset.searchWith) {
classhelper.dataset.searchWith
.split(',')
.forEach(param => {
keys.add(param.split("[]")[0]);
});
}

const a = classhelper.querySelector("a");
if (a && a.dataset.helpurl) {
let searchParams = new URLSearchParams(a.dataset.helpurl.split("?")[1]);
let properties = searchParams.get("properties");
if (properties) {
properties.split(',').forEach(key => keys.add(key));
}
}
}

CLASSHELPER_TRANSLATION_KEYWORDS.forEach(key => keys.add(key));

ClassHelper.translations = {};
for (let key of keys) {
ClassHelper.translations[key] = key;
}

let tracker = window.location.pathname.split('/')[1];
let url = new URL(window.location.origin + "/" + tracker);
url.searchParams.append("@template", "translation");
url.searchParams.append("properties", Object.keys(translations).join(','));
url.searchParams.append("properties", Array.from(keys.values()).join(','));

let resp, json;

Expand Down Expand Up @@ -321,7 +335,9 @@ class ClassHelper extends HTMLElement {
throw new Error(message);
}

ClassHelper.translations = json;
for (let entry of Object.entries(json)) {
ClassHelper.translations[entry[0]] = entry[1];
}
}

async fetchDropdownsData() {
Expand Down Expand Up @@ -547,7 +563,7 @@ class ClassHelper extends HTMLElement {
const label = document.createElement("label");
label.classList.add("search-label"); // Add class for styling
label.setAttribute("for", param);
label.textContent = param + ":";
label.textContent = ClassHelper.translations[param] + ":";

let input;
if (this.dropdownsData[param]) {
Expand Down Expand Up @@ -602,7 +618,7 @@ class ClassHelper extends HTMLElement {
buttonCell.colSpan = 1;

const search = document.createElement("button");
search.textContent = ClassHelper.translations["Search"];
search.textContent = ClassHelper.translations["search"];
search.classList.add("search-button"); // Add class for styling
search.addEventListener("click", (e) => {
e.preventDefault();
Expand All @@ -615,7 +631,7 @@ class ClassHelper extends HTMLElement {
});

const reset = document.createElement("button");
reset.textContent = ClassHelper.translations["Reset"];
reset.textContent = ClassHelper.translations["reset"];
reset.classList.add("reset-button"); // Add class for styling
reset.addEventListener("click", (e) => {
e.preventDefault();
Expand Down Expand Up @@ -665,7 +681,7 @@ class ClassHelper extends HTMLElement {

const prev = document.createElement("button");
prev.innerHTML = "<";
prev.setAttribute("aria-label", ClassHelper.translations["Prev"]);
prev.setAttribute("aria-label", ClassHelper.translations["prev"]);
prev.setAttribute("disabled", "disabled");
if (prevUrl) {
prev.removeAttribute("disabled");
Expand All @@ -680,7 +696,7 @@ class ClassHelper extends HTMLElement {

const next = document.createElement("button");
next.innerHTML = ">";
next.setAttribute("aria-label", ClassHelper.translations["Next"]);
next.setAttribute("aria-label", ClassHelper.translations["next"]);
next.setAttribute("disabled", "disabled");
if (nextUrl) {
next.removeAttribute("disabled");
Expand Down Expand Up @@ -714,7 +730,7 @@ class ClassHelper extends HTMLElement {
}

const cancel = document.createElement("button");
cancel.textContent = ClassHelper.translations["Cancel"];
cancel.textContent = ClassHelper.translations["cancel"];
cancel.addEventListener("click", () => {
this.dispatchEvent(new CustomEvent("valueSelected", {
detail: {
Expand All @@ -726,7 +742,7 @@ class ClassHelper extends HTMLElement {
const apply = document.createElement("button");
apply.id = "popup-apply";
apply.classList.add("popup-apply");
apply.textContent = ClassHelper.translations["Apply"];
apply.textContent = ClassHelper.translations["apply"];
apply.addEventListener("click", () => {
this.dispatchEvent(new CustomEvent("valueSelected", {
detail: {
Expand Down Expand Up @@ -774,7 +790,7 @@ class ClassHelper extends HTMLElement {

headers.forEach(header => {
const th = document.createElement('th');
th.textContent = header;
th.textContent = ClassHelper.translations[header];
headerRow.appendChild(th);
});
thead.appendChild(headerRow);
Expand Down Expand Up @@ -830,19 +846,7 @@ class ClassHelper extends HTMLElement {
}

// Create table footer with the same column values as headers
const footerRow = document.createElement('tr');

if (includeCheckbox) {
let footThx = document.createElement("th");
footThx.textContent = "X";
footerRow.appendChild(footThx);
}

headers.forEach(header => {
const th = document.createElement('th');
th.textContent = header;
footerRow.appendChild(th);
});
const footerRow = headerRow.cloneNode(true);
Copy link
Contributor

Choose a reason for hiding this comment

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

Good catch.

tfoot.appendChild(footerRow);

// Assemble the table
Expand Down Expand Up @@ -1268,7 +1272,7 @@ function enableClassHelper() {
return;
}

/**@todo - make api call? get 404 then early return? */
/** make api call if error then do not register*/
// http://localhost/demo/rest

fetch("rest")
Expand All @@ -1279,6 +1283,11 @@ function enableClassHelper() {
return;
}
customElements.define(CLASSHELPER_TAG_NAME, ClassHelper);
ClassHelper.fetchTranslations()
.catch(error => {
console.warn("Classhelper failed in translating.")
console.error(error);
});
}).catch(err => {
console.error(err);
});
Expand Down
Loading