Merge pull request 'Search Feature implementation' (#3) from search into master

Reviewed-on: http://git.jdsfaulkner.com/dtookey/Engine_Rebuild/pulls/3
RebeccaBranch
David Tookey 5 years ago
commit a89f9b728e

@ -8,28 +8,32 @@
"description": "Track your time off, manage your benefits plans, and access pay stubs using this human-resources application.",
"imagePath": "paycor-logo3-100x100.png",
"urlText": "https://www.paycor.com/",
"altText": "Paycor logo"
"altText": "Paycor logo",
"keywords": "human resources, benefits, vacation, sick, bereavement, health, insurance, enrollment"
},
{
"title": "Swag Store",
"description": "Buy polo shirts and other logo gear here. Costs are deducted from Funny Money coupons or your paycheck.",
"imagePath": "swag-store-icon-100x100.png",
"urlText": "https://www.companycasuals.com/JDSfaulknerapparel/start.jsp",
"altText": "Store icon"
"altText": "Store icon",
"keywords": "human resources"
},
{
"title": "NC-4EZ Form",
"description": "Submit this form to HR so that the correct amount of state income tax can be witheld from your paychecks.",
"imagePath": "tax-icon-100x100.png",
"urlText": "https://www.ncdor.gov/documents/employees-withholding-allowance-certificate-nc-4ez",
"altText": "tax icon"
"altText": "tax icon",
"keywords": "human resources"
},
{
"title": "W-4 Form",
"description": "Fill out this form and submit to HR so that the company can withhold the correct federal income tax from your pay.",
"imagePath": "tax-icon-100x100.png",
"urlText": "https://www.irs.gov/forms-pubs/about-form-w-4",
"altText": "tax icon"
"altText": "tax icon",
"keywords": "human resources"
}
]
},
@ -41,28 +45,32 @@
"description": "Our website conveys the company's value and convinces visitors to choose JDSfaulkner, all in the blink of an eye.",
"imagePath": "jdsfaulkner-small-icon.png",
"urlText": "https://jdsfaulkner.com/",
"altText": "JDSfaulkner brand mark"
"altText": "JDSfaulkner brand mark",
"keywords": "marketing"
},
{
"title": "Salesforce",
"description": "Focus on the customer experience with the help of the Salesforce customer relationship management application.",
"imagePath": "salesforce-logo-100x100.png",
"urlText": "https://login.salesforce.com/",
"altText": "Salesforce logo"
"altText": "Salesforce logo",
"keywords": "marketing"
},
{
"title": "Facebook",
"description": "Through Facebook, the company connects with the community by sharing content and interacting with the public.",
"imagePath": "facebooklogogrey_100x100.png",
"urlText": "https://www.facebook.com/JDSfaulkner/",
"altText": "Facebook icon"
"altText": "Facebook icon",
"keywords": "marketing, social"
},
{
"title": "LinkedIn",
"description": "JDSfaulkner maintains a presence on LinkedIn for professional networking, posting job openings and receiving resumes.",
"imagePath": "linkedinlogo_100x100.png",
"urlText": "https://www.linkedin.com/company/jds-consulting-&-design",
"altText": "LinkedIn icon"
"altText": "LinkedIn icon",
"keywords": "marketing, social"
}
]
},
@ -74,28 +82,32 @@
"description": "Access your company e-mail along with a suite of Google apps, including a calendar, instant messaging and cloud storage.",
"imagePath": "gmail-logo2-100x100.png",
"urlText": "https://mail.google.com",
"altText": "Gmail logo"
"altText": "Gmail logo",
"keywords": "productivity"
},
{
"title": "Workplace",
"description": "Get the latest news and connect with colleagues. JDSfaulkner uses Workplace by Facebook for posting and sharing.",
"imagePath": "workplace-logo3-100x100.png",
"urlText": "https://jdsfaulkner.workplace.com",
"altText": "Workplace logo"
"altText": "Workplace logo",
"keywords": "productivity, social"
},
{
"title": "Google Workspace",
"description": "This suite of Google products includes Gmail, Calendar, Meet, Chat, Drive, Docs, Sheets, Slides, Forms and more.",
"imagePath": "google-logo2-100x100.png",
"urlText": "https://myaccount.google.com/",
"altText": "Google Workspace logo"
"altText": "Google Workspace logo",
"keywords": "productivity, e-mail"
},
{
"title": "Dropbox",
"description": "The Structural Engineering Design department stores most of its files and folders in the Dropbox cloud-based system.",
"imagePath": "dropbox-logo3-100x100.png",
"urlText": "https://www.dropbox.com/login",
"altText": "Dropbox logo"
"altText": "Dropbox logo",
"keywords": "productivity, storage"
}
]
},
@ -107,35 +119,40 @@
"description": "Visit your central location for e-learning, offering the flexibility to learn on your own schedule and at your own pace. Password: jdsfaulknerschool",
"imagePath": "learning-center-icon4-100x100.png",
"urlText": "https://jdsfaulkner.workplace.com",
"altText": "Learning Center icon"
"altText": "Learning Center icon",
"keywords": "training, courses"
},
{
"title": "Company Procedures",
"description": "Find out how to carry out specific tasks at JDSfaulkner in a manner that ensures company-wide consistency and quality. Password: jdsfaulknerschool",
"description": "Find out how to carry out specific tasks at JDSfaulkner in a manner that ensures company-wide consistency and quality. Learning Center password: jdsfaulknerschool",
"imagePath": "learning-center-icon4-100x100.png",
"urlText": "https://learning.carolina.engineering/additional-resources/",
"altText": "Learning Center icon"
"altText": "Learning Center icon",
"keywords": "SOP, standard operating procedure, training, instructions"
},
{
"title": "Field Guide",
"description": "This quick-reference guide helps engineering technicians find helpful charts, tables and information. Password: jdsfaulknerschool",
"description": "This quick-reference guide helps engineering technicians find helpful charts, tables and information. Learning Center password: jdsfaulknerschool",
"imagePath": "learning-center-icon4-100x100.png",
"urlText": "https://learning.carolina.engineering/additional-resources/",
"altText": "Learning Center icon"
"altText": "Learning Center icon",
"keywords": "training"
},
{
"title": "CAD Tech Study Guide",
"description": "This guide presents lessons for drafters, each of which can help a drafter advance to CAD Tech II status. Password: jdsfaulknerschool",
"description": "This guide presents lessons for drafters, each of which can help a drafter advance to CAD Tech II status. Learning Center password: jdsfaulknerschool",
"imagePath": "learning-center-icon4-100x100.png",
"urlText": "https://learning.carolina.engineering/additional-resources/",
"altText": "Learning Center icon"
"altText": "Learning Center icon",
"keywords": "training, modules, drafting, design"
},
{
"title": "Deltek University",
"description": "Increase your Deltek knowledge with courses designed to teach you how to use Deltek solutions.",
"imagePath": "deltek-logo-black.png",
"urlText": "https://www.deltek.com/en/support/deltek-university",
"altText": "Deltek logo"
"altText": "Deltek logo",
"keywords": "training"
}
]
},
@ -147,42 +164,48 @@
"description": "Create, track, review and bill field-engineering projects, start to finish, with Clarity project management software.",
"imagePath": "clarity-icon-100x100.png",
"urlText": "https://learning.carolina.engineering/introduction-to-clarity/",
"altText": "Clarity image"
"altText": "Clarity image",
"keywords": "workflow, applications, account"
},
{
"title": "Project Insight",
"description": "Structural Engineering Design uses this project management software to centralize the group's work, tasks and projects.",
"imagePath": "project-insight-logo6-100x100.png",
"urlText": "https://jds.projectinsight.net/",
"altText": "Project Insight logo"
"altText": "Project Insight logo",
"keywords": "workflow, applications, CAD, draft, plans, account, track"
},
{
"title": "Deltek",
"description": "Project intelligence, management and collaboration software helps maximize productivity and revenue.",
"imagePath": "deltek-logo-black.png",
"urlText": "https://www.deltek.com/en",
"altText": "Deltek logo"
"altText": "Deltek logo",
"keywords": "workflow, applications, account, track"
},
{
"title": "Procore",
"description": "Administrators for field engineering projects use Procore for collecting, reviewing and approving invoices.",
"imagePath": "ProcoreLogo2.png",
"urlText": "https://www.procore.com/",
"altText": "Procore logo"
"altText": "Procore logo",
"keywords": "workflow, applications, software, account"
},
{
"title": "Client W-9 Form",
"description": "A W-9 form is required by JDSfaulkner so that the company can file an information return with the IRS.",
"imagePath": "tax-icon-100x100.png",
"urlText": "https://www.irs.gov/forms-pubs/about-form-w-9",
"altText": "tax icon"
"altText": "tax icon",
"keywords": "workflow, tax, account"
},
{
"title": "Project Folders",
"description": "Access vital information about specific projects from initial set-up to final delivery in an accessible and central location.",
"imagePath": "project-folder-icon-100x100.png",
"urlText": "../resources/coming-soon.pdf",
"altText": "Project folder icon"
"altText": "Project folder icon",
"keywords": "workflow"
}
]
}

@ -24,6 +24,24 @@
alt="JDSfaulkner logo">
 Resource Center
</a>
<nav class="my-2 my-md-0 mr-md-3">
<div class="sb-example-1">
<div class="search">
<input id="searchfield" type="text" class="searchTerm" placeholder="Search">
<button id="searchbutton" type="submit" class="searchbutton">
<svg width="100%" height="auto" viewBox="-1 -3 22 22" class="bi bi-search" fill="info"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M10.442 10.442a1 1 0 0 1 1.415 0l3.85 3.85a1 1 0 0 1-1.414 1.415l-3.85-3.85a1 1 0 0 1 0-1.415z"/>
<path fill-rule="evenodd"
d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zM13 6.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
</svg>
</button>
</div>
</div>
</nav>
<nav class="my-2 my-md-0 mr-md-3">
<div class="helpdropdown">
<a class="p-2 navigationitem" href="#" role="button" id="helpdropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-offset="-75,4">Help</a>
@ -122,24 +140,11 @@
</nav>
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
<div class="justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3">
<div class="justify-content-between flex-wrap flex-md-nowrap align-items-center pt-5 pb-2 mb-3">
<div class="album py-5">
<div class="sb-example-1">
<div class="search">
<input type="text" class="searchTerm" placeholder="Search">
<button type="submit" class="searchbutton">
<svg width="100%" height="auto" viewBox="-1 -3 22 22" class="bi bi-search" fill="info"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M10.442 10.442a1 1 0 0 1 1.415 0l3.85 3.85a1 1 0 0 1-1.414 1.415l-3.85-3.85a1 1 0 0 1 0-1.415z"/>
<path fill-rule="evenodd"
d="M6.5 12a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zM13 6.5a6.5 6.5 0 1 1-13 0 6.5 6.5 0 0 1 13 0z"/>
</svg>
</button>
</div>
</div>
<div class="album py-5 ">
@ -168,6 +173,7 @@
<script src="scripts/tsUtil.js"></script>
<script>loadTSTarget("themes.js");</script>
<script>let help = loadTSTarget("help.js");</script>
<script>loadTSTarget("search.js");</script>
<script src="scripts/index_app.js"></script>
</html>

@ -2,7 +2,7 @@ const path = require('path');
const factory = require(path.join(appDir, 'viewFactory'))
function loadDocuments() {
factory.buildWebCardsFromConfig("resources-landing-page.json");
factory.buildUiFromConfig("resources-landing-page.json");
}
loadDocuments();

@ -102,27 +102,35 @@ body {
position: relative;
display: flex;
margin: auto;
max-width: 1100px
max-width: 1100px;
}
.sb-example-1 .searchTerm {
width: 100%;
border: 1px solid;
border-color: map-get($theme-colors, boxborder2);
border-color: map-get($theme-colors, boxborder3);
border-right: none;
padding-left: 15px;
padding-right: 15px;
border-radius: 25px 0 0 25px;
stroke: map-get($theme-colors, searchicon);
color: map-get($theme-colors, searchhint);
background-color: map-get($theme-colors, info);
background-color: map-get($theme-colors, searchfill);
box-shadow: none;
outline: none;
}
.sb-example-1 .searchTerm:hover {
stroke: map-get($theme-colors, searchiconhover);
background-color: map-get($theme-colors, searchfill);
box-shadow: none;
color: map-get($theme-colors, searchfont) !important;
outline: none;
}
.sb-example-1 .searchTerm:focus {
stroke: map-get($theme-colors, searchicon);
background-color: map-get($theme-colors, info);
stroke: map-get($theme-colors, searchiconhover);
background-color: map-get($theme-colors, searchfill);
box-shadow: none;
color: map-get($theme-colors, searchfont) !important;
outline: none;
@ -143,14 +151,29 @@ body {
outline: none;
}
.sb-example-1 .searchbutton:hover {
width: 40px;
height: 50px;
border: 1px solid;
border-color: map-get($theme-colors, boxborder2);
background-color: map-get($theme-colors, searchbuttonfill);
text-align: center;
fill: map-get($theme-colors, searchiconhover) !important;
border-radius: 0 25px 25px 0;
cursor: pointer;
font-weight: normal;
box-shadow: none;
outline: none;
}
.sb-example-1 .searchbutton:focus {
width: 40px;
height: 50px;
border: 1px solid;
border-color: map-get($theme-colors, boxborder2);
background-color: map-get($theme-colors, searchbuttonfillfocus);
background-color: map-get($theme-colors, searchbuttonfill);
text-align: center;
fill: map-get($theme-colors, searchiconfocus);
fill: map-get($theme-colors, searchiconfocus) !important;
border-radius: 0 25px 25px 0;
cursor: pointer;
font-weight: normal;
@ -193,7 +216,7 @@ body {
.feedbackdropdown .dropdown-menu {
background-color: map-get($theme-colors, menudropdownfill);
font-size: 15px;
margin-bottom: 9 px;
margin-bottom: 9px;
color: map-get($theme-colors, activetextaccordion);
box-shadow: -1 1 3 1 #cccccc;
}
@ -286,4 +309,9 @@ hr {
margin-bottom: 1rem;
border: 0;
border-top: 1px solid rgba(0, 0, 0, 0.1);
}
.highlight {
color: map-get($theme-colors, highlight-text-color);
background-color: map-get($theme-colors, highlight-background);
}

@ -11,15 +11,19 @@ $theme-colors: (
"inactivecard": #333337,
"activecard": #4f4f56,
"boxborder": #272727,
"boxborder2": #2f2f2f,
"boxborder2": #3c3c42,
"boxborder3": #323237,
"activecardfont":#e1e4e8,
"searchhint": #6b6866,
"searchfont": #9f9c9a,
"searchfill": #323237,
"sidebarfill": #202023,
"searchbuttonfill": #39393f,
"searchbuttonfillfocus": #3e3e45,
"searchicon": #737373,
"searchiconfocus": #878787,
"searchbuttonfill": #585861,
"searchbuttonfillhover": #808080,
"searchbuttonfillfocus": #585861,
"searchicon": #808080,
"searchiconhover": #c5c5c5,
"searchiconfocus": #c5c5c5,
"sidebartext": #7d7d7d,
"sidebarbg": #29292d,
"webcardimagebackground": #707070,
@ -51,7 +55,9 @@ $theme-colors: (
"footerbackhover": rgba(157, 157, 157, .8),
"helpmenudropdowntext": #9d9d9d,
"helpmenudropdowntexthover": #a8a8a8,
"helpmenudropdownbghover": #5c5c66,
"helpmenudropdownbghover": #5c5c66,
"highlight-text-color": #000,
"highlight-background": #ece665,
);
.theme-button{

@ -11,17 +11,21 @@ $theme-colors: (
"inactivecard": #ffffff,
"activecard": #13a04a,
"boxborder": #c0c2c6,
"boxborder2": #c0c2c6,
"boxborder2": #ececec,
"boxborder3": #ebebeb,
"activecardfont": #e1e4e8,
"searchhint": #c0c2c6,
"searchfont": #2c2c2c,
"sidebarfill": #efefef,
"sidebartext": #3f4959,
"sidebarbg": #e5e5e5,
"searchbuttonfill": #f6f6f6,
"searchfill": #f0f0f2,
"searchbuttonfill": #ffffff,
"searchbuttonfillhover": #f6f6f6,
"searchbuttonfillfocus": #f1f1f1,
"searchicon": #3f4959,
"searchiconfocus": #38414f,
"searchiconhover": #000,
"searchiconfocus": #000,
"webcardimagebackground": #eeeeee,
"webcardimagebackgroundhover": #f0f0f0,
"headertextcolor": #080404,
@ -53,6 +57,8 @@ $theme-colors: (
"helpmenudropdowntext": #3f4a5a,
"helpmenudropdowntexthover": #080404,
"helpmenudropdownbghover": #f2f2f2,
"highlight-text-color": #000,
"highlight-background": #ece665,
);
.theme-button{

@ -1,5 +1,6 @@
{
"title": "Direct Deposit",
"description": "Would you like have your paychecks deposited into your bank account? Fill out this form and submit it to HR.",
"altText": "PDF icon"
"altText": "PDF icon",
"keywords": "human resources"
}

@ -2,5 +2,6 @@
"title": "Employment Application",
"description": "Would you or someone you know like to apply for a position? JDSfaulkner is always accepting applications.",
"altText": "Document icon"
"altText": "Document icon",
"keywords": "human resources, career, job"
}

@ -1,5 +1,6 @@
{
"title": "Expense Report",
"description": "Request reimbursement for preapproved, company-related expenses. Send this form and receipts to Accounts Payable.",
"altText": "PDF icon"
"altText": "PDF icon",
"keywords": "human resources, purchase"
}

@ -1,5 +1,6 @@
{
"title": "Drafting Quiz",
"description": "Click here to access a prequalifying quiz that is a requirement for those applying for drafting positions.",
"altText": "Document icon"
"altText": "Document icon",
"keywords": "human resources, plans, design, job, career, interview"
}

@ -1,5 +1,6 @@
{
"title": "Employee Handbook",
"description": "Read the handbook to learn about the companys policies related to employment, including pay and benefits.",
"altText": "PDF icon"
"altText": "PDF icon",
"keywords": "human resources"
}

@ -1,5 +1,6 @@
{
"title": "SRA",
"description": "A salary reduction agreement helps you to establish or change the part of your compensation that goes to an IRA.",
"altText": "PDF icon"
"altText": "PDF icon",
"keywords": "human resources, savings, retirement"
}

@ -1,5 +1,6 @@
{
"title": "JDSfaulkner Brochure",
"description": "Share the company's brochure with existing and potential clients to showcase the value JDSfaulkner has to offer.",
"altText": "PDF icon"
"altText": "PDF icon",
"keywords": "marketing, publications"
}

@ -1,5 +1,6 @@
{
"title": "JDSfaulkner SOQ",
"description": "SOQs present the experience and capabilities that qualify JDSfaulkner to win contracts or new clients.",
"altText": "PDF icon"
"altText": "PDF icon",
"keywords": "marketing, statement, qualifications, publications"
}

@ -1,5 +1,6 @@
{
"title": "JDSfaulkner Letterhead",
"description": "Represent the company in a professional and consistent manner by writing your letters using this official letterhead template.",
"altText": "Document icon"
"description": "Represent the company in a professional and consistent manner using the official letterhead for correspondence.",
"altText": "Document icon",
"keywords": "marketing, template"
}

@ -1,5 +1,6 @@
{
"title": "JDSfaulkner Logo - EPS",
"description": "Do you need to present the logo in your work? Here's an eps format to use in collateral and merchandise.",
"altText": "Image icon"
"description": "Do you need to present the logo in your work? Here's an EPS format to use in collateral and merchandise.",
"altText": "Image icon",
"keywords": "marketing"
}

@ -1,5 +1,6 @@
{
"title": "JDSfaulkner Logo - PNG",
"description": "Do you need to present the logo in your work? Here's a png format to use in collateral and merchandise.",
"altText": "Image icon"
"description": "Do you need to present the logo in your work? Here's a PNG format to use in collateral and merchandise.",
"altText": "Image icon",
"keywords": "marketing"
}

@ -2,8 +2,8 @@
<div class="col-md-4 mb-4 web-card" id="{{{id}}}">
<div class="card mb-4 h-100 shadow-sm web-card-background">
<div class="card-body d-flex flex-column text-center">
<h6 class="card-text text-header" style="text-align:center">{{title}}</h6>
<p class="card-text text-paragraph text-align-left">{{description}} </p>
<h6 class="card-text text-header" style="text-align:center">{{{title}}}</h6>
<p class="card-text text-paragraph text-align-left">{{{description}}} </p>
<div class="d-inline-block mt-auto mx-auto justify-content-between align-items-center web-card-image-background">
<img id="collapse-image" class="rounded-circle mx-auto d-block img-fluid"
src="{{{imgPath}}}" alt="{{{altText}}}"

@ -108,33 +108,30 @@ export class DocumentDirectory {
root: DirectoryNode;
getCards(): Map<String, object[]> {
getCards(): Map<string, object[]> {
return DocumentDirectory.walkCards(this.root);
}
private static walkCards(d: DirectoryNode): Map<String, object[]> {
let cardsByCategory = new Map<String, object[]>();
for (let i = 0, l = d.children.length; i < l; i++) {
let child = d.children[i];
private static walkCards(d: DirectoryNode): Map<string, object[]> {
let cardsByCategory = new Map<string, object[]>();
for (let child of d.children) {
if (child instanceof DirectoryNode) {
let dir = child as DirectoryNode;
if (dir.containsDirectory()) {
let childDirectories = dir.getDirectories();
for (let j = 0, k = childDirectories.length; j < k; j++) {
let dir = childDirectories[j];
for (let dir of childDirectories) {
let subCards = DocumentDirectory.walkCards(dir);
this.mergeMaps(cardsByCategory, subCards);
}
}
let sCards = dir.getDocuments();
let category = dir.getCategory();
for (let sCard in sCards) {
let scrd = sCards[sCard];
for (let sCard of sCards) {
let cards = cardsByCategory.get(category);
if (cards === undefined || cards === null) {
cards = [];
}
cards.push(scrd.toCard());
cards.push(sCard.toCard());
cardsByCategory.set(category, cards);
}
} else {
@ -151,10 +148,9 @@ export class DocumentDirectory {
return cardsByCategory;
}
private static mergeMaps(a: Map<String, Object[]>, b: Map<String, Object[]>) {
private static mergeMaps(a: Map<string, Object[]>, b: Map<string, Object[]>) {
let keys = Object.keys(b);
for (let z in keys) {
let key = keys[z];
for (let key of keys) {
let sa = a.get(key)
if (sa === undefined || sa === null) {
sa = [];
@ -180,7 +176,7 @@ export class FileNode {
this.parent = parent;
}
static loadAltProps(path: String): object {
static loadAltProps(path: string): object {
let props = {};
let jsonPath = path + ".json"
if (fs.existsSync(jsonPath)) {
@ -213,19 +209,19 @@ export class FileNode {
"imagePath": imageName,
"urlText": this.filePath,
"altText": "",
"fileCard": true
"fileCard": true,
"open": this.open
}
let altKeys = Object.keys(altProps);
for (let kidx in altKeys) {
let key = altKeys[kidx];
for (let key of altKeys) {
cardObj[key] = altProps[key]
}
return cardObj
}
getTitle(): String {
getTitle(): string {
let name = path.basename(this.filePath);
let ext = path.extname(name);
let cName = name.replace(ext, "");
@ -251,9 +247,9 @@ export class DirectoryNode extends FileNode {
let stats = fs.lstatSync(filePath);
if (stats.isDirectory()) {
let contents = fs.readdirSync(filePath);
for (let i = 0, l = contents.length; i < l; i++) {
if (path.extname(contents[i]) === ".json") continue;
let childPath = path.join(filePath, contents[i]);
for (let fileName of contents) {
if (path.extname(fileName) === ".json") continue;
let childPath = path.join(filePath, fileName);
let childStats = fs.lstatSync(childPath);
if (childStats.isDirectory()) {
this.children.push(new DirectoryNode(childPath, this));
@ -282,14 +278,13 @@ export class DirectoryNode extends FileNode {
}
containsDirectory(): Boolean {
for (let i = 0, l = this.children.length; i < l; i++) {
let child = this.children[i];
for (let child of this.children) {
if (child instanceof DirectoryNode) return true;
}
return false
}
getCategory(): String {
getCategory(): string {
let rawName = path.basename(this.filePath);
let parts = rawName.split("-");
for (let i = 0, l = parts.length; i < l; i++) {

@ -0,0 +1,160 @@
import {Configurator, DocumentDirectory} from "./fileutils";
import * as path from "path";
import {buildCardsFromConfig, buildUiFromConfig} from "./viewFactory";
function register() {
let searchBar = $("#searchfield");
let searchButton = $("#searchbutton");
searchBar.on("keyup", (evt) => {
if ("Enter" === evt.code) {
let term = searchBar.val().toString();
if (!term || 0 === term.length) {
reset()
} else {
search(term);
}
} else {
let term = searchBar.val().toString();
if (!term || 0 === term.length) {
reset()
}
}
});
searchButton.on("click", () => {
let term = searchBar.val().toString();
if (!term || 0 === term.length) {
reset()
} else {
search(term);
}
})
}
function reset() {
buildUiFromConfig("resources-landing-page.json");
}
function search(term: string) {
let webCards = getWebCardsWithSearchTerm(term);
let fileCards = getFileCardsWithSearchTerm(term);
copyMissingKeys(webCards, fileCards);
buildCardsFromConfig(webCards, fileCards);
expandAllContainers();
}
function copyMissingKeys(webCards: object, fileCards: Map<string, object>) {
let elementConfig = Configurator.loadAppConfig("resources-landing-page.json");
let containerKeys = Object.keys(elementConfig);
for (let containerKey of containerKeys) {
let container = webCards[containerKey];
let elementContainer = elementConfig[containerKey];
for (let [key, value] of fileCards) {
if (!container[key]) {
let original = elementContainer[key];
original["cards"] = [];
container[key] = original;
}
}
}
}
function getFileCardsWithSearchTerm(term): Map<string, object> {
let map = new Map<string, object>()
let directoryPath = path.join(__dirname, "../assets/resources");
let fileCards = new DocumentDirectory(directoryPath).getCards();
for (let [key, value] of fileCards) {
for (let card of value) {
if (cardContainsTerm(term, card)) {
addToFileMap(map, key, highlightCardTerm(term, card));
}
}
}
return map;
}
function getWebCardsWithSearchTerm(term): object {
let map = {};
let elementConfig = Configurator.loadAppConfig("resources-landing-page.json");
let containerKeys = Object.keys(elementConfig);
for (let i = 0, l = containerKeys.length; i < l; i++) {
let containerKey = containerKeys[i];
map[containerKey] = {};
let container = elementConfig[containerKey];
let categoryKeys = Object.keys(container);
for (let categoryIdx in categoryKeys) {
let categoryKey = categoryKeys[categoryIdx]
let category = container[categoryKey];
let cards = category.cards;
for (let j = 0, k = cards.length; j < k; j++) {
let card = cards[j];
if (cardContainsTerm(term, card)) {
addToWebMap(map, containerKey, categoryKey, category["description"], highlightCardTerm(term, card));
}
}
}
}
return map;
}
function addToWebMap(map: object, containerKey: string, categoryKey: string, categoryDescription: string, card: object) {
let container = map[containerKey];
if (!container) {
container = {};
}
let category = container[categoryKey];
if (!category) {
category = {"description": categoryDescription, "cards": []}
}
category["cards"].push(card);
container[categoryKey] = category;
map[containerKey] = container;
}
function addToFileMap(map: Map<string, object>, categoryKey: string, card) {
if (!map.get(categoryKey)) {
map.set(categoryKey, []);
}
let cards = map.get(categoryKey) as Array<object>;
cards.push(card);
map.set(categoryKey, cards);
}
function cardContainsTerm(term: string, card: object): boolean {
let titleContains = card["title"].toLowerCase().includes(term.toLowerCase());
let descriptionContains = card["description"].toLowerCase().includes(term.toLowerCase());
let keywordContains = false;
if (card["keywords"]) {
keywordContains = card["keywords"].toLowerCase().includes(term.toLowerCase());
}
//todo: add keywords
return titleContains || descriptionContains || keywordContains;
}
function highlightCardTerm(term: string, card: object): object {
let regexTerm = escapeRegExp(term);
let pattern = new RegExp(regexTerm, 'ig');
card["title"] = card["title"].replace(pattern, `<span class="highlight">$&</span>`);
card["description"] = card["description"].replace(pattern, `<span class="highlight">$&</span>`);
return card;
}
function escapeRegExp(term: string): string {
return term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
function expandAllContainers() {
let containers = $('[id$="collapser"]')
for (let container of containers) {
container.click()
}
}
register()

@ -22,7 +22,6 @@ export class CardModel {
}
export function buildFileCard(elem: JQuery<HTMLElement>, obj, append: boolean = false, $: any = require('jquery')) {
console.log(obj);
let model = new CardModel(
obj["title"],
obj["description"],
@ -40,30 +39,32 @@ export function buildFileCard(elem: JQuery<HTMLElement>, obj, append: boolean =
if (model["show"] !== undefined) {
$(`#${id}`).on("click", () => {
console.log("showing")
shell.showItemInFolder(model.resourcePath)
});
} else {
$(`#${id}`).on("click", () => {
console.log("opening")
shell.openItem(model.resourcePath)
});
}
});
}
export function buildWebCardsFromConfig(configName: string) {
export function buildUiFromConfig(configName: string){
let elementConfig = Configurator.loadAppConfig(configName);
let $ = require('jquery')
let containers = Object.keys(elementConfig);
let directoryPath = path.join(__dirname, "../assets/resources");
let fileCards = new DocumentDirectory(directoryPath).getCards();
for (let i = 0, l = containers.length; i < l; i++) {
buildCardsFromConfig(elementConfig, fileCards);
}
export function buildCardsFromConfig(elementConfig: object, fileCards: Map<string, object>) {
let $ = require('jquery')
let containers = Object.keys(elementConfig);
for (let i = 0, l = containers.length; i < l; i++) {
let containerName = containers[i];
let containerObject = elementConfig[containerName];
let containerElem = $(`#${containerName}`);
containerElem.html("")
let containerCategories = Object.keys(containerObject);
for (let j = 0, m = containerCategories.length; j < m; j++) {
@ -89,25 +90,7 @@ export function buildWebCardsFromConfig(configName: string) {
let view = $(`#${categoryKey}-container`);
let collapseButton = $(`#${categoryKey}-collapser`);
collapseButton.on("click", () => {
let imageMatchRegex = /\.\.\/images\/chevron-(\w+)-(\w+)\.svg$/ig;
let collapsable = $(`#${categoryKey}-container`);
let collapseButton = $(`#${categoryKey}-collapser`);
let collapseImg = $(`#${categoryKey}-img`);
if ("none" === collapsable.css('display')) {
collapsable.css("display", "");
collapseButton.addClass("active");
} else {
collapsable.css("display", "none");
collapseButton.removeClass("active");
}
let srcImg = collapseImg.attr("src");
let groups = imageMatchRegex.exec(srcImg);
let direction = groups[1];
let theme = groups[2];
let newDirection = direction === "up"? "down": "up";
collapseImg.attr("src", `../images/chevron-${newDirection}-${theme}.svg`);
});
setCollapseOnElement(collapseButton, categoryKey);
for (let j in files) {
let file = files[j];
@ -118,13 +101,32 @@ export function buildWebCardsFromConfig(configName: string) {
let content = contentList[j];
buildWebCard(view, content, true, $);
}
}
}
}
function setCollapseOnElement(collapseButton: JQuery<HTMLElement>, categoryKey: string){
collapseButton.on("click", () => {
let imageMatchRegex = /\.\.\/images\/chevron-(\w+)-(\w+)\.svg$/ig;
let collapsable = $(`#${categoryKey}-container`);
let collapseButton = $(`#${categoryKey}-collapser`);
let collapseImg = $(`#${categoryKey}-img`);
if ("none" === collapsable.css('display')) {
collapsable.css("display", "");
collapseButton.addClass("active");
} else {
collapsable.css("display", "none");
collapseButton.removeClass("active");
}
let srcImg = collapseImg.attr("src");
let groups = imageMatchRegex.exec(srcImg);
let direction = groups[1];
let theme = groups[2];
let newDirection = direction === "up"? "down": "up";
collapseImg.attr("src", `../images/chevron-${newDirection}-${theme}.svg`);
});
}
export function buildWebCard(elem: JQuery<HTMLElement>, obj, append: boolean = false, $: any = require('jquery')) {
let model = new CardModel(
obj["title"],

Loading…
Cancel
Save