Skip to content

(Optional) Typescript #131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ build
/.pydevproject*
/.pytest_cache/
/.settings/

# Ignore ts build folders
/ts/node_modules
/ts/build
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ ENV JUPYTERHUB_TEMPLATES_DIR=/templates
RUN mkdir -p ${JUPYTERHUB_TEMPLATES_DIR}
COPY ./templates/ ${JUPYTERHUB_TEMPLATES_DIR}

# Generate static assets
COPY ./ts/ /ts-working/
WORKDIR /ts-working
RUN npm ci && npm run build
RUN mkdir -p /opt/bitnami/python/share/jupyterhub/static/ts/
RUN cp -R ts-build/. /opt/bitnami/python/share/jupyterhub/static/ts/
WORKDIR /

RUN npm install -g configurable-http-proxy

COPY ./src/ /src
Expand Down
78 changes: 3 additions & 75 deletions templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -69,81 +69,9 @@ <h1>Sign in</h1>
{% endblock main %}
{% block script %}
{{ super() }}
<script src="{{ static_url('ts/templates/login.js') }}"/></script>
<script>
if (!window.isSecureContext) {
// unhide http warning
var warning = document.getElementById('insecure-login-warning');
warning.className = warning.className.replace(/\bhidden\b/, '');
}
// setup onSubmit feedback
$('form').submit((e) => {
var form = $(e.target);
form.find('.feedback-container>input').attr('disabled', true);
form.find('.feedback-container>*').toggleClass('hidden');
form.find('.feedback-widget>*').toggleClass('fa-pulse');
});

const enviromentOrigin = "{{ kbase_origin }}"

$('#login_not_ok').click(function () {
window.location.href = enviromentOrigin + '/login?nextRequest=%22/cdm/redirect%22';
})

// Initial state update
updateState();
// Check for cookie changes in other windows w/ setInterval,
// in case someone goes to another window to log in
// instead of clicking through our flow.
let currentCookie = "";
setInterval(() => {
const tokenCookie = getCookie('kbase_session');
// if cookie changes
if (tokenCookie !== currentCookie) {
currentCookie = tokenCookie;
updateState();
}
}, 200);

function updateState() {
// Check KBase token is present and valid
checkKBaseCookie().then((username) => {
if (username) {
const buttonText = 'Log in with KBase as "' + username + '"';
$('#login_submit').attr('value', buttonText);
$('#login_submit').toggleClass('hidden', false);
$('#login_not_ok').toggleClass('hidden', true);
} else {
$('#login_submit').toggleClass('hidden', true);
$('#login_not_ok').toggleClass('hidden', false);
}
})
}

function checkKBaseCookie() {
const tokenCookie = getCookie('kbase_session');
if (!tokenCookie) return Promise.resolve(null);
return fetch(enviromentOrigin + '/services/auth/api/V2/me', {
headers: {
Authorization: tokenCookie,
},
method: 'GET'
}).then((resp) => {
return resp.json();
}).then(json => {
if ('user' in json) {
return json.user
} else {
return null;
}
}).catch((resp) => {
return null;
});
}

function getCookie(name) {
const escapedName = name.replace(/([.*+?\^$(){}|\[\]\/\\])/g, '\\$1');
var match = document.cookie.match(RegExp('(?:^|;\\s*)' + escapedName + '=([^;]*)'));
return match ? match[1] : null;
}
const enviromentOrigin = "{{ kbase_origin }}";
init(enviromentOrigin);
</script>
{% endblock script %}
11 changes: 11 additions & 0 deletions ts/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Typescript Build Env for JupyterHub server assets

# Adding new asset exports
Specify assets to export in the "inputs" option in `rollup.config.mjs`. See Rollup Docs.

# Referencing exported assets in a jupyterhub template
If a file is exported using entriesFromGlob, it will be available at the same subpath on `hub/static/ts/[file]` as it lives in `/ts/src/[file]`

E.G.

`src/templates/login.ts` exported with `entriesFromGlob("templates/**/*.ts")` can be referenced in a jinja template with: `{{ static_url('ts/templates/login.js') }}`
7 changes: 7 additions & 0 deletions ts/globals.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import type JQueryStatic from 'jquery';

declare global {
interface Window {
$: JQueryStatic;
}
}
Loading
Loading