kcc-gem-theme 1.67.69 → 1.70.71
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/_data/theme_hash.yml +1 -1
- data/_includes/contacts-tan.html +39 -28
- data/_includes/contacts.html +6 -22
- data/_includes/hero-slider.html +1 -1
- data/_layouts/default-core.html +1 -1
- data/_layouts/default.html +1 -1
- data/_layouts/sub-nav-core.html +6 -0
- data/assets/img/placeholder_16to9.jpg +0 -0
- data/assets/img/placeholder_4by3.jpg +0 -0
- data/assets/img/placeholder_square.jpg +0 -0
- data/assets/js/theme/alerts/alerts.js +9 -2
- data/assets/js/theme/alerts/cacheResponse.js +23 -0
- data/assets/js/theme/alerts/campusAlertsSheetsAPI.js +35 -23
- data/assets/js/theme/alerts/createAlertsHtml.js +13 -8
- data/assets/js/theme/alerts/getCachedResponse.js +41 -0
- data/assets/js/theme/alerts/tabLink.js +81 -0
- data/assets/js/theme/dist/alerts.bundle.js +1 -1
- data/assets/js/theme/dist/kcc-mega-nav.bundle.js +1 -1
- data/assets/js/theme/dist/kcc-nav.bundle.js +1 -1
- data/assets/js/theme/dist/kcc-theme-landing.bundle.js +1 -1
- data/assets/js/theme/dist/kcc-theme.bundle.js +1 -1
- data/assets/js/theme/src/test.js +1 -35
- metadata +9 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24f4acacd0f4a33d8a95da3480fb67c4f958544775c0f5e8194df7c8724b287c
|
4
|
+
data.tar.gz: cee877dfe62050535469131681e592d870b1a7f596f6a56f620655bc29e42ef0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 68475fcde0d91e47be7e4d2dd60a58e9edf9d34aa12eed453b5f53cea6b78f1882bc41a2b5a0700f92af41bcc297198186a5a92cbdf11a655f4bc0e6ff9098b2
|
7
|
+
data.tar.gz: 867cd775d7a83fd93636d5cb63f983c03fcdce208140c17cd58c3534ea36cdf2c31fa7f52a835ba3312b51f58d1f1e07f9c71aaa0d5e1454b7b25981ac22170c
|
data/_data/theme_hash.yml
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
37746a1db9406814aa58
|
data/_includes/contacts-tan.html
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
{
|
1
|
+
{%- assign sorted_contacts = site.contacts | sort: "display_order" -%}
|
2
2
|
<section>
|
3
3
|
<div class="container">
|
4
4
|
<div class="row">
|
5
|
-
<div class="col
|
5
|
+
<div class="col mt-1 home__col--heading-underline home__col--heading-underline-tan">
|
6
6
|
<h3 id="contact" class="typography__section--heading margins__heading--btm links__offset">Contacts</h3>
|
7
7
|
</div>
|
8
8
|
</div>
|
@@ -14,15 +14,15 @@
|
|
14
14
|
</div>
|
15
15
|
</div>
|
16
16
|
<div class="row">
|
17
|
-
{
|
18
|
-
{
|
19
|
-
{
|
20
|
-
{
|
21
|
-
{% if contact.
|
17
|
+
{%- for contact in sorted_contacts -%}
|
18
|
+
{%- assign contact_name = contact.name | split: " " -%}
|
19
|
+
{%- assign first = contact_name[0] -%}
|
20
|
+
{%- assign last = contact_name[1] -%}
|
21
|
+
{% if contact.portrait_image != "For departments with no contact photos, do not change this field." %}
|
22
22
|
<div class="col-md-6 contacts__col-bottom-margin">
|
23
23
|
<div class="row">
|
24
24
|
<div class="col-4 contacts__col--img">
|
25
|
-
<img src="assets/img/
|
25
|
+
{% if contact.portrait_image != 'none' %}<img src="{{ page.baseurl }}assets/img/placeholder_square.jpg" data-src="{{ page.baseurl }}{{ contact.portrait_image }}" alt="Photo of {{ contact.name }}" class="img-fluid contacts__portrait" />{% endif %}
|
26
26
|
</div>
|
27
27
|
<div class="col-8 float-right">
|
28
28
|
<h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
|
@@ -30,24 +30,8 @@
|
|
30
30
|
<p class="notranslate">
|
31
31
|
{% if contact.phone %}<a href="tel:1{{ contact.phone | remove: '-' }}" class="links__darker-link">{{ contact.phone }}</a><br>{% endif %}
|
32
32
|
{% if contact.email %}<a class="links__darker-link" target="_blank" href="https://secure.jotform.com/90435102482954?to[first]={{ first }}&to[last]={{ last }}&submitEmail={{ contact.email | remove: '@kcc.edu' }}%40kcc.edu">Email</a><br>{% endif %}
|
33
|
-
{
|
34
|
-
|
35
|
-
</div>
|
36
|
-
</div>
|
37
|
-
</div>
|
38
|
-
{% elsif contact.portrait == 'none' %}
|
39
|
-
<div class="col-md-6 contacts__col-bottom-margin">
|
40
|
-
<div class="row">
|
41
|
-
<div class="col-4 contacts__col--img">
|
42
|
-
<!-- Contact has no portrait -->
|
43
|
-
</div>
|
44
|
-
<div class="col-8 float-right">
|
45
|
-
<h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
|
46
|
-
{% if contact.contacts_title %}<h6 class="typography__contacts--title">{{ contact.contacts_title }}</h6>{% endif %}
|
47
|
-
<p class="notranslate">
|
48
|
-
{% if contact.phone %}<a href="tel:1{{ contact.phone | remove: '-' }}" class="links__darker-link">{{ contact.phone }}</a><br>{% endif %}
|
49
|
-
{% if contact.email %}<a class="links__darker-link" target="_blank" href="https://secure.jotform.com/90435102482954?to[first]={{ first }}&to[last]={{ last }}&submitEmail={{ contact.email | remove: '@kcc.edu' }}%40kcc.edu">Email</a><br>{% endif %}
|
50
|
-
{% if contact.fax %}Fax: {{ contact.fax }}{% endif %}
|
33
|
+
{%- if contact.fax -%}Fax: {{ contact.fax }}{% endif %}
|
34
|
+
{%- if contact.bio == true -%}<button type="button" class="btn btn-primary mt-2" data-toggle="modal" data-target="#{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}">View Bio</button>{% endif %}
|
51
35
|
</p>
|
52
36
|
</div>
|
53
37
|
</div>
|
@@ -60,10 +44,37 @@
|
|
60
44
|
{% if contact.phone %}<a href="tel:1{{ contact.phone | remove: '-' }}" class="links__darker-link">{{ contact.phone }}</a><br>{% endif %}
|
61
45
|
{% if contact.email %}<a class="links__darker-link" target="_blank" href="https://secure.jotform.com/90435102482954?to[first]={{ first }}&to[last]={{ last }}&submitEmail={{ contact.email | remove: '@kcc.edu' }}%40kcc.edu">Email</a><br>{% endif %}
|
62
46
|
{% if contact.fax %}Fax: {{ contact.fax }}{% endif %}
|
47
|
+
{% if contact.bio == true %}<button type="button" class="btn btn-primary mt-2" data-toggle="modal" data-target="#{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}">View Bio</button>{% endif %}
|
63
48
|
</p>
|
64
49
|
</div>
|
65
|
-
{
|
66
|
-
{
|
50
|
+
{%- endif -%}
|
51
|
+
{%- endfor -%}
|
67
52
|
</div>
|
68
53
|
</div>
|
69
54
|
</section>
|
55
|
+
{% for contact in sorted_contacts %}
|
56
|
+
{%- if contact.bio == true -%}
|
57
|
+
<!-- Modal -->
|
58
|
+
<div class="modal fade" id="{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}" tabindex="-1" aria-labelledby="{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}-label" aria-hidden="true">
|
59
|
+
<div class="modal-dialog">
|
60
|
+
<div class="modal-content">
|
61
|
+
<div class="modal-header">
|
62
|
+
<h5 class="typography__h6" id="{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}-label">{{ contact.name }} Bio</h5>
|
63
|
+
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
64
|
+
<span aria-hidden="true">×</span>
|
65
|
+
</button>
|
66
|
+
</div>
|
67
|
+
<div class="modal-body">
|
68
|
+
{% if contact.portrait_image != 'For departments with no contact photos, do not change this field.' and contact.portrait_image != 'none' %}<img src="{{ page.baseurl }}assets/img/placeholder_square.jpg" data-src="{{ page.baseurl }}{{ contact.portrait_image }}" class="img-fluid float-left mr-2 mb-2" alt="Photo of {{ contact.name }} KCC's {{ contact.contacts_title }}">{% endif %}
|
69
|
+
<h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
|
70
|
+
{% if contact.contacts_title %}<h6 class="typography__contacts--title">{{ contact.contacts_title }}</h6>{% endif %}
|
71
|
+
{{ contact.content }}
|
72
|
+
</div>
|
73
|
+
<div class="modal-footer">
|
74
|
+
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
75
|
+
</div>
|
76
|
+
</div>
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
{%- endif -%}
|
80
|
+
{% endfor %}
|
data/_includes/contacts.html
CHANGED
@@ -2,10 +2,12 @@
|
|
2
2
|
<section>
|
3
3
|
<div class="container">
|
4
4
|
<div class="row">
|
5
|
-
<div class="col mt-1 home__col--heading-underline">
|
5
|
+
<div class="col mt-1 home__col--heading-underline{% if page.contacts_background_tan == true %} home__col--heading-underline-tan{% endif %}">
|
6
6
|
<h3 id="contact" class="typography__section--heading margins__heading--btm links__offset">Contacts</h3>
|
7
7
|
</div>
|
8
8
|
</div>
|
9
|
+
{% if page.contacts_background_tan == true %}</div>
|
10
|
+
<div class="container contacts__padding-top background__color--tan">{% endif %}
|
9
11
|
<div class="row editor-link">
|
10
12
|
<div class="col editor-link mb-3">
|
11
13
|
<a href="cloudcannon:collections/_contacts/" class="btn btn-success editor-button">Edit Contacts</a>
|
@@ -16,29 +18,11 @@
|
|
16
18
|
{%- assign contact_name = contact.name | split: " " -%}
|
17
19
|
{%- assign first = contact_name[0] -%}
|
18
20
|
{%- assign last = contact_name[1] -%}
|
19
|
-
{% if contact.
|
21
|
+
{% if contact.portrait_image != "For departments with no contact photos, do not change this field." %}
|
20
22
|
<div class="col-md-6 contacts__col-bottom-margin">
|
21
23
|
<div class="row">
|
22
24
|
<div class="col-4 contacts__col--img">
|
23
|
-
|
24
|
-
</div>
|
25
|
-
<div class="col-8 float-right">
|
26
|
-
<h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
|
27
|
-
{% if contact.contacts_title %}<h6 class="typography__contacts--title">{{ contact.contacts_title }}</h6>{% endif %}
|
28
|
-
<p class="notranslate">
|
29
|
-
{% if contact.phone %}<a href="tel:1{{ contact.phone | remove: '-' }}" class="links__darker-link">{{ contact.phone }}</a><br>{% endif %}
|
30
|
-
{% if contact.email %}<a class="links__darker-link" target="_blank" href="https://secure.jotform.com/90435102482954?to[first]={{ first }}&to[last]={{ last }}&submitEmail={{ contact.email | remove: '@kcc.edu' }}%40kcc.edu">Email</a><br>{% endif %}
|
31
|
-
{%- if contact.fax -%}Fax: {{ contact.fax }}{% endif %}
|
32
|
-
{%- if contact.bio == true -%}<button type="button" class="btn btn-primary mt-2" data-toggle="modal" data-target="#{{ contact.name | downcase | replace: ' ', '-' | remove: '.' | remove: '/' | remove: "'" | remove: '’' }}">View Bio</button>{% endif %}
|
33
|
-
</p>
|
34
|
-
</div>
|
35
|
-
</div>
|
36
|
-
</div>
|
37
|
-
{% elsif contact.portrait == 'none' %}
|
38
|
-
<div class="col-md-6 contacts__col-bottom-margin">
|
39
|
-
<div class="row">
|
40
|
-
<div class="col-4 contacts__col--img">
|
41
|
-
<!-- No contact portrait -->
|
25
|
+
{% if contact.portrait_image != 'none' %}<img src="{{ page.baseurl }}assets/img/placeholder_square.jpg" data-src="{{ page.baseurl }}{{ contact.portrait_image }}" width="150px" height="150px" alt="Photo of {{ contact.name }}" class="img-fluid contacts__portrait" />{% endif %}
|
42
26
|
</div>
|
43
27
|
<div class="col-8 float-right">
|
44
28
|
<h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
|
@@ -81,7 +65,7 @@
|
|
81
65
|
</button>
|
82
66
|
</div>
|
83
67
|
<div class="modal-body">
|
84
|
-
{% if contact.
|
68
|
+
{% if contact.portrait_image != 'For departments with no contact photos, do not change this field.' and contact.portrait_image != 'none' %}<img src="{{ page.baseurl }}assets/img/placeholder_square.jpg" data-src="{{ page.baseurl }}{{ contact.portrait_image }}" class="img-fluid float-left mr-2 mb-2" width="150px" height="150px" alt="Photo of {{ contact.name }} KCC's {{ contact.contacts_title }}">{% endif %}
|
85
69
|
<h5 class="typography__contacts--name notranslate">{{ contact.name }}</h5>
|
86
70
|
{% if contact.contacts_title %}<h6 class="typography__contacts--title">{{ contact.contacts_title }}</h6>{% endif %}
|
87
71
|
{{ contact.content }}
|
data/_includes/hero-slider.html
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
</div>
|
13
13
|
{% else %}
|
14
14
|
<div>
|
15
|
-
<a {% if slide.url contains "https://" or slide.url contains "http://" %}href="{{ slide.url }}"{% elsif url_first_char == "." or url_first_char == "/" %}href="{{ slide.url }}"{% else %}href="{{ page.baseurl }}{{ slide.url }}{% endif %}"{% if slide.new_tab == true %} target="_blank" rel="noopener noreferrer"{% endif %}><img src="{{ page.baseurl }}assets/img/
|
15
|
+
<a {% if slide.url contains "https://" or slide.url contains "http://" %}href="{{ slide.url }}"{% elsif url_first_char == "." or url_first_char == "/" %}href="{{ slide.url }}"{% else %}href="{{ page.baseurl }}{{ slide.url }}{% endif %}"{% if slide.new_tab == true %} target="_blank" rel="noopener noreferrer"{% endif %}><img src="{{ page.baseurl }}assets/img/placeholder_16to9.jpg" data-src="{{page.baseurl}}{{slide.image}}" class="img-fluid hero-slider__slider--slide-img {% if slide.white_background %} hero-slider__slide-img--border{% endif %}" alt="{{slide.alt-text}}" /></a>
|
16
16
|
{% if slide.text and slide.text != "" %}<div class="hero-slider__slider--heading-container text-center">
|
17
17
|
<h3 class="hero-slider__slider--slide-heading">{{slide.text}}</h3>
|
18
18
|
</div>{% endif %}
|
data/_layouts/default-core.html
CHANGED
@@ -14,7 +14,7 @@
|
|
14
14
|
{% include scripts/google-noscript.html %}
|
15
15
|
{% if site.translate == true %}{% include translate.html %}{% endif %}
|
16
16
|
{% include header-global.html %}
|
17
|
-
{% if site.core_root != true %}{% include emergency-alerts.html %}{% endif %}
|
17
|
+
{% if site.core_root != true and page.no_alert != true %}{% include emergency-alerts.html %}{% endif %}
|
18
18
|
{{ content }}
|
19
19
|
{% include footer.html %}
|
20
20
|
{% include scripts/vendor-cdn.html %}
|
data/_layouts/default.html
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
{% if site.translate == true %}{% include translate.html %}{% endif %}
|
16
16
|
{% include nav-global.html %}
|
17
17
|
{% if page.no_local_nav != true %}{% include nav-local.html %}{% endif %}
|
18
|
-
{% include emergency-alerts.html %}
|
18
|
+
{% if page.no_alert != true %}{% include emergency-alerts.html %}{% endif %}
|
19
19
|
{{ content }}
|
20
20
|
{% include footer.html %}
|
21
21
|
{% include scripts/vendor-cdn.html %}
|
Binary file
|
Binary file
|
Binary file
|
@@ -1,5 +1,12 @@
|
|
1
|
+
/*
|
2
|
+
// Custom JS | written by https://github.com/wdzajicek
|
3
|
+
// © 2020 Kankakee Community College
|
4
|
+
// =================================================== */
|
1
5
|
import start from './campusAlertsSheetsAPI.js';
|
6
|
+
import getCachedResponse from './getCachedResponse.js';
|
2
7
|
|
3
|
-
document.addEventListener('DOMContentLoaded',
|
4
|
-
|
8
|
+
document.addEventListener('DOMContentLoaded', () => {
|
9
|
+
! window.sessionStorage.getItem('Alert-Content') ? // Checks if our cached alert is already in sessionStorage
|
10
|
+
gapi.load('client', start) // If not, build the alert from a new Google API response
|
11
|
+
: getCachedResponse(); // Otherwise, build the alert from our cached response
|
5
12
|
});
|
@@ -0,0 +1,23 @@
|
|
1
|
+
/*
|
2
|
+
// Custom JS | written by https://github.com/wdzajicek
|
3
|
+
// © 2020 Kankakee Community College
|
4
|
+
// =================================================== */
|
5
|
+
// Modules' default function stores our Google Sheet response in sessionStorage to be retrieved later
|
6
|
+
// Each key gets set to a column in our data
|
7
|
+
// Each key's value gets set to the corresponding cell in the row below
|
8
|
+
// ====================================================================
|
9
|
+
function cacheResponse(response) { // response from Google API's spreadsheet.values.get() method
|
10
|
+
const VALUES = response.result.values; // This is where the table's data is in a Sheets response in Sheets API V4
|
11
|
+
const TABLE_HEADER_ROW = VALUES[1]; // 2nd row in the sheet (first row is instructions to the user)
|
12
|
+
const TABLE_BODY_ROW = VALUES[2]; // The only row of data in our table
|
13
|
+
|
14
|
+
for (let i = 0, len = TABLE_BODY_ROW.length; i < len; i++ ) {
|
15
|
+
const cell = TABLE_BODY_ROW[i];
|
16
|
+
const column = TABLE_HEADER_ROW[i];
|
17
|
+
|
18
|
+
window.sessionStorage.setItem(column.replace(' ', '-'), cell);
|
19
|
+
}
|
20
|
+
//window.sessionStorage.clear();
|
21
|
+
}
|
22
|
+
|
23
|
+
export default cacheResponse;
|
@@ -1,40 +1,52 @@
|
|
1
|
+
/*
|
2
|
+
// Custom JS | written by https://github.com/wdzajicek
|
3
|
+
// © 2020 Kankakee Community College
|
4
|
+
// =================================================== */
|
5
|
+
// 1. Execute Google API call to grab Google Sheet data from:
|
6
|
+
// https://docs.google.com/spreadsheets/d/1plXBiZY5pVbhNT-mszxEuqCl4zy8wMnz9gXXbbT_yLs/edit#gid=0
|
7
|
+
// 2. Build & inject the alert message into the page
|
8
|
+
// 3. Run the `tabLink.js` module after alert has painted into DOM (and altered documents hight)
|
9
|
+
// 4. Cache the API response in sessionStorage
|
10
|
+
// =================================================== //
|
1
11
|
import setSheetParameters from './simpleSetSheetParameters.js';
|
2
12
|
import createAlertsHtml from './createAlertsHtml.js';
|
13
|
+
import makeTabsLinkable from './tabLink.js';
|
14
|
+
import cacheResponse from './cacheResponse.js';
|
3
15
|
|
4
16
|
const SHEET_KEY = '1plXBiZY5pVbhNT-mszxEuqCl4zy8wMnz9gXXbbT_yLs';
|
5
17
|
const SHEET_TAB_NAME = 'Alerts';
|
6
18
|
const EMERGENCY_ALERT_DIV_ID = 'emergencyAlerts'
|
19
|
+
const SHEET_PARAMS = setSheetParameters(SHEET_KEY, SHEET_TAB_NAME);
|
20
|
+
const PARAMS = { // This is configuration for API call with spreadsheets that are setup as readonly
|
21
|
+
'apiKey': 'AIzaSyCEBsbXfFcdbkASlg-PodD1rT_Fe3Nw62A',
|
22
|
+
'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/sheets/v4/rest']
|
23
|
+
};
|
24
|
+
|
25
|
+
function init() {
|
26
|
+
gapi.client.init(PARAMS).then(function() { // Executes an API request, and returns a Promise.
|
27
|
+
return gapi.client.sheets.spreadsheets.values.get(SHEET_PARAMS)
|
28
|
+
.then((response) => {
|
29
|
+
createAlertsHtml(response); // Build the html & inject it into the DOM
|
30
|
+
return response;
|
31
|
+
}).then((response) => {
|
32
|
+
makeTabsLinkable(); // Handle hash & query URI's to target accordion and tabbed-nav content
|
33
|
+
cacheResponse(response); // Cache the Google API response for subsequent page loads in the site
|
34
|
+
},
|
35
|
+
function(err) {
|
36
|
+
console.error("Execute error", err);
|
37
|
+
makeTabsLinkable();
|
38
|
+
});
|
39
|
+
});
|
40
|
+
}
|
7
41
|
|
8
42
|
function start() {
|
9
43
|
if ( ! document.getElementById(EMERGENCY_ALERT_DIV_ID) )
|
10
|
-
return;
|
44
|
+
return makeTabsLinkable();
|
11
45
|
|
12
|
-
//var t0 = performance.now();
|
13
46
|
init();
|
14
47
|
//var t1 = performance.now();
|
15
48
|
//console.info("Call to 'init' took " + (t1 - t0) + " milliseconds.");
|
16
49
|
}
|
17
|
-
|
18
|
-
function init() {
|
19
|
-
const params = {
|
20
|
-
'apiKey': 'AIzaSyCEBsbXfFcdbkASlg-PodD1rT_Fe3Nw62A',
|
21
|
-
'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/sheets/v4/rest']
|
22
|
-
};
|
23
|
-
const sheetParams = setSheetParameters(SHEET_KEY, SHEET_TAB_NAME);
|
24
|
-
|
25
|
-
gapi.client.init(params).then(function() { // Executes an API request, and returns a Promise.
|
26
|
-
function execute() {
|
27
|
-
return gapi.client.sheets.spreadsheets.values.get(sheetParams)
|
28
|
-
.then(function(response) {
|
29
|
-
createAlertsHtml(response);
|
30
|
-
},
|
31
|
-
function(err) {
|
32
|
-
console.error("Execute error", err);
|
33
|
-
});
|
34
|
-
}
|
35
|
-
execute();
|
36
|
-
});
|
37
|
-
}
|
38
50
|
// Loads the JavaScript client library and invokes `start` afterwards.
|
39
51
|
// Usage:
|
40
52
|
// gapi.load('client', start);
|
@@ -1,9 +1,13 @@
|
|
1
|
-
|
2
|
-
//
|
3
|
-
//
|
4
|
-
//
|
1
|
+
/*
|
2
|
+
// Custom JS | written by https://github.com/wdzajicek
|
3
|
+
// © 2020 Kankakee Community College
|
4
|
+
// =================================================== */
|
5
|
+
// JS module to build alert message using data from Google Sheets API v4
|
6
|
+
//
|
7
|
+
// This exported module requires you pass it's default-function the `response` object from the API call, as the only argument
|
8
|
+
import makeTabsLinkable from './tabLink.js';
|
5
9
|
import parseMarkdownToHTML from './parseMarkdownToHTML.js';
|
6
|
-
|
10
|
+
//
|
7
11
|
const CAMPUS_ALERTS_DIV_ID_STRING = 'emergencyAlerts'; // ID of the div to house campus alerts - already built into the page.
|
8
12
|
const BOOTSTRAP_CONTAINER_CLASS = 'container'; // Class used in Bootstrap 4
|
9
13
|
const BOOTSTRAP_ROW_CLASS = 'row'; // Class used in Bootstrap 4
|
@@ -12,7 +16,6 @@ const BOOTSTRAP_CLOSE_CLASS = 'close'; // Class used in Bootstrap 4
|
|
12
16
|
const TRUE_FROM_SHEETS = 'TRUE'; // Because Google Sheets does 'TRUE' & 'FALSE' in all caps, unlike JavaScript
|
13
17
|
const FALSE_FROM_SHEETS = 'FALSE'; // Because Google Sheets does 'TRUE' & 'FALSE' in all caps, unlike JavaScript
|
14
18
|
const BOOTSTRAP_ALERT_CLASS_ARRAY = ['alert', 'alert-warning']; // BS4 classes for alerts
|
15
|
-
const PARAGRAPH_CLASS_ARRAY = ['typography__alert', 'mb-0']; // KCC Gem Theme & Bootstrap 4 class strings in an array
|
16
19
|
const ALERTS_VISIBLE_CLASS = 'position__offset-alert--visible';
|
17
20
|
|
18
21
|
function addClassesToEl(el, classArr) {
|
@@ -67,7 +70,7 @@ function init(SHEET_DATA) {
|
|
67
70
|
}
|
68
71
|
|
69
72
|
function checkAlertPages(SHEET_DATA) {
|
70
|
-
const DISPLAY_ALERT_ON_ALL_PAGES = SHEET_DATA[1] === TRUE_FROM_SHEETS; // Second cell toggles if it
|
73
|
+
const DISPLAY_ALERT_ON_ALL_PAGES = SHEET_DATA[1] === TRUE_FROM_SHEETS; // Second cell toggles if it displays on just homepages or all pages of the sites
|
71
74
|
const pathname = window.location.pathname;
|
72
75
|
const locationIsHomepage = pathname === '/';
|
73
76
|
|
@@ -79,11 +82,13 @@ function checkAlertPages(SHEET_DATA) {
|
|
79
82
|
}
|
80
83
|
|
81
84
|
function createAlertsHtml(response) { // Incoming response from our Google Sheet via the Sheets API
|
85
|
+
if ( ! document.getElementById(CAMPUS_ALERTS_DIV_ID_STRING) )
|
86
|
+
return makeTabsLinkable();
|
87
|
+
|
82
88
|
// This is where the cell values hide in the response object from the Google API.
|
83
89
|
const SHEET_CELL_VALUES_ARRAY = response.result.values; // `values` is an array consisting of an array for each row (i.e an array of arrays)
|
84
90
|
const SHEET_DATA = SHEET_CELL_VALUES_ARRAY[2]; // Selecting the third row of the values array. This is where all the important options/data are in the Google Sheet
|
85
91
|
const ALERT_VISIBILITY_IS_FALSE = SHEET_DATA[0] === FALSE_FROM_SHEETS; // First cell(SHEET_DATA[0]) is to toggle the alert's visibility.
|
86
|
-
|
87
92
|
if ( ALERT_VISIBILITY_IS_FALSE )
|
88
93
|
return;
|
89
94
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
/*
|
2
|
+
// Custom JS | written by https://github.com/wdzajicek
|
3
|
+
// © 2020 Kankakee Community College
|
4
|
+
// =================================================== */
|
5
|
+
// Module to retrieve our cached Google Sheet response from sessionStorage
|
6
|
+
// 1. Create an object that replicates an API response where `response.result.values`
|
7
|
+
// is an array containing an array representing each row in the sheet.
|
8
|
+
// 2. Then we pass our mock-sheet response object to the `createAlertsHtml` module to
|
9
|
+
// build and inject the alert into the DOM.
|
10
|
+
import createAlertsHtml from './createAlertsHtml.js';
|
11
|
+
import makeTabsLinkable from './tabLink.js';
|
12
|
+
const cache = window.sessionStorage;
|
13
|
+
|
14
|
+
function processCachedResponse(response, callback) {
|
15
|
+
createAlertsHtml(response);
|
16
|
+
return callback();
|
17
|
+
}
|
18
|
+
|
19
|
+
function createCachedResponseObject() {
|
20
|
+
let cachedResponse = { // Reconstructing our own Google Sheet-like response from the sessionStorage items
|
21
|
+
result: {
|
22
|
+
values: [
|
23
|
+
0, // First two rows aren't used by the `createAlertsHtml()` function
|
24
|
+
0,
|
25
|
+
[ cache.Visible, cache.getItem('All-Pages'), cache.getItem('Alert-Content'), cache.getItem('Alert-Expiration'), cache.Start, cache.End ]
|
26
|
+
]
|
27
|
+
}
|
28
|
+
}
|
29
|
+
processCachedResponse(cachedResponse, makeTabsLinkable);
|
30
|
+
}
|
31
|
+
|
32
|
+
function getCachedResponse() {
|
33
|
+
try {
|
34
|
+
createCachedResponseObject();
|
35
|
+
} catch (error) {
|
36
|
+
makeTabsLinkable();
|
37
|
+
console.error(`Error retrieving cached response in sessionStorage:\nName: ${error.name}\nMessage: ${error.message}\n${error}`);
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
export default getCachedResponse;
|
@@ -0,0 +1,81 @@
|
|
1
|
+
// Custom JS to do cool stuff with BS accordions and tabs by manipulating URL hashes and query's
|
2
|
+
// EXAMPLE:
|
3
|
+
// https://<ORIGIN>/?id=course-withdrawals#tuition-payment-and-deadlines
|
4
|
+
// The above URL will:
|
5
|
+
// 1. Open the #tuition-payment-and-deadlines accordion if it exists
|
6
|
+
// 2. The ?id=course-withdrawals query will:
|
7
|
+
// - look inside the opened accordion for an element with the id 'course-withdrawals', and
|
8
|
+
// - scroll that matching element into the user's viewport (in this case it's a heading within that accordion card)
|
9
|
+
//
|
10
|
+
// This JS will allow us to link to a specific area of content in a page where a traditional hash link wouldn't work
|
11
|
+
// In this case hash links won't work because the element with he matching ID is "stuck" in a closed accordion or tab.
|
12
|
+
//
|
13
|
+
const idRegex = /^id=/g; // Lets just cache these reused regex's here
|
14
|
+
const queryStartRegex = /^\?/g;
|
15
|
+
const endingSlashRegex = /\/$/g;
|
16
|
+
|
17
|
+
function processIdQuery(query, hash) {
|
18
|
+
let id = query.replace(idRegex, '');
|
19
|
+
const parentEl = document.querySelector(hash);
|
20
|
+
const heading = parentEl.querySelector(`#${id}`);
|
21
|
+
|
22
|
+
heading.scrollIntoView()
|
23
|
+
heading.focus();
|
24
|
+
}
|
25
|
+
|
26
|
+
function checkForQuery(query, hash) {
|
27
|
+
query.search(idRegex) !== -1 ?
|
28
|
+
processIdQuery(query, hash)
|
29
|
+
: null;
|
30
|
+
}
|
31
|
+
|
32
|
+
function checkForMatchingTabOrAccordion(hash) {
|
33
|
+
if ( document.querySelector(`.nav-tabs a[href="${hash}"]`) ) { // Looks for a matching BS4 tab element
|
34
|
+
let tab = $(`.nav-tabs a[href="${hash}"]`); // **SIGH**, BS4 requires JQuery
|
35
|
+
|
36
|
+
tab
|
37
|
+
.on('shown.bs.tab', () => { // Bootstrap 4 method for tab events // Must be defined before the tab is activated
|
38
|
+
window.location.search ?
|
39
|
+
checkForQuery(window.location.search.replace(queryStartRegex, ''), hash)
|
40
|
+
: null; })
|
41
|
+
.tab('show'); // Bootstrap 4 Tab method
|
42
|
+
} else if ( document.querySelector(`${hash}.collapse`) ) { // Looks for a matching BS4 collapse element
|
43
|
+
let card = $(hash); // **SIGH**, BS4 requires JQuery
|
44
|
+
|
45
|
+
card
|
46
|
+
.on('shown.bs.collapse', () => { // Bootstrap 4 Collapse method // Must be defined before the collapse is activated
|
47
|
+
window.location.search ?
|
48
|
+
checkForQuery(window.location.search.replace(queryStartRegex, ''), hash)
|
49
|
+
: null; })
|
50
|
+
.collapse('show'); // Bootstrap 4 Collapse method
|
51
|
+
const target = document.querySelector(hash);
|
52
|
+
|
53
|
+
target.scrollIntoView();
|
54
|
+
target.focus(); // For screen readers
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
function checkForHash(e) {
|
59
|
+
// Select the node that will be observed for mutations
|
60
|
+
|
61
|
+
if (window.location.hash) {
|
62
|
+
let hash = window.location.hash.replace(endingSlashRegex, '');
|
63
|
+
|
64
|
+
checkForMatchingTabOrAccordion(hash);
|
65
|
+
}
|
66
|
+
return;
|
67
|
+
}
|
68
|
+
|
69
|
+
function initTabs() {
|
70
|
+
checkForHash();
|
71
|
+
window.addEventListener('hashchange', checkForHash, false);
|
72
|
+
}
|
73
|
+
|
74
|
+
function makeTabsLinkable() {
|
75
|
+
if (!document.querySelector('#accordion') && !document.querySelector('.nav.nav-tabs'))
|
76
|
+
return;
|
77
|
+
|
78
|
+
initTabs();
|
79
|
+
}
|
80
|
+
|
81
|
+
export default makeTabsLinkable;
|