Skip to content

Commit

Permalink
Merge pull request #10 from UoA-eResearch/IDS-956-implement-validatio…
Browse files Browse the repository at this point in the history
…ns-in-pages

IDS-956 implement validations in pages
  • Loading branch information
uoa-noel authored Dec 2, 2024
2 parents 92bcbca + 2b194a8 commit a71fbf9
Show file tree
Hide file tree
Showing 20 changed files with 722 additions and 187 deletions.
11 changes: 11 additions & 0 deletions web/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
<script setup lang="ts">
import { RouterView } from 'vue-router'
import { formState } from './store';
window.addEventListener('beforeunload', (event) => {
// If the user has started the form but hasn't finished it, give a warning before
// they close the tab.
if ((formState.hasStartedForm && !formState.hasFinishedForm)) {
event.preventDefault();
event.returnValue = true;
}
});
</script>

<template>
Expand Down
1 change: 1 addition & 0 deletions web/src/assets/btn.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
display: inline-block;
font-family: NationalBold, sans-serif;
text-decoration: none;
user-select: none;
}

.btn-primary {
Expand Down
9 changes: 9 additions & 0 deletions web/src/assets/error.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.error {
border-left: 6px solid rgb(212, 53, 28);
padding-left: 1rem;
}

.error-msg {
color: rgb(212, 53, 28);
font-family: 'NationalBold';
}
31 changes: 31 additions & 0 deletions web/src/assets/form.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.option-list {
margin-top: 1rem;
display: grid;
grid-template-columns: max-content 1fr;
gap: 1rem;
align-items: center;
}

.option-list input[type=radio] {
height: 1.5rem;
width: 1.5rem;
}

.form-group {
display: flex;
flex-direction: column;
margin-top: 1.5rem;
}

input[type=text],
input[type=number],
textarea {
border: 2px solid gray;
padding: 0.35rem;
margin-top: 0.5rem;
}

/*Remove default spinner in number field.*/
input[type=number] {
appearance: textfield;
}
8 changes: 7 additions & 1 deletion web/src/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
@tailwind components;
@tailwind utilities; */

/*UoA official fonts.*/
@import url(btn.css);
@import url(text.css);
@import url(error.css);
@import url(form.css);

/*UoA official fonts.*/
@font-face {
font-family: 'NationalBold';
font-weight: bold;
Expand Down Expand Up @@ -103,4 +105,8 @@ strong {

.forward-btn {
margin: 2rem 0;
}

.box {
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
}
5 changes: 4 additions & 1 deletion web/src/assets/text.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
.page-title {
font-family: "NationalBold";
font-size: 2.5rem;
margin-bottom: 2rem;
}

.app-title {
font-size: 1.5rem;
color: gray;
}

.title-section {
margin-bottom: 2rem;
}
62 changes: 62 additions & 0 deletions web/src/fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Fixtures containing a sample project and drive. TODO replace with an API client.
*/
import type { ResearchDriveService, Project, Member, Role } from "./project";

export function getDrive(): ResearchDriveService {
return {
name: "reslig-202200001-Tītoki-metabolomics",
allocated_gb: 25600.0,
used_gb: 1596.0
};
}

export function getProject(): Project {
return {
title: "Tītoki metabolomics",
description: "Stress in plants could be defined as any change in growth condition(s) that disrupts metabolic homeostasis and requires an adjustment of metabolic pathways in a process that is usually referred to as acclimation. Metabolomics could contribute significantly to the study of stress biology in plants and other organisms by identifying different compounds, such as by-products of stress metabolism, stress signal transduction molecules or molecules that are part of the acclimation response of plants.",
division: "Liggins Institute",
members: [
{
person: {
full_name: "Samina Nicholas",
email: "[email protected]",
username: "snic021"
},
roles: [{
name: "Project Owner"
}]
},
{
person: {
full_name: "Zach Luther",
email: "[email protected]",
username: "zlut014"
},
roles: [{
name: "Project Team Member"
}]
},
{
person: {
full_name: "Jarrod Hossam",
email: "[email protected]",
username: "jhos225"
},
roles: [{
name: "Project Team Member"
}]
},
{
person: {
full_name: "Melisa Edric",
email: "[email protected]",
username: "medr894"
},
roles: [{
name: "Project Team Member"
}]
}
]
};
}
87 changes: 87 additions & 0 deletions web/src/project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Type definitions for project information. TODO - generate based on output types in Python.
*/
export interface Person {
email: string | null;
full_name: string;
username: string;
}

export interface Role {
name: string
}

export interface Member {
person: Person;
roles: Role[]
}

export interface Project {
title: string
description: string
division: string
members: Member[]
}

export interface ResearchDriveService {
allocated_gb: number
name: string
used_gb: number
}

export enum DataClassification {
Public = "Public",
Internal = "Internal",
Sensitive = "Sensitive",
Restricted = "Restricted"
}

/**
* Makes and returns an empty Project.
* @returns An empty Project.
*/
export function makeProject(): Project {
return {
title: "",
description: "",
division: "",
members: []
}
}

/**
* Given a list of members, filter for project owners.
* @param members List of members to search through
* @returns Members who are project owners.
*/
export function getProjectOwners(members: Member[]): Member[] {
return members.filter(member =>
member.roles.some(
(role: Role) => role.name === "Project Owner"
)
);
}

/**
* Given a list of project members, filter for ordinary members.
* @param members List of members to search through
* @returns Members who are not project owners.
*/
export function getProjectMembers(members: Member[]): Member[] {
return members.filter(member =>
!member.roles.some(
(role: Role) => role.name === "Project Owner"
)
);
}

/**
* Given a list of members, return a string of their names.
* @param members Members to return names for.
* @returns A string representing all member names.
*/
export function membersToString(members: Member[]): string {
return members.map(member =>
member.person.full_name
).join(", ");
}
15 changes: 15 additions & 0 deletions web/src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ const router = createRouter({
name: 'summary',
component: () => import('../views/SummaryView.vue')
},
{
path: "/check-details",
name: 'check-details',
component: () => import("../views/CheckDetailsView.vue")
},
{
path: "/update-details",
name: 'update-details',
Expand All @@ -29,6 +34,11 @@ const router = createRouter({
name: "retention-period",
component: () => import("../views/RetentionPeriodView.vue")
},
{
path: "/custom-retention-period",
name: "custom-retention-period",
component: () => import("../views/CustomRetentionPeriodView.vue")
},
{
path: "/confirm",
name: "confirm",
Expand All @@ -38,6 +48,11 @@ const router = createRouter({
path: "/finish",
name: "finish",
component: () => import("../views/FinishView.vue")
},
{
path: "/unable-to-archive",
name: "unable-to-archive",
component: () => import("../views/UnableToArchiveView.vue")
}
]
})
Expand Down
24 changes: 24 additions & 0 deletions web/src/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { reactive } from 'vue';
import { DataClassification, makeProject, type Project } from './project';

interface FormStateStore {
hasStartedForm: boolean;
hasFinishedForm: boolean;
isCorrectDrive: boolean | null;
areProjectDetailsCorrect: boolean | null;
project: Project;
dataClassification: DataClassification | null;
retentionPeriod: number | null;
isRetentionPeriodCustom: boolean | null;
}

export const formState: FormStateStore = reactive({
hasStartedForm: false,
hasFinishedForm: false,
isCorrectDrive: null,
areProjectDetailsCorrect: null,
project: makeProject(),
dataClassification: null,
isRetentionPeriodCustom: null,
retentionPeriod: null
});
Loading

0 comments on commit a71fbf9

Please sign in to comment.