Skip to content

Commit

Permalink
Redigering av prosjektegenskaper i Panel - synkronisering til portefø…
Browse files Browse the repository at this point in the history
…ljeområdet (#1227)
  • Loading branch information
olemp authored Aug 16, 2023
1 parent 89501ee commit 8fe53b0
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 26 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { MessageBarType } from '@fluentui/react'
import strings from 'ProjectWebPartsStrings'
import { IProjectInformationData } from 'pp365-shared-library'
import { CustomError } from 'pp365-shared-library/lib/models'
import { useState } from 'react'
import SPDataAdapter from '../../../data'
import { useProjectInformationContext } from '../context'
import { CLOSE_PANEL, PROPERTIES_UPDATED } from '../reducer'
import { CLOSE_PANEL, UPDATE_DATA } from '../reducer'
import { usePropertiesSync } from '../usePropertiesSync'
import { UseModelReturnType } from './useModel'

Expand All @@ -25,10 +26,11 @@ export function useSubmit(model: UseModelReturnType) {
* clear the local storage and close the panel.
*/
const onSave = async () => {
let data: IProjectInformationData = null
setError(null)
setSaveStatus(strings.UpdatingProjectPropertiesStatusText)
try {
await SPDataAdapter.project.updateProjectProperties(model.properties)
data = await SPDataAdapter.project.updateProjectProperties(model.properties, true)
} catch (e) {
setError(
CustomError.createError(e, MessageBarType.error, strings.UpdatingProjectPropertiesErrorText)
Expand All @@ -41,7 +43,7 @@ export function useSubmit(model: UseModelReturnType) {
}
setSaveStatus(strings.SynchronizingProjectPropertiesToPortfolioSiteStatusText)
try {
await syncPropertyItemToHub(() => null, model.properties)
await syncPropertyItemToHub(data)
} catch (e) {
setError(
CustomError.createError(
Expand All @@ -57,8 +59,8 @@ export function useSubmit(model: UseModelReturnType) {
return
}
localStorage.clear()
context.dispatch(UPDATE_DATA({ data }))
context.dispatch(CLOSE_PANEL())
context.dispatch(PROPERTIES_UPDATED({ refetch: true }))
setSaveStatus(null)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createAction, createReducer } from '@reduxjs/toolkit'
import { CustomError } from 'pp365-shared-library/lib/models'
import { IProjectInformationData } from 'pp365-shared-library'
import { CustomError, ProjectInformationField } from 'pp365-shared-library/lib/models'
import { useMemo, useReducer } from 'react'
import { IProgressDialogProps } from './ProgressDialog/types'
import {
Expand All @@ -18,6 +19,7 @@ export const INIT_DATA = createAction<{
state: Partial<IProjectInformationState>
error?: CustomError
}>('INIT_DATA')
export const UPDATE_DATA = createAction<{ data: IProjectInformationData }>('UPDATE_DATA')
export const FETCH_DATA_ERROR = createAction<{ error: CustomError }>('FETCH_DATA_ERROR')
export const SET_PROGRESS = createAction<IProgressDialogProps>('SET_PROGRESS')
export const OPEN_PANEL = createAction<ProjectInformationPanelType>('OPEN_PANEL')
Expand All @@ -26,6 +28,23 @@ export const OPEN_DIALOG = createAction<ProjectInformationDialogType>('OPEN_DIAL
export const CLOSE_DIALOG = createAction('CLOSE_DIALOG')
export const PROPERTIES_UPDATED = createAction<{ refetch: boolean }>('PROPERTIES_UPDATED')

/**
* Create properties from the state.
*
* @param state State of the `ProjectInformation` component.
*/
function createProperties(state: IProjectInformationState) {
return state.data.fields
.map((field) =>
new ProjectInformationField(field).init(state.data.columns).setValue(state.data)
)
.sort((a, b) => {
if (!a.column) return 1
if (!b.column) return -1
return a.column.sortOrder - b.column.sortOrder
})
}

/**
* Create project information reducer.
*/
Expand All @@ -38,8 +57,16 @@ const createProjectInformationReducer = () =>
state.isProjectDataSynced = action.payload.state.isProjectDataSynced
state.isParentProject = action.payload.state.isParentProject
state.userHasEditPermission = action.payload.state.userHasEditPermission
state.properties = createProperties(state as IProjectInformationState)
state.isDataLoaded = true
})
.addCase(UPDATE_DATA, (state, action) => {
state.data = {
...(state.data ?? {}),
...action.payload.data
}
state.properties = createProperties(state as IProjectInformationState)
})
.addCase(FETCH_DATA_ERROR, (state, action) => {
state.error = action.payload.error
state.isDataLoaded = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
ListLogger,
ProjectAdminPermission,
ProjectColumnConfig,
ProjectInformationField,
ProjectInformationParentProject,
SectionModel,
StatusReport
Expand Down Expand Up @@ -137,15 +136,6 @@ const fetchData: DataFetchFunction<
userHasEditPermission: false,
isProjectDataSynced: false
}
data.properties = projectInformationData.fields
.map((field) =>
new ProjectInformationField(field).init(columns).setValue(projectInformationData)
)
.sort((a, b) => {
if (!a.column) return 1
if (!b.column) return -1
return a.column.sortOrder - b.column.sortOrder
})
if (isFrontpage) {
data.userHasEditPermission = await SPDataAdapter.checkProjectAdminPermissions(
ProjectAdminPermission.EditProjectProperties,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ export function usePropertiesSync(context: IProjectInformationContext = null) {
/**
* Sync properties to the hub site.
*
* @param data Project properties data.
* @param progressFunc Progress callback function.
* @param properties Properties to sync to the hub site (default: `context.state.data.fieldValuesText`)
*/
const syncPropertyItemToHub = async (
progressFunc: (progress: IProgressIndicatorProps) => void,
properties = context.state.data.fieldValuesText
data = context.state.data,
progressFunc: (progress: IProgressIndicatorProps) => void = () => null
) => {
const { fieldValues, fieldValuesText, templateParameters } = context.state.data
const { fieldValues, fieldValuesText, templateParameters } = data
await SPDataAdapter.syncPropertyItemToHub(
{ ...fieldValuesText, ...properties, Title: context.props.webTitle },
{ ...fieldValuesText, Title: context.props.webTitle },
fieldValues,
templateParameters,
progressFunc
Expand Down Expand Up @@ -102,7 +102,8 @@ export function usePropertiesSync(context: IProjectInformationContext = null) {
const { list } = await syncList(context)
created = list.created
}
if (!created && params.syncPropertyItemToHub) await syncPropertyItemToHub(progressFunc)
if (!created && params.syncPropertyItemToHub)
await syncPropertyItemToHub(undefined, progressFunc)
SPDataAdapter.clearCache()
await sleep(5)
if (params.reload) window.location.reload()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,15 @@ export class ProjectDataService {
* separately, as expanding `ctx.item()` with `FieldValuesAsText` will result in
* corrupt data.
*/
private async _getLocalProjectInformationItem(): Promise<IProjectInformationData> {
private async _getLocalProjectInformationItem(
fieldsFilter = "substringof('Gt', InternalName)"
): Promise<IProjectInformationData> {
try {
const ctx = await this._getLocalProjectInformationItemContext()
if (!ctx) return null
const fields = await ctx.list.fields
.select(...getClassProperties(SPField))
// eslint-disable-next-line quotes
.filter("substringof('Gt', InternalName)")<SPField[]>()
.filter(fieldsFilter)<SPField[]>()
const userFields = fields.filter((fld) => fld.TypeAsString.indexOf('User') === 0)
const [fieldValuesText, fieldValues] = await Promise.all([
ctx.item.fieldValuesAsText(),
Expand Down Expand Up @@ -269,16 +270,25 @@ export class ProjectDataService {
}

/**
* Update properties for the project using the local property list.
* Update properties for the project using the local property list. If `returnData` is true,
* the updated data from `this.getProjectInformationData` will be returned.
*
* @param properties Properties to update
* @param returnData Return data after update
*/
public async updateProjectProperties(properties: { [key: string]: string }): Promise<void> {
public async updateProjectProperties(
properties: { [key: string]: string },
returnData = false
): Promise<IProjectInformationData | null> {
try {
const propertyItemContext = await this._getLocalProjectInformationItemContext()
if (propertyItemContext) {
await propertyItemContext.item.update(properties)
}
if (returnData) {
return await this.getProjectInformationData()
}
return null
} catch (error) {
throw error
}
Expand Down

0 comments on commit 8fe53b0

Please sign in to comment.