-
Notifications
You must be signed in to change notification settings - Fork 35
Onboarding Project: Meezaan #49
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
Open
MeezaanD
wants to merge
43
commits into
IMQS:master
Choose a base branch
from
MeezaanD:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
24da354
first push
MeezaanD f3ec479
update to search
MeezaanD a1270ce
update on how I display records on the load up page
MeezaanD 77728c9
fixed the filtering issues and displaying on the large screen
MeezaanD fc0e2d9
fixed the issue where I can do the next page on the last page
MeezaanD 7c0db77
updates on resizing not completely functional yet
MeezaanD 0614c90
upadtes on resizing according to the searchResults
MeezaanD 93d1277
add page number out total pages display on the dom
MeezaanD 320c076
changed the page to update according to the first record to always ch…
MeezaanD f6ae00b
added a background-color to search results
MeezaanD fba4223
first record on different page update
MeezaanD e1ea02b
updates to last page
MeezaanD 504dabe
new changes with the resize
MeezaanD f7d63df
upadtes
MeezaanD 4e33773
working search after resizing issue
MeezaanD 7eb6cf8
updates 30 Aug
MeezaanD 0b79c4a
updates
MeezaanD 55e4984
updates Aug 30
MeezaanD df6f87d
worked on navigations with buttons regarding to first and last page
MeezaanD e188ba6
first pull request changes
MeezaanD 56968ae
reduced global variables and other pull request changes
MeezaanD 9033e9c
first round of pull request changes made
MeezaanD 1297016
updates
MeezaanD 5bea166
updates 8 Sep
MeezaanD 9c91a08
updates 11 Sep
MeezaanD 6d189b1
updates 12 Sep
MeezaanD ca099e1
switching to class
MeezaanD d41e2f4
updated async functions to normal with adjustments and added javadoc …
MeezaanD b0e10fb
chnages 14 Sep
MeezaanD 4b1bb4b
small updates
MeezaanD 3211f9e
removed unnecessary spaces
MeezaanD 5fb8789
a few type adjustments
MeezaanD 581729c
updates 15 Sep
MeezaanD 8663db3
updates Wed 20 morning
MeezaanD b578caa
request for pr review
MeezaanD 510571e
removed the unnecessary return of the displayData on the updateScreen…
MeezaanD c9d1b4c
update
MeezaanD 3649ab6
css updates
MeezaanD 042d9ac
removed unnecessary returns
MeezaanD a00ccbc
small changes
MeezaanD 966ea03
removed unnecessary brackets
MeezaanD f0fb7a2
update
MeezaanD 65fb57b
update Oct 9
MeezaanD File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| // Use IntelliSense to learn about possible attributes. | ||
| // Hover to view descriptions of existing attributes. | ||
| // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | ||
| "version": "0.2.0", | ||
| "configurations": [ | ||
| { | ||
| "type": "chrome", | ||
| "request": "launch", | ||
| "name": "Launch Chrome against localhost", | ||
| "url": "http://localhost:2050", | ||
| "webRoot": "${workspaceFolder}", | ||
| "sourceMapPathOverrides": { | ||
| "webpack:///./*": "${webRoot}/*" | ||
| } | ||
| } | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| { | ||
| "cSpell.words": [ | ||
| "IMQS" | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,353 @@ | ||
| class InitializeApp { | ||
| IMQS: string = "http://localhost:2050"; | ||
| /** Current value of the first record being displayed */ | ||
| currentValueOfFirstRecord: number = 0; | ||
| /** Index of the first record currently displayed on the page */ | ||
| currentFirstRecordIndex: number = 0; | ||
| /** Current page number (changes dynamically) */ | ||
| currentPage: number = 1; | ||
| /** Total number of pages available (changes dynamically) */ | ||
| totalPages: number = 1; | ||
| /** Default number of records to display per page (changes on screen size) */ | ||
| recordsPerPage: number = 16; | ||
| /** Index of the record being searched for (null if not searching) */ | ||
| searchedIndex: number | null = null; | ||
| /** Actual value of the record being searched for (null if not searching) */ | ||
| searchedValue: number | null = null; | ||
| /** Checks if the button is enabled/disabled */ | ||
| isButtonDisabled: boolean = false; | ||
|
|
||
| constructor() { | ||
| $(window).on( | ||
| "resize", | ||
| this.debounce(() => { | ||
| this.updateScreen(); | ||
| }, 250) | ||
| ); | ||
| this.fetchColumns(); | ||
| this.updateScreen(); | ||
| this.eventHandlers(); | ||
| } | ||
|
|
||
| /** Fetch the total number of records from the server */ | ||
| totalRecords(): Promise<number> { | ||
| return fetch(`${this.IMQS}/recordCount`) | ||
| .then(recordCountResponse => { | ||
| if (!recordCountResponse.ok) { | ||
| throw new Error("Error trying to get recordCount"); | ||
| } | ||
| return recordCountResponse.text(); | ||
| }) | ||
| .then(recordCountData => { | ||
| return parseInt(recordCountData); | ||
| }) | ||
| .catch(error => { | ||
| throw error; | ||
| }); | ||
| } | ||
|
|
||
| /** Fetch column names and create them as table headings */ | ||
| fetchColumns(): Promise<string[]> { | ||
| return fetch(`${this.IMQS}/columns`) | ||
| .then((columnsResponse) => { | ||
| if (!columnsResponse.ok) { | ||
| throw new Error("Error trying to fetch the columns"); | ||
| } | ||
| return columnsResponse.json(); | ||
| }) | ||
| .then((columns: string[]) => { | ||
| const tableHeaderRow = $("#tableHeaderRow"); | ||
| for (const columnName of columns) { | ||
| const th = $("<th>").text(columnName); | ||
| tableHeaderRow.append(th); | ||
| } | ||
| return columns; | ||
| }) | ||
| .catch((error) => { | ||
| throw error; | ||
| }); | ||
| } | ||
|
|
||
| /** Fetch records within a specified range */ | ||
| fetchRecords(fromRecord: number, toRecord: number): Promise<string[]> { | ||
| if (fromRecord > toRecord) { | ||
| return Promise.reject( | ||
| new Error( | ||
| "Invalid arguments: fromRecord cannot be greater than toRecord" | ||
| ) | ||
| ); | ||
| } | ||
| return fetch(`${this.IMQS}/records?from=${fromRecord}&to=${toRecord}`).then( | ||
| (response) => { | ||
| if (!response.ok) { | ||
| throw new Error("Network response was not ok"); | ||
| } | ||
| return response.json(); | ||
| } | ||
| ); | ||
| } | ||
|
|
||
| displayData(fromRecord: number, recordsDisplayed: number): void { | ||
| $("#loader").show(); | ||
| $("#tableWrapper").hide(); | ||
| const adjustedFromRecord = Math.max(fromRecord, 0); | ||
| let recordCount: number; | ||
| this.totalRecords() | ||
| .then(count => { | ||
| recordCount = count; | ||
| this.totalPages = Math.ceil(recordCount / this.recordsPerPage); | ||
| if (this.currentPage > this.totalPages) { | ||
| this.currentPage = this.totalPages; | ||
| this.currentFirstRecordIndex = | ||
| Math.max(0, (this.currentPage - 1) * this.recordsPerPage); | ||
| } | ||
| const maxToRecord = | ||
| Math.min(adjustedFromRecord + recordsDisplayed - 1, recordCount - 1); | ||
| // Check if the calculated range exceeds the total records | ||
| if (maxToRecord < adjustedFromRecord) { | ||
| throw new Error("Error trying to display the data"); | ||
| } | ||
| return this.fetchRecords(adjustedFromRecord, maxToRecord).then( | ||
| (data) => { | ||
| return { data, maxToRecord }; | ||
| } | ||
| ); | ||
| }) | ||
| .then(({ data, maxToRecord }) => { | ||
| let tableData = ""; | ||
| if (data && data.length > 0) { | ||
| this.currentValueOfFirstRecord = parseInt(data[0][0]); | ||
| this.currentFirstRecordIndex = adjustedFromRecord; | ||
| for (const record of data) { | ||
| tableData += "<tr>"; | ||
| for (const value of record) { | ||
| tableData += `<td>${value}</td>`; | ||
| } | ||
| tableData += "</tr>"; | ||
| } | ||
| } | ||
| // Hide the "Next Page" button if maxToRecord is the last record | ||
| if (maxToRecord >= recordCount - 1) { | ||
| $("#nextPageButton").hide(); | ||
| } else { | ||
| $("#nextPageButton").show(); | ||
| } | ||
| if (this.searchedIndex !== null) { | ||
| this.currentPage = Math.ceil( | ||
| (this.searchedIndex + 1) / this.recordsPerPage | ||
| ); | ||
| this.currentFirstRecordIndex = Math.max( | ||
| this.searchedIndex - this.recordsPerPage + 1, 0 | ||
| ); | ||
| this.searchedIndex = null; | ||
| } | ||
| $("#tableBody").html(tableData); | ||
| $("#loader").hide(); | ||
| $("#tableWrapper").show(); | ||
| }) | ||
| .catch(error => { | ||
| throw new Error("An error occurred while fetching and displaying data." + error); | ||
| }); | ||
| } | ||
|
|
||
| /** Handle the search method */ | ||
| async searchMethod(searchValue: number): Promise<void> { | ||
| const totalRecCount = await this.totalRecords() | ||
| .catch(error => { | ||
| throw new Error("No valid records found" + error); | ||
| }); | ||
| if (searchValue < 0 || searchValue >= totalRecCount) { | ||
| window.alert("Record not found on this database"); | ||
| return; | ||
| } | ||
| const lastRecordIndex = totalRecCount - 1; | ||
| const targetPage = Math.ceil((searchValue + 1) / this.recordsPerPage); | ||
| const fromRecord = (targetPage - 1) * this.recordsPerPage; | ||
| const toRecord = Math.min( | ||
| fromRecord + this.recordsPerPage, | ||
| lastRecordIndex | ||
| ); | ||
| this.currentPage = targetPage; | ||
| this.searchedValue = searchValue; | ||
| this.currentFirstRecordIndex = fromRecord; | ||
| this.displayData(fromRecord, this.recordsPerPage); | ||
| } | ||
|
|
||
| /** Update the screen layout and data display */ | ||
| updateScreen(): void { | ||
| const newScreenHeight = window.innerHeight; | ||
| this.recordsPerPage = this.windowAdjustments(newScreenHeight); | ||
| this.totalRecords() | ||
| .then(totalRecCount => { | ||
| let fromRecord: number; | ||
| if (this.searchedValue !== null) { | ||
| const searchIndex = Math.min(this.searchedValue, totalRecCount - 1); | ||
| const targetPage = Math.ceil((searchIndex + 1) / this.recordsPerPage); | ||
| fromRecord = (targetPage - 1) * this.recordsPerPage; | ||
| } else { | ||
| const previousFirstRecordIndex = this.currentFirstRecordIndex; | ||
| this.currentPage = Math.ceil( | ||
| (previousFirstRecordIndex + 1) / this.recordsPerPage | ||
| ); | ||
| fromRecord = this.currentFirstRecordIndex; | ||
| } | ||
| if (this.currentPage * this.recordsPerPage > totalRecCount - 1) { | ||
| const lastPage = Math.ceil(totalRecCount / this.recordsPerPage); | ||
| this.currentPage = lastPage; | ||
| fromRecord = (lastPage - 1) * this.recordsPerPage; | ||
| } | ||
| this.displayData(fromRecord, this.recordsPerPage); | ||
| }) | ||
FritzOnFire marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| .catch(error => { | ||
| throw new Error("Error updating screen:" + error); | ||
| }); | ||
| } | ||
|
|
||
| /** Adjust the number of records displayed based on screen height */ | ||
| windowAdjustments(screenHeight: number): number { | ||
| const estimatedRowHeightFactor = 1; | ||
| const estimatedRowHeight = estimatedRowHeightFactor * 50; | ||
| const availableScreenHeight = screenHeight - 140; | ||
| this.recordsPerPage = Math.floor( | ||
| availableScreenHeight / estimatedRowHeight | ||
| ); | ||
| // This ensures that will at least be 1 record on display | ||
| return Math.max(this.recordsPerPage, 1); | ||
| } | ||
|
|
||
| /** Create a debounce function to delay function execution */ | ||
| debounce(func: any, delay: number) { | ||
| let timeoutId: any; | ||
| return function (...args: any) { | ||
| clearTimeout(timeoutId); | ||
| timeoutId = setTimeout(() => { | ||
| func(...args); | ||
| }, delay); | ||
| }; | ||
| } | ||
|
|
||
| /** Handles the events such as pagination buttons, input handling and search form */ | ||
| eventHandlers(): void { | ||
| /* Ensures that only positive numbers is accepted */ | ||
| $("#searchInput").on("input", (e) => { | ||
| const inputElement = e.target as HTMLInputElement; | ||
| const inputValue = inputElement.value; | ||
| const validInputRegex = /^[0-9]+$/; | ||
| if (!validInputRegex.test(inputValue)) { | ||
| const sanitizedInput = inputValue.replace(/[^0-9]/g, ""); | ||
| inputElement.value = sanitizedInput; | ||
| } | ||
| }); | ||
|
|
||
| /* Handle form submission for searching */ | ||
| $("#searchForm").submit((e) => { | ||
| e.preventDefault(); | ||
| const searchInputValue = <string>$("#searchInput").val(); | ||
| const searchValue = Number(searchInputValue); | ||
| this.searchedIndex = null; | ||
| this.searchMethod(searchValue) | ||
| .catch(error => { | ||
| window.alert("An error occurred during search. Please try again." + error); | ||
| }); | ||
| }); | ||
|
|
||
| /* Handle previous page button click */ | ||
| $("#prevPageButton").on("click", () => { | ||
| if ($("#prevPageButton").hasClass("hidden")) { | ||
| return; | ||
| } | ||
| if (this.currentFirstRecordIndex <= 0) { | ||
| const errorMessage = "Already on the first page"; | ||
| window.alert(errorMessage); | ||
| return; | ||
| } | ||
| $("#prevPageButton").addClass("hidden"); | ||
| this.searchedIndex = null; | ||
| this.searchedValue = null; | ||
| const firstRecordOfCurrentPage = | ||
| (this.currentPage - 1) * this.recordsPerPage; | ||
| let fromRecord = firstRecordOfCurrentPage; | ||
| $("#nextPageButton").hide(); | ||
| $("#prevPageButton").hide(); | ||
| $("#tableWrapper").hide(); | ||
| $("#loader").show(); | ||
| this.totalRecords() | ||
| .then(() => { | ||
| $("#prevPageButton").removeClass("hidden"); | ||
| $("#loader").hide(); | ||
| $("#tableWrapper").show(); | ||
| $("#nextPageButton").show(); | ||
| $("#prevPageButton").show(); | ||
| if (this.currentPage < this.totalPages) { | ||
| $("#nextPageButton").show(); | ||
| } | ||
| }) | ||
| .then(() => { | ||
| if (this.currentValueOfFirstRecord <= this.recordsPerPage) { | ||
| this.currentPage = 1; | ||
| this.currentFirstRecordIndex = 0; | ||
| } else { | ||
| this.currentPage--; | ||
| this.currentFirstRecordIndex -= this.recordsPerPage; | ||
| } | ||
| fromRecord = this.currentFirstRecordIndex; | ||
| this.displayData(fromRecord, this.recordsPerPage); | ||
| }) | ||
| .catch(error => { | ||
| throw new Error("Error while trying go to the previous page" + error); | ||
| }); | ||
| }); | ||
|
|
||
| /* Handle next page button click */ | ||
| $("#nextPageButton").on("click", () => { | ||
| if ($("#nextPageButton").hasClass("hidden")) { | ||
| return; | ||
| } | ||
| if (this.currentPage >= this.totalPages) { | ||
| const errorMessage = "Already on the last page"; | ||
| window.alert(errorMessage); | ||
| return; | ||
| } | ||
| $("#nextPageButton").addClass("hidden"); | ||
| this.searchedIndex = null; | ||
| this.searchedValue = null; | ||
| let fromRecord = this.currentFirstRecordIndex; | ||
| $("#nextPageButton").hide(); | ||
| $("#prevPageButton").hide(); | ||
| $("#tableWrapper").hide(); | ||
| $("#loader").show(); | ||
| this.totalRecords() | ||
| .then((totalRecCount: number) => { | ||
| $("#nextPageButton").removeClass("hidden"); | ||
| $("#loader").hide(); | ||
| $("#tableWrapper").show(); | ||
| $("#nextPageButton").show(); | ||
| $("#prevPageButton").show(); | ||
| if ( | ||
| typeof totalRecCount === "number" && | ||
| this.currentFirstRecordIndex >= totalRecCount | ||
| ) { | ||
| $("#nextPageButton").hide(); | ||
| } | ||
| }) | ||
| .then(() => { | ||
| if (this.currentPage < this.totalPages) { | ||
| this.currentPage++; | ||
| this.currentFirstRecordIndex += this.recordsPerPage; | ||
| } else { | ||
| this.currentPage = this.totalPages; | ||
| } | ||
| fromRecord = this.currentFirstRecordIndex; | ||
| this.displayData(fromRecord, this.recordsPerPage); | ||
| }) | ||
| .catch(() => { | ||
| throw new Error("Error while trying go to the next page"); | ||
| }); | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| window.onload = () => { | ||
| $("#loader").hide(); | ||
| new InitializeApp(); | ||
| }; | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice