From c343f9819e99acc16f643db06e9bdfb7e80d90c5 Mon Sep 17 00:00:00 2001 From: Grady Ward Date: Tue, 23 Jan 2024 16:40:29 -0700 Subject: [PATCH] Initial Redesign of Portfolio List View --- frontend/assets/css/overrides.css | 4 + frontend/components/CommonAccordionHeader.vue | 29 +++++ frontend/components/portfolio/ListView.vue | 103 +++++++++++++++--- frontend/lang/en.json | 17 +++ frontend/lib/mydata/index.ts | 1 + frontend/pages/my-data.vue | 22 ++++ frontend/plugins/primevue.ts | 2 + 7 files changed, 160 insertions(+), 18 deletions(-) create mode 100644 frontend/components/CommonAccordionHeader.vue diff --git a/frontend/assets/css/overrides.css b/frontend/assets/css/overrides.css index e769930..007eef0 100644 --- a/frontend/assets/css/overrides.css +++ b/frontend/assets/css/overrides.css @@ -54,3 +54,7 @@ div.p-chips .p-chips-multiple-container { div.p-chips .p-chips-multiple-container .p-chips-token { margin-right: 0; } + +div.p-accordion .p-accordion-header:not(.p-disabled).p-highlight .p-accordion-header-link { + background-color: #f5f5f5 +} \ No newline at end of file diff --git a/frontend/components/CommonAccordionHeader.vue b/frontend/components/CommonAccordionHeader.vue new file mode 100644 index 0000000..6af2243 --- /dev/null +++ b/frontend/components/CommonAccordionHeader.vue @@ -0,0 +1,29 @@ + + + diff --git a/frontend/components/portfolio/ListView.vue b/frontend/components/portfolio/ListView.vue index 8f6cf6d..453f9de 100644 --- a/frontend/components/portfolio/ListView.vue +++ b/frontend/components/portfolio/ListView.vue @@ -3,6 +3,7 @@ import { portfolioEditor } from '@/lib/editor' import { type Portfolio, AuditLogQuerySortBy, type PortfolioGroup, type Initiative, type Analysis } from '@/openapi/generated/pacta' import { selectedCountSuffix } from '@/lib/selection' import { createURLAuditLogQuery } from '@/lib/auditlogquery' +import { type WritableComputedRef } from 'vue' const { linkToPortfolioGroup } = useMyDataURLs() const { humanReadableTimeFromStandardString } = useTime() @@ -19,11 +20,13 @@ interface Props { analyses: Analysis[] selectedPortfolioIds: string[] expandedPortfolioIds: string[] + expandedSections: Map } const props = defineProps() interface Emits { (e: 'update:selectedPortfolioIds', value: string[]): void (e: 'update:expandedPortfolioIds', value: string[]): void + (e: 'update:expandedSections', value: Map): void (e: 'refresh'): void } const emit = defineEmits() @@ -38,11 +41,15 @@ const expandedPortfolioIdsModel = computed({ get: () => props.expandedPortfolioIds ?? [], set: (value: string[]) => { emit('update:expandedPortfolioIds', value) }, }) -const expendedPortfolioSections = useState>('ListView.expandedPortfolioSections', () => new Map()) +const expandedSectionsModel = computed({ + get: () => props.expandedSections ?? new Map(), + set: (value: Map) => { emit('update:expandedSections', value) }, +}) interface EditorObject extends ReturnType { id: string analyses: Analysis[] + expandedSections: WritableComputedRef } const prefix = 'components/portfolio/ListView' @@ -70,7 +77,6 @@ const expandedRows = computed({ } const ids = expandedPortfolioIdsModel.value const result = editorObjects.value.filter((editorObject) => ids.includes(editorObject.id)) - console.log('expandedRows = ', result.length) return result }, set: (value: EditorObject[]) => { @@ -80,11 +86,22 @@ const expandedRows = computed({ }, }) -const editorObjects = computed(() => props.portfolios.map((item) => ({ - id: item.id, - ...portfolioEditor(item, i18n), - analyses: props.analyses.filter((a) => a.portfolioSnapshot.portfolio?.id === item.id), -}))) +const editorObjects = computed(() => props.portfolios.map((item) => { + const expandedSectionSuffix = item.id.substring(item.id.length - 4) + return ({ + ...portfolioEditor(item, i18n), + id: item.id, + analyses: props.analyses.filter((a) => a.portfolioSnapshot.portfolio?.id === item.id), + expandedSections: computed({ + get: () => expandedSectionsModel.value.get(expandedSectionSuffix) ?? [], + set: (value: number[]) => { + const m = new Map(expandedSectionsModel.value) + m.set(expandedSectionSuffix, value) + expandedSectionsModel.value = m + }, + }), + }) +})) const selectedPortfolios = computed(() => selectedRows.value.map((row) => row.currentValue.value)) @@ -217,16 +234,21 @@ const auditLogURL = (id: string) => { #expansion="slotProps" >
-

+

{{ tt('Portfolio') }}: {{ slotProps.data.currentValue.value.name }}

- + + {
- + +
{ />
- + + { @refresh="refresh" /> - - + + >({ + get: () => { + const result = new Map() + expandedSectionsArray.value.forEach((v) => { + const [k, ...vv] = v.split(':') + result.set(k, vv.map((vvv) => parseInt(vvv))) + }) + return result + }, + set: (v: Map) => { + const result: string[] = [] + v.forEach((vv, k) => { + if (vv.length > 0) { + result.push(`${k}:${vv.join(':')}`) + } + }) + expandedSectionsArray.value = result + }, +}) const [ { data: incompleteUploadsData, refresh: refreshIncompleteUploadsApi }, @@ -149,6 +170,7 @@ const activeIndex = computed({ v-if="portfolioData && portfolioGroupData && initiativeData" v-model:selected-portfolio-ids="selectedPortfolioIds" v-model:expanded-portfolio-ids="expandedPortfolioIds" + v-model:expanded-sections="expandedSections" :portfolios="portfolioData.items" :portfolio-groups="portfolioGroupData.items" :analyses="analysesData.items" diff --git a/frontend/plugins/primevue.ts b/frontend/plugins/primevue.ts index e80e3ee..c74301f 100644 --- a/frontend/plugins/primevue.ts +++ b/frontend/plugins/primevue.ts @@ -16,6 +16,7 @@ import Dialog from 'primevue/dialog' import Dropdown from 'primevue/dropdown' import FileUpload from 'primevue/fileupload' import Image from 'primevue/image' +import InlineMessage from 'primevue/inlinemessage' import InputNumber from 'primevue/inputnumber' import InputSwitch from 'primevue/inputswitch' import InputText from 'primevue/inputtext' @@ -50,6 +51,7 @@ export default defineNuxtPlugin(({ vueApp }) => { vueApp.component('PVDropdown', Dropdown) vueApp.component('PVFileUpload', FileUpload) vueApp.component('PVImage', Image) + vueApp.component('PVInlineMessage', InlineMessage) vueApp.component('PVInputNumber', InputNumber) vueApp.component('PVInputSwitch', InputSwitch) vueApp.component('PVInputText', InputText)