diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b480f96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +# local repo extras +readme-committing-changes.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..05428c7 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# CX-Tools + +## Installation steps +In a browser add on like GreaseMonkey (FireFox) or TamperMonkey (Chrome) you can install the Javascript via following the instructions here: +[Tampermonkey FAQ](https://www.tampermonkey.net/faq.php?ext=gcal&show=gcal#Q102) + + +![Tampermonkey Utilities button](assets/TM-utilities.png) +![Tampermonkey Import from URL](assets/TM-install-from-URL.png) + +The URL to install from is: +https://raw.githubusercontent.com/clmcavaney/CX-Tools/master/canvasBetter.js + +That URL points to a cached copy of the script. The cached copy should update soon after any pushed change. + +## Notes +When a setting is only visible to a SiteAdmin, it is highlighted like this: +![SiteAdmin highlighting example](assets/siteadmin-highlighted-setting-example.png) + +Note that there is also reference to some internal documentation on what this setting is for. diff --git a/assets/TM-install-from-URL.png b/assets/TM-install-from-URL.png new file mode 100644 index 0000000..328afdc Binary files /dev/null and b/assets/TM-install-from-URL.png differ diff --git a/assets/TM-utilities.png b/assets/TM-utilities.png new file mode 100644 index 0000000..45699fb Binary files /dev/null and b/assets/TM-utilities.png differ diff --git a/assets/check-mark-512x512.png b/assets/check-mark-512x512.png new file mode 100755 index 0000000..8bfe07c Binary files /dev/null and b/assets/check-mark-512x512.png differ diff --git a/assets/check-mark-64x64.png b/assets/check-mark-64x64.png new file mode 100755 index 0000000..a89e525 Binary files /dev/null and b/assets/check-mark-64x64.png differ diff --git a/assets/dabpanda-16x16.png b/assets/dabpanda-16x16.png new file mode 100644 index 0000000..953ded5 Binary files /dev/null and b/assets/dabpanda-16x16.png differ diff --git a/assets/dabpanda-32x32.png b/assets/dabpanda-32x32.png new file mode 100644 index 0000000..dd39d55 Binary files /dev/null and b/assets/dabpanda-32x32.png differ diff --git a/assets/dabpanda-64x64.png b/assets/dabpanda-64x64.png new file mode 100644 index 0000000..fa99931 Binary files /dev/null and b/assets/dabpanda-64x64.png differ diff --git a/assets/dabpanda-cropped-16x16.png b/assets/dabpanda-cropped-16x16.png new file mode 100755 index 0000000..22ae032 Binary files /dev/null and b/assets/dabpanda-cropped-16x16.png differ diff --git a/assets/dabpanda-cropped-32x32.png b/assets/dabpanda-cropped-32x32.png new file mode 100755 index 0000000..1c4c882 Binary files /dev/null and b/assets/dabpanda-cropped-32x32.png differ diff --git a/assets/dabpanda-cropped-64x64.png b/assets/dabpanda-cropped-64x64.png new file mode 100755 index 0000000..f38fbc0 Binary files /dev/null and b/assets/dabpanda-cropped-64x64.png differ diff --git a/assets/dabpanda-cropped.png b/assets/dabpanda-cropped.png new file mode 100755 index 0000000..52248d0 Binary files /dev/null and b/assets/dabpanda-cropped.png differ diff --git a/assets/dabpanda.jpg b/assets/dabpanda.jpg new file mode 100755 index 0000000..abdaee7 Binary files /dev/null and b/assets/dabpanda.jpg differ diff --git a/assets/processing-animation.gif b/assets/processing-animation.gif new file mode 100755 index 0000000..8bee3c5 Binary files /dev/null and b/assets/processing-animation.gif differ diff --git a/assets/siteadmin-highlighted-setting-example.png b/assets/siteadmin-highlighted-setting-example.png new file mode 100644 index 0000000..761ee36 Binary files /dev/null and b/assets/siteadmin-highlighted-setting-example.png differ diff --git a/canvasBetter.css b/canvasBetter.css new file mode 100644 index 0000000..e631292 --- /dev/null +++ b/canvasBetter.css @@ -0,0 +1,56 @@ +.cx-tools-ribbon { + opacity: 0.4; + height: 26px; + width: 200px; + background: #FF0000; + font-family: ‘Roboto’, sans-serif; + font-size: 12px; + font-weight: 700; + color: #FFFF3D; + text-align: center; + text-transform: uppercase; + line-height: 24px; + letter-spacing: 1px; + position: fixed; + top: 35px; + right: -55px; + border: 1px solid white; + z-index: 999; + pointer-events: none; + transform: rotate(45deg); + -moz-transform: rotate(45deg); + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + vertical-align: top; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-shadow: 1px 1px 1px rgba(0,0,0,0.004); +} + +.cx-tools-access-token-warning { + position: absolute; + right: 10rem; + top: 0; + z-index: 1000; + background: #f00; + opacity: 0.4; + font-family: ‘Roboto’, sans-serif; + font-size: 12px; + color: #ffff3d; + padding-left: 0.5rem; + padding-right: 0.5rem; +} + +#cx_processing { + position: fixed; + top: 115; + right: 55px; + z-index: 999; +} + +#cx_processing img { + width: 128px; +} diff --git a/canvasBetter.js b/canvasBetter.js old mode 100644 new mode 100755 index e9533ef..e1fb1db --- a/canvasBetter.js +++ b/canvasBetter.js @@ -1,19 +1,28 @@ // ==UserScript== -// @name DG Tools - PAW-15414 +// @name Canvas Experience (CX) Tools // @namespace https://siteadmin.instructure.com/ // @namespace https://instructure.my.salesforce.com/* -// @version 20220104_01 -// @description try to take over the world! -// @author Daniel Gilogley, Zoe Bogner +// @version 2025032402 +// @description Trying to take over the world! "Canvas Experience (CX) Tools" +// @author Daniel Gilogley, Zoe Bogner and Christopher McAvaney // @match https://*.test.instructure.com/* // @match https://*.beta.instructure.com/* // @match https://*.instructure.com/* +// @match https://*.security.instructure.com/* // @match https://s3.amazonaws.com/SSL_Assets/APAC/ticketpage.html* // @match https://instructure.my.salesforce.com/* // @exclude https://siteadmin*instructure.com/* // @exclude https://reports.instructure.com/* +// @exclude https://gerrit.instructure.com/* +// @exclude https://identity.instructure.com/* // @grant GM_getValue // @grant GM_setValue +// @grant GM_getResourceText +// @grant GM_addStyle +// @run-at document-idle +// @require https://gist.github.com/raw/2625891/waitForKeyElements.js +// @resource customCSS https://raw.githubusercontent.com/clmcavaney/CX-Tools/master/canvasBetter.css +// @icon https://www.google.com/s2/favicons?sz=64&domain=instructure.com // ==/UserScript== @@ -29,42 +38,61 @@ if (typeof jQuery == 'undefined' || typeof jQuery === undefined || typeof jQuery } function myJQueryCode() { - //global variables + // global variables var domain = 'https://' + document.location.hostname; var userToken = getItem('token'); var token = userToken; + var _cx_tools_on = false; + var _cx_tools_version = '2025032402'; // If on an instructure page if (document.location.hostname.indexOf('instructure.com') >= 0) { $(document).ready(function() { + var cssTxt = GM_getResourceText("customCSS"); + GM_addStyle(cssTxt); + //add the settings link - $('#menu > li:last').after(''); + $('#menu > li:last').after(''); - //add the DG Tools link - $('#menu > li:last').after(''); + //add the CX Tools link + $('#menu > li:last').after(''); //remove the images if on the old UI remove the images if ($('#menu > li:contains("Dashboard")').length <= 0) { - $('#dg_li_self img, #dg_li_settings img').hide(); - $('#dg_link_self, #dg_link_settings').attr('class', 'menu-item-no-drop'); + $('#cx_li_self img, #cx_li_settings img').hide(); + $('#cx_link_self, #cx_link_settings').attr('class', 'menu-item-no-drop'); } - if (document.location.pathname === "/accounts/self/settings" || document.location.pathname === "/accounts/self/settings/configurations" || document.location.pathname === "/accounts/1/settings" || document.location.pathname === "/accounts/1/settings/configurations") { //if on the settings page + // some regular expressions to match "users", "settings" and "permissions" pages + const re_users=/accounts\/(\d+|self)\/users/; + const re_settings=/\/accounts\/(\d+|self)\/settings/; + const re_perms=/\/accounts\/[^\/]+\/permissions/; + const re_auth_providers=/\/accounts\/[^\/]+\/authentication_providers/; + + const sa_setting_hl_colour='#fdf3f3'; + + const admin_shield_svg = ''; + + + // if on the settings page + if ( document.location.pathname.toLowerCase().match(re_settings) !== null ) { + _cx_tools_on = true; + //focus on the settings link $('li.ic-app-header__menu-list-item--active').attr('class', "menu-item ic-app-header__menu-list-item"); - $('li#dg_li_settings').attr('class', "menu-item ic-app-header__menu-list-item ic-app-header__menu-list-item--active"); + $('li#cx_li_settings').attr('class', "menu-item ic-app-header__menu-list-item ic-app-header__menu-list-item--active"); //Add a Salesforce link to the Account at the bottom of the page - $('#account_external_integration_keys_salesforce_account_id').after(''); + $('#account_external_integration_keys_salesforce_account_id').after(''); //---------On the main Settings page of 'Settings----------------- //create the button to do the default settings - $('#account_settings > legend').after(''); + $('#account_settings > legend').after(''); //apply the action of clicking the default button - $('#dg_button_applyDefaults_settings').click(function(e) { + $('#cx_button_applyDefaults_settings').click(function(e) { e.preventDefault(); if (confirm("Are you sure?")) { - $('#dg_button_applyDefaults_settings').attr('disabled', 'disabled').css('cursor', 'default'); //Disable the button after click + $('#cx_button_applyDefaults_settings').attr('disabled', 'disabled').css('cursor', 'default'); //Disable the button after click //apply the defaults on the settings page $('#account_default_locale').val($('#account_default_locale > option:contains("English (Australia)")').val()); //Default Language @@ -159,12 +187,13 @@ function myJQueryCode() { //Add the show LTIs button on the settings page //users must first be on the page before pressing the button - if(document.location.pathname.toLowerCase().indexOf("/accounts/1/settings/") >= 0 || document.location.pathname.toLowerCase().indexOf("/accounts/self/settings/") >= 0){ - $('nav#breadcrumbs').after('

'); - $("#dg_listLti_ID").click(function(e){ + var settings_match = document.location.pathname.toLowerCase().match(re_settings); + if ( settings_match !== null ) { + $('nav#breadcrumbs').after('
'); + $("#cx_listLti_ID").click(function(e){ e.preventDefault(); - $("#dg_listLti_ID").attr('disabled','disabled'); - listLtiID(); + $("#cx_listLti_ID").attr('disabled','disabled'); + listLtiID(settings_match[1]); return 0; }); } @@ -175,6 +204,62 @@ function myJQueryCode() { }); //----------End do the apply default button ----------------------- + + // Adding identifiers to items that only SiteAdmin users can change + $('#account_settings tr td > label[for=account_settings_mfa_settings]').parent().prepend(admin_shield_svg); + $('#account_settings tr td > label[for=account_settings_mfa_settings]').parent().parent().css('border', '1px dashed red').css('background-color', sa_setting_hl_colour); + $('#account_settings tr td > label[for=account_settings_mfa_settings]').parent().next().append('
setting definition
'); + + $('#account_settings tr td > label[for=account_settings_include_students_in_global_survey]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + + $('#account_settings > div > label[for=account_settings_increase_calendar_limit]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + + $('#account_settings > fieldset.account_domains > legend:contains(Canvas Cloud Information)').css('align-items', 'center').css('display', 'flex').append(admin_shield_svg).css('background-color', sa_setting_hl_colour).next().append('
setting definition
'); + $('#account_settings > fieldset.account_domains > legend:contains(Canvas Cloud Information)').next().append(admin_shield_svg).css('background-color', sa_setting_hl_colour); + $('#account_settings > fieldset.account_domains > select').after(admin_shield_svg).css('background-color', sa_setting_hl_colour); + $('#account_settings > fieldset.account_domains > ul li.new_domain button.add_domain_button').after(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour); + $('#account_settings > fieldset.account_domains > div').append(admin_shield_svg).css('background-color', sa_setting_hl_colour); + + $('#account_settings > fieldset > legend:contains(Acceptable Use Policy)').css('align-items', 'center').css('display', 'flex').append(admin_shield_svg).css('background-color', sa_setting_hl_colour).after('
setting definition
'); + +// Canvas for Elementary is available to an account admin, removing this one +// // Features - group the ones that are Site Admin specific +// // comment for "Canvas for Elementary" +// var _site_admin_div = $('#account_settings > fieldset > legend:contains(Features)').parent('fieldset').find('div').slice(1,3).wrapAll('
').parent(); + // _site_admin_div.prepend(admin_shield_svg).css('background-color', sa_setting_hl_colour).prepend('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_admins_can_change_passwords]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_admins_can_view_notifications]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_enable_eportfolios]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_allow_sis_import]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_include_integration_ids_in_gradebook_exports]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_allow_invitation_previews]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_enable_alerts]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_global_includes]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).prepend('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_show_scheduler]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_enable_profiles]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_limit_parent_app_web_access]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=enable_equella]').parent().append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_settings_enable_turnitin]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_services_account_survey_notifications]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + $('#account_settings > fieldset > legend:contains(Features)').parent().find('div > label[for=account_services_beta_for_students]').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).append('
setting definition
'); + + $('#account_settings > fieldset#add_sis_app_token > legend:contains(SIS Agent Token Authentication)').css('align-items', 'center').css('display', 'flex').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).prepend('
setting definition
'); + + $('#account_settings > fieldset#external_integration_keys > legend:contains(External Integration Keys)').css('align-items', 'center').css('display', 'flex').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour).prepend('
setting definition
'); + + $('nav ul#section-tabs > li > a:contains(Domain Lookups)').css('align-items', 'center').css('display', 'flex').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour); + $('nav ul#section-tabs > li > a:contains(SFTP User)').css('align-items', 'center').css('display', 'flex').append(admin_shield_svg).parent().css('background-color', sa_setting_hl_colour); + + // reference to the Canvas Feature Option Summary + waitForKeyElements("#tab-features > div > span", append_feature_details); + // 20231006 - can't get the correct trigger for this to work correctly + // waitForKeyElements('#tab-features > div > table > tbody', append_feature_account_details); + + // END - adding SiteAdmin user shield + + + + // 20230824 - I think this code below no longer works - may remove it on a future release //Changes to the 'Apps' tab - only if you click on my settings link, and did not navigate there natuarally $('#account_settings_tabs > ul > li:contains("Apps"):first > a:first').click(function(a) { a.preventDefault(); @@ -182,14 +267,14 @@ function myJQueryCode() { $('#external_tools > div > div > div.Header > h2 > div > span.AddExternalToolButton > a.btn.btn-primary.add_tool_link.lm').click(function(b) { b.preventDefault(); setTimeout(function() { - $('body > div.ReactModalPortal > div > div > div > div > div.ReactModal__Header-Title > h4').after(''); + $('body > div.ReactModalPortal > div > div > div > div > div.ReactModal__Header-Title > h4').after(''); var name = "Commons Setup"; var consumerKey = "1"; var sharedSecret = "c9b6c488-4750-48ce-897c-b919ff3cb0f1"; var configURL = "https://lor.instructure.com/api/account-setup/tool-config"; - $('#dg_button_canvasCommons').click(function(c) { + $('#cx_button_canvasCommons').click(function(c) { c.preventDefault(); - $('#dg_button_canvasCommons').attr('disabled', 'disabled').css('cursor', 'default'); //Disable the button after click + $('#cx_button_canvasCommons').attr('disabled', 'disabled').css('cursor', 'default'); //Disable the button after click //select URL $('#configuration_type_selector-bs > ul > li:nth-child(2) > a').click(); @@ -209,37 +294,42 @@ function myJQueryCode() { } //Add Auth changer to users - if (document.location.pathname.indexOf("/accounts/self/users/") >= 0 || document.location.pathname.indexOf("/users/") >=0 || document.location.pathname.indexOf("/accounts/1/users/") >= 0) { + if ( document.location.pathname.toLowerCase().match(re_users) !== null ) { + _cx_tools_on = true; + //figure out how many logins there are and create a select list for them var optionCountHTML = ''; for (var i = 1; i <= $('fieldset#login_information > table.ic-Table > tbody > tr.login:not(:last)').length; i++) { optionCountHTML += ''; } - optionCountHTML = ''; + optionCountHTML = ''; //Create the auth method select for Canvas, LDAP, SAML, Microsoft, and Google - var changeAuthSelect = ''; - //Put in the option to the page for the auth method - $('#name_and_email > table > tbody > tr:last').after('
' + changeAuthSelect + ''); + var changeAuthSelect = ''; + var deleteAndGoButton = ' '; + var td_details = changeAuthSelect + optionCountHTML + deleteAndGoButton; + + //Put in the option to the page for the auth method + $('#name_and_email > table > tbody > tr:last').after(''); + //put in the options dropdown - $('#dg_changeAuth_tr').append('' + optionCountHTML + ''); - //add the 'Go' button - $('#dg_changeAuthCount_td').after('Delete old Method'); + $('#cx_changeAuth_tr').append('' + td_details + ''); + //When you click the 'Go' button - $('#dg_changeAuth_button').click(function(e) { + $('#cx_changeAuth_button').click(function(e) { e.preventDefault(); //disable the options - $('#dg_changeAuth_button,#dg_changeAuth,#dg_deleteOldAuthMethod,#dg_changeAuthCount').attr('disabled', 'disabled'); + $('#cx_changeAuth_button,#cx_changeAuth,#cx_deleteOldAuthMethod,#cx_changeAuthCount').attr('disabled', 'disabled'); //replace the 'Go' button with the spinny wheel - $('#dg_changeAuth_button').html('
'); + $('#cx_changeAuth_button').html('
'); //check to see a proper value is selected - if ($('#dg_changeAuth').val() === "null" || $('#dg_changeAuthCount').val() === "null") { + if ($('#cx_changeAuth').val() === "null" || $('#cx_changeAuthCount').val() === "null") { alert('No Auth method or Number selected!'); return; } else { var currentUserID = ENV.USER_ID; - var authMethodSelected = $('#dg_changeAuth').val(); - var authMethodNumber = $('#dg_changeAuthCount').val(); - var authDeleteOld = $('#dg_deleteOldAuthMethod:checked').length; + var authMethodSelected = $('#cx_changeAuth').val(); + var authMethodNumber = $('#cx_changeAuthCount').val(); + var authDeleteOld = $('#cx_deleteOldAuthMethod:checked').length; var loginID = $('fieldset#login_information > table.ic-Table > tbody > tr.login:eq(' + (authMethodNumber - 1) + ') b.unique_id').text().trim(); var sisID = $('fieldset#login_information > table.ic-Table > tbody > tr.login:eq(' + (authMethodNumber - 1) + ') th[scope="row"] div:eq(0)').text().trim().split('SIS ID: ').join(''); @@ -284,34 +374,45 @@ function myJQueryCode() { xhr.send(data); } }); - } else if (document.location.pathname.toLowerCase() === "/accounts/1/settings/configurations" || document.location.pathname.toLowerCase() === "/accounts/1/settings" || document.location.pathname.toLowerCase().indexOf("/accounts/self/") >=0 ) { + } else if ( document.location.pathname.toLowerCase().match(re_settings) !== null ) { + _cx_tools_on = true; + //token storage and update - var tokenInputHTML = '

'; + var tokenInputHTML = '

'; $('#right-side').prepend(tokenInputHTML); - $('#dg_apiTokenButton').click(function(e) { + $('#cx_apiTokenButton').click(function(e) { e.preventDefault(); - if (confirm("Update token with: " + $('#dg_apiToken').val())) { - storeItem('token', $('#dg_apiToken').val()); + if (confirm("Update token with: " + $('#cx_apiToken').val())) { + storeItem('token', $('#cx_apiToken').val()); location.reload(); } return; }); - } else if (document.location.pathname.toLowerCase() === "/dgtools") { - //focus on the DG links page + } else if ( document.location.pathname.toLowerCase().match(re_auth_providers) !== null ) { + _cx_tools_on = true; + + // new common identity box on the authentication page + // ic-Form-control with a child input tag with name attribute of "authentication_provider[instructure_identity_login_percentage]" + $('#application div.ic-Form-control > input[name="authentication_provider[instructure_identity_login_percentage]"]').parent().append(admin_shield_svg).css('background-color', sa_setting_hl_colour); + + } else if (document.location.pathname.toLowerCase() === "/cxtools1") { + _cx_tools_on = true; + + //focus on the CX Tools links page $('li.ic-app-header__menu-list-item--active').attr('class', "menu-item ic-app-header__menu-list-item"); - $('li#dg_li_self').attr('class', "menu-item ic-app-header__menu-list-item ic-app-header__menu-list-item--active"); + $('li#cx_li_self').attr('class', "menu-item ic-app-header__menu-list-item ic-app-header__menu-list-item--active"); - document.title = "DG - Update User SIS id from one to another"; - $('#main').html('

Update User SIS id from one to another

Old SIS ID / Canvas ID New SIS ID Console Log



Useful links;
'); + document.title = "CX Tools - Update User SIS id from one to another"; + $('#main').html('

Update User SIS id from one to another

Old SIS ID / Canvas ID New SIS ID Console Log



Useful links;
'); - $('button#dg_updateGo').click(function(e) { + $('button#cx_updateGo').click(function(e) { e.preventDefault(); //disable fields and buttons - $('button#dg_updateGo, #dg_old_sis_id, #dg_new_sis_id, #dg_canvasOrSIS').attr('disabled', 'disabled'); + $('button#cx_updateGo, #cx_old_sis_id, #cx_new_sis_id, #cx_canvasOrSIS').attr('disabled', 'disabled'); //get the arrays and confrim that they match - var old_sis_ID = csvOrNot($('#dg_old_sis_id').val()); - var new_sis_ID = csvOrNot($('#dg_new_sis_id').val()); + var old_sis_ID = csvOrNot($('#cx_old_sis_id').val()); + var new_sis_ID = csvOrNot($('#cx_new_sis_id').val()); //create new object array var newObjectArray = []; @@ -325,7 +426,7 @@ function myJQueryCode() { newObjectArray.push(tmp); }); if (confirm("Are you sure?\nThis can't be undone?")) { - update_sis_id(newObjectArray, $('#dg_canvasOrSIS').val()); + update_sis_id(newObjectArray, $('#cx_canvasOrSIS').val()); } else { return 0; } @@ -333,55 +434,144 @@ function myJQueryCode() { return alert('Array lengths do not match!'); } }); - } else if(document.location.pathname.toLowerCase() === "/dgtools2") { - document.title = "DG Tools"; - $('#main').html('

DG Tools

DG Tools are the best!
' + - '

Links

Tools


' + - '


'); - - //LTI Buttons Function - $('li.dg_action_lti').click(function(e){ + } else if(document.location.pathname.toLowerCase() === "/cxtools2") { + _cx_tools_on = true; + + document.title = "CX Tools"; + const _main_menu_html_tpl = ` +
+

Canvas Experience (CX) Tools

+
+ CX Tools are the best! Version: _VERSION_ +
+
+
+
+

Links

+ +

Tools

+ + +
+

Acknowledgements:

+ +
+
+
+
+ +
+ + +
+
`.trim(); + + + var _subdomain = document.location.hostname.split('.')[0]; + var _main_menu_html = _main_menu_html_tpl.replaceAll("_VERSION_", _cx_tools_version).replaceAll('_userToken_', userToken).replaceAll('_INSTANCE_URL_', document.location.hostname).replaceAll('_INSTANCE_SUBDOMAIN_', _subdomain); + $('#main').html(_main_menu_html); + + // LTI Buttons Function + $('li.cx_action_lti button').click(function(e){ e.preventDefault(); console.log("Installing this Tool: " + $(this).text()); - console.log("Key: " + $("button", this).attr("key")); - console.log("Secret: " + $("button", this).attr("secret")); - console.log("URL: " + $("button", this).attr("url")); + console.log("Key: " + $(this).attr("key")); + console.log("Secret: " + $(this).attr("secret")); + console.log("URL: " + $(this).attr("url")); //Disable the button - $("button", this).attr("disabled","disabled"); + $(this).attr("disabled","disabled"); + + // show the user something is happening + $('#cx_processing').show(); //Call the function to install LTI based on the paramters in the HTML Buttons - installLTI($(this).text(), $("button", this).attr('key'), $("button", this).attr('secret'), $("button", this).attr('url')); + installLTI($(this).text(), $(this).attr('key'), $(this).attr('secret'), $(this).attr('url'), "", $(this)); }); //Outcomes Install - $('li.dg_action_outcome').click(function(e){ + $('li.cx_action_outcome button').click(function(e){ e.preventDefault(); console.log('Installing outcomes: ' + $(this).text()); //Disable the button @@ -390,7 +580,7 @@ function myJQueryCode() { }); //External tool link (Office365 / GAFE) - $('li.dg_action_externalTool').click(function(e){ + $('li.cx_action_externalTool button').click(function(e){ e.preventDefault(); $("button", this).attr("disabled","disabled"); @@ -399,19 +589,69 @@ function myJQueryCode() { //window.open("/accounts/self/settings/configurations#tab-tools", "_blank"); //Config Page - Not needed in 2.1 }); + // Inherited LTI developer key + $('li.cx_enable_inherited_lti_and_app button').click(function(e){ + e.preventDefault(); + + // need to get the specific button + var id = $(this).prop('id'); + // disable the button + $('#'+id).attr("disabled","disabled"); + + // show the user something is happening + $('#cx_processing').show(); + + // proposed function + enableLTIKeyandInstallLTI($(this).attr('client_id'), $('#'+id)); + }); + + $('li.cx_enable_inherited_lti_only button').click(function(e){ + e.preventDefault(); + + // need to get the specific button + var id = $(this).prop('id'); + // disable the button + $('#'+id).attr("disabled","disabled"); + + // show the user something is happening + $('#cx_processing').show(); + + // proposed function + enableLTIKeyandInstallLTI($(this).attr('client_id'), $('#'+id), false); + }); + + $('li.cx_enable_credentials button').click(function(e){ + e.preventDefault(); + + // need to get the specific button + var id = $(this).prop('id'); + + // disable the button + $('#'+id).attr("disabled","disabled"); + + // show the user something is happening + $('#cx_processing').show(); + + // proposed function + enableLTIKeyandInstallLTI($(this).attr('client_id_api'), $('#'+id), false, handle_credentials_api_key_enable); + enableLTIKeyandInstallLTI($(this).attr('client_id_lti'), $('#'+id), false, handle_credentials_lti_key_enable); + }); + //Update Token function - $('#dg_apiTokenButton').click(function(e) { + $('#cx_apiTokenButton').click(function(e) { e.preventDefault(); - if (confirm("Update token with: " + $('#dg_apiToken').val())) { - storeItem('token', $('#dg_apiToken').val()); + if (confirm("Update token with: " + $('#cx_apiToken').val())) { + storeItem('token', $('#cx_apiToken').val()); location.reload(); } return; }); - }else if(document.location.pathname.toLowerCase() === "/dgtools3") { + }else if(document.location.pathname.toLowerCase() === "/cxtools3") { + _cx_tools_on = true; + //Create users page - document.title="DG - Create Users" - $('#main').html('

Create Users

First Name Last Name User ID Login ID Email Address



Console Log

Useful links;


'); + document.title="CX Tools - Create Users" + $('#main').html('

Create Users

"User ID" and "Login ID" are the only required fields.

Multiple users can be specified and each users details can be comma separated or new line separated.

First Name Last Name User ID Login ID Email Address



Console Log

Useful links;


'); //getting the auto created users from SF var urlVars = getUrlVars(); @@ -420,32 +660,32 @@ function myJQueryCode() { $.each(splitUsers,function(){ var thisUser = this.split('~'); if(thisUser[0]!="undefined" && thisUser[0]!="" && thisUser[1]!="undefined" && thisUser[1]!="" && thisUser[2]!="undefined" && thisUser[2]!=""){ - $('#dg_first_name').val($('#dg_first_name').val() + thisUser[0] + '\n'); - $('#dg_last_name').val($('#dg_last_name').val() + thisUser[1] + '\n'); - $('#dg_user_id').val($('#dg_user_id').val() + thisUser[2] + '\n'); - $('#dg_login_id').val($('#dg_login_id').val() + thisUser[2] + '\n'); - $('#dg_email').val($('#dg_email').val() + thisUser[2] + '\n'); + $('#cx_first_name').val($('#cx_first_name').val() + thisUser[0] + '\n'); + $('#cx_last_name').val($('#cx_last_name').val() + thisUser[1] + '\n'); + $('#cx_user_id').val($('#cx_user_id').val() + thisUser[2] + '\n'); + $('#cx_login_id').val($('#cx_login_id').val() + thisUser[2] + '\n'); + $('#cx_email').val($('#cx_email').val() + thisUser[2] + '\n'); } }); } - $('button#dg_create_users').click(function(e) { + $('button#cx_create_users').click(function(e) { e.preventDefault(); //disable fields and buttons - $('#dg_create_users,#dg_set_auth,#dg_first_name,#dg_last_name,#dg_login_id,#dg_user_id,#dg_email,#dg_notifyUsers').attr('disabled', 'disabled'); + $('#cx_create_users,#cx_set_auth,#cx_first_name,#cx_last_name,#cx_login_id,#cx_user_id,#cx_email,#cx_notifyUsers').attr('disabled', 'disabled'); //check the "Notify" flag - var notifyCheck = $('#dg_notifyUsers').prop('checked'); + var notifyCheck = $('#cx_notifyUsers').prop('checked'); //if its not null or canvas, then u can't notify - if($('#dg_set_auth').val() == '' || $('#dg_set_auth').val() == 'canvas' || $('#dg_set_auth').val() == 'Null') notifyCheck = false; + if($('#cx_set_auth').val() == '' || $('#cx_set_auth').val() == 'canvas' || $('#cx_set_auth').val() == 'Null') notifyCheck = false; //get the arrays and confrim that they match - var first_name = csvOrNot($('#dg_first_name').val()); - var last_name = csvOrNot($('#dg_last_name').val()); - var login_id = csvOrNot($('#dg_login_id').val()); - var user_id = csvOrNot($('#dg_user_id').val()); - var email = csvOrNot($('#dg_email').val()); - var auth_id = $('#dg_set_auth').val(); + var first_name = csvOrNot($('#cx_first_name').val()); + var last_name = csvOrNot($('#cx_last_name').val()); + var login_id = csvOrNot($('#cx_login_id').val()); + var user_id = csvOrNot($('#cx_user_id').val()); + var email = csvOrNot($('#cx_email').val()); + var auth_id = $('#cx_set_auth').val(); //create new object array var createNewUserArray = []; @@ -474,52 +714,107 @@ function myJQueryCode() { return alert('Array lengths do not match!'); } }); - }else if(document.location.pathname.toLowerCase() === "/dgtools4") { - document.title="DG - Create Sandboxes"; - $('#main').html('

Create Users

  • User ID



    Console Log

    Useful links;
    '); - //Create canavs101 Button - $('#dg_button_create_canvas101').click(function(){ - $('#dg_button_create_canvas101').attr('disabled','disabled'); - var createCanvas101 = createCanvasCourse("Canvas 101","canvas101","sandbox","Growing With Canvas",null); - }); + }else if(document.location.pathname.toLowerCase() === "/cxtools4") { + _cx_tools_on = true; + + document.title="CX Tools - Create Sandboxes"; + const _create_sandboxes_html_tpl = ` +
    +

    Create Sandboxes

    +
    +

    Actions

    + + + + +
    +
      +
    • +
    • +
    • +
      +

      Create sandbox courses for each user below:

      +

      User ID(s)

      + +

      You can choose to enrol these users into the "Canvas 101 (Growing with Canvas)" course too.
      + + +

      + +
      +
    • +
    +
    + +

    API token

    + +
    + +

    Console Log

    + +
    + +
    +

    Useful links

    + +
    +
    +
    + `.trim(); + var _create_sandboxes_html = _create_sandboxes_html_tpl.replaceAll('_userToken_', userToken); + $('#main').html(_create_sandboxes_html); //Create Sandbox Account - $('#dg_button_create_sandbox').click(function(){ - $('#dg_button_create_sandbox').attr('disabled','disabled'); + $('#cx_button_create_sandbox').click(function(){ + $('#cx_button_create_sandbox').attr('disabled','disabled'); var createSandbox = createSandboxAccount(); }); + //Create canavs101 Button + $('#cx_button_create_canvas101').click(function(){ + $('#cx_button_create_canvas101').attr('disabled','disabled'); + var createCanvas101 = createCanvasCourse("Canvas 101","canvas101","sandbox","Growing With Canvas",null); + }); + //create Sandboxes function - $('#dg_create_sandboxes').click(function(){ - $('#dg_create_sandboxes, #dg_user_id, #dg_canvas101').attr('disabled','disabled'); - var userID_array = csvOrNot($('#dg_user_id').val()); - var alsoCanvas101 = $('#dg_canvas101').val(); + $('#cx_create_sandboxes').click(function(){ + $('#cx_create_sandboxes, #cx_user_id, #cx_canvas101').attr('disabled','disabled'); + var userID_array = csvOrNot($('#cx_user_id').val()); + var alsoCanvas101 = $('#cx_canvas101').val(); sandboxCreate(userID_array,alsoCanvas101); }); - }else if(document.location.pathname.toLowerCase() === "/dgtools5") { - document.title="DG - Create Trust"; - $('#main').html('

    Trust Account









    Console Log

    Useful links;


    '); + }else if(document.location.pathname.toLowerCase() === "/cxtools5") { + _cx_tools_on = true; - //When the user clicks "Create trust" - $('#dg_createTrust').click(function(e){ + document.title="CX Tools - Create Trust"; + $('#main').html('

    Trust Account









    Console Log

    Useful links;


    '); + + // When the user clicks "Create trust" + $('#cx_createTrust').click(function(e){ e.preventDefault(); updateConsoleLog('Start creating trust...'); //disbaled the button and fields - $('#dg_createTrust, #dg_trustID, #dg_shard').attr('disabled','disabled'); + $('#cx_createTrust, #cx_trustID, #cx_shard').attr('disabled','disabled'); //action the function to create the trust - var trustID = $('#dg_trustID').val(); - var shardID = $('#dg_shard').val(); + var trustID = $('#cx_trustID').val(); + var shardID = $('#cx_shard').val(); createTrust(trustID,shardID); return 0; }); //List trusts attached to the Canvas - $('#dg_ListTrust').click(function(e){ + $('#cx_ListTrust').click(function(e){ e.preventDefault(); updateConsoleLog('Checking trusts...'); - $('#dg_ListTrust').attr('disabled','disabled'); + $('#cx_ListTrust').attr('disabled','disabled'); listTrusts(); }); } @@ -527,7 +822,7 @@ function myJQueryCode() { //link to the IC support page within the Canvas help $($('#global_nav_help_link').parent()).click(function() { //check to see if the link has been made, as the canvas help only renders on the help link click! - if ($('#dg_icSupportLink').length === 0) { + if ($('#cx_icSupportLink').length === 0) { var buildIcLink = []; var linkURL = "https://s3.amazonaws.com/SSL_Assets/APAC/ticketpage.html"; @@ -545,7 +840,7 @@ function myJQueryCode() { $.ajax(settings).done(function(response) { buildIcLink = { - dgtools: true, + cxtools: true, name: response.name, currentURL: document.location.toString(), DOMAIN_ROOT_ACCOUNT_ID: ENV.DOMAIN_ROOT_ACCOUNT_ID, @@ -558,7 +853,7 @@ function myJQueryCode() { //build the support link URI linkURL = buildURI(buildIcLink, linkURL); console.log(linkURL); - $('#help_tray > ul:first > li:first').before('
  • IC Support
  • '); + $('#help_tray > ul:first > li:first').before('
  • IC Support
  • '); }); } return; @@ -567,16 +862,40 @@ function myJQueryCode() { //if within a course if(document.location.pathname.toLowerCase().indexOf('/courses/') >= 0){ + // Add button to take user back to courses list for root account + $('div.ic-app-nav-toggle-and-crumbs > div.right-of-crumbs').append(' View all courses'); + + if(document.location.pathname.toLowerCase() === "/courses/" + ENV.course_id){ + _cx_tools_on = true; + //If on the homepage of the course //Settings link above the options on RHS - $('#course_show_secondary > div.course-options > a.btn.button-sidebar-wide.course-home-sub-navigation-lti:last').before(' Course Settings'); + $('#course_show_secondary > div.course-options > a.btn.button-sidebar-wide.course-home-sub-navigation-lti:last').before(' Course Settings'); //Undelete option - $('#course_show_secondary > div.course-options > a.btn.button-sidebar-wide.course-home-sub-navigation-lti:last').before(' Undelete Course Content'); + $('#course_show_secondary > div.course-options > a.btn.button-sidebar-wide.course-home-sub-navigation-lti:last').before(' Undelete Course Content'); } } + if ( document.location.pathname.match(re_perms) !== null ) { + _cx_tools_on = true; + + // change each header to be no longer than 18 characters followed by an ellipses - but only call the function once the table has been loaded + waitForKeyElements("table.ic-permissions__table", fix_permission_header); + } + + // Turn on ribbon if a page has modification through the CX Tools + if (_cx_tools_on == true) { + // put the banner div after the body + $('body').prepend('
    CX Tools ON
    '); + } + + // Display a warning so that users know to configure their access token + if (token === null || (typeof token === "string" && token.length === 0)) { + $('body').prepend('
    NO ACCESS TOKEN CONFIGURED
    '); + } + }); // ELSE if on the IC request page } else if (document.location.hostname === "s3.amazonaws.com") { @@ -611,8 +930,8 @@ function myJQueryCode() { var icSupportObject = getUrlVars(); - //if done via DG tools - if (icSupportObject.dgtools == "true") { + //if done via CX Tools + if (icSupportObject.cxtools == "true") { console.log('gg'); //fill out the title field $('#school_name').val(icSupportObject.name); @@ -640,7 +959,7 @@ function myJQueryCode() { }, 5000 ); } - }else if(document.location.pathname.toLowerCase() === "/dgtools3") { + }else if(document.location.pathname.toLowerCase() === "/cxtools3") { //Once on the create users page var urlVars = getUrlVars(); if(urlVars.sfUsers == "true"){ @@ -648,11 +967,11 @@ function myJQueryCode() { $.each(splitUsers,function(){ var thisUser = this.split('~'); if(thisUser[0]!="undefined" && thisUser[0]!="" && thisUser[1]!="undefined" && thisUser[1]!="" && thisUser[2]!="undefined" && thisUser[2]!=""){ - $('#dg_first_name').val($('#dg_first_name').val() + thisUser[0] + '\n'); - $('#dg_last_name').val($('#dg_last_name').val() + thisUser[1] + '\n'); - $('#dg_user_id').val($('#dg_user_id').val() + thisUser[2] + '\n'); - $('#dg_login_id').val($('#dg_login_id').val() + thisUser[2] + '\n'); - $('#dg_email').val($('#dg_email').val() + thisUser[2] + '\n'); + $('#cx_first_name').val($('#cx_first_name').val() + thisUser[0] + '\n'); + $('#cx_last_name').val($('#cx_last_name').val() + thisUser[1] + '\n'); + $('#cx_user_id').val($('#cx_user_id').val() + thisUser[2] + '\n'); + $('#cx_login_id').val($('#cx_login_id').val() + thisUser[2] + '\n'); + $('#cx_email').val($('#cx_email').val() + thisUser[2] + '\n'); } }); } @@ -662,10 +981,10 @@ function myJQueryCode() { // ============== My functions ===================== //get all the LTIs installed - function listLtiID(){ + function listLtiID(canvas_account_id){ var form = new FormData(); var settings = { - "url": "/api/v1/accounts/1/external_tools?per_page=100", + "url": "/api/v1/accounts/" + canvas_account_id + "/external_tools?per_page=100", "method": "GET", "timeout": 0, "headers": { @@ -679,21 +998,21 @@ function myJQueryCode() { $.ajax(settings).done(function (response) { console.log(response); - apiReply = JSON.parse(response); + var apiReply = JSON.parse(response); if(apiReply.length > 0){ $.each(apiReply,function(index,element){ console.log(element); - $("td.external_tool.e-tool-table-data[title='"+ element.name + "']").append(' - LTI ID #' + element.id); + $("td.external_tool.e-tool-table-data[title='"+ element.name.replace(/[']/g, '\\$&') + "']").append(' - LTI ID #' + element.id); }); //add the hide button too - var buildHideButton = '
    '; + var buildHideButton = ' '; $('div.Header > div > p:last').after(buildHideButton); - $("#dg_hideLTI_submit").click(function(e){ + $("#cx_hideLTI_submit").click(function(e){ e.preventDefault(); - $("#dg_hideLTI_submit").attr('disabled','disabled'); + $("#cx_hideLTI_submit").attr('disabled','disabled'); if(confirm("Are you sure you want to do this?! It cannot be undone!") === true) hideElement(); }); } @@ -733,12 +1052,14 @@ function myJQueryCode() { //Add the show LTIs button on the settings page //users must first be on the page before pressing the button - if(document.location.pathname.toLowerCase().indexOf("/accounts/1/settings/") >= 0 || document.location.pathname.toLowerCase().indexOf("/accounts/self/settings/") >= 0){ - $('nav#breadcrumbs').after('

    '); - $("#dg_listLti_ID").click(function(e){ + const re_settings=/\/accounts\/(\d+|self)\/settings/; + var settings_match = document.location.pathname.toLowerCase().match(re_settings); + if ( settings_match !== null ) { + $('nav#breadcrumbs').after('
    '); + $("#cx_listLti_ID").click(function(e){ e.preventDefault(); - $("#dg_listLti_ID").attr('disabled','disabled'); - listLtiID(); + $("#cx_listLti_ID").attr('disabled','disabled'); + listLtiID(settings_match[1]); return 0; }); } @@ -773,7 +1094,7 @@ function myJQueryCode() { "error": function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 404 || errorThrown == 'Not Found') { console.log("Error: " + jqXHR.status + " - User not found: " + element.old); - $('#dg_console_log').val("Error: " + jqXHR.status + " - User not found: " + element.old + " \n" + $('#dg_console_log').val()); + $('#cx_console_log').val("Error: " + jqXHR.status + " - User not found: " + element.old + " \n" + $('#cx_console_log').val()); } } }; @@ -787,7 +1108,7 @@ function myJQueryCode() { xhr.addEventListener("readystatechange", function() { if (this.readyState === 4) { console.log("Completed id update for: " + this.responseText); - $('#dg_console_log').val("Completed id update for: " + element.new + " [" + element.old + "]\n" + $('#dg_console_log').val()); + $('#cx_console_log').val("Completed id update for: " + element.new + " [" + element.old + "]\n" + $('#cx_console_log').val()); } }); @@ -797,7 +1118,7 @@ function myJQueryCode() { xhr.setRequestHeader("cache-control", "no-cache"); xhr.send(data); console.log("Processing for: " + element.new + "[" + element.old + "]"); - $('#dg_console_log').val("Processing for: " + element.new + "[" + element.old + "]\n" + $('#dg_console_log').val()); + $('#cx_console_log').val("Processing for: " + element.new + "[" + element.old + "]\n" + $('#cx_console_log').val()); }); }); } @@ -844,8 +1165,8 @@ function myJQueryCode() { } } - //Install LTIs that use URL Install - function installLTI(name,consumer_key,shared_secret,config_url,canvas_lti_url){ + // Install LTIs that use URL Install + function installLTI(name, consumer_key, shared_secret, config_url, canvas_lti_url, button_trigger) { var data = null; var xhr = new XMLHttpRequest(); @@ -855,16 +1176,6 @@ function myJQueryCode() { canvas_lti_url = ""; } - xhr.addEventListener("readystatechange", function () { - if (this.readyState === 4) { - console.log(this.responseText); - alert(this.responseText); - if(name === "Canvas Commons"){ - window.open("/accounts/self/settings/configurations#tab-tools", "_blank"); - } - } - }); - //Build the API Call var apiURL = canvas_lti_url + "/api/v1/accounts/self/external_tools?name="; apiURL += encodeURI(name) + "&privacy_level=public&consumer_key="; @@ -877,6 +1188,124 @@ function myJQueryCode() { xhr.setRequestHeader("Cache-Control", "no-cache"); xhr.send(data); + + xhr.onload = function() { + if ( xhr.status != 200 ) { + alert(`${xhr.status}: ${xhr.statusText}`); + } + $(button_trigger).removeAttr("disabled"); + $('#cx_processing').hide(); + + // Show the user something + $(button_trigger).parent().append(' LTI installed '); + + // LTI specific code can go here if required + + // If the LTI is Canvas Commons, there is one more step so present the link to head on over and complete that step + if ( name.match('Canvas Commons') != null ) { + $(button_trigger).parent().append(' — now complete configuration via root account settings/apps area'); + } + }; + } + + // enable an inherited LTI developer key + // Note: this will install the LTI, unless install_lti == false + function enableLTIKeyandInstallLTI(client_id, button_trigger, install_lti = true, s_func = null) { + // relative to the domain of the Canvas instance being browsed + var apiURL = '/api/v1/accounts/self/developer_keys/' + client_id + '/developer_key_account_bindings'; + // JSON body + var payload = JSON.stringify({developer_key_account_binding:{workflow_state:'on'}}); + + // debugging + // alert('enableLTIKey(): apiURL == ' + apiURL); + // alert('enableLTIKey(): payload == ' + payload); + + $.ajax({ + type: "POST", + url: apiURL, + headers: { + "Authorization": "Bearer " + userToken, + "Cache-Control": "no-cache", + }, + data: payload, + contentType: "application/json; charset=utf-8", + dataType: "json", + success: function(response) { + console.log('successfully enabled developer LTI key: ' + client_id); + parsed_response = $.parseJSON(JSON.stringify(response)); + console.log('developer LTI key: ' + parsed_response.workflow_state); + if ( install_lti == true ) { + // debugging + // alert('at this point make a HTTP POST request to install the app/LTI'); + installLTIviaClientID(client_id, button_trigger); + } else { + $(button_trigger).removeAttr("disabled"); + $('#cx_processing').hide(); + + $(button_trigger).parent().append(' developer key (' + client_id + ') enabled'); + + // call additional "success function" if one supplied + if ( s_func != null ) { + s_func(button_trigger); + } + } + }, + error: function(e) { + console.log(e); + console.log(JSON.parse(e.responseText)); + json_msg = $.parseJSON(e.responseText); + var err_msg = json_msg['errors']['base']; + console.log('Unable to enable developer LTI key: ' + err_msg); + } + }); + } + + // install LTI via client_id + function installLTIviaClientID(client_id, button_trigger) { + // relative to the domain of the Canvas instance being browsed + var apiURL = '/api/v1/accounts/1/external_tools/'; + + // debugging + // alert('installLTIviaClientID(): client_id == ' + client_id); + + $.ajax({ + type: "POST", + url: apiURL + '?' + $.param({client_id: client_id}), + headers: { + "Authorization": "Bearer " + userToken, + "Cache-Control": "no-cache", + }, + success: function(response) { + console.log('successfully installed external tool (aka LTI)'); + parsed_response = $.parseJSON(JSON.stringify(response)); + console.log('name of installed LTI: ' + parsed_response.name); + + $(button_trigger).removeAttr("disabled"); + $('#cx_processing').hide(); + + $(button_trigger).parent().append(' LTI "' + parsed_response.name + '" installed'); + }, + error: function(e) { + console.log(e); + console.log(JSON.parse(e.responseText)); + json_msg = $.parseJSON(e.responseText); + var err_msg = json_msg['errors']['base']; + console.log('Unable to install external tool: ' + err_msg); + } + }); + } + + // Note: this are very specific to the Credentials button + function handle_credentials_api_key_enable(button_trigger) { + var lti_span; + lti_span=$(button_trigger).parent().find("span:nth-of-type(1)").css('padding', '0.25rem').css('background-color','lightgreen').css('color', 'white'); + $(lti_span).find("input").prop('checked', true); + } + // Note: this are very specific to the Credentials button + function handle_credentials_lti_key_enable(button_trigger) { + var lti_span; + lti_span=$(button_trigger).parent().find("span:nth-of-type(2)").css('padding', '0.25rem').css('background-color','lightgreen').css('color', 'white'); + $(lti_span).find("input").prop('checked', true); } //Import Outcomes Function @@ -929,7 +1358,7 @@ function myJQueryCode() { }*/ }); //Build Post Call - var postCall = "/api/v1/accounts/1/users?user[name]=" + encodeURIComponent(e.full_name); + var postCall = "/api/v1/accounts/self/users?user[name]=" + encodeURIComponent(e.full_name); postCall += "&user[skip_registration]="+!notifyCheck; postCall += "&pseudonym[send_confirmation]="+notifyCheck; //postCall += "&pseudonym[force_self_registration]=" + notifyCheck; @@ -951,7 +1380,7 @@ function myJQueryCode() { } function updateConsoleLog(newVal){ - $('#dg_console_log').val(timeStamp() + " | " + newVal + "\n" + $('#dg_console_log').val()); + $('#cx_console_log').val(timeStamp() + " | " + newVal + "\n" + $('#cx_console_log').val()); } function timeStamp() { @@ -1091,40 +1520,44 @@ function myJQueryCode() { } - //Create trust function + // Create trust function function createTrust(targetID,shardID){ - //build Post URL - //Example post: "https://apaccs.instructure.com/api/v1/accounts/13677~1/trust_links?trust_link%5Bmanaging_account_id%5D=16292~1" + // build Post URL + // Example post: "https://apaccs.instructure.com/api/v1/accounts/13677~1/trust_links?trust_link%5Bmanaging_account_id%5D=16292~1" var buildPost = "/api/v1/accounts/"; - //add this accounts ID + // add this accounts ID buildPost += ENV.DOMAIN_ROOT_ACCOUNT_ID; - buildPost += "/trust_links?trust_link%5Bmanaging_account_id%5D="; - - //Add the trust from ID and Shard - buildPost += targetID + "~" + shardID; - - var data = new FormData(); - - var xhr = new XMLHttpRequest(); - xhr.withCredentials = true; + buildPost += "/trust_links"; - xhr.addEventListener("readystatechange", function() { - if(this.readyState === 4) { - console.log(this.responseText); - if(this.responseText.toLowerCase().indexOf('error') >=0 || this.responseText.toLowerCase().indexOf('fail') >=0){ - updateConsoleLog('Failed creating Trust with error: ' + this.responseText); - }else{ - updateConsoleLog('Success! Creating Trust with message: ' + this.responseText); - } + $.ajaxSetup({ + headers:{ + "Authorization": "Bearer " + userToken, + "Cache-Control": "no-cache", } }); - xhr.open("POST", buildPost); - xhr.setRequestHeader("Authorization", "Bearer " + userToken); - xhr.setRequestHeader("Cache-Control", "no-cache"); - - xhr.send(data); + var trust_data = 'trust_link[managing_account_id]=' + targetID + "~" + shardID; + console.log(trust_data); + $.ajax({ + url: buildPost, + type: 'POST', + data: trust_data, + success: function(response) { + console.log("success"); + console.log(response); + updateConsoleLog('Success! Created Trust - ID:' + response['id']); + }, + error: function(e) { + console.log(e); + console.log(JSON.parse(e.responseText)); + json_msg = jQuery.parseJSON(e.responseText); + var err_attr = json_msg['errors']['managed_role_id'][0]['attribute']; + var err_msg = json_msg['errors']['managed_role_id'][0]['message']; + updateConsoleLog('Unable to create trust: ' + err_attr + ' - ' + err_msg); + }, + dataType: "json" + }); } function listTrusts(){ @@ -1132,30 +1565,45 @@ function myJQueryCode() { buildPost += ENV.DOMAIN_ROOT_ACCOUNT_ID; buildPost += '/trust_links'; - //build call - var data = new FormData(); - - var xhr = new XMLHttpRequest(); - xhr.withCredentials = true; - - xhr.addEventListener("readystatechange", function() { - if(this.readyState === 4) { - console.log(this.responseText); - if(this.responseText.toLowerCase().indexOf('error') >=0 || this.responseText.toLowerCase().indexOf('fail') >=0){ - updateConsoleLog('Failed with error: ' + this.responseText); - }else{ - var newLineReply = this.responseText.split('}').join('}\n').split(',').join(''); - newLineReply = newLineReply.split('[').join('').split(']').join(''); - updateConsoleLog('Success! Listing IDs of trusted Canvi:\n ' + newLineReply); - } + $.ajaxSetup({ + headers:{ + "Authorization": "Bearer " + userToken, + "Cache-Control": "no-cache", + "Accept": "application/json+canvas-string-ids" } }); - xhr.open("GET", buildPost); - xhr.setRequestHeader("Authorization", "Bearer " + userToken); - xhr.setRequestHeader("Cache-Control", "no-cache"); - - xhr.send(data); + $.get( buildPost, function( data ) { + console.log("success"); + + updateConsoleLog('API call success! Now listing IDs of trusted Canvi: (above - can take a little while)'); + + console.log("length of data is " + data.length); + + if ( data.length == 0 ) { + updateConsoleLog('No trusts found') + } else { + // Get details (i.e. name of each trusted instance) + // "/api/v1/accounts/"; + // console.log(json_resp); + $.each(data, function( key, value ) { + // console.log(value); + $.get( "/api/v1/accounts/" + value.managing_account_id, function( data ) { + console.log("success"); + updateConsoleLog(JSON.stringify(value)); + updateConsoleLog('ID: ' + value.id + ' Name: ' + data.name); + }, 'json') + .fail(function() { + console.log("error"); + updateConsoleLog('Unable to get account name for "' + value.managing_account_id + '"'); + }); + }); + } + }, 'json') + .fail(function() { + console.log("error"); + updateConsoleLog('Unable to get trusts: ' + data); + }); } function getUsersFullName(sisUserId){ @@ -1254,7 +1702,7 @@ function myJQueryCode() { console.log('Canvas Destination: ' + ltiDestination) //build the paramters URL - ltiDestination += "/accounts/self/settings/configurations#tab-tools?dg_installLTI=true"; + ltiDestination += "/accounts/self/settings/configurations#tab-tools?cx_installLTI=true"; ltiDestination += "<iName=" + encodeURI(ltiName); ltiDestination += "<iKey=" + encodeURI(ltiKey); ltiDestination += "<iSecret=" + encodeURI(ltiSecret); @@ -1272,7 +1720,7 @@ function myJQueryCode() { //now on the LTI config Settings if(document.location.pathname === "/accounts/self/settings/configurations"){ var ltiURLvals = getUrlVars(); - if(ltiURLvals.dg_installLTI === undefined || ltiURLvals.dg_installLTI === null){ + if(ltiURLvals.cx_installLTI === undefined || ltiURLvals.cx_installLTI === null){ console.log('No LTI to install'); }else{ alert("Installing LTI: " + ltiURLvals.ltiName + "\nClick 'OK' and the page will refresh with the LTI Installed"); @@ -1297,7 +1745,8 @@ function myJQueryCode() { jqTag.type = 'text/javascript'; jqTag.src = 'https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'; headTag.appendChild(jqTag); - jqTag.onload = myJQueryCode;} + jqTag.onload = myJQueryCode; +} function openInNewTab(url) { @@ -1354,35 +1803,70 @@ function getUsers(){ function buildTheContactsTableUI(){ //Put the action box at the top if($('h2.mainTitle').text() === "Account Detail"){ - $('div.listRelatedObject.contactBlock input[value="New Contact"]').after(''); + $('div.listRelatedObject.contactBlock input[value="New Contact"]').after(''); }else{ - $('div.pbHeader:first').after(''); + $('div.pbHeader:first').after(''); } //put the checkboxes in - $('#bodyCell div.pbBody table:contains("Contact Status") th.actionColumn').prepend(''); //Master checkbox + $('#bodyCell div.pbBody table:contains("Contact Status") th.actionColumn').prepend(''); //Master checkbox //user array - $('#bodyCell div.pbBody table:contains("Contact Status") td.actionColumn').prepend(''); + $('#bodyCell div.pbBody table:contains("Contact Status") td.actionColumn').prepend(''); //function to check, or uncheck all based on the master checkbox - $('#dg_checkUsersMaster').change(function(e){ + $('#cx_checkUsersMaster').change(function(e){ e.preventDefault(); //console.log('here'); - var checkBoxes = $('input.dg_checkUsers:not(:first)'); + var checkBoxes = $('input.cx_checkUsers:not(:first)'); checkBoxes.prop("checked", !checkBoxes.prop("checked")); }); - $('#dg_userToCanvas').click(function(e){ - $('#dg_canvasURL, #dg_userToCanvas, input.dg_checkUsers').attr('disabled','disabled'); + $('#cx_userToCanvas').click(function(e){ + $('#cx_canvasURL, #cx_userToCanvas, input.cx_checkUsers').attr('disabled','disabled'); e.preventDefault(); //sessionStorage.setItem('userArrayString',getUsers()); //Local storage doesnt seem to be working adding it to the link var userString = getUsers(); userString = userString.trim(); userString = encodeURI(userString); - var buildCanvasURL = "https://" + $('#dg_canvasURL').val() + ".instructure.com/dgtools3?sfUsers=true&userData=" + userString; + var buildCanvasURL = "https://" + $('#cx_canvasURL').val() + ".instructure.com/cxtools3?sfUsers=true&userData=" + userString; openInNewTab(buildCanvasURL); }); } +// shorten some text to textLength long and add an ellipses +function shorten(text, textLength){ + if(text.length > textLength){ + text = text.substring(0, textLength) + '…'; + } + return text; +} + +function fix_permission_header() { + var existing_label; + var new_label; + + // very specific selector + $('table.ic-permissions__table > thead > tr.ic-permissions__top-header > th.ic-permissions__top-header__col-wrapper-th > div > div > span > button > span').each(function(i, obj) { + existing_label = $(this).text(); + new_label = shorten(existing_label, 18); + $(this).html(new_label); + }); +} + +function append_feature_details(node) { + const admin_shield_svg = ''; + + node.append('
    ' + admin_shield_svg + ' Canvas Feature Option Summary
    '); +} + +// 20231006 - can't get this to fire at the correct time - really needs to be supplied by the underling code +/* +function append_feature_account_details(node) { + // attempting to append a feature + $('#tab-features > div > table > tbody > tr > td > div > button > span > span:contains("Account and Course Level Outcome Mastery Scales")').closest('div').find('div > div > div').append('
    feature definition'); + alert('in append_feature_account_details()') +} +*/ +// vim:expandtab ts=4 sw=4 diff --git a/dabpanda.jpg b/dabpanda.jpg deleted file mode 100644 index 58922dc..0000000 Binary files a/dabpanda.jpg and /dev/null differ