1
1
mirror of https://github.com/aelve/guide.git synced 2024-12-23 04:42:24 +03:00

Front/fix/category sections enabling (#335)

* Formatting

* Category sections enabling fixes #317;
Warning when disabling editing secitons;

* Removed unused import
This commit is contained in:
avele 2019-07-13 17:29:23 +04:00 committed by GitHub
parent 59deb57474
commit f0f9c458a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 134 additions and 32 deletions

View File

@ -30,6 +30,7 @@
:toc="value.toc" :toc="value.toc"
:notes="value.notes" :notes="value.notes"
:kind="value.kind" :kind="value.kind"
:sections="category.sections"
/> />
</template> </template>
<v-btn <v-btn

View File

@ -37,20 +37,23 @@
class="mb-2" class="mb-2"
/> />
<v-checkbox <v-checkbox
v-model="checkboxSections" :inputValue="checkboxSections"
label="Pros/cons enabled" @click.native.capture.prevent.stop="updateSectionEnabling('ItemProsConsSection', 'Pros/Cons')"
label="Pros/cons section"
value="ItemProsConsSection" value="ItemProsConsSection"
class="mt-0 hide-v-messages" class="mt-0 hide-v-messages"
/> />
<v-checkbox <v-checkbox
v-model="checkboxSections" :inputValue="checkboxSections"
label="Ecosystem field enabled" @click.native.capture.prevent.stop="updateSectionEnabling('ItemEcosystemSection', 'Ecosystem')"
label="Ecosystem section"
value="ItemEcosystemSection" value="ItemEcosystemSection"
class="mt-0 hide-v-messages" class="mt-0 hide-v-messages"
/> />
<v-checkbox <v-checkbox
v-model="checkboxSections" :inputValue="checkboxSections"
label="Notes field enabled" @click.native.capture.prevent.stop="updateSectionEnabling('ItemNotesSection', 'Notes')"
label="Notes section"
value="ItemNotesSection" value="ItemNotesSection"
class="mt-0 hide-v-messages" class="mt-0 hide-v-messages"
/> />
@ -83,7 +86,6 @@
import Vue from 'vue' import Vue from 'vue'
import Component from 'vue-class-component' import Component from 'vue-class-component'
import { Prop, Watch } from 'vue-property-decorator' import { Prop, Watch } from 'vue-property-decorator'
import { CategoryStatus } from 'client/service/Category'
@Component @Component
export default class CategoryInfoEdit extends Vue { export default class CategoryInfoEdit extends Vue {
@ -95,6 +97,13 @@ export default class CategoryInfoEdit extends Vue {
checkboxSections: any[] = [] checkboxSections: any[] = []
isValid: boolean = false isValid: boolean = false
// TODO replace ItemProsConsSection and other to constants
sectionDisableWarningAgreed = {
ItemProsConsSection: false,
ItemEcosystemSection: false,
ItemNotesSection: false
}
categoryStatuses = [ categoryStatuses = [
{ name: 'Complete', value: 'CategoryFinished' }, { name: 'Complete', value: 'CategoryFinished' },
{ name: 'Work in progress', value: 'CategoryWIP' }, { name: 'Work in progress', value: 'CategoryWIP' },
@ -118,19 +127,35 @@ export default class CategoryInfoEdit extends Vue {
} }
this.title = category.title this.title = category.title
this.group = category.group this.group = category.group
this.checkboxSections = category.sections this.checkboxSections = category.sections.slice()
this.categoryStatus = category.status this.categoryStatus = category.status
this.sectionDisableWarningAgreed = {
ItemProsConsSection: false,
ItemEcosystemSection: false,
ItemNotesSection: false
}
} }
transformCategoryStatus (status: string) { async updateSectionEnabling (sectionValue, sectionName) {
switch (status) { const index = this.checkboxSections.indexOf(sectionValue)
case CategoryStatus.finished: const isSectionRemoved = index !== -1
return 'Complete' if (!isSectionRemoved) {
case CategoryStatus.inProgress: this.checkboxSections.push(sectionValue)
return 'Work in progress' return
default:
return 'Stub'
} }
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 () { close () {

View File

@ -27,31 +27,40 @@
/> />
</category-item-section> </category-item-section>
<div class="category-item-traits"> <div
v-if="isSectionEnabled('ItemProsConsSection')"
class="category-item-traits"
>
<category-item-traits <category-item-traits
type="Pro" type="Pro"
:itemId="itemUid" :itemId="itemUid"
:traits="pros" :traits="pros"
:isAnyTraitEditing.sync="isPropsEditing"
/> />
<category-item-traits <category-item-traits
type="Con" type="Con"
:itemId="itemUid" :itemId="itemUid"
:traits="cons" :traits="cons"
:isAnyTraitEditing.sync="isConsEditing"
/> />
</div> </div>
<category-item-section <category-item-section
v-if="isSectionEnabled('ItemEcosystemSection')"
title="Ecosystem" title="Ecosystem"
:editText="ecosystem.text" :editText="ecosystem.text"
@save="updateEcosystem({original: ecosystem.text, modified: $event})" @save="updateEcosystem({original: ecosystem.text, modified: $event})"
@toggleEdit="toggleItemEcosystemEditState"
> >
<div v-html="ecosystem.html" /> <div v-html="ecosystem.html" />
</category-item-section> </category-item-section>
<category-item-section <category-item-section
v-if="isSectionEnabled('ItemNotesSection')"
title="Notes" title="Notes"
:editText="notes.text" :editText="notes.text"
@save="updateNotes({original: notes.text, modified: $event})" @save="updateNotes({original: notes.text, modified: $event})"
@toggleEdit="toggleItemNotesEditState"
> >
<v-btn <v-btn
small small
@ -102,7 +111,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue' import Vue from 'vue'
import Component from 'vue-class-component' 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 { ICategoryItem } from 'client/service/CategoryItem.ts'
import CategoryItemToolbar from 'client/components/CategoryItemToolbar.vue' import CategoryItemToolbar from 'client/components/CategoryItemToolbar.vue'
import CategoryItemSection from 'client/components/CategoryItemSection.vue' import CategoryItemSection from 'client/components/CategoryItemSection.vue'
@ -132,8 +141,26 @@ export default class CategoryItem extends Vue {
@Prop(String) itemUid!: string @Prop(String) itemUid!: string
@Prop(String) link!: string @Prop(String) link!: string
@Prop(String) hackage!: string @Prop(String) hackage!: string
@Prop(Array) sections!: string[]
isNoteExpanded: boolean = false 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 { expandNotes (): void {
this.isNoteExpanded = true this.isNoteExpanded = true
@ -143,6 +170,14 @@ export default class CategoryItem extends Vue {
this.isNoteExpanded = false this.isNoteExpanded = false
} }
toggleItemEcosystemEditState () {
this.$store.dispatch('category/toggleItemEcosystemSectionEdit', this.itemUid)
}
toggleItemNotesEditState () {
this.$store.dispatch('category/toggleItemNotesSectionEdit', this.itemUid)
}
@CatchConflictDecorator @CatchConflictDecorator
async updateSummary ({ original, modified }): Promise<void> { async updateSummary ({ original, modified }): Promise<void> {
await this.$store.dispatch('categoryItem/updateItemSummary', { await this.$store.dispatch('categoryItem/updateItemSummary', {

View File

@ -64,8 +64,8 @@ export default class CategoryItemSection extends Vue {
isEdit: boolean = false isEdit: boolean = false
toggleEdit (): void { toggleEdit (): void {
this.$emit('toggleEdit')
if (this.customEdit) { if (this.customEdit) {
this.$emit('toggleEdit')
return return
} }
this.isEdit = !this.isEdit this.isEdit = !this.isEdit

View File

@ -118,27 +118,29 @@ export default class CategoryItemTraits extends Vue {
@Prop(Array) traits!: any[] @Prop(Array) traits!: any[]
@Prop(String) type!: string @Prop(String) type!: string
@Prop(String) itemId: string @Prop(String) itemId: string
@Prop(Boolean) isAnyTraitEditing: boolean
isEdit: boolean = false
isAddTrait: boolean = false isAddTrait: boolean = false
traitsModel = [] traitsModel = []
get title () { get title () {
return this.type + 's' return this.type + 's'
} }
get isAnyTraitEditingOrAdding () {
return this.traitsModel.some(x => x.isEdit) || this.isAddTrait
}
@Watch('traits', { @Watch('isAnyTraitEditingOrAdding', { immediate: true })
immediate: true updateIsEditing (newVal) {
}) this.$emit('update:isAnyTraitEditing', newVal)
}
@Watch('traits', { immediate: true })
setTraitsModel (traits) { setTraitsModel (traits) {
this.traitsModel = _cloneDeep(traits) this.traitsModel = _cloneDeep(traits)
this.traitsModel.forEach(x => this.$set(x, 'isEdit', false)) this.traitsModel.forEach(x => this.$set(x, 'isEdit', false))
} }
toggleEdit () {
this.isEdit = !this.isEdit
}
@CatchConflictDecorator @CatchConflictDecorator
async saveEdit ({ trait, original, modified }) { async saveEdit ({ trait, original, modified }) {
await this.$store.dispatch('categoryItem/updateItemTrait', { await this.$store.dispatch('categoryItem/updateItemTrait', {

View File

@ -1,14 +1,25 @@
import { ActionTree, GetterTree, MutationTree, ActionContext, Module } from 'vuex' import { ActionTree, GetterTree, MutationTree, ActionContext, Module } from 'vuex'
import { ICategoryInfo, ICategoryFull, CategoryService } from 'client/service/Category' import { ICategoryInfo, ICategoryFull, CategoryService } from 'client/service/Category'
import { ICategoryItem } from 'client/service/CategoryItem'
interface ICategoryState { interface ICategoryState {
categoryList: ICategoryInfo[], categoryList: ICategoryInfo[],
category: ICategoryFull category: ICategoryFull,
itemsSectionsInEdit: {
ItemProsConsSection: Array<ICategoryItem['id']>
ItemEcosystemSection: Array<ICategoryItem['id']>
ItemNotesSection: Array<ICategoryItem['id']>
}
} }
const state = (): ICategoryState => ({ const state = (): ICategoryState => ({
categoryList: [], categoryList: [],
category: null category: null,
itemsSectionsInEdit: {
ItemProsConsSection: [],
ItemEcosystemSection: [],
ItemNotesSection: []
}
}) })
const getters: GetterTree<ICategoryState, any> = {} const getters: GetterTree<ICategoryState, any> = {}
@ -44,15 +55,33 @@ const actions: ActionTree<ICategoryState, any> = {
dispatch('loadCategoryList') dispatch('loadCategoryList')
return createdId return createdId
}, },
async updateCategoryInfo (context: ActionContext<ICategoryState, any>, {id, title, group, status, sections}) { async updateCategoryInfo (context: ActionContext<ICategoryState, any>, { id, title, group, status, sections }) {
await CategoryService.updateCategoryInfo({id, title, group, status, sections}) await CategoryService.updateCategoryInfo({ id, title, group, status, sections })
}, },
async deleteCategory ( async deleteCategory (
{ dispatch }: ActionContext<ICategoryState, any>, { dispatch }: ActionContext<ICategoryState, any>,
id: ICategoryInfo['id'] id: ICategoryInfo['id']
): Promise<void> { ): Promise<void> {
await CategoryService.deleteCategory(id) await CategoryService.deleteCategory(id)
} },
toggleItemProsConsSectionEdit (
{ commit }: ActionContext<ICategoryState, any>,
itemId: ICategoryItem['id']
) {
commit('toggleSectionEditState', { sectionName: 'ItemProsConsSection', itemId })
},
toggleItemEcosystemSectionEdit (
{ commit }: ActionContext<ICategoryState, any>,
itemId: ICategoryItem['id']
) {
commit('toggleSectionEditState', { sectionName: 'ItemEcosystemSection', itemId })
},
toggleItemNotesSectionEdit (
{ commit }: ActionContext<ICategoryState, any>,
itemId: ICategoryItem['id']
) {
commit('toggleSectionEditState', { sectionName: 'ItemNotesSection', itemId })
},
} }
const mutations: MutationTree<ICategoryState> = { const mutations: MutationTree<ICategoryState> = {
@ -61,6 +90,16 @@ const mutations: MutationTree<ICategoryState> = {
}, },
setCategory: (state: ICategoryState, payload: ICategoryFull) => { setCategory: (state: ICategoryState, payload: ICategoryFull) => {
state.category = payload 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)
}
} }
} }