refactor(web2): remove extra components

This commit is contained in:
Denis Gukov 2020-11-04 21:06:49 +05:00
parent bdbfdbec84
commit b60ff1a22d
11 changed files with 319 additions and 261 deletions

View File

@ -1,14 +1,38 @@
<template>
<v-app v-if="state === 'success'" class="app">
<NewProjectDialog
v-model="newProjectDialog"
/>
<UserDialog
v-model="userDialog"
:user-id="user ? user.id : null"
/>
<ItemDialog
v-model="taskLogDialog"
save-button-text="Delete"
title="Task Log"
:max-width="800"
>
<template v-slot:form="{}">
<TaskLogView :project-id="projectId" :item-id="taskId" />
</template>
</ItemDialog>
<ItemDialog
v-model="newProjectDialog"
save-button-text="Create"
title="New Project"
event-name="i-project"
>
<template v-slot:form="{ onSave, onError, needSave, needReset }">
<ProjectForm
item-id="new"
@save="onSave"
@error="onError"
:need-save="needSave"
:need-reset="needReset"
/>
</template>
</ItemDialog>
<v-snackbar
v-model="snackbar"
:color="snackbarColor"
@ -254,6 +278,25 @@
<v-app v-else></v-app>
</template>
<style lang="scss">
.breadcrumbs {
}
.breadcrumbs__item {
}
.breadcrumbs__item--link {
text-decoration-line: none;
&:hover {
text-decoration-line: underline;
}
}
.breadcrumbs__separator {
padding: 0 10px;
}
.app__project-selector {
height: 64px;
.v-list-item__icon {
@ -284,9 +327,15 @@
.v-data-table > .v-data-table__wrapper > table > tbody > tr {
background: transparent !important;
//& > td:first-child {
// font-weight: bold !important;
//}
& > td:first-child {
//font-weight: bold !important;
a {
text-decoration-line: none;
&:hover {
text-decoration-line: underline;
}
}
}
}
.v-data-table > .v-data-table__wrapper > table > tbody > tr > th,
@ -323,9 +372,11 @@
<script>
import axios from 'axios';
import NewProjectDialog from '@/components/NewProjectDialog.vue';
import { getErrorMessage } from '@/lib/error';
import UserDialog from '@/components/UserDialog.vue';
import ItemDialog from '@/components/ItemDialog.vue';
import TaskLogView from '@/components/TaskLogView.vue';
import ProjectForm from '@/components/ProjectForm.vue';
import EventBus from './event-bus';
const PROJECT_COLORS = [
@ -338,8 +389,10 @@ const PROJECT_COLORS = [
export default {
name: 'App',
components: {
NewProjectDialog,
UserDialog,
ItemDialog,
TaskLogView,
ProjectForm,
},
data() {
return {
@ -352,6 +405,8 @@ export default {
projects: null,
newProjectDialog: null,
userDialog: null,
taskLogDialog: null,
taskId: null,
};
},
@ -395,6 +450,12 @@ export default {
await this.tryToSwitchToLastProject();
}
if (this.$route.query.t) {
EventBus.$emit('i-show-task', {
itemId: parseInt(this.$route.query.t || '', 10),
});
}
this.state = 'success';
} catch (err) { // notify about problem and sign out
EventBus.$emit('i-snackbar', {
@ -428,6 +489,11 @@ export default {
this.drawer = true;
});
EventBus.$on('i-show-task', async (e) => {
this.taskId = e.taskId;
this.taskLogDialog = true;
});
EventBus.$on('i-open-last-project', async () => {
await this.tryToSwitchToLastProject();
});

View File

@ -1,7 +1,7 @@
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
<v-dialog
v-model="dialog"
max-width="400"
:max-width="maxWidth || 400"
persistent
:transition="false"
>
@ -42,11 +42,15 @@
</template>
<script>
import EventBus from '@/event-bus';
export default {
props: {
title: String,
saveButtonText: String,
value: Boolean,
maxWidth: Number,
eventName: String,
},
data() {
@ -74,6 +78,9 @@ export default {
this.clearFlags();
if (e) {
this.$emit('save', e);
if (this.eventName) {
EventBus.$emit('i-project', e);
}
}
},

View File

@ -71,19 +71,21 @@ export default {
},
/**
* Saves or creates user via API.
* Saves or creates item via API.
* @returns {Promise<null>} null if validation didn't pass or user data if user saved.
*/
async save() {
this.formError = null;
if (!this.$refs.form.validate()) {
return;
return null;
}
this.formSaving = true;
let item;
try {
const item = (await axios({
item = (await axios({
method: this.isNew ? 'post' : 'put',
url: this.isNew
? this.getItemsUrl()
@ -101,6 +103,8 @@ export default {
} finally {
this.formSaving = false;
}
return item || this.item;
},
},
};

View File

@ -1,87 +0,0 @@
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
<v-dialog
v-model="dialog"
max-width="400"
persistent
:transition="false"
>
<v-card>
<v-card-title class="headline">New Project</v-card-title>
<v-card-text>
<ProjectForm project-id="new" ref="form" />
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="dialog = false"
>
Cancel
</v-btn>
<v-btn
color="blue darken-1"
text
@click="save()"
>
Create
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
import ProjectForm from '@/components/ProjectForm.vue';
import EventBus from '@/event-bus';
export default {
components: { ProjectForm },
props: {
projectId: [Number, String],
value: Boolean,
},
data() {
return {
dialog: false,
};
},
watch: {
async dialog(val) {
this.$emit('input', val);
if (await this.$refs.form) {
await this.$refs.form.reset();
}
},
async value(val) {
if (!val) {
this.dialog = val;
return;
}
this.dialog = val;
},
},
methods: {
async save() {
const item = await this.$refs.form.save();
if (!item) {
return null;
}
EventBus.$emit('i-project', {
action: 'new',
item,
});
this.dialog = false;
return item;
},
},
};
</script>

View File

@ -3,7 +3,7 @@
ref="form"
lazy-validation
v-model="formValid"
v-if="isNew || isLoaded"
v-if="item != null"
>
<v-alert
:value="formError"
@ -32,87 +32,16 @@
</v-form>
</template>
<script>
import axios from 'axios';
import { getErrorMessage } from '@/lib/error';
import ItemFormBase from '@/components/ItemFormBase';
export default {
props: {
projectId: [Number, String],
},
data() {
return {
item: null,
formValid: false,
formError: null,
formSaving: false,
};
},
async created() {
await this.loadData();
},
computed: {
isLoaded() {
return this.item != null;
},
isNew() {
return this.projectId === 'new';
},
itemId() {
return this.projectId;
},
},
mixins: [ItemFormBase],
methods: {
async reset() {
this.$refs.form.resetValidation();
await this.loadData();
getItemsUrl() {
return '/api/projects';
},
async loadData() {
if (this.isNew) {
this.item = {};
} else {
this.item = (await axios({
method: 'get',
url: `/api/project/${this.projectId}`,
responseType: 'json',
})).data;
}
},
/**
* Saves or creates project via API.
* @returns {Promise<null>} null if validation didn't pass or project data if project saved.
*/
async save() {
this.formError = null;
if (!this.$refs.form.validate()) {
return null;
}
this.formSaving = true;
let item;
try {
item = (await axios({
method: this.isNew ? 'post' : 'put',
url: this.isNew
? '/api/projects'
: `/api/project/${this.projectId}`,
responseType: 'json',
data: this.item,
})).data;
} catch (err) {
this.formError = getErrorMessage(err);
} finally {
this.formSaving = false;
}
return item || this.item;
getSingleItemUrl() {
return `/api/project/${this.itemId}`;
},
},
};

View File

@ -0,0 +1,83 @@
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
<v-dialog
v-model="dialog"
persistent
:transition="false"
v-if="item != null"
>
<v-toolbar flat color="white">
<v-btn
icon
class="mr-4"
>
<v-icon>mdi-arrow-left</v-icon>
</v-btn>
<v-toolbar-title class="breadcrumbs">
<router-link
class="breadcrumbs__item breadcrumbs__item--link"
:to="`/project/${projectId}/`"
>Task Templates</router-link>
<span class="breadcrumbs__separator">&gt;</span>
<router-link
class="breadcrumbs__item breadcrumbs__item--link"
:to="`/project/${projectId}/templates/${templateId}`"
>Task Templates</router-link>
<span class="breadcrumbs__separator">&gt;</span>
<span class="breadcrumbs__item">{{ item.id }}</span>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn
icon
color="black"
@click="dialog = true"
>
<v-icon left>mdi-close</v-icon>
</v-btn>
</v-toolbar>
</v-dialog>
</template>
<script>
import axios from 'axios';
export default {
props: {
value: Boolean,
projectId: Number,
itemId: Number,
},
data() {
return {
dialog: false,
item: null,
};
},
watch: {
async dialog(val) {
this.$emit('input', val);
this.needReset = val;
},
async value(val) {
this.dialog = val;
},
},
async created() {
await this.loadData();
},
methods: {
async loadData() {
this.item = (await axios({
method: 'get',
url: `/api/project/${this.projectId}/tasks/${this.itemId}`,
responseType: 'json',
})).data;
},
},
};
</script>

View File

@ -1,58 +1,77 @@
<template>
<v-container>
<v-row>
<v-col>
<v-list two-line subheader>
<v-list-item>
<v-list-item-content>
<v-list-item-title>Author</v-list-item-title>
<v-list-item-subtitle>{{ item.user_name }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<div>
<v-container class="pa-0" v-if="item != null && output != null">
<v-row no-gutters>
<v-col>
<v-list two-line subheader class="pa-0">
<v-list-item class="pa-0">
<v-list-item-content>
<v-list-item-title>Author</v-list-item-title>
<v-list-item-subtitle>{{ item.user_name }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-content>
<v-list-item-title>Status</v-list-item-title>
<v-list-item-subtitle>{{ item.status }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</v-col>
<v-col>
<v-list two-line subheader>
<v-list-item>
<v-list-item-content>
<v-list-item-title>Created</v-list-item-title>
<v-list-item-subtitle>{{ item.created }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item class="pa-0">
<v-list-item-content>
<v-list-item-title>Status</v-list-item-title>
<v-list-item-subtitle>{{ item.status }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</v-col>
<v-col>
<v-list two-line subheader class="pa-0">
<v-list-item class="pa-0">
<v-list-item-content>
<v-list-item-title>Created</v-list-item-title>
<v-list-item-subtitle>{{ item.created }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-content>
<v-list-item-title>Started</v-list-item-title>
<v-list-item-subtitle>{{ item.start }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item class="pa-0">
<v-list-item-content>
<v-list-item-title>Started</v-list-item-title>
<v-list-item-subtitle>{{ item.start }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-list-item>
<v-list-item-content>
<v-list-item-title>Ended</v-list-item-title>
<v-list-item-subtitle>{{ item.end }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</v-col>
</v-row>
</v-container>
<v-list-item class="pa-0">
<v-list-item-content>
<v-list-item-title>Ended</v-list-item-title>
<v-list-item-subtitle>{{ item.end }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</v-col>
</v-row>
</v-container>
<div class="text-view" style="height: 400px;" v-text="output">
</div>
</div>
</template>
<style lang="scss">
.text-view {
overflow: auto;
border: 1px solid gray;
border-radius: 4px;
font-family: monospace;
}
</style>
<script>
import axios from 'axios';
export default {
props: {
taskId: Number,
itemId: Number,
projectId: Number,
},
data() {
return {
item: null,
output: null,
};
},
async created() {
await this.loadData();
},
@ -60,14 +79,14 @@ export default {
async loadData() {
this.item = (await axios({
method: 'get',
url: `/api/project/${this.projectId}/tasks/${this.taskId}`,
url: `/api/project/${this.projectId}/tasks/${this.itemId}`,
responseType: 'json',
})).data;
this.output = (await axios({
method: 'get',
url: `/api/project/${this.projectId}/tasks/${this.taskId}/output`,
url: `/api/project/${this.projectId}/tasks/${this.itemId}/output`,
responseType: 'json',
})).data;
})).data.map((line) => line.output).join('\n');
},
},
};

View File

@ -1,5 +1,16 @@
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
<div v-if="items != null">
<ItemDialog
v-model="taskLogDialog"
save-button-text="Delete"
title="Task Log"
:max-width="800"
>
<template v-slot:form="{}">
<TaskLogView :project-id="projectId" :item-id="taskId" />
</template>
</ItemDialog>
<v-toolbar flat color="white">
<v-app-bar-nav-icon @click="showDrawer()"></v-app-bar-nav-icon>
<v-toolbar-title>Dashboard</v-toolbar-title>
@ -18,15 +29,35 @@
hide-default-footer
class="mt-4"
>
<template v-slot:item.tpl_alias="{ item }">
<a @click="showTaskLog(item.id)">{{ item.tpl_alias }}</a>
<span style="color: gray; margin-left: 10px;">#{{ item.id }}</span>
</template>
<template v-slot:item.status="{ item }">
{{ item.status }}
</template>
</v-data-table>
</div>
</template>
<script>
import ItemListPageBase from '@/components/ItemListPageBase';
import ItemDialog from '@/components/ItemDialog.vue';
import TaskLogView from '@/components/TaskLogView.vue';
export default {
components: {
ItemDialog, TaskLogView,
},
mixins: [ItemListPageBase],
data() {
return {
taskLogDialog: null,
taskId: null,
};
},
watch: {
async projectId() {
await this.loadItems();
@ -34,6 +65,11 @@ export default {
},
methods: {
showTaskLog(taskId) {
this.taskId = taskId;
this.taskLogDialog = true;
},
getHeaders() {
return [
{

View File

@ -1,36 +1,11 @@
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
<div>
<v-dialog
<YesNoDialog
v-model="deleteProjectDialog"
max-width="290">
<v-card>
<v-card-title class="headline">Delete project</v-card-title>
<v-card-text>
Are you really want to delete this project?
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn
color="blue darken-1"
text
@click="deleteProjectDialog = false"
>
Cancel
</v-btn>
<v-btn
color="blue darken-1"
text
@click="deleteProject()"
>
Yes
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
title="Delete project"
text="Are you really want to delete this project?"
@yes="deleteProject()"
/>
<v-toolbar flat color="white">
<v-app-bar-nav-icon @click="showDrawer()"></v-app-bar-nav-icon>
@ -46,7 +21,7 @@
</v-toolbar>
<div class="project-settings-form">
<div style="height: 220px;">
<ProjectForm :project-id="projectId" ref="editForm"/>
<ProjectForm :item-id="projectId" ref="form"/>
</div>
<div class="text-right">
@ -84,9 +59,10 @@ import EventBus from '@/event-bus';
import ProjectForm from '@/components/ProjectForm.vue';
import { getErrorMessage } from '@/lib/error';
import axios from 'axios';
import YesNoDialog from '@/components/YesNoDialog.vue';
export default {
components: { ProjectForm },
components: { YesNoDialog, ProjectForm },
props: {
projectId: Number,
},
@ -103,7 +79,7 @@ export default {
},
async saveProject() {
const item = await this.$refs.editForm.save();
const item = await this.$refs.form.save();
if (!item) {
return;
}

View File

@ -1,5 +1,7 @@
<template xmlns:v-slot="http://www.w3.org/1999/XSL/Transform">
<div v-if="item != null && tasks != null">
<TaskLogDialog v-model="editDialog" />
<ItemDialog
v-model="editDialog"
save-button-text="Save"
@ -45,8 +47,14 @@
<v-toolbar flat color="white">
<v-app-bar-nav-icon @click="showDrawer()"></v-app-bar-nav-icon>
<v-toolbar-title>Task Template: {{ item.alias }}</v-toolbar-title>
<v-toolbar-title class="breadcrumbs">
<router-link
class="breadcrumbs__item breadcrumbs__item--link"
:to="`/project/${projectId}/templates/`"
>Task Templates</router-link>
<span class="breadcrumbs__separator">&gt;</span>
<span class="breadcrumbs__item">{{ item.alias }}</span>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn
@ -127,6 +135,12 @@
hide-default-footer
class="mt-2"
>
<template v-slot:item.id="{ item }">
<a @click="showTaskLog(item.id)">#{{ item.id }}</a>
</template>
<template v-slot:item.status="{ item }">
{{ item.status }}
</template>
</v-data-table>
</div>
</template>
@ -140,9 +154,12 @@ import { getErrorMessage } from '@/lib/error';
import YesNoDialog from '@/components/YesNoDialog.vue';
import ItemDialog from '@/components/ItemDialog.vue';
import TemplateForm from '@/components/TemplateForm.vue';
import TaskLogDialog from '@/components/TaskLogDialog.vue';
export default {
components: { YesNoDialog, ItemDialog, TemplateForm },
components: {
YesNoDialog, ItemDialog, TemplateForm, TaskLogDialog,
},
props: {
projectId: Number,
},
@ -180,6 +197,8 @@ export default {
deleteDialog: null,
editDialog: null,
copyDialog: null,
taskLogDialog: null,
taskId: null,
};
},
@ -203,6 +222,11 @@ export default {
},
methods: {
showTaskLog(taskId) {
this.taskId = taskId;
this.taskLogDialog = true;
},
showDrawer() {
EventBus.$emit('i-show-drawer');
},

View File

@ -42,9 +42,10 @@
save-button-text="Delete"
title="Task Log"
@save="onTaskAskDelete"
:max-width="800"
>
<template v-slot:form="{}">
<TaskLogView :item-id="taskId" />
<TaskLogView :project-id="projectId" :item-id="taskId" />
</template>
</ItemDialog>