Skip to content

Commit

Permalink
prototype for input forum validation
Browse files Browse the repository at this point in the history
  • Loading branch information
kuthedk committed Jul 4, 2023
1 parent ad1ebd2 commit 6584460
Show file tree
Hide file tree
Showing 10 changed files with 1,189 additions and 0 deletions.
41 changes: 41 additions & 0 deletions docs/prototypes/forum-valadation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Forum Validation Prototype Implementation

This README provides instructions on how to incorporate files related to a forum validation implementation into the main
project.

## File Structure

The files are organized in the following way:

- Frontend JavaScript and Vue components and their corresponding test files
- End-to-end system test files

## Instructions

1. **Frontend**
- `inputDialog.js` should be placed directly under your project's `frontend/src` directory.

- The Vue components `InputDialog.vue`, `InputDialogAttachUrl.vue`, and `InputDialogUploadFile.vue` should be placed
inside the directory `src/components/Dialogs/` under your project's `frontend` directory. The path should look
like: `frontend/src/components/Dialogs/`.

- Test files for these components `InputDialog.spec.js`, `InputDialogAttachUrl.spec.js`,
`InputDialogUploadFile.spec.js` should be placed in `test/components/Dialogs/` under your project's `frontend`
directory. The path should look like: `frontend/test/components/Dialogs/`.

2. **System-tests**
- End-to-end test files `case_supporting_evidence.cy.js` and `import_new_case.cy.js` should be placed inside the
`e2e` directory under the `system-tests` directory in your main project.
The path should look like: `system-tests/e2e/`.

3. **Testing**
- To test the frontend components, run `yarn test:unit` in your main project's `frontend` directory.
- To test the end-to-end system tests, first make sure the application is running locally. Then, run `yarn test:e2e`
in your main project's `system-tests` directory.

Please ensure you maintain this directory structure for the application to function correctly.

## Notes

- After adding these files, you might need to rebuild the docker containers based on your development environment.
- Make sure to run all the tests to ensure the integration went smoothly.
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
<template>
<div v-if="dialog.state.active" class="modal-background">
<div :class="['modal-container', dialog.state.message ? 'limit-width' : '']">
<div class="tab-header">
<button
v-for="(tab, index) in dialog.state.tabs"
:key="`button-${tab.name}-${index}`"
:class="tab.name == dialog.state.activeTabName ? 'tab-button-active' : ''"
class="tab-button"
@click="dialog.state.activeTabName = tab.name"
:data-test="`button-${tab.name}`"
>
<img
v-if="tab.icon == 'phenotips'"
src="@/assets/phenotips-favicon-96x96.png"
/>
<font-awesome-icon v-else
:icon="'file' == tab.icon ? ['far', 'file'] : tab.icon"
size="2xl">
</font-awesome-icon>
</button>
</div>
<div v-if="dialog.state.message"
class="warning-message"
v-html="dialog.state.message"
data-test="warning-message">
</div>
<component v-bind:is="dialog.state.activeTabName"
:userInput = "dialog.activeTab().input"
v-bind="dialog.activeTab().props"
:runValidation="shouldRunValidation"
@update:userInput="dialog.updateActiveTabInput"
@update:allRequiredFieldsFilled="allRequiredFieldsFilled = $event"
@validationDone="shouldRunValidation = false"
/>
<div class="button-row">
<button class="secondary-button" @click="dialog.cancel()" data-test="cancel">
{{ dialog.state.cancelText }}
</button>
<button class="secondary-button" v-if="dialog.state.deleteText!=''" @click="dialog.delete()" data-test="delete">
{{ dialog.state.deleteText }}
</button>
<button class="primary-button"
@click="confirmClicked()"
data-test="confirm">
{{ dialog.state.confirmText }}
</button>
</div>
</div>
</div>
</template>

<script>
import InputDialogAttachUrl from '@/components/Dialogs/InputDialogAttachUrl.vue';
import InputDialogUploadFile from '@/components/Dialogs/InputDialogUploadFile.vue';
import dialog from '@/inputDialog.js';
export default {
name: 'input-dialog',
components: {
InputDialogAttachUrl,
InputDialogUploadFile,
},
data: function() {
return {
dialog,
allRequiredFieldsFilled: false,
shouldRunValidation: false,
};
},
methods: {
confirmClicked() {
if (!this.allRequiredFieldsFilled) {
this.shouldRunValidation = true;
this.$nextTick(() => {
if (this.allRequiredFieldsFilled) {
this.dialog.confirmation(this.dialog.activeTab().input);
this.allRequiredFieldsFilled = false;
}
});
} else {
this.dialog.confirmation(this.dialog.activeTab().input);
this.allRequiredFieldsFilled = false;
}
},
},
};
</script>

<style scoped>
.modal-container {
padding: var(--p-16);
display: flex;
flex-direction: column;
min-width: 25rem;
min-height: auto;
gap: var(--p-16);
align-items: stretch;
}
.tab-header {
margin: auto;
border: 2px var(--rosalution-grey-100) solid;
border-radius: var(--input-border-radius);
width: 160px;
display: flex;
justify-content: center;
}
.tab-button {
width: 2.5rem;
background-color: var(--rosalution-white);
border: none;
padding-top: var(--p-10);
padding-bottom: var(--p-10);
}
.tab-header .tab-button:not(:first-child) {
border-left: 2px var(--rosalution-grey-100) solid;
padding-left: var(--p-8);
}
.tab-button-active {
color: var(--rosalution-blue-200) !important;
}
.button-row {
display: flex;
justify-content: flex-end;
align-items: center;
gap: var(--p-16);
}
.warning-message{
font-size: var(--font-size-16);
font-weight: var(--font-weight-regular);
line-height: var(--line-height-24);
text-align: center;
}
.limit-width {
max-width: 25rem;
}
</style>
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<template>
<input v-if="'name' in userInput" placeholder="Text to display (required)" v-model="name" data-test="name-input"
:class="{ 'invalid-input-highlight': highlight && !name }" />
<div v-if="'name' in userInput && highlight && !name" class="required-message" data-test="required">
*required
</div>
<input placeholder="Paste a link (required)" v-model="url" data-test="link-input"
:class="{ 'invalid-input-highlight': highlight && !url }" />
<div v-if="highlight && !url" class="required-message" data-test="required">
*required
</div>
<textarea v-if="'comments' in userInput" class="comments" placeholder="Comments" v-model="comments"
data-test="comments-text-area">
</textarea>
</template>


<script>
export default {
name: 'input-dialog-attach-url',
emits: ['update:userInput', 'update:allRequiredFieldsFilled', 'validationDone'],
props: {
userInput: {
type: Object,
required: true,
},
runValidation: {
type: Boolean,
},
},
data() {
return {
highlight: false,
};
},
computed: {
requiredFields() {
return this.userInput.requiredFields || [];
},
name: {
get() {
return this.userInput.name;
},
set(value) {
this.updateUserInput('name', value);
},
},
url: {
get() {
return this.userInput.data;
},
set(value) {
this.updateUserInput('data', value);
},
},
comments: {
get() {
return this.userInput['comments'];
},
set(value) {
this.updateUserInput('comments', value);
},
},
allRequiredFieldsFilled() {
return this.requiredFields.every((field) => !!this[field] && this[field].length > 0);
},
},
watch: {
runValidation(currentValidationState, previousValidationState) {
if (currentValidationState !== previousValidationState && currentValidationState === true) {
this.validateRequiredFields();
this.$emit('validationDone');
}
},
},
methods: {
confirmClicked() {
this.validateRequiredFields();
},
updateUserInput(field, value) {
const input = this.userInput;
input[field] = value;
this.$emit('update:userInput', input);
},
validateRequiredFields() {
const allFieldsFilled = this.requiredFields.every((field) => !!this[field] && this[field].length > 0);
if (!allFieldsFilled) {
this.highlightRequiredFields();
} else {
this.$emit('update:allRequiredFieldsFilled', allFieldsFilled);
}
},
highlightRequiredFields() {
this.highlight = true;
},
},
};
</script>


<style>
.comments {
flex: 3 0 auto;
height: 8rem;
}
.required-message {
color: var(--rosalution-red-100);
transform: translateY(-1rem);
}
</style>
Loading

0 comments on commit 6584460

Please sign in to comment.