Commit 29e1442d authored by Julien BOUYER's avatar Julien BOUYER
Browse files

UNOTOPLYS-171 feat(screen) : drag-n-drop des Ecrans

parent e06ffd6d
This diff is collapsed.
import Vue from 'vue';
import { Component, Prop } from 'vue-property-decorator';
import { IScreen } from '@/shared/model/screen.model';
@Component
export default class DndList extends Vue {
@Prop()
public screenList: any[];
@Prop()
public idScreen: number;
private currentList: any[];
constructor() {
super();
this.currentList = this.screenList;
}
public set list(screenList: any[]) {
this.currentList = screenList;
}
public get list(): any[] {
return this.currentList;
}
public get options() {
return {
dropzoneSelector: 'ol',
draggableSelector: 'li',
excludeOlderBrowsers: true,
showDropzoneAreas: true,
};
}
public isCurrentPanel(panel: any): boolean {
return this.idScreen == panel.id;
}
public selectScreen(panelScreen: IScreen): void {
this.$emit('selectScreen', panelScreen);
}
public reordered(e: CustomEvent) {
const selectedElm = e.detail.items[0];
const screen = this.screenList.find(s => s.id === Number.parseInt(selectedElm.getAttribute('data-screenid'), 10));
this.$emit('update', { screen, newIndex: e.detail.index });
}
}
<template>
<div v-drag-and-drop:options="options">
<ol class="p-2 text-sm select-none" @reordered="reordered">
<li
v-for="panelScreen in list"
:key="panelScreen.index"
:class="[
'flex items-center p-1 leading-tight transition rounded-md cursor-pointer group hover:absolute focus:ring ',
isCurrentPanel(panelScreen) ? 'font-medium text-white bg-blue-600 hover:bg-blue-700' : 'hover:bg-blue-100',
]"
tabindex="0"
:data-screenid="panelScreen.id"
role="button"
@click="selectScreen(panelScreen)"
>
<span
:class="[
'flex-shrink-0 inline-block w-8 h-6 mr-2 text-sm text-center border rounded-md',
isCurrentPanel(panelScreen)
? 'text-blue-900 bg-blue-100 border-white group-hover:border-blue-900-400'
: 'bg-white border-gray-300 group-hover:border-gray-400',
]"
>{{ panelScreen.index }}</span
>{{ panelScreen.titleBo }}
</li>
</ol>
</div>
</template>
<script lang="ts" src="./dnd-list.component.ts" />
import Vue from 'vue';
import { Component } from 'vue-property-decorator';
import { IScreen } from '@/shared/model/screen.model';
import DndList from '@/components/dnd-list/dnd-list.vue';
import Icon from '@/components/icon/icon.vue';
@Component({
components: {
DndList,
Icon,
},
})
export default class Panel extends Vue {
public get screenList(): boolean {
public get screenList(): any[] {
return this.$store.getters.screenList;
}
public isCurrentPanel(panel) {
return this.idScreen == panel.id;
public updateScreenIndex({ screen, newIndex }) {
this.$store.dispatch('updateScreenIndex', { screen, newIndex });
}
public get idWorkspace(): string {
......@@ -25,18 +29,18 @@ export default class Panel extends Vue {
return this.$store.getters.idForm;
}
public get idScreen(): string {
public get idScreen(): number {
return this.$store.getters.idScreen;
}
public selectScreen(screen) {
public selectScreen(screen: IScreen) {
if (screen.id != this.idScreen) {
this.$router.push({
name: 'ScreenEditComponent',
params: {
idWorkspace: this.idWorkspace,
idForm: this.idForm,
idScreen: screen.id,
idScreen: `${screen.id}`,
},
});
}
......
......@@ -13,29 +13,7 @@
<icon name="trash" />
</button>
</div>
<ol class="p-2 text-sm select-none">
<li
v-for="panelScreen in screenList"
:key="panelScreen.index"
:class="[
'flex items-center p-1 leading-tight transition rounded-md cursor-pointer group hover:absolute focus:ring ',
isCurrentPanel(panelScreen) ? 'font-medium text-white bg-blue-600 hover:bg-blue-700' : 'hover:bg-blue-100',
]"
tabindex="0"
role="button"
@click="selectScreen(panelScreen)"
>
<span
:class="[
'flex-shrink-0 inline-block w-8 h-6 mr-2 text-sm text-center border rounded-md',
isCurrentPanel(panelScreen)
? 'text-blue-900 bg-blue-100 border-white group-hover:border-blue-900-400'
: 'bg-white border-gray-300 group-hover:border-gray-400',
]"
>{{ panelScreen.index }}</span
>{{ panelScreen.titleBo }}
</li>
</ol>
<dnd-list :screenList="screenList" :idScreen="idScreen" @update="updateScreenIndex" @selectScreen="selectScreen" />
</div>
</aside>
</template>
......
......@@ -95,4 +95,17 @@ export default class ScreenService {
});
});
}
public updateIndex(id: number, index: number): Promise<IScreen> {
return new Promise<IScreen>((resolve, reject) => {
axios
.patch(`${baseApiUrl}/${id}`, { index })
.then(res => {
resolve(res.data);
})
.catch(err => {
reject(err);
});
});
}
}
......@@ -3,6 +3,7 @@
import Vue from 'vue';
import App from './app.vue';
import Vue2Filters from 'vue2-filters';
import VueDraggable from 'vue-draggable';
import router from './router';
import { metaInfo } from './shared/meta';
import * as config from './shared/config/config';
......@@ -18,6 +19,7 @@ import HeaderService from '@/shared/service/header-service';
Vue.config.productionTip = false;
config.initVueApp(Vue);
Vue.use(Vue2Filters);
Vue.use(VueDraggable);
const i18n = config.initI18N(Vue);
const store = config.initVueXStore(Vue);
......
import { Module } from 'vuex';
import FormService from '@/entities/form/form.service';
import ScreenService from '@/entities/screen/screen.service';
import { IScreen } from '@/shared/model/screen.model';
const formService = new FormService();
const screenService = new ScreenService();
......@@ -17,6 +18,14 @@ export const formStore: Module<any, any> = {
screenList: state => state.screenList,
},
actions: {
updateScreenIndex({ state, dispatch }, { screen, newIndex }) {
screenService
.updateIndex(screen.id, newIndex)
.then(() => {
dispatch('loadScreens', state.idForm);
})
.catch(console.error);
},
loadScreens({ commit }, idForm) {
screenService.findByFormId(idForm).then(res => {
commit('setScreenList', res);
......
......@@ -33,3 +33,20 @@
content: '/';
@apply inline-block px-4 font-light text-gray-200;
}
@keyframes nodeInserted {
from {
opacity: 0.2;
}
to {
opacity: 0.8;
}
}
.item-dropzone-area {
height: 2rem;
background: #888;
opacity: 0.8;
animation-duration: 0.5s;
animation-name: nodeInserted;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment