bloker-modal, master-task-modal, date-picker

This commit is contained in:
romankko2 committed 2022-12-05 18:46:01 +01:00
1 parent 46572a61f5
commit e6198ea89f
18 files changed
+568 -234

No files matched your search

+56
View File
@@ -14,6 +14,7 @@
"@mdi/font": "5.9.55", "@mdi/font": "5.9.55",
"@vuelidate/core": "^2.0.0", "@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0", "@vuelidate/validators": "^2.0.0",
"@vuepic/vue-datepicker": "^3.6.0",
"axios": "^1.1.3", "axios": "^1.1.3",
"axios-auth-refresh": "^3.3.4", "axios-auth-refresh": "^3.3.4",
"core-js": "^3.8.3", "core-js": "^3.8.3",
@@ -3430,6 +3431,21 @@
} }
} }
}, },
"node_modules/@vuepic/vue-datepicker": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-3.6.0.tgz",
"integrity": "sha512-9oYegvCSV2fssvcwL/tfzNvgExvNt2PhlSgIPhrFyEJvPACL3nv6161CU3++Aiysv5uotOjkVs4xFR/gh99P7w==",
"dependencies": {
"date-fns": "^2.29.3",
"date-fns-tz": "^1.3.7"
},
"engines": {
"node": ">=14"
},
"peerDependencies": {
"vue": ">=3.2.0"
}
},
"node_modules/@vuetify/loader-shared": { "node_modules/@vuetify/loader-shared": {
"version": "1.7.0", "version": "1.7.0",
"resolved": "https://registry.npmjs.org/@vuetify/loader-shared/-/loader-shared-1.7.0.tgz", "resolved": "https://registry.npmjs.org/@vuetify/loader-shared/-/loader-shared-1.7.0.tgz",
@@ -5389,6 +5405,26 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
}, },
"node_modules/date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==",
"engines": {
"node": ">=0.11"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/date-fns"
}
},
"node_modules/date-fns-tz": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.3.7.tgz",
"integrity": "sha512-1t1b8zyJo+UI8aR+g3iqr5fkUHWpd58VBx8J/ZSQ+w7YrGlw80Ag4sA86qkfCXRBLmMc4I2US+aPMd4uKvwj5g==",
"peerDependencies": {
"date-fns": ">=2.0.0"
}
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -16162,6 +16198,15 @@
} }
} }
}, },
"@vuepic/vue-datepicker": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/@vuepic/vue-datepicker/-/vue-datepicker-3.6.0.tgz",
"integrity": "sha512-9oYegvCSV2fssvcwL/tfzNvgExvNt2PhlSgIPhrFyEJvPACL3nv6161CU3++Aiysv5uotOjkVs4xFR/gh99P7w==",
"requires": {
"date-fns": "^2.29.3",
"date-fns-tz": "^1.3.7"
}
},
"@vuetify/loader-shared": { "@vuetify/loader-shared": {
"version": "1.7.0", "version": "1.7.0",
"resolved": "https://registry.npmjs.org/@vuetify/loader-shared/-/loader-shared-1.7.0.tgz", "resolved": "https://registry.npmjs.org/@vuetify/loader-shared/-/loader-shared-1.7.0.tgz",
@@ -17670,6 +17715,17 @@
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==" "integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
}, },
"date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.29.3.tgz",
"integrity": "sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA=="
},
"date-fns-tz": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/date-fns-tz/-/date-fns-tz-1.3.7.tgz",
"integrity": "sha512-1t1b8zyJo+UI8aR+g3iqr5fkUHWpd58VBx8J/ZSQ+w7YrGlw80Ag4sA86qkfCXRBLmMc4I2US+aPMd4uKvwj5g==",
"requires": {}
},
"debug": { "debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+1
View File
@@ -14,6 +14,7 @@
"@mdi/font": "5.9.55", "@mdi/font": "5.9.55",
"@vuelidate/core": "^2.0.0", "@vuelidate/core": "^2.0.0",
"@vuelidate/validators": "^2.0.0", "@vuelidate/validators": "^2.0.0",
"@vuepic/vue-datepicker": "^3.6.0",
"axios": "^1.1.3", "axios": "^1.1.3",
"axios-auth-refresh": "^3.3.4", "axios-auth-refresh": "^3.3.4",
"core-js": "^3.8.3", "core-js": "^3.8.3",
+20
View File
@@ -0,0 +1,20 @@
{
"data": {
"id": 1,
"name": "Team 1",
"employees": [
{
"id": 1,
"name": "Matej",
"surname": "Glasnak"
},
{
"id": 2,
"name": "Mate",
"surname": "Klempa"
}
]
},
"status": 200
}
+6 -5
View File
@@ -4,13 +4,14 @@
"name": "Team 1", "name": "Team 1",
"employees": [ "employees": [
{ {
"id": 1 "id": 1,
"name": "Matej",
"surname": "Glasnak"
}, },
{ {
"id": 4 "id": 2,
}, "name": "Mate",
{ "surname": "Klempa"
"id": 5
} }
] ]
}, },
@@ -11,14 +11,27 @@
></v-icon> ></v-icon>
</div> </div>
<v-card-actions class="d-flex flex-column modal-content"> <v-card-actions class="d-flex flex-column-reverse modal-content">
<v-text-field <Datepicker
class="modal-input" class="modal-input"
label="Názov blokeru" v-model="date"
variant="outlined" :format="dateFormat"
></v-text-field> locale="sk"
select-text="Vybrať"
<div class="employee-position w-100" v-for="(employee, index) in selectedEmployees" :key="employee.id"> cancel-text="Zrušiť"
placeholder="02.12.2022,10:17 - 18.12.2022,10:17"
range
/>
<W-autocomplete
:options="employeesOptions"
class="modal-input"
@option-selected="employeeSelected"
/>
<div
class="employee-position w-100"
v-for="(employee, index) in selectedEmployees"
:key="employee.id"
>
<v-text-field <v-text-field
class="modal-input" class="modal-input"
disabled disabled
@@ -32,12 +45,13 @@
@click.stop="removeInput(index)" @click.stop="removeInput(index)"
icon="mdi-close" icon="mdi-close"
size="small" size="small"
></v-icon ></v-icon>
>
</div> </div>
<v-text-field
<W-autocomplete :options="employeesOptions" class="modal-input" @option-selected="employeeSelected" /> class="modal-input"
label="Názov blokeru"
variant="outlined"
></v-text-field>
</v-card-actions> </v-card-actions>
<v-btn class="z-btn" @click="createBloker()">VYTVORIŤ</v-btn> <v-btn class="z-btn" @click="createBloker()">VYTVORIŤ</v-btn>
@@ -48,26 +62,23 @@
<script> <script>
import WAutocomplete from './w-autocomplete.vue' import WAutocomplete from './w-autocomplete.vue'
import Datepicker from '@vuepic/vue-datepicker'
export default { export default {
components: { components: {
WAutocomplete WAutocomplete,
Datepicker,
}, },
props: [ props: ['visible'],
'visible'
],
data() { data() {
return { return {
selectedEmployee: "", selectedEmployee: '',
selectedEmployees: [], selectedEmployees: [],
employees: null, employees: null,
menu: [], date: '',
foos: [ dateFormat: 'dd.MM.yyyy, HH:mm'
{ id: 1, date: new Date() },
{ id: 2, date: new Date() },
]
} }
}, },
@@ -85,21 +96,21 @@ export default {
}, },
employeeSelected(selectedOption) { employeeSelected(selectedOption) {
const employee = this.employees.find(empl => empl.id == selectedOption.key) const employee = this.employees.find((empl) => empl.id == selectedOption.key)
employee._fullName = `${employee.name} ${employee.surname}` employee._fullName = `${employee.name} ${employee.surname}`
this.selectedEmployees.push(employee) this.selectedEmployees.push(employee)
}, },
async createBloker() { async createBloker() {
try{ try {
await this.$axios.post_auth('v1/blockers') await this.$axios.post_auth('v1/blockers')
this.$router.push({ name: 'Dashboard - Tasks' }) this.$router.push({ name: 'Dashboard - Tasks' })
this.show = false this.show = false
} catch (error) { } catch (error) {
this.$toast.error(error.response.data.error) this.$toast.error(error.response.data.error)
} }
} },
}, },
computed: { computed: {
@@ -111,10 +122,10 @@ export default {
(employee) => !selectedEmployeesIds.includes(employee.id) (employee) => !selectedEmployeesIds.includes(employee.id)
) )
return employees.map(employee => { return employees.map((employee) => {
return { return {
key: employee.id, key: employee.id,
value: `${employee.name} ${employee.surname}` value: `${employee.name} ${employee.surname}`,
} }
}) })
}, },
@@ -125,19 +136,17 @@ export default {
}, },
set(value) { set(value) {
if (!value) this.$emit("close") if (!value) this.$emit('close')
}, },
}, },
}, },
watch: { watch: {
selectedEmployee() { selectedEmployee() {
const selectedEmployee = this.selectedEmployee.split(" ") const selectedEmployee = this.selectedEmployee.split(' ')
const employee = this.employees.find( const employee = this.employees.find(
(e) => (e) => e.name == selectedEmployee[0] && e.surname == selectedEmployee[1]
e.name == selectedEmployee[0] &&
e.surname == selectedEmployee[1]
) )
this.selectedEmployees.push(JSON.parse(JSON.stringify(employee))) this.selectedEmployees.push(JSON.parse(JSON.stringify(employee)))
@@ -157,6 +166,7 @@ export default {
flex: 1 1 100% flex: 1 1 100%
margin: 10px 0 margin: 10px 0
overflow-y: scroll overflow-y: scroll
justify-content: flex-end
.z-btn .z-btn
height: 50px height: 50px
@@ -1,156 +0,0 @@
<template>
<v-dialog v-model="showModal" max-width="650" max-height="90%" height="700px">
<W-loadable :content="employees" class="h-100">
<v-card v-if="employees" height="100%" class="d-flex flex-column">
<div class="d-flex justify-space-between align-center modal-header">
<h1>Editovať tím</h1>
<v-icon
@click.stop="$emit('close-modal')"
icon="mdi-close"
size="large"
></v-icon>
</div>
<v-card-actions class="d-flex flex-column modal-content">
<v-text-field
class="modal-input"
label="Názov tímu"
variant="outlined"
v-model="teamName"
></v-text-field>
<div class="employee-position w-100" v-for="(employee, index) in selectedEmployees" :key="employee.id">
<v-text-field
class="modal-input"
disabled
label="Zamestanec"
variant="outlined"
v-model="selectedEmployees[index]._fullName"
>
</v-text-field>
<v-icon
class="remove-input"
@click="removeInput(index)"
icon="mdi-close"
size="small"
></v-icon
>
</div>
<W-autocomplete :options="employeesOptions" class="modal-input" @option-selected="employeeSelected" />
</v-card-actions>
<v-btn class="z-btn" @click="editTeam()">EDITOVAŤ</v-btn>
</v-card>
</W-loadable>
</v-dialog>
</template>
<script>
import WAutocomplete from './w-autocomplete.vue'
export default {
emits: ['close-modal'],
components: {
WAutocomplete
},
props: {
show: {
type: Boolean,
required: true
},
team: {
type: Object,
required: true
}
},
data() {
return {
selectedEmployees: [],
employees: null,
teamName: this.team.name
}
},
async created() {
try {
this.employees = await this.$axios.get_auth_data('v1/employees')
} catch (error) {
console.log(error)
}
},
methods: {
removeInput(index) {
this.selectedEmployees.splice(index, 1)
},
employeeSelected(selectedOption) {
const employee = this.employees.find(empl => empl.id == selectedOption.key)
employee._fullName = `${employee.name} ${employee.surname}`
this.selectedEmployees.push(employee)
},
async editTeam() {
try{
await this.$axios.post_auth('v1/teams')
this.$router.push({ name: 'Overview - Teams' })
this.showModal = false
} catch (error) {
this.$toast.error(error.response.data.error)
}
}
},
computed: {
employeesOptions() {
const unselectedEmployees = this.employees.filter(employee => this.selectedEmployees.find(e => e.id == employee.od))
return unselectedEmployees.map(employee => {
return {
key: employee.id,
value: `${employee.name} ${employee.surname}`
}
})
},
showModal() {
return this.show
}
}
}
</script>
<style lang="sass" scoped>
.modal-input
width: 100%
flex: 0 0 auto
.modal-header
flex: 0 0 auto
.modal-content
flex: 1 1 100%
margin: 10px 0
overflow-y: scroll
.z-btn
height: 50px
width: 100%
flex: 0 0 auto
.remove-input
pointer-events: auto
opacity: 2
position: absolute
left: 92%
top: 25%
.employee-position
position: relative
</style>
@@ -0,0 +1,122 @@
<template>
<v-dialog v-model="show" max-width="650" max-height="90%" height="700px">
<v-card height="100%" class="d-flex flex-column">
<div class="d-flex justify-space-between align-center modal-header">
<h1>Vytvoriť master task</h1>
<v-icon
@click.stop="show = false"
icon="mdi-close"
size="large"
></v-icon>
</div>
<v-card-actions class="d-flex flex-column-reverse modal-content">
<v-select
class="modal-input"
label="Tím"
variant="outlined"
></v-select>
<v-text-field
class="modal-input mt-5"
label="Celkový odhad"
variant="outlined"
type="number"
placeholder="h"
></v-text-field>
<Datepicker
class="modal-input"
v-model="date"
:format="dateFormat"
locale="sk"
select-text="Vybrať"
cancel-text="Zrušiť"
placeholder="Deadline"
/>
<v-text-field
class="modal-input"
label="Názov mastertasku"
variant="outlined"
></v-text-field>
<v-text-field
class="modal-input"
label="Kód projektu"
variant="outlined"
></v-text-field>
</v-card-actions>
<v-btn class="z-btn" @click="createMasterTask()">VYTVORIŤ</v-btn>
</v-card>
</v-dialog>
</template>
<script>
import Datepicker from '@vuepic/vue-datepicker'
export default {
props: ['visible'],
components: {
Datepicker
},
data() {
return {
date: '',
dateFormat: 'dd.MM.yyyy, HH:mm'
}
},
methods: {
async createMasterTask() {
try {
await this.$axios.post_auth('v1/master-tasks')
this.$router.push({ name: 'Dashboard - Tasks' })
this.show = false
} catch (error) {
this.$toast.error(error.response.data.error)
}
},
},
computed: {
show: {
get() {
return this.visible
},
set(value) {
if (!value) this.$emit('close')
},
},
}
}
</script>
<style lang="sass" scoped>
.modal-input
width: 100% !important
flex: 0 0 auto
.modal-header
flex: 0 0 auto
.modal-content
flex: 1 1 100%
margin: 10px 0
overflow-y: scroll
justify-content: flex-end
.z-btn
height: 50px
width: 100%
flex: 0 0 auto
.remove-input
pointer-events: auto
opacity: 2
position: absolute
left: 92%
top: 25%
.employee-position
position: relative
</style>
@@ -0,0 +1,220 @@
<template>
<v-dialog v-model="showModal" max-width="650" max-height="90%" height="700px">
<W-loadable :content="team" class="h-100">
<v-card v-if="employees" height="100%" class="d-flex flex-column">
<div class="d-flex justify-space-between align-center modal-header">
<h1>Editovať tím</h1>
<v-icon
@click.stop="$emit('close-modal')"
icon="mdi-close"
size="large"
></v-icon>
</div>
<v-card-actions class="d-flex flex-column modal-content">
<v-text-field
class="modal-input"
label="Názov tímu"
:class="{ error: v$.team.name.$errors.length }"
:hint="
v$.team.name.$errors
? errorUtils.parseErrors(v$.team.name.$errors)
: null
"
variant="solo"
v-model="team.name"
></v-text-field>
<div
class="employee-position w-100"
v-for="(employee, index) in team.employees"
:key="employee.id"
>
<v-text-field
class="modal-input"
disabled
label="Zamestanec"
variant="outlined"
v-model="team.employees[index]._fullName"
>
</v-text-field>
<v-icon
class="remove-input"
@click="removeInput(index)"
icon="mdi-close"
size="small"
></v-icon>
</div>
<W-autocomplete
:options="employeesOptions"
class="modal-input"
@option-selected="employeeSelected"
/>
</v-card-actions>
<v-btn class="z-btn" @click="editTeam()">EDITOVAŤ</v-btn>
</v-card>
</W-loadable>
</v-dialog>
</template>
<script>
import WAutocomplete from './w-autocomplete.vue'
import useVuelidate from '@vuelidate/core'
import { required } from '@vuelidate/validators'
import errorUtils from '@/plugins/lib@auth/_utils/error.utils'
export default {
emits: ['close-modal'],
components: {
WAutocomplete,
},
props: {
show: {
type: Boolean,
required: true,
},
teamId: {
type: Number,
required: false,
default: null,
},
},
data() {
return {
team: null,
selectedEmployees: [],
employees: null,
v$: useVuelidate(),
errorUtils,
teams: null,
}
},
validations() {
return {
team: {
name: { required },
},
}
},
async created() {
try {
this.employees = await this.$axios.get_auth_data('v1/employees')
} catch (error) {
console.log(error)
}
if (!this.teamId) {
return (this.team = {
name: '',
employees: [],
})
}
try {
const team = await this.$axios.get_auth_data(`v1/teams/${this.teamId}`)
team.employees = team.employees.map((employee) => {
employee._fullName = `${employee.name} ${employee.surname}`
return employee
})
this.team = team
} catch (error) {
console.log(error)
}
},
methods: {
removeInput(index) {
this.team.employees.splice(index, 1)
},
async _loadTeams() {
try {
this.teams = await this.$axios.get_auth_data('v1/teams')
} catch (error) {
this.teams = { error: error.data.error }
this.$toast.error(error.data.error)
}
},
employeeSelected(selectedOption) {
const employee = this.employees.find((empl) => empl.id == selectedOption.key)
employee._fullName = `${employee.name} ${employee.surname}`
this.team.employees.push(employee)
},
async editTeam() {
if (!(await this.v$.$validate())) return console.log(this.v$)
try {
await this.$axios.post_auth('v1/teams')
// do close modal listeneru pridaj ze ak pride true refreshne teamy
this.$emit('close-modal', true)
this._loadTeams()
} catch (error) {
this.$toast.error(error.response.data.error)
}
},
},
computed: {
employeesOptions() {
const unselectedEmployees = this.employees.filter((employee) =>
this.team.employees.find((e) => e.id == employee.id) ? false : true
)
console.log(unselectedEmployees)
return unselectedEmployees.map((employee) => {
return {
key: employee.id,
value: `${employee.name} ${employee.surname}`,
}
})
},
showModal() {
return this.show
},
},
}
</script>
<style lang="sass" scoped>
.modal-input
width: 100%
flex: 0 0 auto
.modal-header
flex: 0 0 auto
.modal-content
flex: 1 1 100%
margin: 10px 0
overflow-y: scroll
.z-btn
height: 50px
width: 100%
flex: 0 0 auto
.remove-input
pointer-events: auto
opacity: 2
position: absolute
left: 92%
top: 25%
.employee-position
position: relative
</style>
@@ -15,10 +15,21 @@
<v-text-field <v-text-field
class="modal-input" class="modal-input"
label="Názov tímu" label="Názov tímu"
variant="outlined" variant="solo"
:class="{ error: v$.team.name.$errors.length }"
:hint="
v$.team.name.$errors
? errorUtils.parseErrors(v$.team.name.$errors)
: null
"
v-model="team.name"
></v-text-field> ></v-text-field>
<div class="employee-position w-100" v-for="(employee, index) in selectedEmployees" :key="employee.id"> <div
class="employee-position w-100"
v-for="(employee, index) in selectedEmployees"
:key="employee.id"
>
<v-text-field <v-text-field
class="modal-input" class="modal-input"
disabled disabled
@@ -32,12 +43,14 @@
@click.stop="removeInput(index)" @click.stop="removeInput(index)"
icon="mdi-close" icon="mdi-close"
size="small" size="small"
></v-icon ></v-icon>
>
</div> </div>
<W-autocomplete :options="employeesOptions" class="modal-input" @option-selected="employeeSelected" /> <W-autocomplete
:options="employeesOptions"
class="modal-input"
@option-selected="employeeSelected"
/>
</v-card-actions> </v-card-actions>
<v-btn class="z-btn" @click="createTeam()">VYTVORIŤ</v-btn> <v-btn class="z-btn" @click="createTeam()">VYTVORIŤ</v-btn>
@@ -48,21 +61,33 @@
<script> <script>
import WAutocomplete from './w-autocomplete.vue' import WAutocomplete from './w-autocomplete.vue'
import useVuelidate from '@vuelidate/core'
import { required } from '@vuelidate/validators'
import errorUtils from '@/plugins/lib@auth/_utils/error.utils'
export default { export default {
components: { components: {
WAutocomplete WAutocomplete,
}, },
props: [ props: ['visible'],
'visible'
],
data() { data() {
return { return {
selectedEmployee: "", selectedEmployee: '',
selectedEmployees: [], selectedEmployees: [],
employees: null, employees: null,
v$: useVuelidate(),
errorUtils,
team: {},
}
},
validations() {
return {
team: {
name: { required },
},
} }
}, },
@@ -80,21 +105,23 @@ export default {
}, },
employeeSelected(selectedOption) { employeeSelected(selectedOption) {
const employee = this.employees.find(empl => empl.id == selectedOption.key) const employee = this.employees.find((empl) => empl.id == selectedOption.key)
employee._fullName = `${employee.name} ${employee.surname}` employee._fullName = `${employee.name} ${employee.surname}`
this.selectedEmployees.push(employee) this.selectedEmployees.push(employee)
}, },
async createTeam() { async createTeam() {
try{ if (!(await this.v$.$validate())) return console.log(this.v$)
try {
await this.$axios.post_auth('v1/teams') await this.$axios.post_auth('v1/teams')
this.$router.push({ name: 'Overview - Teams' }) this.$router.push({ name: 'Overview - Teams' })
this.show = false this.show = false
} catch (error) { } catch (error) {
this.$toast.error(error.response.data.error) this.$toast.error(error.response.data.error)
} }
} },
}, },
computed: { computed: {
@@ -106,10 +133,10 @@ export default {
(employee) => !selectedEmployeesIds.includes(employee.id) (employee) => !selectedEmployeesIds.includes(employee.id)
) )
return employees.map(employee => { return employees.map((employee) => {
return { return {
key: employee.id, key: employee.id,
value: `${employee.name} ${employee.surname}` value: `${employee.name} ${employee.surname}`,
} }
}) })
}, },
@@ -120,19 +147,17 @@ export default {
}, },
set(value) { set(value) {
if (!value) this.$emit("close") if (!value) this.$emit('close')
}, },
}, },
}, },
watch: { watch: {
selectedEmployee() { selectedEmployee() {
const selectedEmployee = this.selectedEmployee.split(" ") const selectedEmployee = this.selectedEmployee.split(' ')
const employee = this.employees.find( const employee = this.employees.find(
(e) => (e) => e.name == selectedEmployee[0] && e.surname == selectedEmployee[1]
e.name == selectedEmployee[0] &&
e.surname == selectedEmployee[1]
) )
this.selectedEmployees.push(JSON.parse(JSON.stringify(employee))) this.selectedEmployees.push(JSON.parse(JSON.stringify(employee)))
+2
View File
@@ -24,6 +24,7 @@ import '@ionic/vue/css/display.css'
import '@/plugins/app/_theme/index.sass' import '@/plugins/app/_theme/index.sass'
import 'vue-loading-overlay/dist/vue-loading.css' import 'vue-loading-overlay/dist/vue-loading.css'
import '@vuepic/vue-datepicker/dist/main.css'
loadFonts() loadFonts()
@@ -61,6 +62,7 @@ const options: Options = {
'POST v1/tasks/(id)': true, 'POST v1/tasks/(id)': true,
'DELETE v1/tasks/(id)': true, 'DELETE v1/tasks/(id)': true,
'GET v1/teams/(id)': true,
'POST v1/teams/(id)': true, 'POST v1/teams/(id)': true,
'DELETE v1/teams/(id)': true, 'DELETE v1/teams/(id)': true,
'GET v1/teams': true, 'GET v1/teams': true,
@@ -17,7 +17,7 @@
</template> </template>
<v-list> <v-list>
<v-list-item class="cursor-pointer hover-background">MASTER TASK</v-list-item> <v-list-item class="cursor-pointer hover-background" @click="createMasterTaskDialog = true">MASTER TASK</v-list-item>
<v-list-item class="cursor-pointer hover-background">SUB TASK</v-list-item> <v-list-item class="cursor-pointer hover-background">SUB TASK</v-list-item>
<v-list-item class="cursor-pointer hover-background" @click="createTeamDialog = true">TÍM</v-list-item> <v-list-item class="cursor-pointer hover-background" @click="createTeamDialog = true">TÍM</v-list-item>
<v-list-item class="cursor-pointer hover-background" @click="createBlokerDialog = true">BLOKER</v-list-item> <v-list-item class="cursor-pointer hover-background" @click="createBlokerDialog = true">BLOKER</v-list-item>
@@ -50,6 +50,7 @@
</div> </div>
</div> </div>
<A-master-task-modal :visible="createMasterTaskDialog" @close="createMasterTaskDialog = false"/>
<A-bloker-modal :visible="createBlokerDialog" @close="createBlokerDialog = false" /> <A-bloker-modal :visible="createBlokerDialog" @close="createBlokerDialog = false" />
<A-team-modal :visible="createTeamDialog" @close="createTeamDialog = false" /> <A-team-modal :visible="createTeamDialog" @close="createTeamDialog = false" />
</v-app-bar> </v-app-bar>
@@ -58,18 +59,21 @@
<script> <script>
import ATeamModal from '@/plugins/app/_components/a-team-modal.vue' import ATeamModal from '@/plugins/app/_components/a-team-modal.vue'
import ABlokerModal from '@/plugins/app/_components/a-bloker-modal.vue' import ABlokerModal from '@/plugins/app/_components/a-bloker-modal.vue'
import AMasterTaskModal from '@/plugins/app/_components/a-master-task-modal.vue'
export default { export default {
components: { components: {
ATeamModal, ATeamModal,
ABlokerModal ABlokerModal,
AMasterTaskModal
}, },
data() { data() {
return { return {
user: null, user: null,
createTeamDialog: false, createTeamDialog: false,
createBlokerDialog: false createBlokerDialog: false,
createMasterTaskDialog: false
} }
}, },
@@ -2,9 +2,10 @@
<ion-menu ref="menu" content-id="main-content"> <ion-menu ref="menu" content-id="main-content">
<ion-content> <ion-content>
<img <img
class="py-5 px-5" class="py-5 px-5 cursor-pointer"
:src="require('@/plugins/app/_layout/_img/jandl-logo.svg')" :src="require('@/plugins/app/_layout/_img/jandl-logo.svg')"
alt="jandl-logo" alt="jandl-logo"
@click="refreshPage()"
/> />
<ion-list lines="none" id="labels-list"> <ion-list lines="none" id="labels-list">
@@ -77,6 +78,10 @@ export default {
toggleMenu() { toggleMenu() {
this.$refs.menu.$el.toggle() this.$refs.menu.$el.toggle()
}, },
refreshPage() {
window.location = '/app/dashboard/tasks'
}
}, },
} }
</script> </script>
@@ -0,0 +1,18 @@
.dp__input
height: 56px
border: 1px solid #ABABAB !important
.dp__range_end, .dp__range_start, .dp__active_date
background: #7F39FB !important
.dp__select
color: #7F39FB !important
.dp__today
border: 1px solid #7F39FB !important
.dp__range_between
background: #F4E8FF !important
.dp__action
font-weight: 500 !important
+1
View File
@@ -3,6 +3,7 @@
@import './vuetify/v-dialog' @import './vuetify/v-dialog'
@import './_components/z-default-btn' @import './_components/z-default-btn'
@import './_components/z-cancel-btn' @import './_components/z-cancel-btn'
@import './date-picker'
@import './global' @import './global'
@import '@/plugins/lib@auth/_theme/auth.theme' @import '@/plugins/lib@auth/_theme/auth.theme'
@@ -51,6 +51,9 @@
.auth-card .error .v-field .auth-card .error .v-field
border: .5px solid red !important border: .5px solid red !important
.error .v-field
border: .5px solid red !important
.v-input__append .v-input__append
margin: 0 !important margin: 0 !important
@@ -19,9 +19,9 @@
<td class="task-action"> <td class="task-action">
<div class="d-flex justify-start"> <div class="d-flex justify-start">
<img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" /> <img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" />
<img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="showDeleteModal = true" /> <img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="showDeleteModal = { task }" />
<A-delete-task-modal :show="showDeleteModal" :task="task" @delete-task="deleteTask" @close-modal="showDeleteModal = false" /> <A-delete-task-modal v-if="showDeleteModal" :show="showDeleteModal" :task="showDeleteModal.task" @delete-task="deleteTask(showDeleteModal.task.id)" @close-modal="(showDeleteModal = null)" />
</div> </div>
</td> </td>
</tr> </tr>
@@ -46,7 +46,7 @@ export default {
data() { data() {
return { return {
showDeleteModal: false showDeleteModal: null
} }
}, },
@@ -17,9 +17,9 @@
<td class="task-action"> <td class="task-action">
<div class="d-flex justify-start"> <div class="d-flex justify-start">
<img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon"> <img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon">
<img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="showDeleteModal = true"> <img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="showDeleteModal = { task }">
<A-delete-task-modal :show="showDeleteModal" :task="task" @delete-task="deleteTask" @close-modal="showDeleteModal = false" /> <A-delete-task-modal v-if="showDeleteModal" :show="showDeleteModal" :task="showDeleteModal.task" @delete-task="deleteTask(showDeleteModal.task.id)" @close-modal="(showDeleteModal = null)" />
</div> </div>
</td> </td>
</tr> </tr>
@@ -44,7 +44,7 @@ export default {
data() { data() {
return { return {
showDeleteModal: false showDeleteModal: null
} }
}, },
@@ -1,4 +1,5 @@
<template> <template>
<div>
<v-table> <v-table>
<thead> <thead>
<tr> <tr>
@@ -12,26 +13,27 @@
<td>{{ team.name }}</td> <td>{{ team.name }}</td>
<td class="task-action"> <td class="task-action">
<div class="d-flex justify-start"> <div class="d-flex justify-start">
<img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" @click.stop="showEditModal = true" /> <img class="pencil-icon" :src="require('@/plugins/tm@overview/_img/pencil-icon.svg')" alt="pencil-icon" @click.stop="editModal = { team }" />
<img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="showDeleteModal = true" /> <img class="trash-icon" :src="require('@/plugins/tm@overview/_img/trash-icon.svg')" alt="trash-icon" @click.stop="deleteModal = { team }" />
<A-edit-team-modal :show="showEditModal" :team="team" @close-modal="showEditModal = false" />
<A-delete-team-modal :show="showDeleteModal" :team="team" @delete-team="deleteTeam" @close-modal="showDeleteModal = false" />
</div> </div>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</v-table> </v-table>
<A-team-form-modal v-if="editModal" :show="editModal" :teamId="editModal.team.id" @close-modal="(editModal = null)" />
<A-delete-team-modal v-if="deleteModal" :show="deleteModal" :team="deleteModal.team" @delete-team="deleteTeam" @close-modal="(deleteModal = null)" />
</div>
</template> </template>
<script> <script>
import ADeleteTeamModal from '@/plugins/app/_components/a-delete-team-modal.vue' import ADeleteTeamModal from '@/plugins/app/_components/a-delete-team-modal.vue'
import AEditTeamModal from '@/plugins/app/_components/a-edit-team-modal.vue' import ATeamFormModal from '@/plugins/app/_components/a-team-form-modal.vue'
export default { export default {
components: { components: {
ADeleteTeamModal, ADeleteTeamModal,
AEditTeamModal ATeamFormModal
}, },
props: { props: {
@@ -43,8 +45,8 @@ export default {
data() { data() {
return { return {
showDeleteModal: false, editModal: null,
showEditModal: false deleteModal: null
} }
}, },
@@ -52,7 +54,7 @@ export default {
async deleteTeam(id) { async deleteTeam(id) {
try { try {
await this.$axios.delete(`v1/teams/${id}`) await this.$axios.delete(`v1/teams/${id}`)
this.showDeleteModal = false this.deleteModal = null
} catch (error) { } catch (error) {
this.$toast.error(error) this.$toast.error(error)
} }