From f0f9c458a56fbd001afb9be8e12f3f5690dfc11d Mon Sep 17 00:00:00 2001
From: avele <34437766+avele@users.noreply.github.com>
Date: Sat, 13 Jul 2019 17:29:23 +0400
Subject: [PATCH] Front/fix/category sections enabling (#335)
* Formatting
* Category sections enabling fixes #317;
Warning when disabling editing secitons;
* Removed unused import
---
front/client/components/Category.vue | 1 +
front/client/components/CategoryInfoEdit.vue | 57 +++++++++++++------
front/client/components/CategoryItem.vue | 39 ++++++++++++-
.../client/components/CategoryItemSection.vue | 2 +-
.../client/components/CategoryItemTraits.vue | 18 +++---
front/client/store/modules/category.ts | 49 ++++++++++++++--
6 files changed, 134 insertions(+), 32 deletions(-)
diff --git a/front/client/components/Category.vue b/front/client/components/Category.vue
index 480bea3..0c6239e 100644
--- a/front/client/components/Category.vue
+++ b/front/client/components/Category.vue
@@ -30,6 +30,7 @@
:toc="value.toc"
:notes="value.notes"
:kind="value.kind"
+ :sections="category.sections"
/>
@@ -83,7 +86,6 @@
import Vue from 'vue'
import Component from 'vue-class-component'
import { Prop, Watch } from 'vue-property-decorator'
-import { CategoryStatus } from 'client/service/Category'
@Component
export default class CategoryInfoEdit extends Vue {
@@ -95,6 +97,13 @@ export default class CategoryInfoEdit extends Vue {
checkboxSections: any[] = []
isValid: boolean = false
+ // TODO replace ItemProsConsSection and other to constants
+ sectionDisableWarningAgreed = {
+ ItemProsConsSection: false,
+ ItemEcosystemSection: false,
+ ItemNotesSection: false
+ }
+
categoryStatuses = [
{ name: 'Complete', value: 'CategoryFinished' },
{ name: 'Work in progress', value: 'CategoryWIP' },
@@ -118,19 +127,35 @@ export default class CategoryInfoEdit extends Vue {
}
this.title = category.title
this.group = category.group
- this.checkboxSections = category.sections
+ this.checkboxSections = category.sections.slice()
this.categoryStatus = category.status
+ this.sectionDisableWarningAgreed = {
+ ItemProsConsSection: false,
+ ItemEcosystemSection: false,
+ ItemNotesSection: false
+ }
}
- transformCategoryStatus (status: string) {
- switch (status) {
- case CategoryStatus.finished:
- return 'Complete'
- case CategoryStatus.inProgress:
- return 'Work in progress'
- default:
- return 'Stub'
+ async updateSectionEnabling (sectionValue, sectionName) {
+ const index = this.checkboxSections.indexOf(sectionValue)
+ const isSectionRemoved = index !== -1
+ if (!isSectionRemoved) {
+ this.checkboxSections.push(sectionValue)
+ return
}
+
+ const isOriginallyEnabled = this.category.sections.includes(sectionValue)
+ const isSectionInEdit = this.$store.state.category.itemsSectionsInEdit[sectionValue].length
+ const wasAgreedOnce = this.sectionDisableWarningAgreed[sectionValue]
+ if (isOriginallyEnabled && isSectionInEdit && !wasAgreedOnce) {
+ const isConfirmed = await this._confirm({ fullText: `You have unsaved changes in one of items’ ${sectionName} section. If you disable this section, your changes will be lost.` })
+ if (!isConfirmed) {
+ return
+ }
+ this.sectionDisableWarningAgreed[sectionValue] = true
+ }
+
+ this.checkboxSections.splice(index, 1)
}
close () {
diff --git a/front/client/components/CategoryItem.vue b/front/client/components/CategoryItem.vue
index e27b0c0..a40c0d4 100644
--- a/front/client/components/CategoryItem.vue
+++ b/front/client/components/CategoryItem.vue
@@ -27,31 +27,40 @@
/>
-
+
import Vue from 'vue'
import Component from 'vue-class-component'
-import { Prop } from 'vue-property-decorator'
+import { Prop, Watch } from 'vue-property-decorator'
import { ICategoryItem } from 'client/service/CategoryItem.ts'
import CategoryItemToolbar from 'client/components/CategoryItemToolbar.vue'
import CategoryItemSection from 'client/components/CategoryItemSection.vue'
@@ -132,8 +141,26 @@ export default class CategoryItem extends Vue {
@Prop(String) itemUid!: string
@Prop(String) link!: string
@Prop(String) hackage!: string
+ @Prop(Array) sections!: string[]
isNoteExpanded: boolean = false
+ isPropsEditing: boolean = false
+ isConsEditing: boolean = false
+
+ get isAnyTraitEditing () {
+ return this.isPropsEditing || this.isConsEditing
+ }
+
+ @Watch('isAnyTraitEditing', { immediate: true })
+ updateItemTraitEditingState (newVal, prevVal) {
+ if (newVal !== prevVal) {
+ this.$store.dispatch('category/toggleItemProsConsSectionEdit', this.itemUid)
+ }
+ }
+
+ isSectionEnabled (section) {
+ return this.sections.includes(section)
+ }
expandNotes (): void {
this.isNoteExpanded = true
@@ -143,6 +170,14 @@ export default class CategoryItem extends Vue {
this.isNoteExpanded = false
}
+ toggleItemEcosystemEditState () {
+ this.$store.dispatch('category/toggleItemEcosystemSectionEdit', this.itemUid)
+ }
+
+ toggleItemNotesEditState () {
+ this.$store.dispatch('category/toggleItemNotesSectionEdit', this.itemUid)
+ }
+
@CatchConflictDecorator
async updateSummary ({ original, modified }): Promise {
await this.$store.dispatch('categoryItem/updateItemSummary', {
diff --git a/front/client/components/CategoryItemSection.vue b/front/client/components/CategoryItemSection.vue
index 20819b7..3a0cff8 100644
--- a/front/client/components/CategoryItemSection.vue
+++ b/front/client/components/CategoryItemSection.vue
@@ -64,8 +64,8 @@ export default class CategoryItemSection extends Vue {
isEdit: boolean = false
toggleEdit (): void {
+ this.$emit('toggleEdit')
if (this.customEdit) {
- this.$emit('toggleEdit')
return
}
this.isEdit = !this.isEdit
diff --git a/front/client/components/CategoryItemTraits.vue b/front/client/components/CategoryItemTraits.vue
index 19d80d5..fd2591a 100644
--- a/front/client/components/CategoryItemTraits.vue
+++ b/front/client/components/CategoryItemTraits.vue
@@ -118,27 +118,29 @@ export default class CategoryItemTraits extends Vue {
@Prop(Array) traits!: any[]
@Prop(String) type!: string
@Prop(String) itemId: string
+ @Prop(Boolean) isAnyTraitEditing: boolean
- isEdit: boolean = false
isAddTrait: boolean = false
traitsModel = []
get title () {
return this.type + 's'
}
+ get isAnyTraitEditingOrAdding () {
+ return this.traitsModel.some(x => x.isEdit) || this.isAddTrait
+ }
- @Watch('traits', {
- immediate: true
- })
+ @Watch('isAnyTraitEditingOrAdding', { immediate: true })
+ updateIsEditing (newVal) {
+ this.$emit('update:isAnyTraitEditing', newVal)
+ }
+
+ @Watch('traits', { immediate: true })
setTraitsModel (traits) {
this.traitsModel = _cloneDeep(traits)
this.traitsModel.forEach(x => this.$set(x, 'isEdit', false))
}
- toggleEdit () {
- this.isEdit = !this.isEdit
- }
-
@CatchConflictDecorator
async saveEdit ({ trait, original, modified }) {
await this.$store.dispatch('categoryItem/updateItemTrait', {
diff --git a/front/client/store/modules/category.ts b/front/client/store/modules/category.ts
index 0f8a216..0dc5fd5 100644
--- a/front/client/store/modules/category.ts
+++ b/front/client/store/modules/category.ts
@@ -1,14 +1,25 @@
import { ActionTree, GetterTree, MutationTree, ActionContext, Module } from 'vuex'
import { ICategoryInfo, ICategoryFull, CategoryService } from 'client/service/Category'
+import { ICategoryItem } from 'client/service/CategoryItem'
interface ICategoryState {
categoryList: ICategoryInfo[],
- category: ICategoryFull
+ category: ICategoryFull,
+ itemsSectionsInEdit: {
+ ItemProsConsSection: Array
+ ItemEcosystemSection: Array
+ ItemNotesSection: Array
+ }
}
const state = (): ICategoryState => ({
categoryList: [],
- category: null
+ category: null,
+ itemsSectionsInEdit: {
+ ItemProsConsSection: [],
+ ItemEcosystemSection: [],
+ ItemNotesSection: []
+ }
})
const getters: GetterTree = {}
@@ -44,15 +55,33 @@ const actions: ActionTree = {
dispatch('loadCategoryList')
return createdId
},
- async updateCategoryInfo (context: ActionContext, {id, title, group, status, sections}) {
- await CategoryService.updateCategoryInfo({id, title, group, status, sections})
+ async updateCategoryInfo (context: ActionContext, { id, title, group, status, sections }) {
+ await CategoryService.updateCategoryInfo({ id, title, group, status, sections })
},
async deleteCategory (
{ dispatch }: ActionContext,
id: ICategoryInfo['id']
): Promise {
await CategoryService.deleteCategory(id)
- }
+ },
+ toggleItemProsConsSectionEdit (
+ { commit }: ActionContext,
+ itemId: ICategoryItem['id']
+ ) {
+ commit('toggleSectionEditState', { sectionName: 'ItemProsConsSection', itemId })
+ },
+ toggleItemEcosystemSectionEdit (
+ { commit }: ActionContext,
+ itemId: ICategoryItem['id']
+ ) {
+ commit('toggleSectionEditState', { sectionName: 'ItemEcosystemSection', itemId })
+ },
+ toggleItemNotesSectionEdit (
+ { commit }: ActionContext,
+ itemId: ICategoryItem['id']
+ ) {
+ commit('toggleSectionEditState', { sectionName: 'ItemNotesSection', itemId })
+ },
}
const mutations: MutationTree = {
@@ -61,6 +90,16 @@ const mutations: MutationTree = {
},
setCategory: (state: ICategoryState, payload: ICategoryFull) => {
state.category = payload
+ },
+ toggleSectionEditState (state, { sectionName, itemId }) {
+ const sectionEditState = state.itemsSectionsInEdit[sectionName]
+
+ if (sectionEditState.includes(itemId)) {
+ const index = sectionEditState.indexOf(itemId)
+ sectionEditState.splice(index, 1)
+ } else {
+ sectionEditState.push(itemId)
+ }
}
}