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.", "description": "Track your time off, manage your benefits plans, and access pay stubs using this human-resources application.",
"imagePath": "paycor-logo3-100x100.png", "imagePath": "paycor-logo3-100x100.png",
"urlText": "https://www.paycor.com/", "urlText": "https://www.paycor.com/",
"altText": "Paycor logo" "altText": "Paycor logo",
"keywords": "human resources, benefits, vacation, sick, bereavement, health, insurance, enrollment"
}, },
{ {
"title": "Swag Store", "title": "Swag Store",
"description": "Buy polo shirts and other logo gear here. Costs are deducted from Funny Money coupons or your paycheck.", "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", "imagePath": "swag-store-icon-100x100.png",
"urlText": "https://www.companycasuals.com/JDSfaulknerapparel/start.jsp", "urlText": "https://www.companycasuals.com/JDSfaulknerapparel/start.jsp",
"altText": "Store icon" "altText": "Store icon",
"keywords": "human resources"
}, },
{ {
"title": "NC-4EZ Form", "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.", "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", "imagePath": "tax-icon-100x100.png",
"urlText": "https://www.ncdor.gov/documents/employees-withholding-allowance-certificate-nc-4ez", "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", "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.", "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", "imagePath": "tax-icon-100x100.png",
"urlText": "https://www.irs.gov/forms-pubs/about-form-w-4", "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.", "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", "imagePath": "jdsfaulkner-small-icon.png",
"urlText": "https://jdsfaulkner.com/", "urlText": "https://jdsfaulkner.com/",
"altText": "JDSfaulkner brand mark" "altText": "JDSfaulkner brand mark",
"keywords": "marketing"
}, },
{ {
"title": "Salesforce", "title": "Salesforce",
"description": "Focus on the customer experience with the help of the Salesforce customer relationship management application.", "description": "Focus on the customer experience with the help of the Salesforce customer relationship management application.",
"imagePath": "salesforce-logo-100x100.png", "imagePath": "salesforce-logo-100x100.png",
"urlText": "https://login.salesforce.com/", "urlText": "https://login.salesforce.com/",
"altText": "Salesforce logo" "altText": "Salesforce logo",
"keywords": "marketing"
}, },
{ {
"title": "Facebook", "title": "Facebook",
"description": "Through Facebook, the company connects with the community by sharing content and interacting with the public.", "description": "Through Facebook, the company connects with the community by sharing content and interacting with the public.",
"imagePath": "facebooklogogrey_100x100.png", "imagePath": "facebooklogogrey_100x100.png",
"urlText": "https://www.facebook.com/JDSfaulkner/", "urlText": "https://www.facebook.com/JDSfaulkner/",
"altText": "Facebook icon" "altText": "Facebook icon",
"keywords": "marketing, social"
}, },
{ {
"title": "LinkedIn", "title": "LinkedIn",
"description": "JDSfaulkner maintains a presence on LinkedIn for professional networking, posting job openings and receiving resumes.", "description": "JDSfaulkner maintains a presence on LinkedIn for professional networking, posting job openings and receiving resumes.",
"imagePath": "linkedinlogo_100x100.png", "imagePath": "linkedinlogo_100x100.png",
"urlText": "https://www.linkedin.com/company/jds-consulting-&-design", "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.", "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", "imagePath": "gmail-logo2-100x100.png",
"urlText": "https://mail.google.com", "urlText": "https://mail.google.com",
"altText": "Gmail logo" "altText": "Gmail logo",
"keywords": "productivity"
}, },
{ {
"title": "Workplace", "title": "Workplace",
"description": "Get the latest news and connect with colleagues. JDSfaulkner uses Workplace by Facebook for posting and sharing.", "description": "Get the latest news and connect with colleagues. JDSfaulkner uses Workplace by Facebook for posting and sharing.",
"imagePath": "workplace-logo3-100x100.png", "imagePath": "workplace-logo3-100x100.png",
"urlText": "https://jdsfaulkner.workplace.com", "urlText": "https://jdsfaulkner.workplace.com",
"altText": "Workplace logo" "altText": "Workplace logo",
"keywords": "productivity, social"
}, },
{ {
"title": "Google Workspace", "title": "Google Workspace",
"description": "This suite of Google products includes Gmail, Calendar, Meet, Chat, Drive, Docs, Sheets, Slides, Forms and more.", "description": "This suite of Google products includes Gmail, Calendar, Meet, Chat, Drive, Docs, Sheets, Slides, Forms and more.",
"imagePath": "google-logo2-100x100.png", "imagePath": "google-logo2-100x100.png",
"urlText": "https://myaccount.google.com/", "urlText": "https://myaccount.google.com/",
"altText": "Google Workspace logo" "altText": "Google Workspace logo",
"keywords": "productivity, e-mail"
}, },
{ {
"title": "Dropbox", "title": "Dropbox",
"description": "The Structural Engineering Design department stores most of its files and folders in the Dropbox cloud-based system.", "description": "The Structural Engineering Design department stores most of its files and folders in the Dropbox cloud-based system.",
"imagePath": "dropbox-logo3-100x100.png", "imagePath": "dropbox-logo3-100x100.png",
"urlText": "https://www.dropbox.com/login", "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", "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", "imagePath": "learning-center-icon4-100x100.png",
"urlText": "https://jdsfaulkner.workplace.com", "urlText": "https://jdsfaulkner.workplace.com",
"altText": "Learning Center icon" "altText": "Learning Center icon",
"keywords": "training, courses"
}, },
{ {
"title": "Company Procedures", "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", "imagePath": "learning-center-icon4-100x100.png",
"urlText": "https://learning.carolina.engineering/additional-resources/", "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", "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", "imagePath": "learning-center-icon4-100x100.png",
"urlText": "https://learning.carolina.engineering/additional-resources/", "urlText": "https://learning.carolina.engineering/additional-resources/",
"altText": "Learning Center icon" "altText": "Learning Center icon",
"keywords": "training"
}, },
{ {
"title": "CAD Tech Study Guide", "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", "imagePath": "learning-center-icon4-100x100.png",
"urlText": "https://learning.carolina.engineering/additional-resources/", "urlText": "https://learning.carolina.engineering/additional-resources/",
"altText": "Learning Center icon" "altText": "Learning Center icon",
"keywords": "training, modules, drafting, design"
}, },
{ {
"title": "Deltek University", "title": "Deltek University",
"description": "Increase your Deltek knowledge with courses designed to teach you how to use Deltek solutions.", "description": "Increase your Deltek knowledge with courses designed to teach you how to use Deltek solutions.",
"imagePath": "deltek-logo-black.png", "imagePath": "deltek-logo-black.png",
"urlText": "https://www.deltek.com/en/support/deltek-university", "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.", "description": "Create, track, review and bill field-engineering projects, start to finish, with Clarity project management software.",
"imagePath": "clarity-icon-100x100.png", "imagePath": "clarity-icon-100x100.png",
"urlText": "https://learning.carolina.engineering/introduction-to-clarity/", "urlText": "https://learning.carolina.engineering/introduction-to-clarity/",
"altText": "Clarity image" "altText": "Clarity image",
"keywords": "workflow, applications, account"
}, },
{ {
"title": "Project Insight", "title": "Project Insight",
"description": "Structural Engineering Design uses this project management software to centralize the group's work, tasks and projects.", "description": "Structural Engineering Design uses this project management software to centralize the group's work, tasks and projects.",
"imagePath": "project-insight-logo6-100x100.png", "imagePath": "project-insight-logo6-100x100.png",
"urlText": "https://jds.projectinsight.net/", "urlText": "https://jds.projectinsight.net/",
"altText": "Project Insight logo" "altText": "Project Insight logo",
"keywords": "workflow, applications, CAD, draft, plans, account, track"
}, },
{ {
"title": "Deltek", "title": "Deltek",
"description": "Project intelligence, management and collaboration software helps maximize productivity and revenue.", "description": "Project intelligence, management and collaboration software helps maximize productivity and revenue.",
"imagePath": "deltek-logo-black.png", "imagePath": "deltek-logo-black.png",
"urlText": "https://www.deltek.com/en", "urlText": "https://www.deltek.com/en",
"altText": "Deltek logo" "altText": "Deltek logo",
"keywords": "workflow, applications, account, track"
}, },
{ {
"title": "Procore", "title": "Procore",
"description": "Administrators for field engineering projects use Procore for collecting, reviewing and approving invoices.", "description": "Administrators for field engineering projects use Procore for collecting, reviewing and approving invoices.",
"imagePath": "ProcoreLogo2.png", "imagePath": "ProcoreLogo2.png",
"urlText": "https://www.procore.com/", "urlText": "https://www.procore.com/",
"altText": "Procore logo" "altText": "Procore logo",
"keywords": "workflow, applications, software, account"
}, },
{ {
"title": "Client W-9 Form", "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.", "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", "imagePath": "tax-icon-100x100.png",
"urlText": "https://www.irs.gov/forms-pubs/about-form-w-9", "urlText": "https://www.irs.gov/forms-pubs/about-form-w-9",
"altText": "tax icon" "altText": "tax icon",
"keywords": "workflow, tax, account"
}, },
{ {
"title": "Project Folders", "title": "Project Folders",
"description": "Access vital information about specific projects from initial set-up to final delivery in an accessible and central location.", "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", "imagePath": "project-folder-icon-100x100.png",
"urlText": "../resources/coming-soon.pdf", "urlText": "../resources/coming-soon.pdf",
"altText": "Project folder icon" "altText": "Project folder icon",
"keywords": "workflow"
} }
] ]
} }

@ -24,6 +24,24 @@
alt="JDSfaulkner logo"> alt="JDSfaulkner logo">
 Resource Center  Resource Center
</a> </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"> <nav class="my-2 my-md-0 mr-md-3">
<div class="helpdropdown"> <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> <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> </nav>
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4"> <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="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 "> <div class="album py-5 ">
@ -168,6 +173,7 @@
<script src="scripts/tsUtil.js"></script> <script src="scripts/tsUtil.js"></script>
<script>loadTSTarget("themes.js");</script> <script>loadTSTarget("themes.js");</script>
<script>let help = loadTSTarget("help.js");</script> <script>let help = loadTSTarget("help.js");</script>
<script>loadTSTarget("search.js");</script>
<script src="scripts/index_app.js"></script> <script src="scripts/index_app.js"></script>
</html> </html>

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

@ -102,27 +102,35 @@ body {
position: relative; position: relative;
display: flex; display: flex;
margin: auto; margin: auto;
max-width: 1100px max-width: 1100px;
} }
.sb-example-1 .searchTerm { .sb-example-1 .searchTerm {
width: 100%; width: 100%;
border: 1px solid; border: 1px solid;
border-color: map-get($theme-colors, boxborder2); border-color: map-get($theme-colors, boxborder3);
border-right: none; border-right: none;
padding-left: 15px; padding-left: 15px;
padding-right: 15px; padding-right: 15px;
border-radius: 25px 0 0 25px; border-radius: 25px 0 0 25px;
stroke: map-get($theme-colors, searchicon); stroke: map-get($theme-colors, searchicon);
color: map-get($theme-colors, searchhint); 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; box-shadow: none;
color: map-get($theme-colors, searchfont) !important;
outline: none; outline: none;
} }
.sb-example-1 .searchTerm:focus { .sb-example-1 .searchTerm:focus {
stroke: map-get($theme-colors, searchicon); stroke: map-get($theme-colors, searchiconhover);
background-color: map-get($theme-colors, info); background-color: map-get($theme-colors, searchfill);
box-shadow: none; box-shadow: none;
color: map-get($theme-colors, searchfont) !important; color: map-get($theme-colors, searchfont) !important;
outline: none; outline: none;
@ -143,14 +151,29 @@ body {
outline: none; 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 { .sb-example-1 .searchbutton:focus {
width: 40px; width: 40px;
height: 50px; height: 50px;
border: 1px solid; border: 1px solid;
border-color: map-get($theme-colors, boxborder2); border-color: map-get($theme-colors, boxborder2);
background-color: map-get($theme-colors, searchbuttonfillfocus); background-color: map-get($theme-colors, searchbuttonfill);
text-align: center; text-align: center;
fill: map-get($theme-colors, searchiconfocus); fill: map-get($theme-colors, searchiconfocus) !important;
border-radius: 0 25px 25px 0; border-radius: 0 25px 25px 0;
cursor: pointer; cursor: pointer;
font-weight: normal; font-weight: normal;
@ -287,3 +310,8 @@ hr {
border: 0; border: 0;
border-top: 1px solid rgba(0, 0, 0, 0.1); 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, "inactivecard": #333337,
"activecard": #4f4f56, "activecard": #4f4f56,
"boxborder": #272727, "boxborder": #272727,
"boxborder2": #2f2f2f, "boxborder2": #3c3c42,
"boxborder3": #323237,
"activecardfont":#e1e4e8, "activecardfont":#e1e4e8,
"searchhint": #6b6866, "searchhint": #6b6866,
"searchfont": #9f9c9a, "searchfont": #9f9c9a,
"searchfill": #323237,
"sidebarfill": #202023, "sidebarfill": #202023,
"searchbuttonfill": #39393f, "searchbuttonfill": #585861,
"searchbuttonfillfocus": #3e3e45, "searchbuttonfillhover": #808080,
"searchicon": #737373, "searchbuttonfillfocus": #585861,
"searchiconfocus": #878787, "searchicon": #808080,
"searchiconhover": #c5c5c5,
"searchiconfocus": #c5c5c5,
"sidebartext": #7d7d7d, "sidebartext": #7d7d7d,
"sidebarbg": #29292d, "sidebarbg": #29292d,
"webcardimagebackground": #707070, "webcardimagebackground": #707070,
@ -52,6 +56,8 @@ $theme-colors: (
"helpmenudropdowntext": #9d9d9d, "helpmenudropdowntext": #9d9d9d,
"helpmenudropdowntexthover": #a8a8a8, "helpmenudropdowntexthover": #a8a8a8,
"helpmenudropdownbghover": #5c5c66, "helpmenudropdownbghover": #5c5c66,
"highlight-text-color": #000,
"highlight-background": #ece665,
); );
.theme-button{ .theme-button{

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

@ -1,5 +1,6 @@
{ {
"title": "Direct Deposit", "title": "Direct Deposit",
"description": "Would you like have your paychecks deposited into your bank account? Fill out this form and submit it to HR.", "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", "title": "Employment Application",
"description": "Would you or someone you know like to apply for a position? JDSfaulkner is always accepting applications.", "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", "title": "Expense Report",
"description": "Request reimbursement for preapproved, company-related expenses. Send this form and receipts to Accounts Payable.", "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", "title": "Drafting Quiz",
"description": "Click here to access a prequalifying quiz that is a requirement for those applying for drafting positions.", "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", "title": "Employee Handbook",
"description": "Read the handbook to learn about the companys policies related to employment, including pay and benefits.", "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", "title": "SRA",
"description": "A salary reduction agreement helps you to establish or change the part of your compensation that goes to an IRA.", "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", "title": "JDSfaulkner Brochure",
"description": "Share the company's brochure with existing and potential clients to showcase the value JDSfaulkner has to offer.", "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", "title": "JDSfaulkner SOQ",
"description": "SOQs present the experience and capabilities that qualify JDSfaulkner to win contracts or new clients.", "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", "title": "JDSfaulkner Letterhead",
"description": "Represent the company in a professional and consistent manner by writing your letters using this official letterhead template.", "description": "Represent the company in a professional and consistent manner using the official letterhead for correspondence.",
"altText": "Document icon" "altText": "Document icon",
"keywords": "marketing, template"
} }

@ -1,5 +1,6 @@
{ {
"title": "JDSfaulkner Logo - EPS", "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.", "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" "altText": "Image icon",
"keywords": "marketing"
} }

@ -1,5 +1,6 @@
{ {
"title": "JDSfaulkner Logo - PNG", "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.", "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" "altText": "Image icon",
"keywords": "marketing"
} }

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

@ -108,33 +108,30 @@ export class DocumentDirectory {
root: DirectoryNode; root: DirectoryNode;
getCards(): Map<String, object[]> { getCards(): Map<string, object[]> {
return DocumentDirectory.walkCards(this.root); return DocumentDirectory.walkCards(this.root);
} }
private static walkCards(d: DirectoryNode): Map<String, object[]> { private static walkCards(d: DirectoryNode): Map<string, object[]> {
let cardsByCategory = new Map<String, object[]>(); let cardsByCategory = new Map<string, object[]>();
for (let i = 0, l = d.children.length; i < l; i++) { for (let child of d.children) {
let child = d.children[i];
if (child instanceof DirectoryNode) { if (child instanceof DirectoryNode) {
let dir = child as DirectoryNode; let dir = child as DirectoryNode;
if (dir.containsDirectory()) { if (dir.containsDirectory()) {
let childDirectories = dir.getDirectories(); let childDirectories = dir.getDirectories();
for (let j = 0, k = childDirectories.length; j < k; j++) { for (let dir of childDirectories) {
let dir = childDirectories[j];
let subCards = DocumentDirectory.walkCards(dir); let subCards = DocumentDirectory.walkCards(dir);
this.mergeMaps(cardsByCategory, subCards); this.mergeMaps(cardsByCategory, subCards);
} }
} }
let sCards = dir.getDocuments(); let sCards = dir.getDocuments();
let category = dir.getCategory(); let category = dir.getCategory();
for (let sCard in sCards) { for (let sCard of sCards) {
let scrd = sCards[sCard];
let cards = cardsByCategory.get(category); let cards = cardsByCategory.get(category);
if (cards === undefined || cards === null) { if (cards === undefined || cards === null) {
cards = []; cards = [];
} }
cards.push(scrd.toCard()); cards.push(sCard.toCard());
cardsByCategory.set(category, cards); cardsByCategory.set(category, cards);
} }
} else { } else {
@ -151,10 +148,9 @@ export class DocumentDirectory {
return cardsByCategory; 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); let keys = Object.keys(b);
for (let z in keys) { for (let key of keys) {
let key = keys[z];
let sa = a.get(key) let sa = a.get(key)
if (sa === undefined || sa === null) { if (sa === undefined || sa === null) {
sa = []; sa = [];
@ -180,7 +176,7 @@ export class FileNode {
this.parent = parent; this.parent = parent;
} }
static loadAltProps(path: String): object { static loadAltProps(path: string): object {
let props = {}; let props = {};
let jsonPath = path + ".json" let jsonPath = path + ".json"
if (fs.existsSync(jsonPath)) { if (fs.existsSync(jsonPath)) {
@ -213,19 +209,19 @@ export class FileNode {
"imagePath": imageName, "imagePath": imageName,
"urlText": this.filePath, "urlText": this.filePath,
"altText": "", "altText": "",
"fileCard": true "fileCard": true,
"open": this.open
} }
let altKeys = Object.keys(altProps); let altKeys = Object.keys(altProps);
for (let kidx in altKeys) { for (let key of altKeys) {
let key = altKeys[kidx];
cardObj[key] = altProps[key] cardObj[key] = altProps[key]
} }
return cardObj return cardObj
} }
getTitle(): String { getTitle(): string {
let name = path.basename(this.filePath); let name = path.basename(this.filePath);
let ext = path.extname(name); let ext = path.extname(name);
let cName = name.replace(ext, ""); let cName = name.replace(ext, "");
@ -251,9 +247,9 @@ export class DirectoryNode extends FileNode {
let stats = fs.lstatSync(filePath); let stats = fs.lstatSync(filePath);
if (stats.isDirectory()) { if (stats.isDirectory()) {
let contents = fs.readdirSync(filePath); let contents = fs.readdirSync(filePath);
for (let i = 0, l = contents.length; i < l; i++) { for (let fileName of contents) {
if (path.extname(contents[i]) === ".json") continue; if (path.extname(fileName) === ".json") continue;
let childPath = path.join(filePath, contents[i]); let childPath = path.join(filePath, fileName);
let childStats = fs.lstatSync(childPath); let childStats = fs.lstatSync(childPath);
if (childStats.isDirectory()) { if (childStats.isDirectory()) {
this.children.push(new DirectoryNode(childPath, this)); this.children.push(new DirectoryNode(childPath, this));
@ -282,14 +278,13 @@ export class DirectoryNode extends FileNode {
} }
containsDirectory(): Boolean { containsDirectory(): Boolean {
for (let i = 0, l = this.children.length; i < l; i++) { for (let child of this.children) {
let child = this.children[i];
if (child instanceof DirectoryNode) return true; if (child instanceof DirectoryNode) return true;
} }
return false return false
} }
getCategory(): String { getCategory(): string {
let rawName = path.basename(this.filePath); let rawName = path.basename(this.filePath);
let parts = rawName.split("-"); let parts = rawName.split("-");
for (let i = 0, l = parts.length; i < l; i++) { 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')) { export function buildFileCard(elem: JQuery<HTMLElement>, obj, append: boolean = false, $: any = require('jquery')) {
console.log(obj);
let model = new CardModel( let model = new CardModel(
obj["title"], obj["title"],
obj["description"], obj["description"],
@ -40,30 +39,32 @@ export function buildFileCard(elem: JQuery<HTMLElement>, obj, append: boolean =
if (model["show"] !== undefined) { if (model["show"] !== undefined) {
$(`#${id}`).on("click", () => { $(`#${id}`).on("click", () => {
console.log("showing")
shell.showItemInFolder(model.resourcePath) shell.showItemInFolder(model.resourcePath)
}); });
} else { } else {
$(`#${id}`).on("click", () => { $(`#${id}`).on("click", () => {
console.log("opening")
shell.openItem(model.resourcePath) shell.openItem(model.resourcePath)
}); });
} }
}); });
} }
export function buildWebCardsFromConfig(configName: string) { export function buildUiFromConfig(configName: string){
let elementConfig = Configurator.loadAppConfig(configName); let elementConfig = Configurator.loadAppConfig(configName);
let $ = require('jquery')
let containers = Object.keys(elementConfig);
let directoryPath = path.join(__dirname, "../assets/resources"); let directoryPath = path.join(__dirname, "../assets/resources");
let fileCards = new DocumentDirectory(directoryPath).getCards(); 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 containerName = containers[i];
let containerObject = elementConfig[containerName]; let containerObject = elementConfig[containerName];
let containerElem = $(`#${containerName}`); let containerElem = $(`#${containerName}`);
containerElem.html("")
let containerCategories = Object.keys(containerObject); let containerCategories = Object.keys(containerObject);
for (let j = 0, m = containerCategories.length; j < m; j++) { for (let j = 0, m = containerCategories.length; j < m; j++) {
@ -89,6 +90,22 @@ export function buildWebCardsFromConfig(configName: string) {
let view = $(`#${categoryKey}-container`); let view = $(`#${categoryKey}-container`);
let collapseButton = $(`#${categoryKey}-collapser`); let collapseButton = $(`#${categoryKey}-collapser`);
setCollapseOnElement(collapseButton, categoryKey);
for (let j in files) {
let file = files[j];
buildFileCard(view, file, true, $)
}
for (let j = 0, m = contentList.length; j < m; j++) {
let content = contentList[j];
buildWebCard(view, content, true, $);
}
}
}
}
function setCollapseOnElement(collapseButton: JQuery<HTMLElement>, categoryKey: string){
collapseButton.on("click", () => { collapseButton.on("click", () => {
let imageMatchRegex = /\.\.\/images\/chevron-(\w+)-(\w+)\.svg$/ig; let imageMatchRegex = /\.\.\/images\/chevron-(\w+)-(\w+)\.svg$/ig;
let collapsable = $(`#${categoryKey}-container`); let collapsable = $(`#${categoryKey}-container`);
@ -108,21 +125,6 @@ export function buildWebCardsFromConfig(configName: string) {
let newDirection = direction === "up"? "down": "up"; let newDirection = direction === "up"? "down": "up";
collapseImg.attr("src", `../images/chevron-${newDirection}-${theme}.svg`); collapseImg.attr("src", `../images/chevron-${newDirection}-${theme}.svg`);
}); });
for (let j in files) {
let file = files[j];
buildFileCard(view, file, true, $)
}
for (let j = 0, m = contentList.length; j < m; j++) {
let content = contentList[j];
buildWebCard(view, content, true, $);
}
}
}
} }
export function buildWebCard(elem: JQuery<HTMLElement>, obj, append: boolean = false, $: any = require('jquery')) { export function buildWebCard(elem: JQuery<HTMLElement>, obj, append: boolean = false, $: any = require('jquery')) {

Loading…
Cancel
Save