Skip to content

Commit

Permalink
UI/UX improvements to Program #693
Browse files Browse the repository at this point in the history
* UI/UX improvements to Program #693

* Disable "Legg til" button in "Legg til prosjekt" if none are selected #693

* Fixed height (750px) for "Legg til prosjekt" dialog #693

* Make the "Project" column in "OverordnetLeveranser" page clickable, to keep the UX consistent with "OverordnetGevinster" and "OverordnetUsikkerheter" pages.

* ProgramAdministrationInfoMessage

* TooltipHeader
  • Loading branch information
olemp authored Nov 8, 2022
1 parent bab41d9 commit e28d9d7
Show file tree
Hide file tree
Showing 16 changed files with 116 additions and 178 deletions.
4 changes: 1 addition & 3 deletions SharePointFramework/ProgramWebParts/.vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
{
"recommendations": [
"msjsdiag.debugger-for-chrome"
]
"recommendations": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";

.root {
.scrollableContent {
height: 750px;
overflow: hidden;
}
}

.dialogContent {
margin-top: 20px;
box-sizing: border-box;
}
Original file line number Diff line number Diff line change
@@ -1,63 +1,76 @@
import {
DefaultButton,
Dialog,
DialogType,
ShimmeredDetailsList,
SelectionMode,
DialogFooter,
DialogType,
PrimaryButton,
DefaultButton
SelectionMode,
ShimmeredDetailsList
} from '@fluentui/react'
import _ from 'lodash'
import * as strings from 'ProgramWebPartsStrings'
import React, { FC, useContext } from 'react'
import { ProgramAdministrationContext } from '../context'
import { addChildProject } from '../data'
import { fields } from '../index'
import styles from '../ProgramAdministration.module.scss'
import styles from './AddProjectDialog.module.scss'
import { ProjectTable } from '../ProjectTable'
import { CHILD_PROJECTS_ADDED, TOGGLE_ADD_PROJECT_DIALOG } from '../reducer'
import { shimmeredColumns } from '../types'
import { useAddProjectDialog } from './useAddProjectDialog'

export const AddProjectDialog: FC = () => {
const context = useContext(ProgramAdministrationContext)
const { selectedProjects, availableProjects } = useAddProjectDialog()
const { selectedProjects, setSelectedProjects, availableProjects } = useAddProjectDialog()

return (
<>
<Dialog
hidden={false}
modalProps={{
containerClassName: styles.root,
scrollableContentClassName: styles.scrollableContent
}}
onDismiss={() => context.dispatch(TOGGLE_ADD_PROJECT_DIALOG())}
minWidth='60em'
maxWidth='1000px'
dialogContentProps={{
type: DialogType.largeHeader,
title: strings.ProgramAddChildsButtonText
title: strings.ProgramAdministrationAddChildsButtonText
}}>
<div className={styles.dialogContent}>
{context.state.loading.AddProjectDialog ? (
<ShimmeredDetailsList
items={[]}
shimmerLines={15}
columns={shimmeredColumns}
columns={[
{
key: 'Title',
name: 'Tittel',
maxWidth: 250,
minWidth: 100
}
]}
enableShimmer
/>
) : (
<ProjectTable
fields={fields(false)}
height={550}
fields={fields({ renderAsLink: false })}
items={availableProjects}
selectionMode={SelectionMode.multiple}
onSelectionChanged={(items) => {
selectedProjects.current = items
onSelectionChanged={(selected) => {
setSelectedProjects(selected)
}}
/>
)}
</div>
<DialogFooter>
<PrimaryButton
text={strings.Add}
disabled={_.isEmpty(selectedProjects)}
onClick={async () => {
await addChildProject(context.props.dataAdapter, selectedProjects.current)
context.dispatch(CHILD_PROJECTS_ADDED({ childProjects: selectedProjects.current }))
await addChildProject(context.props.dataAdapter, selectedProjects)
context.dispatch(CHILD_PROJECTS_ADDED({ childProjects: selectedProjects }))
}}
/>
<DefaultButton
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useContext, useEffect, useRef } from 'react'
import { useContext, useEffect, useState } from 'react'
import { ProgramAdministrationContext } from '../context'
import { getHubSiteProjects } from '../data'
import { DATA_LOADED } from '../reducer'

export const useAddProjectDialog = () => {
const context = useContext(ProgramAdministrationContext)
const selectedProjects = useRef<Array<Record<string, string>>>([])
const [selectedProjects, setSelectedProjects] = useState<any[]>([])

useEffect(() => {
getHubSiteProjects()
Expand All @@ -27,5 +27,5 @@ export const useAddProjectDialog = () => {
)
.filter((project) => project['SPWebURL'])

return { selectedProjects, availableProjects } as const
return { selectedProjects, setSelectedProjects, availableProjects } as const
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const Commands: FC = () => {
const _items: ICommandBarItemProps[] = [
{
key: 'ProgramAddChilds',
text: strings.ProgramAddChildsButtonText,
text: strings.ProgramAdministrationAddChildsButtonText,
iconProps: { iconName: 'Add' },
buttonStyles: { root: { border: 'none' } },
onClick: () => context.dispatch(TOGGLE_ADD_PROJECT_DIALOG()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,4 @@
.root {
height: 100vh;
margin: 20px;

.header {
padding-bottom: 20px;

.title {
font-size: 28px;
font-weight: 100;
margin: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}

.dialogContent {
margin-top: 20px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

.root {
.scroll {
max-height: 800px;
overflow-y: auto;

.list {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const ProjectTable: FC<IProjectTableProps> = (props) => {
return (
<div className={styles.root}>
<SearchBox placeholder={strings.ProgramSearchProjectsText} onChange={handleFilterChanged} />
<div className={styles.scroll}>
<div className={styles.scroll} style={{ height: props.height }}>
<ol
className={styles.list}
style={{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SelectionMode } from '@pnp/spfx-controls-react/lib/ListView'
import { HTMLProps } from 'react'

export interface IProjectTableProps<T = any> {
export interface IProjectTableProps<T = any> extends HTMLProps<HTMLDivElement> {
onSelectionChanged: (selected: T[]) => void
items: T[]
fields: IListField[]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import "~@microsoft/sp-office-ui-fabric-core/dist/sass/SPFabricCore.scss";

.root {
padding-bottom: 20px;

.title {
font-size: 28px;
font-weight: 100;
margin: 0;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;

.icon {
font-size: 18px;
margin: 0 0 0 6px;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Icon, TooltipHost } from '@fluentui/react'
import * as strings from 'ProgramWebPartsStrings'
import React, { FC, useContext } from 'react'
import { ProgramAdministrationContext } from '../context'
import styles from './TooltipHeader.module.scss'

export const TooltipHeader: FC = () => {
const context = useContext(ProgramAdministrationContext)
return (
<div className={styles.root}>
<div className={styles.title}>
<TooltipHost content={<div><p>{strings.ProgramAdministrationInfoMessage}</p></div>}>
<span>{context.props.title}</span>
<Icon iconName='Info' className={styles.icon} />
</TooltipHost>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SelectionMode } from '@pnp/spfx-controls-react/lib/ListView'
import { Link, MessageBar, ShimmeredDetailsList } from '@fluentui/react'
import { isEmpty } from '@microsoft/sp-lodash-subset'
import { SelectionMode } from '@pnp/spfx-controls-react/lib/ListView'
import * as strings from 'ProgramWebPartsStrings'
import React, { FC } from 'react'
import { AddProjectDialog } from './AddProjectDialog'
Expand All @@ -9,9 +10,9 @@ import styles from './ProgramAdministration.module.scss'
import { ProjectTable } from './ProjectTable'
import { IListField } from './ProjectTable/types'
import { SET_SELECTED_TO_DELETE } from './reducer'
import { IProgramAdministrationProps, shimmeredColumns } from './types'
import { TooltipHeader } from './TooltipHeader'
import { IProgramAdministrationProps } from './types'
import { useProgramAdministration } from './useProgramAdministration'
import { isEmpty } from '@microsoft/sp-lodash-subset'

export const ProgramAdministration: FC<IProgramAdministrationProps> = (props) => {
const { state, dispatch } = useProgramAdministration(props)
Expand All @@ -29,29 +30,39 @@ export const ProgramAdministration: FC<IProgramAdministrationProps> = (props) =>

if (state.loading.root) {
return (
<ShimmeredDetailsList items={[]} shimmerLines={15} columns={shimmeredColumns} enableShimmer />
<ShimmeredDetailsList
items={[]}
shimmerLines={15}
columns={[
{
key: 'Title',
name: 'Tittel',
maxWidth: 250,
minWidth: 100
}
]}
enableShimmer
/>
)
}

return (
<ProgramAdministrationContext.Provider value={{ props, state, dispatch }}>
<Commands />
<div className={styles.root}>
<div className={styles.header}>
<div className={styles.title}>{props.title}</div>
</div>
<TooltipHeader />
<div>
{!isEmpty(state.childProjects) ? (
<ProjectTable
fields={fields(true)}
fields={fields({ renderAsLink: true })}
items={state.childProjects}
selectionMode={
state.userHasManagePermission ? SelectionMode.multiple : SelectionMode.none
}
onSelectionChanged={(selected) => dispatch(SET_SELECTED_TO_DELETE({ selected }))}
/>
) : (
<MessageBar>{strings.ProgramAdministration_EmptyMessage}</MessageBar>
<MessageBar>{strings.ProgramAdministrationEmptyMessage}</MessageBar>
)}
</div>
{state.displayAddProjectDialog && <AddProjectDialog />}
Expand All @@ -60,7 +71,7 @@ export const ProgramAdministration: FC<IProgramAdministrationProps> = (props) =>
)
}

export const fields = (renderAsLink: boolean): IListField[] => [
export const fields = ({ renderAsLink = false }): IListField[] => [
{
key: 'Title',
text: 'Tittel',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { WebPartContext } from '@microsoft/sp-webpart-base'
import { SearchResult } from '@pnp/sp'
import { SPDataAdapter } from 'data'
import { IColumn, MessageBarType } from '@fluentui/react'
import { MessageBarType } from '@fluentui/react'

export interface IProgramAdministrationProps {
title: string
Expand Down Expand Up @@ -52,13 +52,3 @@ export interface IProgramAdministrationState {
messageBarType: MessageBarType
}
}

export const shimmeredColumns: IColumn[] = [
{
key: 'Title',
name: 'Tittel',
isResizable: true,
maxWidth: 250,
minWidth: 100
}
]
2 changes: 1 addition & 1 deletion SharePointFramework/ProgramWebParts/src/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ export class SPDataAdapter extends SPDataAdapterBase<ISPDataAdapterBaseConfigura
Querytext: '*',
RowLimit: 500,
TrimDuplicates: false,
SelectProperties: [...selectProperties, 'Path', 'SiteTitle']
SelectProperties: [...selectProperties, 'Path', 'Title', 'SiteTitle', 'SPWebURL']
})
)
})
Expand Down
Loading

0 comments on commit e28d9d7

Please sign in to comment.