Ver código fonte

added first view for the project creation

Dimitri Korsch 3 anos atrás
pai
commit
c86994fbf4

+ 5 - 0
frontend/package-lock.json

@@ -11379,6 +11379,11 @@
       "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
       "dev": true
     },
+    "vuelidate": {
+      "version": "0.7.6",
+      "resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.6.tgz",
+      "integrity": "sha512-suzIuet1jGcyZ4oUSW8J27R2tNrJ9cIfklAh63EbAkFjE380iv97BAiIeolRYoB9bF9usBXCu4BxftWN1Dkn3g=="
+    },
     "vuetify": {
       "version": "2.6.0",
       "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-2.6.0.tgz",

+ 2 - 1
frontend/package.json

@@ -1,5 +1,5 @@
 {
-  "name": "frontend",
+  "name": "PyCS2",
   "version": "0.1.0",
   "private": true,
   "scripts": {
@@ -13,6 +13,7 @@
     "idle-vue": "^2.0.5",
     "vue": "^2.6.11",
     "vue-router": "^3.5.3",
+    "vuelidate": "^0.7.6",
     "vuetify": "^2.4.0",
     "vuex": "^3.6.2"
   },

+ 1 - 1
frontend/src/components/Drawer.vue

@@ -20,7 +20,7 @@
         <div class="col-md-6">{{ username }}</div>
         <div class="col-md-3">
           <div v-if="loggedIn">
-            <v-btn :to = "{ name: 'logout' }" small primary>
+            <v-btn :to = "{ name: 'logout' }" small color="primary">
               <span>Logout</span>
               <v-icon>mdi-logout</v-icon>
             </v-btn>

+ 6 - 4
frontend/src/main.js

@@ -10,13 +10,15 @@ Vue.config.productionTip = false
 
 
 router.beforeEach((to, from, next) => {
-  if (to.matched.some(record => record.meta.requiresLogin))
-    if (!store.state.auth.loggedIn)
-      next({ name: 'login' })
-  next()
+  if (to.matched.some(record => record.meta.public) || store.state.auth.loggedIn)
+    next()
+
+  if (!store.state.auth.loggedIn)
+    next({ name: 'login' })
 })
 
 Vue.use(Vuex);
+
 setupInterceptors(store);
 
 new Vue({

+ 16 - 9
frontend/src/routes.js

@@ -1,7 +1,9 @@
 import Vue from 'vue'
 import VueRouter from 'vue-router'
 import Index from './views/Index'
-import Projects from './views/Projects'
+// import Projects from './views/Projects'
+import ListProjects from './views/project/List'
+import CreateProject from './views/project/Create'
 import Login from './views/Login'
 import Logout from './views/Logout'
 
@@ -19,21 +21,26 @@ export default new VueRouter({
             name: 'index',
             component: Index,
             meta: {
-                requiresLogin: true
+                public: true
             }
         },
         {
-            path: '/projects',
-            name: 'projects',
-            component: Projects,
+            path: '/login',
+            name: 'login',
+            component: Login,
             meta: {
-                requiresLogin: true
+              public: true
             }
         },
         {
-            path: '/login',
-            name: 'login',
-            component: Login,
+            path: '/projects',
+            name: 'projects',
+            component: ListProjects,
+        },
+        {
+            path: '/project/create',
+            name: 'create_project',
+            component: CreateProject,
         },
         {
             path: '/logout',

+ 8 - 0
frontend/src/store/models/project.js

@@ -0,0 +1,8 @@
+export default class Project {
+  constructor() {
+    this.name = '';
+    this.description = '';
+    this.model = null;
+    this.labels = null;
+  }
+}

+ 0 - 0
frontend/src/store/user.js → frontend/src/store/models/user.js


+ 2 - 2
frontend/src/views/Index.vue

@@ -1,7 +1,7 @@
 <template>
-  <div>
+  <v-container fluid>
     <h1>Index Page</h1>
-  </div>
+  </v-container>
 </template>
 
 <script>

+ 1 - 1
frontend/src/views/Login.vue

@@ -54,7 +54,7 @@
 </template>
 
 <script>
-  import User from '@/store/user';
+  import User from '@/store/models/user';
 
   export default {
     name: 'login',

+ 157 - 0
frontend/src/views/project/Create.vue

@@ -0,0 +1,157 @@
+<template>
+  <v-container fluid>
+    <v-row>
+      <v-col :cols=10>
+        <h1>Project Creation</h1>
+      </v-col>
+      <v-col :cols=2 >
+        <v-btn :to = "{ name: 'projects' }" block color="error">
+          <v-icon>mdi-reply</v-icon> Back
+        </v-btn>
+      </v-col>
+    </v-row>
+    <v-card  outlined elevation="2" max-width=80% class="mx-auto">
+      <v-card-title>New Project</v-card-title>
+      <v-card-text>
+
+        <v-container fluid>
+          <v-form
+            @submit.prevent="create"
+            ref="form"
+            >
+            <v-row>
+              <v-col cols=12 sm=12>
+                <v-text-field
+                  v-model="project.name"
+                  name="name"
+                  label="Project Name"
+                  :error-messages="nameErrors"
+                  required>
+                </v-text-field>
+              </v-col>
+            </v-row>
+            <v-row>
+              <v-col cols=12 sm=12>
+                <v-textarea
+                  v-model="project.description"
+                  name="description"
+                  label="Project Description"
+                  :error-messages="descErrors"
+                  auto-grow
+                  rows="3"
+                  row-height="25"
+                  required>
+                </v-textarea>
+              </v-col>
+            </v-row>
+            <v-row>
+              <v-col cols=12 sm=12>
+                <v-select
+                  v-model="project.model"
+                  name="model"
+                  label="Model"
+                  :error-messages="modelErrors"
+                  :items="data.models"
+                  :hint="modelHint"
+                  item-text="name"
+                  item-value="id"
+                  persistent-hint
+                  return-object
+                  required>
+                </v-select>
+              </v-col>
+            </v-row>
+            <v-row>
+              <v-col cols=12 sm=12 class="d-flex align-end flex-column">
+                <v-btn
+                  type="submit"
+                  color="primary"
+                >
+                  Create
+                </v-btn>
+              </v-col>
+            </v-row>
+          </v-form>
+        </v-container>
+      </v-card-text>
+    </v-card>
+
+  </v-container>
+</template>
+
+<script>
+  import Project from '@/store/models/project';
+  import { validationMixin } from 'vuelidate';
+  import { required, minLength } from 'vuelidate/lib/validators';
+  import { mapState } from 'vuex'
+
+  export default {
+    name: 'CreateProject',
+
+    mixins: [validationMixin],
+
+    validations: {
+      project: {
+        name: { required, minLength: minLength(5) },
+        description: { required },
+        model: { required },
+      }
+    },
+
+    data () {
+      return {
+        project: new Project(),
+      }
+    },
+
+    computed: {
+      nameErrors () {
+        const errors = [];
+        if (!this.$v.project.name.$dirty) return errors
+        !this.$v.project.name.minLength && errors.push('Name must be at least 5 characters long')
+        !this.$v.project.name.required && errors.push('Name is required')
+        return errors;
+      },
+
+      descErrors () {
+        const errors = [];
+        if (!this.$v.project.description.$dirty) return errors
+        !this.$v.project.description.required && errors.push('Description is required')
+        return errors;
+      },
+
+      modelErrors () {
+        const errors = [];
+        if (!this.$v.project.model.$dirty) return errors
+        !this.$v.project.model.required && errors.push('Model selection is required')
+        return errors;
+      },
+
+
+      modelHint() {
+        return this.project.model?.description
+      },
+
+      ...mapState(['data'])
+    },
+
+    methods: {
+      create() {
+        this.$v.$touch();
+
+        if (!this.$v.$invalid) {
+          console.log("Creating project:", this.project);
+        }
+      }
+    },
+
+    created () {
+      this.$store.dispatch('data/getModels')
+      this.$store.dispatch('data/getLabelProviders')
+    },
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 3 - 7
frontend/src/views/Projects.vue → frontend/src/views/project/List.vue

@@ -5,8 +5,9 @@
         <h1>Projects</h1>
       </v-col>
       <v-col :cols=2 >
-        <v-btn block color="primary" @click="addProject">
-          Add Project <v-icon>mdi-plus</v-icon>
+        <v-btn :to = "{ name: 'create_project' }" block color="primary">
+          Add Project
+          <v-icon>mdi-plus</v-icon>
       </v-btn>
       </v-col>
     </v-row>
@@ -43,11 +44,6 @@
     created () {
       this.$store.dispatch('data/getModels')
     },
-    methods: {
-      addProject() {
-        console.log("Adding Project")
-      }
-    },
   }
 </script>