From 392b435a8a51e3ab76d415774581c9eaaa8a88da Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Fri, 19 Jul 2024 17:44:06 +0000 Subject: [PATCH 1/2] added new text input to manage filers page --- components/centraldashboard/README.md | 2 +- .../public/assets/i18n/languages.json | 32 ++++++++++++++--- .../public/components/manage-filers-view.css | 10 +++++- .../public/components/manage-filers-view.js | 27 +++++++++++--- .../public/components/manage-filers-view.pug | 36 ++++++++++++------- 5 files changed, 83 insertions(+), 24 deletions(-) diff --git a/components/centraldashboard/README.md b/components/centraldashboard/README.md index 24177b2e0f4..24d6e1cd193 100644 --- a/components/centraldashboard/README.md +++ b/components/centraldashboard/README.md @@ -31,7 +31,7 @@ kubectl --record deployment.apps/centraldashboard \ ## Development ### Getting Started -Make sure you have the latest LTS version of `node` installed along with `npm`. +Make sure you have `node v16` installed along with `npm`. 1. Clone the repository and change directories to `components/centraldashboard` 2. Run `make build-local`. This will install all of the project dependencies and diff --git a/components/centraldashboard/public/assets/i18n/languages.json b/components/centraldashboard/public/assets/i18n/languages.json index b833db7cfc8..bb167bd0f50 100644 --- a/components/centraldashboard/public/assets/i18n/languages.json +++ b/components/centraldashboard/public/assets/i18n/languages.json @@ -131,8 +131,20 @@ "manageUsersViewContributor.errorDeleteGeneral": "An error occured while trying to remove the email. Please try again.", "manageFilersView.lblManageFilers": "Manage Filers", "manageFilersView.lblFilers": "Filers", + "manageFilersView.btnDelete": "Delete", + "manageFilersView.headerAddFiler": "Add a new filer", + "manageFilersView.lblFiler": "Filer", + "manageFilersView.optionFiler": "Select a filer", + "manageFilersView.lblShare": "Share", + "manageFilersView.optionShare": "Select a share", + "manageFilersView.lblExtraShare": "Additional share path", + "manageFilersView.placeholderExtraShare": "Optional path", "manageFilersView.btnSubmit": "Submit", "manageFilersView.successUpdate": "Filers updated!", + "manageFilersView.missingFiler": "Please select a filer", + "manageFilersView.missingShare": "Please select a share", + "manageFilersView.duplicateFiler": "Filer has already been selected", + "manageFilersView.missingDeleteError": "User does not have filer {filerShare}", "s3Proxy.defaultMessage": "This workspace does not include S3 proxy. To start using S3 proxy, please opt in to the service." }, "fr": { @@ -171,7 +183,7 @@ "mainPage.menuKatib": "Katib", "mainPage.menuArtifactStore": "Magasin d'artefact", "mainPage.menuManageContributors": "Gérer les contributeurs", - "mainPage.menuManageFilers": "Gérer les filers", + "mainPage.menuManageFilers": "Gérer les classeurs", "mainPage.menuMetrics": "Mesures", "mainPage.menuGitHub": "GitHub", "mainPage.menuDocumentation": "Documentation", @@ -265,10 +277,22 @@ "manageUsersViewContributor.errorCreateGeneral": "Échec lors de l'ajout d'un courriel. Veuillez vous assurez que le format est valide et qu'il n'y a pas de duplicat dans cet espace de travail.", "manageUsersViewContributor.errorCreateFDI": "Ne peut pas ajouter un utilisateur externe à un espace de travail qui contient des seaux seulement internes. Veuillez contacter l'équipe d'ETAA", "manageUsersViewContributor.errorDeleteGeneral": "Échec lors de la supression du courriel. Veuillez réessayer.", - "manageFilersView.lblManageFilers": "Gérer les filers", - "manageFilersView.lblFilers": "Filers", + "manageFilersView.lblManageFilers": "Gérer les classeurs", + "manageFilersView.lblFilers": "Classeurs", + "manageFilersView.btnDelete": "Supprimer", + "manageFilersView.headerAddFiler": "Ajouter un nouveau classeur", + "manageFilersView.lblFiler": "Classeur", + "manageFilersView.optionFiler": "Sélectionner un classeur", + "manageFilersView.lblShare": "Partage", + "manageFilersView.optionShare": "Sélectionner un partage", + "manageFilersView.lblExtraShare": "Chemin de partage supplémentaire", + "manageFilersView.placeholderExtraShare": "Chemin facultatif", "manageFilersView.btnSubmit": "Soumettre", - "manageFilersView.successUpdate": "Filers mis à jour!", + "manageFilersView.successUpdate": "Classeurs mis à jour!", + "manageFilersView.missingFiler": "Veuillez sélectionner un classeur", + "manageFilersView.missingShare": "Veuillez sélectionner un partage", + "manageFilersView.duplicateFiler": "Le classeur a déjà été sélectionné", + "manageFilersView.missingDeleteError": "L'utilisateur n'a pas le classeur {filerShare}", "s3Proxy.defaultMessage": "Cet espace de travail n'inclue pas S3 proxy. Pour commencer à utiliser S3 proxy, veuilliez choisir de participer au service." } } diff --git a/components/centraldashboard/public/components/manage-filers-view.css b/components/centraldashboard/public/components/manage-filers-view.css index 7a9f6d53429..4c5f9c04155 100644 --- a/components/centraldashboard/public/components/manage-filers-view.css +++ b/components/centraldashboard/public/components/manage-filers-view.css @@ -46,11 +46,12 @@ h2 .icon { } #filersTable{ - margin-bottom: .5em; + margin-bottom: 1.5em; } #filersSubmit{ padding: .5em; + margin: .5em; } [hidden] {display: none !important} @@ -66,3 +67,10 @@ paper-toast#FilersSuccessToast { .Error{ color: #F44336 } + +label { + padding: .25em; +} +.formInputDiv{ + margin-bottom: .5em; +} diff --git a/components/centraldashboard/public/components/manage-filers-view.js b/components/centraldashboard/public/components/manage-filers-view.js index d571c1121e1..9e66e8c8e3d 100644 --- a/components/centraldashboard/public/components/manage-filers-view.js +++ b/components/centraldashboard/public/components/manage-filers-view.js @@ -108,6 +108,7 @@ export class ManageFilersView extends mixinBehaviors([AppLocalizeBehavior], util onChangeFilers(e) { this.filersFormValue = e.target.value; this.$.sharesSelect.value = ''; + this.$.sharesInput.value = ''; this.validateError = ''; } @@ -122,18 +123,27 @@ export class ManageFilersView extends mixinBehaviors([AppLocalizeBehavior], util JSON.parse(this.userFilers.filerShares); // validate mandatory inputs if (formData.get('filersSelect')==='') { - this.validateError = 'Please select a filer'; + this.validateError = this.localize('manageFilersView.missingFiler'); return; } else if (formData.get('sharesSelect')==='') { - this.validateError = 'Please select a share'; + this.validateError = this.localize('manageFilersView.missingShare'); return; } + // cloning to avoid assigning by reference const newUserData = _.clone(userData); + + let sharesInputValue = formData.get('sharesInput').startsWith('/') ? + formData.get('sharesInput') : '/' + formData.get('sharesInput'); + sharesInputValue = sharesInputValue.endsWith('/') ? + sharesInputValue : sharesInputValue + '/'; + const newValue = formData.get('filersSelect') + '/' + - formData.get('sharesSelect')+'/'; + formData.get('sharesSelect')+ sharesInputValue; + if (newUserData.includes(newValue)) { - this.validateError = 'User already has filer share'; + this.validateError = + this.localize('manageFilersView.duplicateFiler'); return; } @@ -160,7 +170,13 @@ export class ManageFilersView extends mixinBehaviors([AppLocalizeBehavior], util JSON.parse(this.userFilers.filerShares); const index = userData.indexOf(filerShare); if (index===-1) { - this.showError(`User does not have filer share ${filerShare}`); + this.showError( + this.localize( + 'manageFilersView.missingDeleteError', + 'filerShare', + filerShare + ) + ); return; } if (userData.length===1) { @@ -198,6 +214,7 @@ export class ManageFilersView extends mixinBehaviors([AppLocalizeBehavior], util this.filersFormValue = ''; this.$.filersSelect.value = ''; this.$.sharesSelect.value = ''; + this.$.sharesInput.value = ''; if (e.detail.error) { const error = this._isolateErrorFromIronRequest(e); diff --git a/components/centraldashboard/public/components/manage-filers-view.pug b/components/centraldashboard/public/components/manage-filers-view.pug index 9c8eac291b3..933008abd6a 100644 --- a/components/centraldashboard/public/components/manage-filers-view.pug +++ b/components/centraldashboard/public/components/manage-filers-view.pug @@ -17,25 +17,35 @@ section#Main-Content .content.small template(is='dom-if', if="[[isLoading(filersLoading, userFilersLoading)]]") paper-spinner-lite(active) - form#filersForm + div table#filersTable template(is='dom-repeat', items='[[formatUserFilers(userFilers)]]') tr td {{item}} td - button(type="button", on-click="deleteFilerShare") Delete - select#filersSelect(name="filersSelect", on-change="onChangeFilers", value="", required) - option(value="") Select a filer - template(is='dom-repeat', items='[[formatFilers(filers)]]') - option(value="{{item.key}}") {{item.name}} - select#sharesSelect(name="sharesSelect", disabled="[[!filersFormValue]]", on-change="onChangeShares", value="", required) - option(value="") Select a share - template(is='dom-repeat', items='[[getShares(filersFormValue)]]') - option {{item}} - aside.Error {{validateError}} + button(type="button", on-click="deleteFilerShare") {{localize('manageFilersView.btnDelete')}} + div + h2 {{localize('manageFilersView.headerAddFiler')}} + form#filersForm + div.formInputDiv + label(for="filersSelect") {{localize('manageFilersView.lblFiler')}} + select#filersSelect(name="filersSelect", on-change="onChangeFilers", value="", required) + option(value="") {{localize('manageFilersView.optionFiler')}} + template(is='dom-repeat', items='[[formatFilers(filers)]]') + option(value="{{item.key}}") {{item.name}} + div.formInputDiv + label(for="sharesSelect") {{localize('manageFilersView.lblShare')}} + select#sharesSelect(name="sharesSelect", disabled="[[!filersFormValue]]", on-change="onChangeShares", value="", required) + option(value="") {{localize('manageFilersView.optionShare')}} + template(is='dom-repeat', items='[[getShares(filersFormValue)]]') + option {{item}} + div.formInputDiv + label(for="sharesInput") {{localize('manageFilersView.lblExtraShare')}} + input#sharesInput(name="sharesInput", disabled="[[!filersFormValue]]", value="", placeholder="{{localize('manageFilersView.placeholderExtraShare')}}") + aside.Error {{validateError}} - template(is='dom-if', if="[[filers]]") - button#filersSubmit(type="button", on-click="updateFilers") {{localize('manageFilersView.btnSubmit')}} + template(is='dom-if', if="[[filers]]") + button#filersSubmit(type="button", on-click="updateFilers") {{localize('manageFilersView.btnSubmit')}} paper-toast#FilersErrorToast(duration=8000, horizontal-align="center") strong [[errorText]] From 5d20c88feaf681692e32d837173c5f8b22d0ac7e Mon Sep 17 00:00:00 2001 From: Mathis Marcotte Date: Mon, 22 Jul 2024 15:53:02 +0000 Subject: [PATCH 2/2] added validation for new input --- .../public/assets/i18n/languages.json | 2 ++ .../public/components/manage-filers-view.js | 27 ++++++++++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/components/centraldashboard/public/assets/i18n/languages.json b/components/centraldashboard/public/assets/i18n/languages.json index bb167bd0f50..8f343c21f5c 100644 --- a/components/centraldashboard/public/assets/i18n/languages.json +++ b/components/centraldashboard/public/assets/i18n/languages.json @@ -143,6 +143,7 @@ "manageFilersView.successUpdate": "Filers updated!", "manageFilersView.missingFiler": "Please select a filer", "manageFilersView.missingShare": "Please select a share", + "manageFilersView.invalidSharePath": "Please input a valid path", "manageFilersView.duplicateFiler": "Filer has already been selected", "manageFilersView.missingDeleteError": "User does not have filer {filerShare}", "s3Proxy.defaultMessage": "This workspace does not include S3 proxy. To start using S3 proxy, please opt in to the service." @@ -291,6 +292,7 @@ "manageFilersView.successUpdate": "Classeurs mis à jour!", "manageFilersView.missingFiler": "Veuillez sélectionner un classeur", "manageFilersView.missingShare": "Veuillez sélectionner un partage", + "manageFilersView.invalidSharePath": "Veuillez saisir un chemin valide", "manageFilersView.duplicateFiler": "Le classeur a déjà été sélectionné", "manageFilersView.missingDeleteError": "L'utilisateur n'a pas le classeur {filerShare}", "s3Proxy.defaultMessage": "Cet espace de travail n'inclue pas S3 proxy. Pour commencer à utiliser S3 proxy, veuilliez choisir de participer au service." diff --git a/components/centraldashboard/public/components/manage-filers-view.js b/components/centraldashboard/public/components/manage-filers-view.js index 9e66e8c8e3d..c6f6190fcee 100644 --- a/components/centraldashboard/public/components/manage-filers-view.js +++ b/components/centraldashboard/public/components/manage-filers-view.js @@ -133,13 +133,26 @@ export class ManageFilersView extends mixinBehaviors([AppLocalizeBehavior], util // cloning to avoid assigning by reference const newUserData = _.clone(userData); - let sharesInputValue = formData.get('sharesInput').startsWith('/') ? - formData.get('sharesInput') : '/' + formData.get('sharesInput'); - sharesInputValue = sharesInputValue.endsWith('/') ? - sharesInputValue : sharesInputValue + '/'; - - const newValue = formData.get('filersSelect') + '/' + - formData.get('sharesSelect')+ sharesInputValue; + let newValue = formData.get('filersSelect') + '/' + + formData.get('sharesSelect')+ '/'; + + if (formData.get('sharesInput') !== '') { + // Trim slashes for regex matching + let sharesInputValue = formData.get('sharesInput').startsWith('/') ? + formData.get('sharesInput').slice(1) : + formData.get('sharesInput'); + sharesInputValue = sharesInputValue.endsWith('/') ? + sharesInputValue : sharesInputValue + '/'; + + // Error if the path doesn't look like a dir path + if (!sharesInputValue.match(/^([^\\/:|<>*?]+\/?)*$/)) { + this.validateError = + this.localize('manageFilersView.invalidSharePath'); + return; + } + + newValue = newValue + sharesInputValue; + } if (newUserData.includes(newValue)) { this.validateError =