diff --git a/package.json b/package.json index 6e5ab0f..82eb3c9 100755 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "normalize.css": "^8.0.0", "npm": "^6.9.0", "nprogress": "^0.2.0", - "quasar": "^1.0.0-beta.11", + "quasar": "^1.0.0-beta.17", "quasar-extras": "^2.0.8", "register-service-worker": "^1.0.0", "vee-validate": "^2.1.2", @@ -85,7 +85,7 @@ "@babel/plugin-syntax-dynamic-import": "^7.2.0", "@babel/plugin-syntax-import-meta": "^7.2.0", "@babel/preset-env": "^7.4.2", - "@quasar/app": "^1.0.0-beta.11", + "@quasar/app": "^1.0.0-beta.18", "@quasar/quasar-app-extension-typescript": "^1.0.0-alpha.11", "@types/dotenv": "^4.0.3", "@types/jest": "^23.1.4", diff --git a/quasar.conf.js b/quasar.conf.js index dfb7e62..0f42405 100644 --- a/quasar.conf.js +++ b/quasar.conf.js @@ -167,12 +167,12 @@ module.exports = function (ctx) { 'QPopupEdit', 'QCarousel', 'QCarouselControl', + 'QCarouselSlide', 'QPageScroller', 'QAvatar', 'QImg', 'QSplitter', - 'QSeparator', - 'QCarouselSlide' + 'QSeparator' ], directives: [ 'Ripple', diff --git a/src/components/projects/SingleProject/SingleProject.ts b/src/components/projects/SingleProject/SingleProject.ts index dc08e41..0f6e0c3 100644 --- a/src/components/projects/SingleProject/SingleProject.ts +++ b/src/components/projects/SingleProject/SingleProject.ts @@ -10,7 +10,6 @@ import { SubMenusProj } from '../SubMenusProj' import { CDate } from '../../CDate' import { date } from 'quasar' -import { askConfirm } from '../../../classes/routinestd' @Component({ components: { SubMenusProj, CDate }, @@ -41,6 +40,14 @@ export default class SingleProject extends Vue { return tools } + get isDisable() { + return !Projects.getters.getifCanISeeProj(this.itemproject) + } + + get CanIModifyProject() { + return Projects.getters.CanIModifyPanelPrivacy(this.itemproject) + } + @Prop({ required: true }) public itemproject: IProject @Watch('itemproject.enableExpiring') public valueChanged4() { @@ -77,6 +84,12 @@ export default class SingleProject extends Vue { @Watch('itemproject.actualphase') public valueChangedactualphase() { this.watchupdate('actualphase') } + @Watch('itemproject.privacyread') public valueChanged_privacyread() { + this.watchupdate('privacyread') + } + @Watch('itemproject.privacywrite') public valueChanged_privacywrite() { + this.watchupdate('privacywrite') + } @Watch('itemproject.totalphases') public valueChangedtotalphases() { this.watchupdate('totalphases') } @@ -88,8 +101,15 @@ export default class SingleProject extends Vue { this.watchupdate('progressCalc') } + get isMainProject() { + return tools.isMainProject(this.itemproject.id_parent) + } + get getlabeltext() { - return this.$t('proj.newproj') + if (this.isMainProject) + return this.$t('proj.newproj') + else + return this.$t('proj.newsubproj') } /* @@ -147,12 +167,6 @@ export default class SingleProject extends Vue { this.clButtPopover += ' pos-item-popover_cursor' } - // this.getinputdescr = 'inputdescr' + this.itemproject._id - - // console.log('classDescrEdit = ', this.classDescrEdit) - // console.log('classDescr', this.classDescr) - - // console.log('UserStore.state.lang', UserStore.state.lang) if (this.isProject()) { this.menuPopupProj = tools.menuPopupProj[UserStore.state.lang] } @@ -178,7 +192,7 @@ export default class SingleProject extends Vue { } public clickRiga(clickmenu: boolean = false) { - // console.log('CLICK RIGA ************') + console.log('CLICK RIGA PROJ************') if (!this.sel) { if (!this.inEdit) { @@ -238,12 +252,16 @@ export default class SingleProject extends Vue { this.editProject() } + get isMyProject() { + return this.itemproject.userId === UserStore.state.userId + } + get getrouteto() { - return '/projects/' + this.itemproject._id + return tools.getUrlByTipoProj(this.isMyProject) + this.itemproject._id } public goIntoTheProject() { - this.$router.replace('/projects/' + this.itemproject._id) + this.$router.replace(tools.getUrlByTipoProj(this.isMyProject) + this.itemproject._id) } public editProject() { @@ -259,7 +277,7 @@ export default class SingleProject extends Vue { this.updateClasses() } - this.faiFocus('inputdescr', false, true) + this.faiFocus('inputprojdescr', false, true) } // console.log('FINE - editProject') } @@ -275,11 +293,12 @@ export default class SingleProject extends Vue { } if (!!theField) { + console.log('FOCUS PROJ', theField) theField.focus() } // console.log('focus()') - }, 100) + }, 500) } public getFocus(e) { diff --git a/src/components/projects/SingleProject/SingleProject.vue b/src/components/projects/SingleProject/SingleProject.vue index 0e81fbc..993c5a2 100644 --- a/src/components/projects/SingleProject/SingleProject.vue +++ b/src/components/projects/SingleProject/SingleProject.vue @@ -1,11 +1,11 @@ + +
{{ prior = 0, priorcomplet = false }}
@@ -75,7 +77,9 @@
+ :itemtodo='mytodo' :CanIModifyTodo="CanIModifyTodo"> + + @@ -107,9 +111,9 @@ + - - @@ -13,9 +15,10 @@ v-model.trim="precDescr" autogrow borderless + :readonly="!CanIModifyTodo" dense :class="classDescrEdit" :max-height="100" - @keydown="keyDownArea" v-on:keydown.esc="exitEdit" @blur="exitEdit(true)" @click="editTodo()"/> + @keydown="keyDownArea" v-on:keydown.esc="exitEdit" @blur="exitEdit(true)" @click="editTodo()">
{{itemtodo.descr}} @@ -37,6 +40,7 @@
{{percentageProgress}}% - @@ -57,14 +62,15 @@
+ data_class="data_string" :readonly="!CanIModifyTodo">
-
+
- + diff --git a/src/model/Projects.ts b/src/model/Projects.ts index c6cf366..35f2286 100644 --- a/src/model/Projects.ts +++ b/src/model/Projects.ts @@ -6,6 +6,8 @@ export interface IProject { _id?: any, userId?: string category?: string + typeproj?: number + id_main_project?: string id_parent?: string descr?: string longdescr?: string @@ -31,6 +33,8 @@ export interface IProject { begin_test?: Date totalphases?: number actualphase?: number + privacyread?: string + privacywrite?: string } export interface IProjectsState { @@ -39,3 +43,15 @@ export interface IProjectsState { insidePending: boolean visuLastCompleted: number } + +export const Privacy = { + all: 'all', + friends: 'friends', + mygroup: 'mygroup', + onlyme: 'onlyme' +} + +export const TypeProj = { + TYPE_PROJECT: 1, + TYPE_SUBDIR: 2 +} diff --git a/src/model/Todos.ts b/src/model/Todos.ts index ea00597..0bc4535 100644 --- a/src/model/Todos.ts +++ b/src/model/Todos.ts @@ -40,6 +40,7 @@ export interface IDrag { category?: string id_proj?: string atfirst?: boolean + mieiproj?: boolean } export interface ITodosState { diff --git a/src/root/malaga/malaga.scss b/src/root/malaga/malaga.scss new file mode 100644 index 0000000..7c1cc3c --- /dev/null +++ b/src/root/malaga/malaga.scss @@ -0,0 +1,410 @@ +body { + font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + color: #a7a7a7; + line-height: 1.5; + //font-size: 1rem; +} + +.carousel_slide { + background-color: black !important; + background-size: contain !important; + background-repeat: no-repeat !important;; + background-position: top !important; +} + +$grayshadow: #555; + +.testo-banda { + //background: -webkit-gradient(linear, left top, left bottom, from(#3144f0), to(transparent)); + //background: linear-gradient(180deg, #3144f0, transparent); + //background: rgba(0, 0, 0, .6) +} + +p { + margin: 0 0 16px; + text-shadow: 2px 2px 4px $grayshadow; +} + +.mycard { + visibility: hidden; +} + +.landing { +} + +.landing_background { + background: #000; + background-size: contain; +} + +.landing > section { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + //padding: 0 16px +} + +.landing > section.padding { + padding: 90px 16px +} + +.landing > section > div { + position: relative; + max-width: 1240px; + width: 100% +} + +.landing__toolbar { + background: -webkit-gradient(linear, left top, left bottom, from(#000), to(transparent)); + background: linear-gradient(180deg, #000, transparent); + padding: 0 !important +} + +.landing__toolbar .q-btn { + border-radius: 0 0 5px 5px; + -ms-flex-item-align: stretch; + align-self: stretch +} + +.landing__hero { + min-height: 90vh +} + +.landing__header { + height: 18vh +} + +.landing__arrow { + bottom: 25px; + opacity: .4 +} + +.landing__front { + background: -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(15%, rgba(0, 0, 0, .6))); + background: linear-gradient(180deg, transparent, rgba(0, 0, 0, .6) 15%) +} + +.landing__logo { + width: 150px; + height: 150px; + margin-top: 21px; + //-webkit-animation: logo-rotate 240s linear infinite; + //animation: logo-rotate 240s linear infinite +} + +.landing__features .q-icon { + font-size: 64px +} + +h4 { + line-height: 1.5; + text-shadow: 4px 4px 8px $grayshadow; +} + +.landing__features h4, .landing__features h6 { + margin: 26px 0 +} + +.landing__features p { + opacity: .7; + font-size: 1rem; + line-height: 1.5; +} + +.landing__footer { + //background: -webkit-gradient(linear, left top, left bottom, color-stop(65%, rgba(0, 0, 0, .1)), to(#000)); + background: linear-gradient(180deg, rgba(0, 0, 0, .8) 75%, #FFF); + padding-top: 72px !important; + padding-bottom: 72px !important +} + +.icon_contact:hover { + color: blue; + border-color: white; + border-width: 1px; +} + +.landing__footer .doc-link { + color: #fff +} + +.landing__footer .doc-link:hover { + opacity: .8 +} + +.landing__swirl-bg { + background-repeat: no-repeat !important; + background-position: top; + background-size: contain !important; + background-image: url(../../statics/images/landing_first_section.png) !important +} + +.feat-descr { + font-size: 1.15rem; +} + +.feat-descr:hover { + transition: opacity 0.5s ease-in-out; + opacity: 0.9; +} + +.q-col-gutter-sm { + padding: 50px 50px; + //margin-left: -48px +} + +body.mobile .landing { + //background: unset +} + +body.mobile .landing:before { + content: ""; + position: fixed; + top: 0; + height: 60vh; + left: 0; + right: 0; + bottom: 0; + z-index: -1; + //background: #000 url(../../statics/images/cover.jpg) 50%; + + background-size: contain; +} + +/* +@-webkit-keyframes logo-rotate { + to { + -webkit-transform: rotate(-1turn); + transform: rotate(-1turn) + } +} + +@keyframes logo-rotate { + to { + -webkit-transform: rotate(-1turn); + transform: rotate(-1turn) + } +} +*/ + +.home { + //background-color: rgb(250, 250, 250); + padding: 5px; + display: flex; + //flex-wrap: nowrap; + flex-direction: column; + align-items: center; + justify-content: space-between; +} + +.btn-start { + margin: 5px; +} + +.shadow { + //color: white; + text-shadow: 2px 2px 4px $grayshadow; +} + +.shadow-max { + //color: white; + text-shadow: 4px 4px 8px $grayshadow; +} + +.text-h1 { + font-size: 3rem; + font-weight: 300; + line-height: 3rem; + letter-spacing: -.01562em; +} + +.text-h2 { + font-size: 3.75rem; + font-weight: 300; + line-height: 3.75rem; + letter-spacing: -.00833em; +} + +.text-weight-bold { + font-weight: 700; +} + +.miosottotit{ + font-size: 2rem; + line-height: 2rem; + margin: 15px !important; + font-weight: bold; + text-shadow: 4px 4px 8px $grayshadow; +} + +.subtitle1 { + font-size: 1.75rem; + line-height: 1.75rem; + text-shadow: 4px 4px 8px $grayshadow; + letter-spacing: .00937em; + &.big { + font-size: 1.5rem; + } +} + +.text-subtitle2 { + font-size: 1.15rem; + font-weight: 400; + line-height: 1.75rem; + letter-spacing: .00937em; + text-shadow: 4px 4px 8px $grayshadow; +} + +.text-subtitle3 { + font-size: 1rem; + font-weight: 400; + line-height: 1.75rem; + letter-spacing: .00937em; + text-shadow: 2px 2px 4px $grayshadow; +} + +.homep-cover-img-1 { + background: #000 url(../../statics/images/cover.jpg) no-repeat 50% fixed; + //transition: background-image 1s ease-in-out; +} + +.homep-cover-img-2 { + background: #000 url(../../statics/images/hand_people.jpg) no-repeat 50% fixed; + //transition: background-image 1s ease-in-out; +} + +.homep-cover-img-3 { + background: #000 url(../../statics/images/cibo_sano.jpg) no-repeat 50% fixed; + //transition: background-image 1s ease-in-out; +} + +.homep-cover-img.hide-filter:before { + opacity: 0 +} + +.landing__footer-icons { + font-size: 28px +} + +.landing__footer-icons a { + margin: 0 8px 8px; + text-decoration: none; + outline: 0; + color: #fff; + transition: color .28s +} + +.landing__footer-icons a:hover { + color: #e0e0e0 +} + +.doc-img { + max-width: 100%; +} + +.mylist { + background: #3fdaff; + padding-left: 20px; +} + +.clgutter { + margin-top: 20px; + padding: 10px; +} + +.carousel_img_3 { + //background-image: url(../../statics/images/cibo_sano.jpg); + background-size: contain !important; + background-position: 50% center !important; + background-repeat: no-repeat !important; +} + + +@media (max-width: 718px) { + // PER VERSIONE MOBILE + + .landing__hero { + text-align: center; + min-height: 60vh + } + + .landing__header { + height: 7vh + } + .clgutter { + margin-top: 0px; + padding: 0px; + } + .landing__hero .text-h1 { + font-size: 2rem; + line-height: 2.05rem; + margin-bottom: 24px + } + + .landing > section.padding { + padding: 10px 16px + //padding-bottom: 90px + } + + .landing__features h4, .landing__features h6 { + margin: 20px 0 + } + + h4 { + line-height: 1.4; + text-shadow: 4px 4px 8px $grayshadow; + } + + .landing .feature-item { + text-align: center; + margin-top: 20px; + } + .landing__hero-content { + padding-bottom: 180px + } + .landing__hero-btns { + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center + } + + .q-col-gutter-sm { + padding: 10px 5px; + } + + .subtitle1 { + font-size: 1rem; + line-height: 1rem; + text-shadow: 4px 4px 8px $grayshadow; + } + .text-subtitle2 { + font-size: 1rem; + padding: 10px 5px; + font-weight: bold; + } + .text-subtitle3 { + font-size: 0.75rem; + padding: 10px 5px; + } + + .carousel_img_3 { + //background-image: url(../../statics/images/cibo_sano.jpg); + background-size: 620px 620px !important; + background-position: 50% top !important; + background-repeat: no-repeat !important; + } + +} + +.custom-caption { + text-align: center; + padding: 12px; + color: white; + background-color: rgba(0, 0, 0, .3); +} + diff --git a/src/root/malaga/malaga.ts b/src/root/malaga/malaga.ts new file mode 100644 index 0000000..f58abe2 --- /dev/null +++ b/src/root/malaga/malaga.ts @@ -0,0 +1,80 @@ +import Vue from 'vue' +import { Component } from 'vue-property-decorator' +import { GlobalStore, UserStore } from '@store' + +import { Logo } from '../../components/logo' + +import VueScrollReveal from 'vue-scroll-reveal' +import { tools } from '@src/store/Modules/tools' + +Vue.use(VueScrollReveal, { + class: 'v-scroll-reveal', // A CSS class applied to elements with the v-scroll-reveal directive; useful for animation overrides. + duration: 1200, + scale: 0.95, + distance: '10px', + rotate: { + x: 0, + y: 0, + z: 0 + } + // mobile: true +}) + +@Component({ + components: { Logo } +}) +export default class Malaga extends Vue { + public text: string = '' + public visibile: boolean = false + public cardvisible: string = 'hidden' + public displaycard: string = 'block' + public $t: any + // public firstClassSection: string = 'landing_background fade homep-cover-img animate-fade homep-cover-img-1' + public firstClassSection: string = 'fade homep-cover-img animate-fade homep-cover-img-1' + public $q + public polling + public slide2 = 0 + public animare: number = 0 + public test1 = GlobalStore.getters.t('piso.matr1') + public getImmagini = [ + {title: GlobalStore.getters.t('piso.cameramatr'), subtitle: GlobalStore.getters.t('piso.matr1'), + img: '../../statics/images/piso/camera_matrimoniale.jpg'}, + {title: GlobalStore.getters.t('piso.mat_scrivania'), subtitle: '', + img: '../../statics/images/piso/matrimoniale_scrivania.jpg'}, + {title: GlobalStore.getters.t('piso.mat_finestra'), subtitle: '', + img: '../../statics/images/piso/matrimoniale_finestra.jpg'}, + {title: GlobalStore.getters.t('piso.mat_armadio'), subtitle: '', + img: '../../statics/images/piso/matrimoniale_armadio.jpg'}, + {title: GlobalStore.getters.t('piso.mat_fin2'), subtitle: '', // 'Finestra dalla camera matrimoniale' + img: '../../statics/images/piso/finestra_della_camera_matrimoniale.jpg'}, + {title: GlobalStore.getters.t('piso.cucina'), subtitle: '', // 'Cucina' + img: '../../statics/images/piso/cucina.jpg'}, + {title: GlobalStore.getters.t('piso.cucina'), subtitle: '', // 'Cucina' + img: '../../statics/images/piso/cucina2.jpg'}, + {title: GlobalStore.getters.t('piso.corridoio'), subtitle: '', // 'Corridoio' + img: '../../statics/images/piso/corridoio.jpg'}, + {title: GlobalStore.getters.t('piso.tv'), subtitle: '', // 'Televisore e Wifi' + img: '../../statics/images/piso/televisore.jpg'}, + {title: GlobalStore.getters.t('piso.terrazza'), subtitle: '', // 'Terrazza' + img: '../../statics/images/piso/terrazza.jpg'}, + {title: GlobalStore.getters.t('piso.terrazza_vista'), subtitle: '', // 'Vista dalla terrazza' + img: '../../statics/images/piso/fuori_dalla_terrazza.jpg'}, + {title: GlobalStore.getters.t('piso.sala'), subtitle: '', // 'Sala' + img: '../../statics/images/piso/sala.jpg'}, + {title: GlobalStore.getters.t('piso.divano'), subtitle: '', // 'Divano' + img: '../../statics/images/piso/divano.jpg'}, + {title: GlobalStore.getters.t('piso.corridoio'), subtitle: '', // 'Corridoio' + img: '../../statics/images/piso/corridoio2.jpg'}, + {title: GlobalStore.getters.t('piso.tavolo_sala'), subtitle: '', // 'Tavolo della sala' + img: '../../statics/images/piso/tavolo_sala.jpg'}, + {title: GlobalStore.getters.t('piso.bagno'), subtitle: '', // 'Bagno' + img: '../../statics/images/piso/bagno.jpg'}, + {title: GlobalStore.getters.t('piso.vasca'), subtitle: '', // 'Vasca con Doccia' + img: '../../statics/images/piso/bagno2.jpg'} + ] + + public getenv(myvar) { + return process.env[myvar] + } + +} diff --git a/src/root/malaga/malaga.vue b/src/root/malaga/malaga.vue new file mode 100644 index 0000000..5d5d223 --- /dev/null +++ b/src/root/malaga/malaga.vue @@ -0,0 +1,69 @@ + + + diff --git a/src/router/index.ts b/src/router/index.ts index c0a3f1e..7709525 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -62,7 +62,7 @@ Router.beforeEach(async (to: IMyRoute, from: IMyRoute, next) => { next() } else { if (!to.meta.transparent && !to.meta.isModal) { - console.log('Route interceptor log: <4>') + // console.log('Route interceptor log: <4>') ProgressBar.mutations.start() } else if (to.meta.transparent && !from.name) { diff --git a/src/router/route-config.ts b/src/router/route-config.ts index 28d8f09..6b93019 100644 --- a/src/router/route-config.ts +++ b/src/router/route-config.ts @@ -91,9 +91,26 @@ export const routesList: IMyRouteConfig[] = [ name: 'Offline', component: () => import('@/views/offline/offline.vue') }, + // { + // path: '/malaga', + // name: 'malaga', + // component: () => import('@/root/malaga/malaga.vue') + // }, { path: '/projects/:idProj', - name: 'progetti', + name: RouteNames.projects, + component: () => import('@/views/projects/proj-list/proj-list.vue'), + meta: { + requiresAuth: true, + async asyncData() { + await Projects.actions.dbLoad({ checkPending: false, onlyiffirsttime: true }) + } + // middleware: [auth] + } + }, + { + path: '/myprojects/:idProj', + name: RouteNames.myprojects, component: () => import('@/views/projects/proj-list/proj-list.vue'), meta: { requiresAuth: true, @@ -104,6 +121,7 @@ export const routesList: IMyRouteConfig[] = [ } } + /* { diff --git a/src/router/route-names.ts b/src/router/route-names.ts index 18b285a..aa8d147 100644 --- a/src/router/route-names.ts +++ b/src/router/route-names.ts @@ -1,4 +1,6 @@ export const RouteNames = { home: 'home', - login: 'login' + login: 'login', + projects: 'projects', + myprojects: 'myprojects' } diff --git a/src/statics/i18n.js b/src/statics/i18n.js index 3d9e87c..af09566 100644 --- a/src/statics/i18n.js +++ b/src/statics/i18n.js @@ -127,7 +127,8 @@ const messages = { Admin: 'Admin', Test1: 'Test1', Test2: 'Test2', - Projects: 'Progetti' + Projects: 'Progetti Condivisi', + MyProjects: 'Progetti Personali' }, components: { authentication: { @@ -242,6 +243,7 @@ const messages = { connection: 'Connessione', proj: { newproj: 'Titolo Progetto', + newsubproj: 'Titolo Sotto-Progetto', longdescr: 'Descrizione', hoursplanned: 'Ore Preventivate', hoursadded: 'Ore Aggiuntive', @@ -252,8 +254,10 @@ const messages = { actualphase: 'Fase Attuale', hoursweeky_plannedtowork: 'Ore settimanali previste', endwork_estimate: 'Data fine lavori stimata', + privacyread: 'Chi lo puo vedere:', + privacywrite: 'Chi lo puo modificare:', totalphases: 'Totale Fasi' - } + }, }, 'es': { dialog: { @@ -323,7 +327,7 @@ const messages = { }, freeliving: { title: 'Free Co-Living', - descr: 'Para unir más realidad, compartiendo la experiencia de vivir juntos, por un período definido:
'+ + descr: 'Para unir más realidad, compartiendo la experiencia de vivir juntos, por un período definido:
' + '1) Hay quien vive solo y tiene un hogar.
' + '2) Quién necesita un alojamiento temporal.

' + 'Hoy en día, más y más personas viven solas y les gustaría seguir viviendo en sus propios hogares.
' + @@ -384,7 +388,8 @@ const messages = { Admin: 'Administración', Test1: 'Test1', Test2: 'Test2', - Projects: 'Projectos', + Projects: 'Proyectos Compartidos', + MyProjects: 'Proyectos Personales', }, components: { authentication: { @@ -492,6 +497,7 @@ const messages = { connection: 'Connection', proj: { newproj: 'Título Projecto', + newsubproj: 'Título Sub-Projecto', longdescr: 'Descripción', hoursplanned: 'Horas Estimadas', hoursadded: 'Horas Adicional', @@ -502,8 +508,10 @@ const messages = { actualphase: 'Fase Actual', hoursweeky_plannedtowork: 'Horarios semanales programados', endwork_estimate: 'Fecha estimada de finalización', + privacyread: 'Quien puede verlo:', + privacywrite: 'Quien puede modificarlo:', totalphases: 'Fases totales' - } + }, }, 'enUs': { dialog: { @@ -634,7 +642,8 @@ const messages = { Admin: 'Admin', Test1: 'Test1', Test2: 'Test2', - Projects: 'Projects', + Projects: 'Shared Projects', + MyProjects: 'Personal Projects', }, components: { authentication: { @@ -742,6 +751,7 @@ const messages = { connection: 'Conexión', proj: { newproj: 'Project Title', + newsubproj: 'SubProject Title', longdescr: 'Description', hoursplanned: 'Estimated Hours', hoursadded: 'Additional Hours', @@ -752,8 +762,10 @@ const messages = { actualphase: 'Actual Phase', hoursweeky_plannedtowork: 'Scheduled weekly hours', endwork_estimate: 'Estimated completion date', + privacyread: 'Who can see it:', + privacywrite: 'Who can modify if:', totalphases: 'Total Phase' - } + }, }, }; diff --git a/src/statics/images/piso/.directory b/src/statics/images/piso/.directory new file mode 100644 index 0000000..46158c5 --- /dev/null +++ b/src/statics/images/piso/.directory @@ -0,0 +1,4 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2019,4,11,16,52,15 +Version=4 diff --git a/src/statics/images/piso/bagno.jpg b/src/statics/images/piso/bagno.jpg new file mode 100644 index 0000000..b89ae69 Binary files /dev/null and b/src/statics/images/piso/bagno.jpg differ diff --git a/src/statics/images/piso/bagno2.jpg b/src/statics/images/piso/bagno2.jpg new file mode 100644 index 0000000..b9b10e6 Binary files /dev/null and b/src/statics/images/piso/bagno2.jpg differ diff --git a/src/statics/images/piso/camera_matrimoniale.jpg b/src/statics/images/piso/camera_matrimoniale.jpg new file mode 100644 index 0000000..f647b8a Binary files /dev/null and b/src/statics/images/piso/camera_matrimoniale.jpg differ diff --git a/src/statics/images/piso/corridoio.jpg b/src/statics/images/piso/corridoio.jpg new file mode 100644 index 0000000..40d7011 Binary files /dev/null and b/src/statics/images/piso/corridoio.jpg differ diff --git a/src/statics/images/piso/corridoio2.jpg b/src/statics/images/piso/corridoio2.jpg new file mode 100644 index 0000000..9df3dc8 Binary files /dev/null and b/src/statics/images/piso/corridoio2.jpg differ diff --git a/src/statics/images/piso/cucina.jpg b/src/statics/images/piso/cucina.jpg new file mode 100644 index 0000000..7029bbc Binary files /dev/null and b/src/statics/images/piso/cucina.jpg differ diff --git a/src/statics/images/piso/cucina2.jpg b/src/statics/images/piso/cucina2.jpg new file mode 100644 index 0000000..831a92d Binary files /dev/null and b/src/statics/images/piso/cucina2.jpg differ diff --git a/src/statics/images/piso/divano.jpg b/src/statics/images/piso/divano.jpg new file mode 100644 index 0000000..5ac5933 Binary files /dev/null and b/src/statics/images/piso/divano.jpg differ diff --git a/src/statics/images/piso/finestra_della_camera_matrimoniale.jpg b/src/statics/images/piso/finestra_della_camera_matrimoniale.jpg new file mode 100644 index 0000000..e350b4f Binary files /dev/null and b/src/statics/images/piso/finestra_della_camera_matrimoniale.jpg differ diff --git a/src/statics/images/piso/fuori_dalla_terrazza.jpg b/src/statics/images/piso/fuori_dalla_terrazza.jpg new file mode 100644 index 0000000..b777c07 Binary files /dev/null and b/src/statics/images/piso/fuori_dalla_terrazza.jpg differ diff --git a/src/statics/images/piso/matrimoniale_armadio.jpg b/src/statics/images/piso/matrimoniale_armadio.jpg new file mode 100644 index 0000000..f5359ee Binary files /dev/null and b/src/statics/images/piso/matrimoniale_armadio.jpg differ diff --git a/src/statics/images/piso/matrimoniale_finestra.jpg b/src/statics/images/piso/matrimoniale_finestra.jpg new file mode 100644 index 0000000..2da2587 Binary files /dev/null and b/src/statics/images/piso/matrimoniale_finestra.jpg differ diff --git a/src/statics/images/piso/matrimoniale_scrivania.jpg b/src/statics/images/piso/matrimoniale_scrivania.jpg new file mode 100644 index 0000000..3295887 Binary files /dev/null and b/src/statics/images/piso/matrimoniale_scrivania.jpg differ diff --git a/src/statics/images/piso/sala.jpg b/src/statics/images/piso/sala.jpg new file mode 100644 index 0000000..d6fef43 Binary files /dev/null and b/src/statics/images/piso/sala.jpg differ diff --git a/src/statics/images/piso/singola_1.jpg b/src/statics/images/piso/singola_1.jpg new file mode 100644 index 0000000..3106fd1 Binary files /dev/null and b/src/statics/images/piso/singola_1.jpg differ diff --git a/src/statics/images/piso/singola_armadio.jpg b/src/statics/images/piso/singola_armadio.jpg new file mode 100644 index 0000000..0ef43ee Binary files /dev/null and b/src/statics/images/piso/singola_armadio.jpg differ diff --git a/src/statics/images/piso/singola_finestra.jpg b/src/statics/images/piso/singola_finestra.jpg new file mode 100644 index 0000000..611770d Binary files /dev/null and b/src/statics/images/piso/singola_finestra.jpg differ diff --git a/src/statics/images/piso/singola_scrivania.jpg b/src/statics/images/piso/singola_scrivania.jpg new file mode 100644 index 0000000..65a541d Binary files /dev/null and b/src/statics/images/piso/singola_scrivania.jpg differ diff --git a/src/statics/images/piso/tavolo_sala.jpg b/src/statics/images/piso/tavolo_sala.jpg new file mode 100644 index 0000000..13cb0de Binary files /dev/null and b/src/statics/images/piso/tavolo_sala.jpg differ diff --git a/src/statics/images/piso/televisore.jpg b/src/statics/images/piso/televisore.jpg new file mode 100644 index 0000000..ea186c4 Binary files /dev/null and b/src/statics/images/piso/televisore.jpg differ diff --git a/src/statics/images/piso/terrazza.jpg b/src/statics/images/piso/terrazza.jpg new file mode 100644 index 0000000..05b0dbd Binary files /dev/null and b/src/statics/images/piso/terrazza.jpg differ diff --git a/src/store/Api/index.ts b/src/store/Api/index.ts index c3b1381..765458d 100644 --- a/src/store/Api/index.ts +++ b/src/store/Api/index.ts @@ -156,12 +156,19 @@ export namespace ApiTool { // console.log('A1) INIZIO.............................................................') return globalroutines(null, 'readall', tablesync, null) .then((alldata) => { - const myrecs = [...alldata] + + let myrecs + + if (alldata === undefined) { + console.log('alldata NON DEFINITA') + return true + } else { + myrecs = [...alldata] + } const promises = myrecs.map((rec) => { let link = '/' + ApiTables.getLinkByTableName(nametab) - if (method !== 'POST') { link += '/' + rec._id } @@ -185,6 +192,9 @@ export namespace ApiTool { } } console.log(' [Alternative] !!!!!!!!!!!!!!! Error while sending data', err, errorfromserver, 'lettoqualcosa', lettoqualcosa) + if (!errorfromserver) { + return globalroutines(null, 'delete', 'swmsg', null, mystrparam) + } }) }) @@ -195,11 +205,11 @@ export namespace ApiTool { return (errorfromserver && !lettoqualcosa) }) - }).catch((e) => { + }).catch((error) => { + console.log('¨¨¨¨¨¨¨¨¨¨¨¨¨¨ errorfromserver:', errorfromserver, error) return (errorfromserver && !lettoqualcosa) }) .then((error) => { - console.log('¨¨¨¨¨¨¨¨¨¨¨¨¨¨ errorfromserver:', errorfromserver, error) const mystate = (error || errorfromserver) ? 'offline' : 'online' GlobalStore.mutations.setStateConnection(mystate) GlobalStore.mutations.saveConfig( { _id: costanti.CONFIG_ID_STATE_CONN, value: mystate }) diff --git a/src/store/Modules/ApiTables.ts b/src/store/Modules/ApiTables.ts index 9fbd41e..971258d 100644 --- a/src/store/Modules/ApiTables.ts +++ b/src/store/Modules/ApiTables.ts @@ -17,7 +17,7 @@ export function getLinkByTableName(nametable) { } } -export const LIST_START = '0' +export const LIST_START = null export const DB = { CMD_SYNC: 'sync', @@ -432,5 +432,5 @@ export function table_DeleteRecord(nametable, myobjtrov, id) { // 3) Delete from the Server (call) Sync_DeleteItem(nametable, myobjtrov, id) - + } diff --git a/src/store/Modules/GlobalStore.ts b/src/store/Modules/GlobalStore.ts index ebd4c62..ff6d237 100644 --- a/src/store/Modules/GlobalStore.ts +++ b/src/store/Modules/GlobalStore.ts @@ -127,17 +127,29 @@ namespace Getters { }) - const arrlistaproj = Projects.getters.listaprojects() - const listaprojects = [] + const arrlistaprojtutti = Projects.getters.listaprojects(false) + const arrlistaprojmiei = Projects.getters.listaprojects(true) + const listaprojectstutti = [] + const listaprojectsmiei = [] - for (const elem of arrlistaproj) { + for (const elem of arrlistaprojtutti) { const item = { materialIcon: 'next_week', name: elem.nametranslate, text: elem.description, - route: '/projects/' + elem.idelem + route: tools.getUrlByTipoProj(false) + elem.idelem } - listaprojects.push(item) + listaprojectstutti.push(item) + } + + for (const elem of arrlistaprojmiei) { + const item = { + materialIcon: 'next_week', + name: elem.nametranslate, + text: elem.description, + route: tools.getUrlByTipoProj(true) + elem.idelem + } + listaprojectsmiei.push(item) } const arrroutes: IListRoutes[] = [] @@ -151,8 +163,14 @@ namespace Getters { level_child: 0.5 }) - addRoute(arrroutes,{ route: '/projects/' + process.env.PROJECT_ID_MAIN, faIcon: 'fa fa-list-alt', materialIcon: 'next_week', name: 'pages.Projects', - routes2: listaprojects, + addRoute(arrroutes,{ route: tools.getUrlByTipoProj(false) + process.env.PROJECT_ID_MAIN, faIcon: 'fa fa-list-alt', materialIcon: 'next_week', name: 'pages.Projects', + routes2: listaprojectstutti, + level_parent: 0, + level_child: 0.5 + }) + + addRoute(arrroutes,{ route: tools.getUrlByTipoProj(true) + process.env.PROJECT_ID_MAIN, faIcon: 'fa fa-list-alt', materialIcon: 'next_week', name: 'pages.MyProjects', + routes2: listaprojectsmiei, level_parent: 0, level_child: 0.5 }) @@ -178,6 +196,20 @@ namespace Getters { }, 'getmenu') + const t = b.read((state) => (params) => { + const msg = params.split('.') + const lang = UserStore.state.lang + + const stringa = messages[lang] + + let ris = stringa + msg.forEach((param) => { + ris = ris[param] + }) + + return ris + }, 't') + export const getters = { get testpao1_getter_contatore() { return testpao1_getter_contatore() @@ -213,6 +245,10 @@ namespace Getters { return getmenu() }, + get t() { + return t() + }, + get isOnline() { // console.log('*********************** isOnline') return state.stateConnection === 'online' @@ -415,20 +451,6 @@ namespace Actions { } - function t(params) { - const msg = params.split('.') - const lang = UserStore.state.lang - - const stringa = messages[lang] - - let ris = stringa - msg.forEach((param) => { - ris = ris[param] - }) - - return ris - } - function prova(context) { // console.log('prova') // state.testp1.mioarray[state.testp1.mioarray.length - 1].valore = 'VALMODIF'; diff --git a/src/store/Modules/Projects.ts b/src/store/Modules/Projects.ts index 72ccedf..5833a6f 100644 --- a/src/store/Modules/Projects.ts +++ b/src/store/Modules/Projects.ts @@ -1,4 +1,5 @@ import { IProject, IProjectsState, IDrag, IMenuList } from 'model' +import { Privacy } from '@src/model' import { storeBuilder } from './Store/Store' import Api from '@api' @@ -20,7 +21,10 @@ const stateglob: IProjectsState = { visuLastCompleted: 10 } -const listFieldsToChange: string [] = ['descr', 'longdescr', 'hoursplanned', 'hoursworked', 'id_parent', 'statusproj', 'category', 'expiring_at', 'priority', 'id_prev', 'pos', 'enableExpiring', 'progressCalc', 'live_url', 'test_url', 'begin_development', 'begin_test', 'actualphase', 'totalphases', 'hoursweeky_plannedtowork', 'endwork_estimate'] +const listFieldsToChange: string [] = ['descr', 'longdescr', 'hoursplanned', 'hoursworked', 'id_parent', 'statusproj', + 'category', 'expiring_at', 'priority', 'id_prev', 'pos', 'enableExpiring', 'progressCalc', 'live_url', 'test_url', + 'begin_development', 'begin_test', 'actualphase', 'totalphases', 'hoursweeky_plannedtowork', 'endwork_estimate', + 'privacyread', 'privacywrite', 'id_main_project', 'typeproj'] const listFieldsUpdateCalculation: string [] = ['hoursplanned', 'hoursworked', 'progressCalc', 'endwork_estimate'] @@ -43,8 +47,16 @@ function initcat() { function updateDataCalculated(projout, projin) { listFieldsUpdateCalculation.forEach((field) => { - projout[field] = projin[field]; - }); + projout[field] = projin[field] + }) +} + +function getproj(projects, idproj, miei: boolean) { + if (miei) { + return tools.mapSort(projects.filter((proj) => (proj.id_parent === idproj) && proj.userId === UserStore.state.userId)) + } else { + return tools.mapSort(projects.filter((proj) => (proj.id_parent === idproj) && proj.userId !== UserStore.state.userId )) + } } namespace Getters { @@ -56,7 +68,9 @@ namespace Getters { _id: objectId(), descr: '', longdescr: '', + typeproj: 0, id_parent: '', + id_main_project: '', priority: tools.Priority.PRIORITY_NORMAL, statusproj: tools.Status.OPENED, created_at: tools.getDateNow(), @@ -75,6 +89,8 @@ namespace Getters { hoursworked: 0, hoursplanned: 0, progressCalc: 0, + privacyread: 'onlyme', + privacywrite: 'onlyme', begin_development: tools.getDateNull(), begin_test: tools.getDateNull(), hoursweeky_plannedtowork: 0, @@ -84,23 +100,25 @@ namespace Getters { return obj }, 'getRecordEmpty') - const items_dacompletare = b.read((state: IProjectsState) => (id_parent: string): IProject[] => { + const projs_dacompletare = b.read((state: IProjectsState) => (id_parent: string, miei: boolean): IProject[] => { + // console.log('projs_dacompletare', miei) if (state.projects) { // console.log('state.projects', state.projects) - return tools.mapSort(state.projects.filter((proj) => proj.id_parent === id_parent)) + return getproj(state.projects, id_parent, miei) } else { return [] } - }, 'items_dacompletare') + }, 'projs_dacompletare') - const listaprojects = b.read((state: IProjectsState) => (): IMenuList[] => { + const listaprojects = b.read((state: IProjectsState) => (miei: boolean): IMenuList[] => { if (state.projects) { // console.log('state.projects', state.projects) - const listaproj = tools.mapSort(state.projects.filter((proj) => proj.id_parent === process.env.PROJECT_ID_MAIN)) + const listaproj = getproj(state.projects, process.env.PROJECT_ID_MAIN, miei) const myarr: IMenuList[] = [] for (const proj of listaproj) { myarr.push({ nametranslate: '', description: proj.descr, idelem: proj._id }) } + console.log(' myarr', myarr, listaproj) return myarr } else { @@ -120,17 +138,6 @@ namespace Getters { return '' }, 'getDescrById') - const getParentById = b.read((state: IProjectsState) => (id: string): string => { - if (state.projects) { - const itemfound = state.projects.find((item) => item._id === id) - if (!!itemfound) { - return itemfound.id_parent - } - } - - return '' - }, 'getParentById') - const getRecordById = b.read((state: IProjectsState) => (id: string): IProject => { if (state.projects) { return state.projects.find((item) => item._id === id) @@ -138,12 +145,49 @@ namespace Getters { return null }, 'getRecordById') + const getifCanISeeProj = b.read((state: IProjectsState) => (proj: IProject): boolean => { + if (proj === undefined) + return false + + if (!!UserStore.state) { + + if (UserStore.state.userId === proj.userId) // If it's the owner + return true + + return (proj.privacyread === Privacy.all) || + (proj.privacyread === Privacy.friends) && (UserStore.getters.IsMyFriend(proj.userId)) + || ((proj.privacyread === Privacy.mygroup) && (UserStore.getters.IsMyGroup(proj.userId))) + } else { + return false + } + + }, 'getifCanISeeProj') + + const CanIModifyPanelPrivacy = b.read((state: IProjectsState) => (proj: IProject): boolean => { + if (proj === undefined) + return false + + if (!!UserStore) { + if (!!UserStore.state) + return ((UserStore.state.userId === proj.userId) || (proj.privacywrite === Privacy.all)) // If it's the owner + else + return false + } + return false + }, 'CanIModifyPanelPrivacy') + export const getters = { + get getifCanISeeProj() { + return getifCanISeeProj() + }, + get CanIModifyPanelPrivacy() { + return CanIModifyPanelPrivacy() + }, get getRecordEmpty() { return getRecordEmpty() }, - get items_dacompletare() { - return items_dacompletare() + get projs_dacompletare() { + return projs_dacompletare() }, get listaprojects() { return listaprojects() @@ -151,13 +195,9 @@ namespace Getters { get getDescrById() { return getDescrById() }, - get getParentById() { - return getParentById() - }, get getRecordById() { return getRecordById() } - } } @@ -219,9 +259,9 @@ namespace Actions { } } - if (UserStore.state.userId === '') { - return false // Login not made - } + // if (UserStore.state.userId === '') { + // return false // Login not made + // } console.log('dbLoad', nametable, checkPending, 'userid=', UserStore.state.userId) @@ -282,6 +322,8 @@ namespace Actions { objproj.descr = myobj.descr objproj.category = myobj.category objproj.id_parent = myobj.id_parent + objproj.id_main_project = myobj.id_main_project + objproj.typeproj = myobj.typeproj let elemtochange: IProject = null @@ -329,7 +371,7 @@ namespace Actions { async function swapElems(context, itemdragend: IDrag) { console.log('PROJECT swapElems', itemdragend, stateglob.projects) - const myarr = Getters.getters.items_dacompletare(itemdragend.id_proj) + const myarr = Getters.getters.projs_dacompletare(itemdragend.id_proj, itemdragend.mieiproj) tools.swapGeneralElem(nametable, myarr, itemdragend, listFieldsToChange) diff --git a/src/store/Modules/Todos.ts b/src/store/Modules/Todos.ts index a4d97cc..5f8ff37 100644 --- a/src/store/Modules/Todos.ts +++ b/src/store/Modules/Todos.ts @@ -1,4 +1,4 @@ -import { ITodo, ITodosState, IParamTodo, IDrag, IProjectsState, IProject } from 'model' +import { ITodo, ITodosState, IParamTodo, IDrag, IProjectsState, IProject, Privacy } from 'model' import { storeBuilder } from './Store/Store' import Api from '@api' @@ -88,6 +88,7 @@ namespace Getters { }, 'getRecordEmpty') const items_dacompletare = b.read((state: ITodosState) => (cat: string): ITodo[] => { const indcat = getindexbycategory(cat) + // console.log('items_dacompletare', 'indcat', indcat, state.todos[indcat]) if (state.todos[indcat]) { return state.todos[indcat].filter((todo) => todo.statustodo !== tools.Status.COMPLETED) } else { diff --git a/src/store/Modules/UserStore.ts b/src/store/Modules/UserStore.ts index 498d2d7..df997da 100644 --- a/src/store/Modules/UserStore.ts +++ b/src/store/Modules/UserStore.ts @@ -67,6 +67,18 @@ namespace Getters { return state.servercode }, 'getServerCode') + const IsMyFriend = b.read((state) => (userIdOwner) => { + // ++TODO Check if userIdOwner is my friend + // userIdOwner is my friend ? + return true + }, 'IsMyFriend') + + const IsMyGroup = b.read((state) => (userIdOwner) => { + // ++TODO Check if userIdOwner is on my groups + // userIdOwner is on my groups ? + return true + }, 'IsMyGroup') + export const getters = { get lang() { return lang() @@ -80,6 +92,12 @@ namespace Getters { get getServerCode() { return getServerCode() }, + get IsMyFriend() { + return IsMyFriend() + }, + get IsMyGroup() { + return IsMyGroup() + } // get fullName() { return fullName();}, } @@ -492,13 +510,15 @@ namespace Actions { // this.$router.push('/signin') } - async function setGlobal(loggedWithNetwork: boolean) { + async function setGlobal(isLogged: boolean) { state.isLogged = true console.log('state.isLogged') - GlobalStore.mutations.setleftDrawerOpen(localStorage.getItem(tools.localStorage.leftDrawerOpen) === 'true') - GlobalStore.mutations.setCategorySel(localStorage.getItem(tools.localStorage.categorySel)) + if (isLogged) { + GlobalStore.mutations.setleftDrawerOpen(localStorage.getItem(tools.localStorage.leftDrawerOpen) === 'true') + GlobalStore.mutations.setCategorySel(localStorage.getItem(tools.localStorage.categorySel)) - GlobalStore.actions.checkUpdates() + GlobalStore.actions.checkUpdates() + } await GlobalStore.actions.loadAfterLogin() .then(() => { @@ -512,36 +532,37 @@ namespace Actions { console.log('*** autologin_FromLocalStorage ***') // INIT + let isLogged = false + UserStore.state.lang = tools.getItemLS(tools.localStorage.lang) const token = localStorage.getItem(tools.localStorage.token) - if (!token) { - return false + if (token) { + const expirationDateStr = localStorage.getItem(tools.localStorage.expirationDate) + const expirationDate = new Date(String(expirationDateStr)) + const now = tools.getDateNow() + if (now < expirationDate) { + const userId = String(localStorage.getItem(tools.localStorage.userId)) + const username = String(localStorage.getItem(tools.localStorage.username)) + const verified_email = localStorage.getItem(tools.localStorage.verified_email) === 'true' + + GlobalStore.state.wasAlreadySubOnDb = localStorage.getItem(tools.localStorage.wasAlreadySubOnDb) === 'true' + + console.log('************* autologin userId', userId) + + UserStore.mutations.setAuth(token) + + Mutations.mutations.authUser({ + userId, + username, + verified_email + }) + + isLogged = true + } } - const expirationDateStr = localStorage.getItem(tools.localStorage.expirationDate) - const expirationDate = new Date(String(expirationDateStr)) - const now = tools.getDateNow() - if (now >= expirationDate) { - console.log('!!! Login Expired') - return false - } - const userId = String(localStorage.getItem(tools.localStorage.userId)) - const username = String(localStorage.getItem(tools.localStorage.username)) - const verified_email = localStorage.getItem(tools.localStorage.verified_email) === 'true' - GlobalStore.state.wasAlreadySubOnDb = localStorage.getItem(tools.localStorage.wasAlreadySubOnDb) === 'true' - - console.log('************* autologin userId', userId) - - UserStore.mutations.setAuth(token) - - Mutations.mutations.authUser({ - userId, - username, - verified_email - }) - - await setGlobal(false) + await setGlobal(isLogged) console.log('autologin userId STATE ', state.userId) diff --git a/src/store/Modules/tools.ts b/src/store/Modules/tools.ts index 7aab703..af40024 100644 --- a/src/store/Modules/tools.ts +++ b/src/store/Modules/tools.ts @@ -3,7 +3,7 @@ import globalroutines from './../../globalroutines/index' import { costanti } from './costanti' import { translation } from './translation' import Quasar, { date } from 'quasar' -import { IProject, ITodo } from '@src/model' +import { IProject, ITodo, Privacy } from '@src/model' import * as ApiTables from '@src/store/Modules/ApiTables' import translate from '@src/globalroutines/util' @@ -136,8 +136,77 @@ export const tools = { value: 3 } ] - }, + + selectPrivacy: { + it: [ + { + id: 1, + label: translation.it.privacy.all, + value: Privacy.all + }, + { + id: 2, + label: translation.it.privacy.friends, + value: Privacy.friends + }, + { + id: 3, + label: translation.it.privacy.mygroup, + value: Privacy.mygroup + }, + { + id: 4, + label: translation.it.privacy.onlyme, + value: Privacy.onlyme + } + ], + es: [ + { + id: 1, + label: translation.es.privacy.all, + value: Privacy.all + }, + { + id: 2, + label: translation.es.privacy.friends, + value: Privacy.friends + }, + { + id: 3, + label: translation.es.privacy.mygroup, + value: Privacy.mygroup + }, + { + id: 4, + label: translation.es.privacy.onlyme, + value: Privacy.onlyme + } + ], + enUs: [ + { + id: 1, + label: translation.enUs.privacy.all, + value: Privacy.all + }, + { + id: 2, + label: translation.enUs.privacy.friends, + value: Privacy.friends + }, + { + id: 3, + label: translation.enUs.privacy.mygroup, + value: Privacy.mygroup + }, + { + id: 4, + label: translation.enUs.privacy.onlyme, + value: Privacy.onlyme + } + ] + }, + selectStatus: { it: [ { @@ -514,13 +583,13 @@ export const tools = { it: [ { id: 5, - label: 'Nuovo Progetto', + label: translation.it.proj.newsubproj, value: 200, // ADD_PROJECT icon: 'next_week' }, { id: 10, - label: 'Mostra Task', + label: translation.it.task.showtask, value: 150, // SHOW_TASK icon: 'rowing' } @@ -529,13 +598,13 @@ export const tools = { [ { id: 5, - label: 'Nuevo Projecto', + label: translation.es.proj.newsubproj, value: 200, // ADD_PROJECT icon: 'next_week' }, { id: 10, - label: 'Mostrar Tareas', + label: translation.es.task.showtask, value: 150, icon: 'rowing' } @@ -544,19 +613,47 @@ export const tools = { [ { id: 5, - label: 'New Project', + label: translation.it.proj.newsubproj, value: 200, // ADD_PROJECT icon: 'next_week' }, { id: 10, - label: 'Show Task', + label: translation.enUs.task.showtask, value: 150, icon: 'rowing' } ] - } - , + }, + + menuPopupConfigMAINProject: { + it: [ + { + id: 5, + label: translation.it.proj.newproj, + value: 200, // ADD_PROJECT + icon: 'next_week' + } + ], + es: + [ + { + id: 5, + label: translation.es.proj.newproj, + value: 200, // ADD_PROJECT + icon: 'next_week' + } + ], + enUs: + [ + { + id: 5, + label: translation.it.proj.newproj, + value: 200, // ADD_PROJECT + icon: 'next_week' + } + ] + }, listOptionShowTask: { it: [ @@ -866,29 +963,28 @@ export const tools = { , getIndexById(myarr, id) { + if (myarr === undefined) + return -1 return myarr.indexOf(tools.getElemById(myarr, id)) } , getElemById(myarr, id) { + if (myarr === undefined) + return null // console.log('getElemById', myarr, id) return myarr.find((elem) => elem._id === id) } , getElemPrevById(myarr, id) { + if (myarr === undefined) + return null return myarr.find((elem) => elem.id_prev === id) } , - getLastFirstElemPriority(myarr, priority - : - number, atfirst - : - boolean, escludiId - : - string - ) { + getLastFirstElemPriority(myarr, priority: number, atfirst: boolean, escludiId: string) { if (myarr === null) { return -1 } @@ -955,9 +1051,13 @@ export const tools = { } , - getLastListNotCompleted(nametable, cat) { - const module = tools.getModulesByTable(nametable) - const arr = module.getters.items_dacompletare(cat) + getLastListNotCompleted(nametable, cat, isproj = false, miei = false) { + // const module = tools.getModulesByTable(nametable) + let arr = [] + if (nametable === 'projects') + arr = Projects.getters.projs_dacompletare(cat, miei) + else if (nametable === 'todos') + arr = Todos.getters.items_dacompletare(cat) return (arr.length > 0) ? arr[arr.length - 1] : null } @@ -1175,9 +1275,10 @@ export const tools = { if (sortedList.length < linkedList.length) { console.log('!!!!! NON CI SONO TUTTI !!!!!', sortedList.length, linkedList.length) // Forget something not in a List ! - for (const itemsorted of sortedList) { - if (linkedList.filter((item) => item._id === itemsorted._id)) { - + for (const itemlinked of linkedList) { + const elemtrov = sortedList.find((item) => item._id === itemlinked._id) + if (elemtrov === undefined) { + sortedList.push(itemlinked) } } } @@ -1211,7 +1312,7 @@ export const tools = { , getstrDate(mytimestamp) { - console.log('getstrDate', mytimestamp) + // console.log('getstrDate', mytimestamp) if (!!mytimestamp) return date.formatDate(mytimestamp, 'DD/MM/YYYY') else @@ -1270,5 +1371,15 @@ export const tools = { return new Date().valueOf() }, + isMainProject(idproj) { + return idproj === process.env.PROJECT_ID_MAIN + }, + + getUrlByTipoProj(miei) { + if (miei) + return '/myprojects/' + else + return '/projects/' + } } diff --git a/src/store/Modules/translation.ts b/src/store/Modules/translation.ts index 8a9661c..b848c80 100644 --- a/src/store/Modules/translation.ts +++ b/src/store/Modules/translation.ts @@ -1,14 +1,53 @@ export const translation = { it: { fase: 'Fase', + privacy: { + all: 'Tutti', + friends: 'Amici', + mygroup: 'Gruppo', + onlyme: 'Solo io' + }, + proj: { + newproj: 'Nuovo Progetto', + newsubproj: 'Nuovo Sotto-Progetto', + }, + task: { + showtask: 'Mostra Task', + }, end: '' }, es: { fase: 'Fase', + privacy: { + all: 'Todos', + friends: 'Amigos', + mygroup: 'Grupos', + onlyme: 'Solo yo' + }, + proj: { + newproj: 'Nuevo Projecto', + newsubproj: 'Nuevo Sub-Projecto', + }, + task: { + showtask: 'Mostrar Tarea', + }, end: '' }, enUs: { fase: 'Phase', + privacy: { + all: 'All', + friends: 'Friends', + mygroup: 'Group', + onlyme: 'Only me' + }, + proj: { + newproj: 'New Project', + newsubproj: 'New Sub-Project', + }, + task: { + showtask: 'Show Task', + }, end: '' } } diff --git a/src/views/offline/offline.ts b/src/views/offline/offline.ts index 690e1a5..ca642c9 100644 --- a/src/views/offline/offline.ts +++ b/src/views/offline/offline.ts @@ -5,6 +5,6 @@ import { Component } from 'vue-property-decorator' }) export default class Offline extends Vue { get logoimg() { - return '/statics/images/' + process.env.LOGO_REG + return 'º' + process.env.LOGO_REG } } diff --git a/src/views/projects/proj-list/proj-list.ts b/src/views/projects/proj-list/proj-list.ts index 9430c98..a05bd2f 100644 --- a/src/views/projects/proj-list/proj-list.ts +++ b/src/views/projects/proj-list/proj-list.ts @@ -1,7 +1,7 @@ import Vue from 'vue' import { Component, Watch } from 'vue-property-decorator' -import { IDrag, IProject, IProjectsState, ITodo } from '../../../model/index' +import { IDrag, IProject, IProjectsState, ITodo, Privacy, TypeProj } from '../../../model/index' import { SingleProject } from '../../../components/projects/SingleProject/index' import { CTodo } from '../../../components/todos/CTodo' @@ -16,6 +16,7 @@ import { Getter } from 'vuex-class' import { date, Screen } from 'quasar' import { CProgress } from '../../../components/CProgress' import { CDate } from '../../../components/CDate' +import { RouteNames } from '@src/router/route-names' const namespace: string = 'Projects' @@ -41,9 +42,9 @@ export default class ProjList extends Vue { public scrollable = true public dragname: string = 'second' public idProjAtt: string = process.env.PROJECT_ID_MAIN - public idProjParentAtt: string = '' public splitterModel = 50 // start at 50% public itemproj: IProject = null + public itemprojparent: IProject = null public idsel: string = '' public itemselproj: IProject = Projects.getters.getRecordEmpty() public itemtodosel: ITodo = Todos.getters.getRecordEmpty() @@ -53,24 +54,30 @@ export default class ProjList extends Vue { public selectStatus: [] = tools.selectStatus[UserStore.state.lang] public selectPhase: [] = tools.selectPhase[UserStore.state.lang] + public selectPrivacy: [] = tools.selectPrivacy[UserStore.state.lang] public $refs: { singleproject: SingleProject[], ctodo: CTodo } - @Getter('items_dacompletare', { namespace }) - public items_dacompletare: (state: IProjectsState, id_parent: string) => IProject[] + @Getter('projs_dacompletare', { namespace }) + public projs_dacompletare: (state: IProjectsState, id_parent: string, miei: boolean) => IProject[] - @Watch('items_dacompletare') + @Watch('projs_dacompletare') public changeitems() { - this.idProjParentAtt = Projects.getters.getParentById(this.idProjAtt) + this.updateindexProj() + } + + @Watch('$route.name') + public changename() { + console.log('tools.getUrlByTipoProj(this.areMyProjects)', tools.getUrlByTipoProj(this.areMyProjects)) } @Watch('$route.params.idProj') public changeparent() { this.idProjAtt = this.$route.params.idProj - this.idProjParentAtt = Projects.getters.getParentById(this.idProjAtt) + this.updateindexProj() this.selproj() } @@ -79,25 +86,51 @@ export default class ProjList extends Vue { this.updateclasses() } - get getidProjParentAtt() { - return this.idProjParentAtt + private updateindexProj() { + // console.log('idProjAtt', this.idProjAtt) + this.itemproj = Projects.getters.getRecordById(this.idProjAtt) + if (!!this.itemproj) { + this.itemprojparent = Projects.getters.getRecordById(this.itemproj.id_parent) + console.log('this.itemproj.descr', this.itemproj.descr) + } + // console.log('idproj', this.idProjAtt, 'params' , this.$route.params) } - // I use this because the statustodo will disappear from the UI, so it won't call the status changed... - // in this case I need to call manually the modify. - public modifyfieldtodo(field) { - console.log('modifyfieldtodo', field) - Todos.actions.modify({ myitem: this.itemtodosel, field }) + get areMyProjects() { + console.log('this.$route.name', this.$route.name) + return this.$route.name === RouteNames.myprojects + } + + get readonly_PanelPrivacy() { + return !this.CanIModifyPanelPrivacy + } + + get readonly_PanelPrivacySel() { + return !this.CanIModifyPanelPrivacySel + } + + get CanISeeProject() { + return Projects.getters.getifCanISeeProj(this.itemproj) + } + + get CanISeeProjectParent() { + return Projects.getters.getifCanISeeProj(this.itemprojparent) + } + + get CanISeeProjectSel() { + return Projects.getters.getifCanISeeProj(this.itemselproj) + } + + get CanIModifyPanelPrivacy() { + return Projects.getters.CanIModifyPanelPrivacy(this.itemproj) + } + + get CanIModifyPanelPrivacySel() { + return Projects.getters.CanIModifyPanelPrivacy(this.itemselproj) } get getrouteup() { - return '/projects/' + this.idProjParentAtt - } - - public selproj() { - this.deselectAllRowsproj(null, false, false) - this.deselectAllRowstodo(null, false, false) - this.setidsel(this.idProjAtt) + return tools.getUrlByTipoProj(this.areMyProjects) + this.itemproj.id_parent } get tools() { @@ -113,8 +146,26 @@ export default class ProjList extends Vue { GlobalStore.mutations.setShowType(value) } + get isRootProject() { + return this.idProjAtt === process.env.PROJECT_ID_MAIN + } + + get getIdParent() { + if (!!this.itemproj) + return this.itemproj.id_parent + else + return '' + } + + get isMainProject() { + return tools.isMainProject(this.idProjAtt) + } + get menuPopupConfigProject() { - return tools.menuPopupConfigProject[UserStore.state.lang] + if (this.isMainProject) + return tools.menuPopupConfigMAINProject[UserStore.state.lang] + else + return tools.menuPopupConfigProject[UserStore.state.lang] } get listOptionShowTask() { @@ -125,11 +176,89 @@ export default class ProjList extends Vue { return Projects.getters.getDescrById(this.idProjAtt) } + get getCalcHoursWorked() { + + if (this.itemselproj.hoursplanned <= 0) { + return 0 + } + return Math.round(this.itemselproj.hoursworked / this.itemselproj.hoursplanned * 100) + + } + + get calcprogressWeekly() { + + if (this.itemselproj.hoursplanned <= 0) { + return 0 + } + return Math.round(this.itemselproj.hoursworked / this.itemselproj.hoursplanned * 100) + } + + get calcEndWork_Estimate() { + if (date.isValid(this.itemselproj.begin_development) && (this.itemselproj.hoursweeky_plannedtowork > 0)) { + const hoursw = this.itemselproj.hoursweeky_plannedtowork + + try { + + let orerimaste = this.itemselproj.hoursplanned - this.itemselproj.hoursworked + if (orerimaste < 0) { + orerimaste = 0 + } + + const weeks = orerimaste / hoursw + const days = Math.round(weeks * 7) + + let mydate = this.itemselproj.begin_development + const datenow = tools.getDateNow() + // if begin is in the past, take the day now + if (date.getDateDiff(mydate, datenow) < 0) { + mydate = datenow + } + console.log('mydate', mydate) + this.itemselproj.endwork_estimate = date.addToDate(mydate, { days }) + + console.log(' days', days, 'weeks', weeks, 'orerimaste', orerimaste, 'dateestimated', this.itemselproj.endwork_estimate) + + return this.itemselproj.endwork_estimate + }catch (e) { + this.itemselproj.endwork_estimate = tools.getDateNull() + } + + return tools.getDateNull() + + } else { + return tools.getDateNull() + } + } + + get getCalcTodoHoursWorked() { + if (this.itemtodosel.hoursplanned <= 0) { + return 0 + } + const myperc = Math.round(this.itemtodosel.hoursworked / this.itemtodosel.hoursplanned * 100) + + return myperc + + } + + // I use this because the statustodo will disappear from the UI, so it won't call the status changed... + // in this case I need to call manually the modify. + public modifyfieldtodo(field) { + console.log('modifyfieldtodo', field) + Todos.actions.modify({ myitem: this.itemtodosel, field }) + } + + public selproj() { + this.deselectAllRowsproj(null, false, false) + this.deselectAllRowstodo(null, false, false) + this.setidsel(this.idProjAtt) + } + public showTask(field_value) { return field_value === tools.MenuAction.SHOW_TASK } public async onEndproj(itemdragend) { + console.log('onEndproj...') await Projects.actions.swapElems(itemdragend) } @@ -141,15 +270,19 @@ export default class ProjList extends Vue { $service.eventBus.$on('dragend', (args) => { - const itemdragend: IDrag = { - field: '', - id_proj: this.idProjAtt, - newIndex: this.getElementIndex(args.el), - oldIndex: this.getElementOldIndex(args.el) - } + // console.log('args proj-list', args) + if (args.name === this.dragname) { + const itemdragend: IDrag = { + field: '', + id_proj: this.idProjAtt, + newIndex: this.getElementIndex(args.el), + oldIndex: this.getElementOldIndex(args.el), + mieiproj: this.areMyProjects + } - // console.log('args', args, itemdragend) - this.onEndproj(itemdragend) + // console.log('args', args, itemdragend) + this.onEndproj(itemdragend) + } }) $service.eventBus.$on('drag', (el, source) => { @@ -164,7 +297,8 @@ export default class ProjList extends Vue { public mounted() { - console.log('Screen.width', Screen.width) + // console.log('Screen.width', Screen.width) + // console.log('this.$route', this.$route) if (Screen.width < 400) { this.splitterModel = 100 @@ -172,9 +306,7 @@ export default class ProjList extends Vue { this.splitterModel = 50 } this.idProjAtt = this.$route.params.idProj - this.idProjParentAtt = Projects.getters.getParentById(this.idProjAtt) - - console.log('this.idProjParentAtt', this.idProjParentAtt, 'idproj', this.idProjAtt, 'params' , this.$route.params) + this.updateindexProj() tools.touchmove(this.scrollable) } @@ -183,12 +315,9 @@ export default class ProjList extends Vue { console.log('LOAD PROJECTS....') if (!!this.$route.params.idProj) { this.idProjAtt = this.$route.params.idProj - this.idProjParentAtt = Projects.getters.getParentById(this.idProjAtt) - this.itemproj = Projects.getters.getRecordById(this.idProjAtt) + this.updateindexProj() } - // console.log('this.idProjAtt', this.idProjAtt, this.idProjParentAtt) - // Set last category selected // localStorage.setItem(tools.localStorage.categorySel, this.categoryAtt) @@ -207,7 +336,7 @@ export default class ProjList extends Vue { } public mydeleteitemproj(idobj: string) { - // console.log('mydeleteitemtodo', idobj) + console.log('mydeleteitemtodo', idobj) return Projects.actions.deleteItem({ idobj }) } @@ -249,6 +378,20 @@ export default class ProjList extends Vue { id_parent: this.idProjAtt } + if (this.itemproj === undefined) + this.itemproj = Projects.getters.getRecordById(this.idProjAtt) + + if (this.isRootProject) { + myobj.typeproj = TypeProj.TYPE_PROJECT + myobj.id_main_project = this.idProjAtt + } else { + myobj.typeproj = TypeProj.TYPE_SUBDIR + if (this.itemproj.id_main_project === process.env.PROJECT_ID_MAIN) + myobj.id_main_project = this.itemproj._id + else + myobj.id_main_project = this.itemproj.id_main_project + } + if (!tools.checkIfUserExist(this)) { return } @@ -279,7 +422,9 @@ export default class ProjList extends Vue { } public deselectAllRowstodo(item: ITodo, check, onlythis: boolean = false) { - console.log('PROJ-LIST deselectAllRowstodo : ', item) + // console.log('PROJ-LIST deselectAllRowstodo : ', item) + + return false // @ts-ignore for (const i in this.$refs.ctodo.$refs.single) { @@ -340,54 +485,6 @@ export default class ProjList extends Vue { ApiTables.waitAndcheckPendingMsg() } - get getCalcHoursWorked() { - - if (this.itemselproj.hoursplanned <= 0) { - return 0 - } - return Math.round(this.itemselproj.hoursworked / this.itemselproj.hoursplanned * 100) - - } - - get calcprogressWeekly() { - - if (this.itemselproj.hoursplanned <= 0) { - return 0 - } - return Math.round(this.itemselproj.hoursworked / this.itemselproj.hoursplanned * 100) - } - - get calcEndWork_Estimate() { - if (date.isValid(this.itemselproj.begin_development) && (this.itemselproj.hoursweeky_plannedtowork > 0)) { - const hoursw = this.itemselproj.hoursweeky_plannedtowork - - try { - - let orerimaste = this.itemselproj.hoursplanned - this.itemselproj.hoursworked - if (orerimaste < 0) { - orerimaste = 0 - } - - const weeks = orerimaste / hoursw - const days = Math.round(weeks * 7) - - const mydate = this.itemselproj.begin_development - this.itemselproj.endwork_estimate = date.addToDate(mydate, { days }) - - console.log(' days', days, 'weeks', weeks, 'orerimaste', orerimaste, 'dateestimated', this.itemselproj.endwork_estimate) - - return this.itemselproj.endwork_estimate - }catch (e) { - this.itemselproj.endwork_estimate = tools.getDateNull() - } - - return tools.getDateNull() - - } else { - return tools.getDateNull() - } - } - private getElementIndex(el: any) { return [].slice.call(el.parentElement.children).indexOf(el) } @@ -396,14 +493,5 @@ export default class ProjList extends Vue { return parseInt(el.attributes.index.value, 10) } - get getCalcTodoHoursWorked() { - if (this.itemtodosel.hoursplanned <= 0) { - return 0 - } - const myperc = Math.round(this.itemtodosel.hoursworked / this.itemtodosel.hoursplanned * 100) - - return myperc - - } } diff --git a/src/views/projects/proj-list/proj-list.vue b/src/views/projects/proj-list/proj-list.vue index ada994e..69c4b6c 100644 --- a/src/views/projects/proj-list/proj-list.vue +++ b/src/views/projects/proj-list/proj-list.vue @@ -1,7 +1,6 @@ -