From f817f4918206a66b8243cb57841f6757944f49f5 Mon Sep 17 00:00:00 2001 From: realaravinth Date: Tue, 4 May 2021 15:18:07 +0530 Subject: [PATCH] doc handler uses const and js, I give upT-T --- src/docs.rs | 24 ++- templates/panel/add-site-key/add-level.html | 2 +- .../panel/add-site-key/addLevelButton.ts | 29 +++- templates/panel/add-site-key/const.ts | 19 ++- .../panel/add-site-key/existing-level.html | 2 +- templates/panel/add-site-key/levels/index.ts | 59 +++++++ .../panel/add-site-key/removeLevelButton.ts | 160 ++++++++++++++++++ 7 files changed, 273 insertions(+), 22 deletions(-) create mode 100644 templates/panel/add-site-key/removeLevelButton.ts diff --git a/src/docs.rs b/src/docs.rs index 8374cf6b..3876ec96 100644 --- a/src/docs.rs +++ b/src/docs.rs @@ -92,23 +92,29 @@ mod tests { use crate::*; #[actix_rt::test] - async fn docs_work() { - const INDEX: &str = "/docs"; - const FILE: &str = "/docs/favicon-32x32.png"; - const SPEC: &str = "/docs/openapi.json"; + async fn docs_works() { + const FILE: &str = "favicon-32x32.png"; let mut app = test::init_service(App::new().configure(services)).await; - let resp = - test::call_service(&mut app, test::TestRequest::get().uri(INDEX).to_request()).await; + let resp = test::call_service( + &mut app, + test::TestRequest::get().uri(DOCS.home).to_request(), + ) + .await; assert_eq!(resp.status(), StatusCode::OK); - let resp = - test::call_service(&mut app, test::TestRequest::get().uri(FILE).to_request()).await; + let resp = test::call_service( + &mut app, + test::TestRequest::get().uri(DOCS.spec).to_request(), + ) + .await; assert_eq!(resp.status(), StatusCode::OK); + let uri = format!("{}{}", DOCS.home, FILE); + let resp = - test::call_service(&mut app, test::TestRequest::get().uri(SPEC).to_request()).await; + test::call_service(&mut app, test::TestRequest::get().uri(&uri).to_request()).await; assert_eq!(resp.status(), StatusCode::OK); } } diff --git a/templates/panel/add-site-key/add-level.html b/templates/panel/add-site-key/add-level.html index d8d1526f..3e25af11 100644 --- a/templates/panel/add-site-key/add-level.html +++ b/templates/panel/add-site-key/add-level.html @@ -1,4 +1,4 @@ -
+
Level <.= level .> diff --git a/templates/panel/add-site-key/addLevelButton.ts b/templates/panel/add-site-key/addLevelButton.ts index db3e3ad9..e4e1b5ee 100644 --- a/templates/panel/add-site-key/addLevelButton.ts +++ b/templates/panel/add-site-key/addLevelButton.ts @@ -14,9 +14,15 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ -import getNumLevels from './levels/getNumLevels'; import validateLevel from './levels/validateLevel'; +import getNumLevels from './levels/getNumLevels'; +import {LEVELS} from './levels/'; import * as UpdateLevel from './levels/updateLevel'; +import { + getRemoveButtonHTML, + addRemoveLevelButtonEventListener, +} from './removeLevelButton'; +import CONST from './const'; const ADD_LEVEL_BUTTON = 'sitekey-form__level-add-level-button'; @@ -27,21 +33,27 @@ const ADD_LEVEL_BUTTON = 'sitekey-form__level-add-level-button'; */ const addLevel = (e: Event) => { const eventTarget = e.target; - const PARENT = eventTarget.parentElement; + const PARENT = eventTarget.parentElement; const FIELDSET = PARENT.parentElement; - const numLevels = getNumLevels(); + const onScreenLevel = getNumLevels(); - const isValid = validateLevel(numLevels); + const isValid = validateLevel(onScreenLevel); console.log(`[addLevelButton] isValid: ${isValid}`); if (!isValid) { return console.error('Aborting level addition'); } - PARENT.remove(); + eventTarget.remove(); + PARENT.innerHTML = getRemoveButtonHTML(onScreenLevel); + PARENT.htmlFor = `${CONST.REMOVE_LEVEL_BUTTON_ID_WITHOUT_LEVEL}${onScreenLevel}`; + //FIELDSET.innerHTML += getRemoveButtonHTML(numLevels); + addRemoveLevelButtonEventListener(onScreenLevel); - const newLevelHTML = getHtml(numLevels + 1); + //PARENT.remove(); + + const newLevelHTML = getHtml(onScreenLevel + 1); FIELDSET.insertAdjacentHTML('afterend', newLevelHTML); - UpdateLevel.register(numLevels); + UpdateLevel.register(onScreenLevel); addLevelButtonAddEventListener(); }; @@ -60,8 +72,9 @@ const addLevelButtonAddEventListener = () => { */ const getHtml = (level: number) => { console.debug(`[generating HTML getHtml]level: ${level}`); + const HTML = ` -
+
Level ${level} diff --git a/templates/panel/add-site-key/const.ts b/templates/panel/add-site-key/const.ts index eb01e72b..ccdde758 100644 --- a/templates/panel/add-site-key/const.ts +++ b/templates/panel/add-site-key/const.ts @@ -16,20 +16,33 @@ */ const LABEL_INNER_TEXT_WITHOUT_LEVEL = 'Level '; +const LABEL_CLASS = 'sitekey-form__level-label'; + const INPUT_ID_WITHOUT_LEVEL = 'level'; -const LABEL_CLASS = 'sitekey-form__label'; +const LEVEL_INPUT_CLASS = 'sitekey-form__level-input'; + const VISITOR_WITHOUT_LEVEL = 'visitor'; const DIFFICULTY_WITHOUT_LEVEL = 'difficulty'; -const LEVEL_CONTAINER_CLASS = "sitekey__level-container"; +const LEVEL_CONTAINER_CLASS = 'sitekey__level-container'; +const LEVEL_FIELDSET_ID_WITHOUT_LEVEL = 'level-group-'; +const LEGEND_CLASS = 'sitekey__level-title'; + +const REMOVE_LEVEL_BUTTON_ID_WITHOUT_LEVEL = 'remove-level'; +const REMOVE_LEVEL_LABEL_TEXT = "Remove Level"; const CONST = { LABEL_CLASS, INPUT_ID_WITHOUT_LEVEL, + LEVEL_INPUT_CLASS, LABEL_INNER_TEXT_WITHOUT_LEVEL, VISITOR_WITHOUT_LEVEL, DIFFICULTY_WITHOUT_LEVEL, LEVEL_CONTAINER_CLASS, -} + LEVEL_FIELDSET_ID_WITHOUT_LEVEL, + LEGEND_CLASS, + REMOVE_LEVEL_BUTTON_ID_WITHOUT_LEVEL, + REMOVE_LEVEL_LABEL_TEXT, +}; export default CONST; diff --git a/templates/panel/add-site-key/existing-level.html b/templates/panel/add-site-key/existing-level.html index e1115831..0bd96ea5 100644 --- a/templates/panel/add-site-key/existing-level.html +++ b/templates/panel/add-site-key/existing-level.html @@ -1,4 +1,4 @@ -
+
Level <.= level .> diff --git a/templates/panel/add-site-key/levels/index.ts b/templates/panel/add-site-key/levels/index.ts index 81ece72a..2bd89ba2 100644 --- a/templates/panel/add-site-key/levels/index.ts +++ b/templates/panel/add-site-key/levels/index.ts @@ -15,6 +15,8 @@ * along with this program. If not, see . */ +import getNumLevels from './getNumLevels'; + /** Datatype represenging an mCaptcha level */ export type Level = { difficulty_factor: number; @@ -24,9 +26,13 @@ export type Level = { /** Datatype representing a collection of mCaptcha levels */ class Levels { levels: Array; + numOnScreen: number; + numRecoreded: number; constructor() { this.levels = []; + this.numRecoreded = 0; + this.numOnScreen = getNumLevels(); } add = (newLevel: Level) => { @@ -66,6 +72,8 @@ class Levels { throw new Error(msg); } else { this.levels.push(newLevel); + this.numOnScreen += 1; + this.numRecoreded += 1; } }; @@ -79,6 +87,16 @@ export const LEVELS = (function() { return { /** get levels */ getLevels: () => levels.get(), + /** + * get levels displayed on screen. + * This includes the one with add level button + * */ + getOnScreen: () => levels.numOnScreen, + /** + * get levels recorded using LEVELS + * This excludes the one with add level button + * */ + getRecored: () => levels.numRecoreded, /** add new level */ add: (newLevel: Level) => levels.add(newLevel), @@ -96,6 +114,47 @@ export const LEVELS = (function() { tmpLevel.add(levels.levels[i]); } } + levels.levels = tmpLevel.levels; + console.log(`post update:`); + LEVELS.print(); + return true; + } catch (e) { + console.log(e); + return false; + } + }, + + print: () => + levels.levels.forEach(level => + console.debug( + `difficulty_factor: ${level.difficulty_factor} visitor ${level.visitor_threshold}`, + ), + ), + + /** remove level */ + remove: (id: number) => { + console.debug(`[LEVELS] received order to remove ${id} element`); + + const tmpLevel = new Levels(); + + id -= 1; + try { + for (let i = 0; i < levels.levels.length; i++) { + if (id != i) { + tmpLevel.add(levels.levels[i]); + } else { + console.debug(`[LEVELS] removing ${i} element`); + const rmElement = levels.levels[i]; + console.debug( + `[LEVELS] removing element: + difficulty_factor: ${rmElement.difficulty_factor} + visitor_threshold: ${rmElement.visitor_threshold}`, + ); + } + } + levels.levels = tmpLevel.levels; + console.debug('Post remove:'); + LEVELS.print(); return true; } catch (e) { console.log(e); diff --git a/templates/panel/add-site-key/removeLevelButton.ts b/templates/panel/add-site-key/removeLevelButton.ts new file mode 100644 index 00000000..f62cc11f --- /dev/null +++ b/templates/panel/add-site-key/removeLevelButton.ts @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2021 Aravinth Manivannan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ +import {LEVELS} from './levels/index'; +import getNumLevels from './levels/getNumLevels'; +import CONST from './const'; + +const REMOVE_LEVEL_BUTTON = 'sitekey-form__level-remove-level-button'; + +/** + * Gets executed when 'Remove' Button is clicked to remove levels + */ +const removeLevel = (e: Event) => { + const eventTarget = e.target; + const PARENT = eventTarget.parentElement; + const FIELDSET = PARENT.parentElement; + + const levelNum = parseInt( + eventTarget.id.slice(CONST.REMOVE_LEVEL_BUTTON_ID_WITHOUT_LEVEL.length), + ); + + if (Number.isNaN(levelNum)) { + const msg = + '[removeLevelButton.ts] error in parsing level number from remove button ID'; + //console.error(msg); + throw new Error(msg); + } + updateLevelNumbersOnDOM(levelNum); + + LEVELS.remove(levelNum); + FIELDSET.remove(); +}; + +/** update level number on fieldset legends and their ids too */ +const updateLevelNumbersOnDOM = (id: number) => { + const numLevels = getNumLevels(); + if (id + 1 == numLevels) { + // this is the first elemet so have to remove fist element + // and downgrade the add thingy + + } + + // since I'm doing id+1, I have to remove id after I'm done + // with inclreasing level numbers + for (let i = id+1; i <= numLevels; i++) { + const newLevel = i-1; + + const levelGroup = document.querySelector( + `#${CONST.LEVEL_FIELDSET_ID_WITHOUT_LEVEL}${i}`, + ); + + if (levelGroup === null) { + const msg = `[removeLevelButton.ts]: + error when trying to fetch level group field set ${i}. got null`; + //console.error(msg); + throw new Error(msg); + } + + // rename legend + levelGroup.getElementsByTagName( + 'legend', + )[0].innerText = `Level ${newLevel}`; + + // rename labels + const labels = >( + levelGroup.querySelectorAll(`.${CONST.LABEL_CLASS}`) + ); + //console.log(labels); + labels.forEach(label => { + //console.log(`${label.htmlFor}`); + if (label.htmlFor.includes(CONST.VISITOR_WITHOUT_LEVEL)) { + label.htmlFor = `${CONST.VISITOR_WITHOUT_LEVEL}${newLevel}`; + } + + if (label.htmlFor.includes(CONST.DIFFICULTY_WITHOUT_LEVEL)) { + label.htmlFor = `${CONST.DIFFICULTY_WITHOUT_LEVEL}${newLevel}`; + } + }); + + // rename inputs + const inputs = >( + levelGroup.querySelectorAll(`.${CONST.LEVEL_INPUT_CLASS}`) + ); + //console.log(inputs); + inputs.forEach(input => { + if (input.id.includes(CONST.VISITOR_WITHOUT_LEVEL)) { + //console.log(`${input.id}`); + //console.log('changing visitor_threshold input'); + input.id = `${CONST.VISITOR_WITHOUT_LEVEL}${newLevel}`; + } + + if (input.id.includes(CONST.DIFFICULTY_WITHOUT_LEVEL)) { + //console.log('changing difficulty input'); + input.id = `${CONST.DIFFICULTY_WITHOUT_LEVEL}${newLevel}`; + } + }); + + levelGroup.id = `${CONST.LEVEL_FIELDSET_ID_WITHOUT_LEVEL}${newLevel}`; + + /* TODO + * change field set ID + * change legend inner Text + * change visitor lable for value + * change visitor input id + * change difficulty for value + * change difficulty input id + */ + } +}; + +/** adds onclick event listener */ +export const addRemoveLevelButtonEventListener = (level: number) => { + const removeButton = ( + document.querySelector( + `#${CONST.REMOVE_LEVEL_BUTTON_ID_WITHOUT_LEVEL}${level}`, + ) + ); + removeButton.addEventListener('click', removeLevel); +}; + +/** adds onclick event listener to all remove buttons */ +export const addRemoveLevelButtonEventListenerAll = () => { + const removeButtons = document.querySelectorAll(`.${REMOVE_LEVEL_BUTTON}`); + removeButtons.forEach(button => + button.addEventListener('click', removeLevel), + ); +}; + +/** + * Generate Remove button HTML. On-click handler should be added + * seprately + */ +export const getRemoveButtonHTML = (level: number) => { + //console.debug(`[generating HTML getHtml]level: ${level}`); + const HTML = ` + ${CONST.REMOVE_LEVEL_LABEL_TEXT} + +
+`; + return HTML; +};