Skip to content

Commit

Permalink
Rettet et problem hvor taksonomifelt i redigeringspanel ikke støttet …
Browse files Browse the repository at this point in the history
…nivåer av termer (#1507)

* Modern taxonomy picker as replacement for tagpicker

* Use dataAdapter context object - description as panel title - ITag -> ITermInfo in model

* Workaround to safely map ModernTaxonomyPicker initial values without affecting other components

* Linting and cleanup

* Changelog

* Initial value for single select taxonomy

* Update CHANGELOG.md

---------

Co-authored-by: Bloom <[email protected]>
  • Loading branch information
stigre and Remi749 authored Apr 24, 2024
1 parent b0c7bc1 commit 5ac9f01
Show file tree
Hide file tree
Showing 10 changed files with 2,378 additions and 202 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Sjekk ut [release notes](./releasenotes/1.9.0.md) for høydepunkter og mer detal
- Rettet et problem hvor visnings-id ikke la seg i URL feltet ved innlastning eller bytting av visninger i Porteføljeoversikt [#1355](https://github.com/Puzzlepart/prosjektportalen365/issues/1355)
- Rettet et problem hvor visnings-id ikke la seg i URL feltet ved opprettelse av nye visninger, samt oppdatering av visningen (Porteføljeoversikter og andre aggregerte oversikter) [#1441](https://github.com/Puzzlepart/prosjektportalen365/issues/1441)
- Rettet et problem hvor `Standardmal` ble satt som standard selvom andre maler var angitt som standard [#1471](https://github.com/Puzzlepart/prosjektportalen365/issues/1471)
- Rettet et problem hvor taksonomifelt i redigeringspanel ikke støttet nivåer av termer [#1504](https://github.com/Puzzlepart/prosjektportalen365/issues/1504)

### Forbedringer

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ export const EditPropertiesPanel: FC = () => {
)
}

EditPropertiesPanel.displayName = 'EditPropertiesPanel'
EditPropertiesPanel.displayName = 'EditPropertiesPanel'
1 change: 1 addition & 0 deletions SharePointFramework/shared-library/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
},
"externals": {},
"localizedResources": {
"ControlStrings": "node_modules/@pnp/spfx-controls-react/lib/loc/{locale}.js",
"SharedLibraryStrings": "lib/loc/{locale}.js"
}
}
2 changes: 2 additions & 0 deletions SharePointFramework/shared-library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"@microsoft/sp-lodash-subset": "1.17.4",
"@pnp/logging": "3.17.0",
"@pnp/sp": "3.17.0",
"@pnp/odata": "2.15.0",
"@pnp/spfx-controls-react": "3.17.0",
"tslib": "2.3.1",
"file-saver": "^2.0.5",
"react-markdown": "^8.0.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,30 @@
import { ITag, TagPicker } from '@fluentui/react'
import React from 'react'
import { FieldContainer } from '../../../FieldContainer'
import styles from '../CustomEditPanelBody.module.scss'
import { useCustomEditPanelContext } from '../../context'
import { FieldElementComponent } from './types'
import { ModernTaxonomyPicker } from '@pnp/spfx-controls-react'
import { Term, useInitialTaxonomyValues } from './useInitialTaxonomyValues'

export const TaxonomyFieldType: FieldElementComponent = ({ field }) => {
const context = useCustomEditPanelContext()
const mapInitialValues = useInitialTaxonomyValues()
const terms = context.model.get<Term[]>(field)

return (
<FieldContainer
iconName='AppsList'
label={field.displayName}
description={field.description}
required={field.required}
>
<TagPicker
styles={{ text: styles.field }}
onResolveSuggestions={async (filter, selectedItems) =>
await context.props.dataAdapter.getTerms(
field.getProperty('TermSetId'),
filter,
selectedItems
)
}
onEmptyResolveSuggestions={async (selectedItems) =>
await context.props.dataAdapter.getTerms(
field.getProperty('TermSetId'),
'',
selectedItems
)
}
defaultSelectedItems={context.model.get<ITag[]>(field)}
itemLimit={1}
<ModernTaxonomyPicker
context={context.props.dataAdapter.spfxContext as any} // Newest version of the control requires this cast for now, as context type is incompatibale with other types of SPFxContext
panelTitle={field.description || field.displayName}
initialValues={terms?.map(mapInitialValues)}
label=''
termSetId={field.getProperty('TermSetId')}
onChange={(items) => context.model.set(field, items)}
/>
</FieldContainer>
)
}
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,31 @@
import { ITag, TagPicker } from '@fluentui/react'
import { ModernTaxonomyPicker } from '@pnp/spfx-controls-react/lib/ModernTaxonomyPicker'
import React from 'react'
import { FieldContainer } from '../../../FieldContainer'
import { useCustomEditPanelContext } from '../../context'
import styles from '../CustomEditPanelBody.module.scss'
import { FieldElementComponent } from './types'
import { Term, useInitialTaxonomyValues } from './useInitialTaxonomyValues'

export const TaxonomyFieldTypeMulti: FieldElementComponent = ({ field }) => {
const context = useCustomEditPanelContext()
const mapInitialValues = useInitialTaxonomyValues()
const terms = context.model.get<Term[]>(field)

return (
<FieldContainer
iconName='AppsList'
label={field.displayName}
description={field.description}
required={field.required}
>
<TagPicker
styles={{ text: styles.field }}
onResolveSuggestions={async (filter, selectedItems) =>
await context.props.dataAdapter.getTerms(
field.getProperty('TermSetId'),
filter,
selectedItems
)
}
onEmptyResolveSuggestions={async (selectedItems) =>
await context.props.dataAdapter.getTerms(
field.getProperty('TermSetId'),
'',
selectedItems
)
}
defaultSelectedItems={context.model.get<ITag[]>(field)}
itemLimit={20}
<ModernTaxonomyPicker
context={context.props.dataAdapter.spfxContext as any} // Newest version of the control requires this cast for now, as context type is incompatibale with other types of SPFxContext
panelTitle={field.description || field.displayName}
initialValues={terms?.map(mapInitialValues)}
allowMultipleSelections
label=''
termSetId={field.getProperty('TermSetId')}
onChange={(items) => context.model.set(field, items)}
/>
</FieldContainer>
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useCallback } from 'react'

interface ITermLabel {
name: string
isDefault: boolean
languageTag: string
}

interface ITagTerm {
key: string
name: string
}

interface IModernTaxonomyTerm {
id: string
labels: ITermLabel[]
}

export type Term = ITagTerm | IModernTaxonomyTerm;

export const useInitialTaxonomyValues = () => {
const mapInitialValues = useCallback((term: Term) => {
if ('id' in term) {
return { labels: term.labels, id: term.id }
} else {
return { labels: [{ name: term.name, isDefault: true, languageTag: 'nb-NO' }], id: term.key }
}
}, [])

return mapInitialValues
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IPersonaProps, ITag } from '@fluentui/react'
import { IPersonaProps } from '@fluentui/react'
import _ from 'lodash'
import { ITermInfo } from '@pnp/sp/taxonomy'
import { useState } from 'react'
import { EditableSPField } from '../../models'
import { DefaultCaching } from '../../data/cache'
Expand Down Expand Up @@ -58,8 +59,13 @@ export function useModel(props: ICustomEditPanelProps) {
.getById(field.getProperty('TextField'))
.select('InternalName')
.using(DefaultCaching)()

const languageTag = props.dataAdapter.spfxContext.pageContext.cultureInfo.currentUICultureName || 'nb-NO'
return [
(value as ITag[]).map((v) => `-1;#${v.name}|${v.key}`).join(';#'),
(value as ITermInfo[]).map((v) => {
const label = v.labels.find(l => l.languageTag === languageTag)
return `-1;#${label?.name}|${v.id}`
}).join(';#'),
textField.InternalName
]
}
Expand All @@ -71,8 +77,13 @@ export function useModel(props: ICustomEditPanelProps) {
.getById(field.getProperty('TextField'))
.select('InternalName')
.using(DefaultCaching)()

const languageTag = props.dataAdapter.spfxContext.pageContext.cultureInfo.currentUICultureName || 'nb-NO'
return [
(value as ITag[]).map((v) => `-1;#${v.name}|${v.key}`).join(';#'),
(value as ITermInfo[]).map((v) => {
const label = v.labels.find(l => l.languageTag === languageTag)
return `-1;#${label?.name}|${v.id}`
}).join(';#'),
textField.InternalName
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export class ProjectDataService extends DataService<IProjectDataServiceParams> {
* corrupt data.
*/
private async _getLocalProjectInformationItem(
fieldsFilter = "substringof('Gt', InternalName)"
fieldsFilter = 'substringof(\'Gt\', InternalName)'
): Promise<IProjectInformationData> {
try {
const ctx = await this._getLocalProjectInformationItemContext()
Expand Down
Loading

0 comments on commit 5ac9f01

Please sign in to comment.