From 8ac1bd36a82000633453556bc53cbfc46885f0a7 Mon Sep 17 00:00:00 2001 From: Inna K Date: Tue, 28 Apr 2026 18:53:13 +0300 Subject: [PATCH] added solution --- .github/workflows/test.yml-template | 29 ++++++ README.md | 14 +-- package-lock.json | 9 +- package.json | 3 +- src/scripts/main.js | 143 +++++++++++++++++++++++++++- 5 files changed, 184 insertions(+), 14 deletions(-) create mode 100644 .github/workflows/test.yml-template diff --git a/.github/workflows/test.yml-template b/.github/workflows/test.yml-template new file mode 100644 index 000000000..44ac4e963 --- /dev/null +++ b/.github/workflows/test.yml-template @@ -0,0 +1,29 @@ +name: Test + +on: + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [20.x] + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm start & sleep 5 && npm test + - name: Upload tests report(cypress mochaawesome merged HTML report) + if: ${{ always() }} + uses: actions/upload-artifact@v2 + with: + name: report + path: reports diff --git a/README.md b/README.md index cca9c9f4a..e29beb146 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ 1. Replace `` with your GitHub username in the link - - [DEMO LINK](https://.github.io/js_employees_table_DOM/) + - [DEMO LINK](https://Inna-code10.github.io/js_employees_table_DOM/) 2. Follow [this instructions](https://mate-academy.github.io/layout_task-guideline/) - Run `npm run test` command to test your code; - Run `npm run test:only -- -n` to run fast test ignoring linter; @@ -44,11 +44,11 @@ Start table: ``` - Add qa attributes for each input field: ``` - data-qa="name" - data-qa="position" - data-qa="office" - data-qa="age" - data-qa="salary" + data-qa="name" + data-qa="position" + data-qa="office" + data-qa="age" + data-qa="salary" ``` - Select should have 6 options: `Tokyo`, `Singapore`, `London`, `New York`, `Edinburgh`, `San Francisco`. - Use texts for labels and buttons from the screenshot below. @@ -64,7 +64,7 @@ Start table: - Notification titles and descriptions are up to you. - Add qa attribute for notification: `data-qa="notification"` and class `error`/`success` depending on the result. -##### Implement editing of table cells by double-clicking on them (optional). +##### Implement editing of table cells by double-clicking on them (optional). - Double click on the cell of the table, which should remove the text, and append input with `cell-input` class. - The input value should be replaced by the input text. - Only one cell can be edited at a time. diff --git a/package-lock.json b/package-lock.json index f844d43fd..84388c8d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@mate-academy/eslint-config": "latest", "@mate-academy/jest-mochawesome-reporter": "^1.0.0", "@mate-academy/linthtml-config": "latest", - "@mate-academy/scripts": "^1.8.5", + "@mate-academy/scripts": "^2.1.3", "@mate-academy/stylelint-config": "latest", "@parcel/transformer-sass": "^2.12.0", "cypress": "^13.13.0", @@ -1467,10 +1467,11 @@ "dev": true }, "node_modules/@mate-academy/scripts": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-1.8.6.tgz", - "integrity": "sha512-b4om/whj4G9emyi84ORE3FRZzCRwRIesr8tJHXa8EvJdOaAPDpzcJ8A0sFfMsWH9NUOVmOwkBtOXDu5eZZ00Ig==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@mate-academy/scripts/-/scripts-2.1.3.tgz", + "integrity": "sha512-a07wHTj/1QUK2Aac5zHad+sGw4rIvcNl5lJmJpAD7OxeSbnCdyI6RXUHwXhjF5MaVo9YHrJ0xVahyERS2IIyBQ==", "dev": true, + "license": "MIT", "dependencies": { "@octokit/rest": "^17.11.2", "@types/get-port": "^4.2.0", diff --git a/package.json b/package.json index 8d3435b6e..33390a32c 100644 --- a/package.json +++ b/package.json @@ -18,13 +18,12 @@ "postinstall": "npm run update", "test": "npm run lint && npm run test:only" }, - "dependencies": {}, "devDependencies": { "@linthtml/linthtml": "^0.9.6", "@mate-academy/eslint-config": "latest", "@mate-academy/jest-mochawesome-reporter": "^1.0.0", "@mate-academy/linthtml-config": "latest", - "@mate-academy/scripts": "^1.8.5", + "@mate-academy/scripts": "^2.1.3", "@mate-academy/stylelint-config": "latest", "@parcel/transformer-sass": "^2.12.0", "cypress": "^13.13.0", diff --git a/src/scripts/main.js b/src/scripts/main.js index a765fdb1d..7b1fc6e5f 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1,3 +1,144 @@ 'use strict'; -// write code here +const table = document.querySelector('table'); +const headers = table.querySelectorAll('th'); +const tbody = table.querySelector('tbody'); + +let sortDirection = true; +let currentColumn = null; + +headers.forEach((th, index) => { + th.addEventListener('click', () => { + if (currentColumn === index) { + sortDirection = !sortDirection; + } else { + sortDirection = true; + currentColumn = index; + } + + const rows = Array.from(tbody.querySelectorAll('tr')); + + rows.sort((a, b) => { + let aText = a.children[index].textContent; + let bText = b.children[index].textContent; + + if (index === 4) { + aText = Number(aText.replace(/[$,]/g, '')); + bText = Number(bText.replace(/[$,]/g, '')); + } + + if (!isNaN(aText)) { + aText = Number(aText); + } + + if (!isNaN(bText)) { + bText = Number(bText); + } + + if (aText > bText) { + return sortDirection ? 1 : -1; + } + + if (aText < bText) { + return sortDirection ? -1 : 1; + } + + return 0; + }); + tbody.append(...rows); + }); +}); + +tbody.addEventListener('click', (e) => { + const row = e.target.closest('tr'); + + if (!row) { + return; + } + + tbody.querySelectorAll('tr').forEach((tr) => tr.classList.remove('active')); + row.classList.add('active'); +}); + +const form = document.createElement('form'); + +form.className = 'new-employee-form'; + +form.innerHTML = ` + + + + + + +`; + +document.body.append(form); + +function showNotification(message, type) { + const div = document.createElement('div'); + + div.className = `notification ${type}`; + div.dataset.qa = 'notification'; + div.textContent = message; + document.body.append(div); + + setTimeout(() => { + div.style.display = 'none'; + }, 2000); +} + +form.addEventListener('submit', (e) => { + e.preventDefault(); + + const userName = form.name.value.trim(); + const position = form.position.value.trim(); + const office = form.office.value; + const age = Number(form.age.value); + const salary = Number(form.salary.value); + + if (!userName || !position || !age || !salary) { + showNotification('All fields are required', 'error'); + + return; + } + + if (userName.length < 4) { + showNotification('Name too short', 'error'); + + return; + } + + if (age < 18 || age > 90) { + showNotification('Invalid age', 'error'); + + return; + } + + const formattedSalary = `$${salary.toLocaleString('en-US')}`; + + const row = document.createElement('tr'); + + row.innerHTML = ` + ${userName} + ${position} + ${office} + ${age} + ${formattedSalary} + `; + + tbody.append(row); + + showNotification('Employee added!', 'success'); + + form.reset(); +});