-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bestillingsløsning (Provisjonering) (#1541)
* Initial webpart * Linting * Add inital Drawer with mvp content * Add correct config file * Add dialog with privision status * Improvements to provision status dialog + actions * Finish the barebones * Restructure, add context and state machine * More restructuring * Minor adjustments * Add setColumn functionality for the fields in the drawer * Finish all the different types of input fields * Add validation check for guest emails * Add ability to create provision request from any given provision site * Run rush after rebase... * Add function to ensure users from the provision site * Add remaining fields for onSave * Minor adjustments * Dynamically get siteTypes * Add toaster * Add strings locale + minor adjustments * Finishing touches * Add "Teamify" option * Rebase with latest 1.10
- Loading branch information
Showing
47 changed files
with
3,783 additions
and
1,536 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
76 changes: 76 additions & 0 deletions
76
SharePointFramework/PortfolioWebParts/src/components/ProjectProvision/ProjectProvision.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { | ||
Menu, | ||
MenuButtonProps, | ||
MenuItem, | ||
MenuList, | ||
MenuPopover, | ||
MenuTrigger, | ||
Skeleton, | ||
SkeletonItem, | ||
SplitButton, | ||
Toaster, | ||
useId, | ||
useRestoreFocusTarget, | ||
useToastController | ||
} from '@fluentui/react-components' | ||
import React, { FC } from 'react' | ||
import { IProjectProvisionProps } from './types' | ||
import { getFluentIcon } from 'pp365-shared-library' | ||
import { ProvisionStatus } from './ProvisionStatus' | ||
import { useProjectProvision } from './useProjectProvision' | ||
import { ProjectProvisionContext } from './context' | ||
import { ProvisionDrawer } from './ProvisionDrawer' | ||
import strings from 'PortfolioWebPartsStrings' | ||
|
||
export const ProjectProvision: FC<IProjectProvisionProps> = (props) => { | ||
const { state, setState, column, setColumn } = useProjectProvision(props) | ||
const restoreFocusTargetAttribute = useRestoreFocusTarget() | ||
const toasterId = useId('saveToaster') | ||
const { dispatchToast } = useToastController(toasterId) | ||
|
||
if (state.loading) { | ||
return ( | ||
<Skeleton> | ||
<SkeletonItem style={{ width: '192px', height: '40px' }} /> | ||
</Skeleton> | ||
) | ||
} | ||
|
||
return ( | ||
<ProjectProvisionContext.Provider value={{ props, state, setState, column, setColumn }}> | ||
<ProvisionDrawer toast={dispatchToast} /> | ||
<Menu positioning='below-end'> | ||
<MenuTrigger disableButtonEnhancement> | ||
{(triggerProps: MenuButtonProps) => ( | ||
<SplitButton | ||
menuButton={triggerProps} | ||
primaryActionButton={{ | ||
onClick: () => setState({ showProvisionDrawer: true }) | ||
}} | ||
icon={getFluentIcon('Add')} | ||
appearance='primary' | ||
size='large' | ||
> | ||
{strings.Provision.ProvisionButtonLabel} | ||
</SplitButton> | ||
)} | ||
</MenuTrigger> | ||
<MenuPopover> | ||
<MenuList> | ||
<MenuItem | ||
{...restoreFocusTargetAttribute} | ||
onClick={() => { | ||
setState({ showProvisionStatus: true }) | ||
}} | ||
> | ||
{strings.Provision.StatusMenuLabel} | ||
</MenuItem> | ||
<MenuItem>{strings.Provision.IdeaMenuLabel}</MenuItem> | ||
</MenuList> | ||
</MenuPopover> | ||
</Menu> | ||
<ProvisionStatus /> | ||
<Toaster toasterId={toasterId} /> | ||
</ProjectProvisionContext.Provider> | ||
) | ||
} |
26 changes: 26 additions & 0 deletions
26
...ramework/PortfolioWebParts/src/components/ProjectProvision/ProvisionDrawer/DebugModel.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import React, { FC } from 'react' | ||
import { useProjectProvisionContext } from '../context' | ||
|
||
/** | ||
* Shows `model.properties` in a `pre` tag. | ||
*/ | ||
export const DebugModel: FC = () => { | ||
const context = useProjectProvisionContext() | ||
return ( | ||
<div> | ||
<pre | ||
style={{ | ||
whiteSpace: 'pre-wrap', | ||
wordWrap: 'break-word', | ||
background: 'rgba(0,0,0,0.1)', | ||
padding: 10, | ||
borderRadius: 5 | ||
}} | ||
> | ||
{JSON.stringify(context.state.properties, null, 2)} | ||
</pre> | ||
</div> | ||
) | ||
} | ||
|
||
DebugModel.displayName = 'DebugModel' |
101 changes: 101 additions & 0 deletions
101
...amework/PortfolioWebParts/src/components/ProjectProvision/ProvisionDrawer/Guest/Guest.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import { | ||
TagPickerProps, | ||
useTagPickerFilter, | ||
TagPickerOption, | ||
Avatar, | ||
Tag, | ||
TagPicker, | ||
TagPickerControl, | ||
TagPickerGroup, | ||
TagPickerInput, | ||
TagPickerList | ||
} from '@fluentui/react-components' | ||
import strings from 'PortfolioWebPartsStrings' | ||
import { useProjectProvisionContext } from 'components/ProjectProvision/context' | ||
import React, { useState } from 'react' | ||
|
||
export const Guest = (props: { disabled?: boolean }) => { | ||
const context = useProjectProvisionContext() | ||
const [query, setQuery] = useState<string>('') | ||
const [selectedGuests, setSelectedGuests] = useState<string[]>(context.column.get('guest') || []) | ||
const options = [query] | ||
|
||
const onOptionSelect: TagPickerProps['onOptionSelect'] = (_, data) => { | ||
if (data.value === 'no-matches') { | ||
return | ||
} | ||
|
||
if (query && (!query.includes('@') || !query.includes('.'))) { | ||
return | ||
} | ||
|
||
if (!data.selectedOptions.find((option) => option === data.value)) { | ||
context.setColumn( | ||
'guest', | ||
context.column.get('guest').filter((guest) => guest !== data.value) | ||
) | ||
} else { | ||
context.setColumn('guest', [...context.column.get('guest'), data.value]) | ||
} | ||
|
||
if (!data.selectedOptions) { | ||
context.setColumn('guest', []) | ||
} | ||
|
||
setSelectedGuests(data.selectedOptions) | ||
setQuery('') | ||
} | ||
|
||
const children = useTagPickerFilter({ | ||
query, | ||
options, | ||
noOptionsElement: ( | ||
<TagPickerOption value='no-matches'> | ||
{strings.Provision.GuestFieldNoOptionsText} | ||
</TagPickerOption> | ||
), | ||
renderOption: (guest) => { | ||
return ( | ||
<TagPickerOption | ||
key={guest} | ||
value={guest} | ||
media={<Avatar aria-hidden name={guest} color='colorful' />} | ||
> | ||
{guest} | ||
</TagPickerOption> | ||
) | ||
}, | ||
filter: (option) => | ||
!selectedGuests.includes(option) && option.toLowerCase().includes(query.toLowerCase()) | ||
}) | ||
|
||
return ( | ||
<div> | ||
<TagPicker | ||
onOptionSelect={onOptionSelect} | ||
selectedOptions={selectedGuests} | ||
disabled={props.disabled} | ||
> | ||
<TagPickerControl> | ||
<TagPickerGroup> | ||
{selectedGuests.map((guest) => ( | ||
<Tag | ||
key={guest} | ||
media={<Avatar aria-hidden name={guest} color='colorful' />} | ||
value={guest} | ||
> | ||
{guest} | ||
</Tag> | ||
))} | ||
</TagPickerGroup> | ||
<TagPickerInput | ||
value={query} | ||
onChange={(e) => setQuery(e.target.value)} | ||
placeholder={strings.Placeholder.GuestField} | ||
/> | ||
</TagPickerControl> | ||
<TagPickerList>{children}</TagPickerList> | ||
</TagPicker> | ||
</div> | ||
) | ||
} |
1 change: 1 addition & 0 deletions
1
...ramework/PortfolioWebParts/src/components/ProjectProvision/ProvisionDrawer/Guest/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './Guest' |
57 changes: 57 additions & 0 deletions
57
...folioWebParts/src/components/ProjectProvision/ProvisionDrawer/ProvisionDrawer.module.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
.toolbar { | ||
justify-content: space-between; | ||
} | ||
|
||
.body { | ||
flex: 1; | ||
width: 100%; | ||
max-width: 100%; | ||
position: relative; | ||
|
||
.content { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 16px; | ||
|
||
.sitetypes { | ||
display: flex; | ||
gap: 12px; | ||
flex-wrap: wrap; | ||
} | ||
|
||
.ignoreGap { | ||
margin-top: 0; | ||
margin-bottom: 0; | ||
} | ||
|
||
.footer { | ||
margin: 12px 0 0 0; | ||
} | ||
|
||
.flexContent { | ||
display: flex; | ||
flex-direction: row; | ||
gap: 16px; | ||
} | ||
} | ||
|
||
.level { | ||
position: "absolute"; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
bottom: 0; | ||
|
||
&:first-child { | ||
padding-top: 0; | ||
} | ||
|
||
&:last-child { | ||
padding-bottom: 0; | ||
} | ||
} | ||
} | ||
|
||
.footer { | ||
justify-content: space-between; | ||
} |
Oops, something went wrong.