Skip to content

Commit

Permalink
Bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
jameshawkinscodes committed Nov 22, 2024
1 parent 8b2c7f0 commit 4d98f05
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 46 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ The Blurb web part offers a clean and stylish way to combine text and images. It

| Version | Date | Comments |
| ------- | ---------------- | --------------- |
| 0.0.1 | October 20, 2024 | Development release |
| 0.0.5 | November 22, 2024 | Development release |
| 0.0.1 | October 20, 2024 | Development release |

## Disclaimer

Expand All @@ -43,13 +44,13 @@ The Blurb web part offers a clean and stylish way to combine text and images. It
The Blurb web part allows users to display information in up to four customizable content containers. Each container can be independently styled and displayed in a single row, making it easy to organize and present multiple pieces of important content side by side.

- **Text and Image Combination**:
Each container supports a combination of rich text and imagery. Users can add a title, formatted text, and hyperlinks, making it flexible for various types of content. Whether it’s a brief announcement or detailed information, the Blurb web part adapts to different needs.
Each container supports a combination of ~~rich~~ text and imagery. Users can add a title, ~~formatted~~ text, and hyperlinks, making it flexible for various types of content. Whether it’s a brief announcement or detailed information, the Blurb web part adapts to different needs. Rich text editor will be added in a future update.

- **Customizable Appearance**:
You can tailor the appearance of each container by setting different border colors and background colors, ensuring that the Blurb fits seamlessly with the design of your SharePoint page.

- **Icon Options**:
Users have the option to choose between an icon or a custom image for each container. Icons are available for quick selection, while custom images can be uploaded to personalize each blurb further.
Users have the option to choose between an icon or ~~a custom image~~ for each container. Icons are available for quick selection, while custom images will be added in a future update.

- **Easy Editing Experience**:
The web part includes an intuitive Edit Web Part panel where users can manage and style containers without leaving the edit mode of the page. The layout and design controls are centralized, simplifying customization.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sharepoint-blurb-web-part",
"version": "0.0.1",
"version": "0.0.5",
"private": true,
"engines": {
"node": ">=18.17.1 <19.0.0"
Expand Down
60 changes: 52 additions & 8 deletions src/webparts/blurb/BlurbWebPart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export interface IBlurbWebPartProps {
linkTarget?: string;
}>;
}

export default class BlurbWebPart extends BaseClientSideWebPart<IBlurbWebPartProps> {
private _isDarkTheme: boolean = false;
private _environmentMessage: string = '';
Expand All @@ -42,24 +41,32 @@ export default class BlurbWebPart extends BaseClientSideWebPart<IBlurbWebPartPro
userDisplayName: this.context.pageContext.user.displayName,
containers: this.properties.containers || [],
containerCount: this.properties.containerCount || 1,
isEditMode: this._isEditMode,

onContainerClick: async (index: number) => {
// Close the property pane if it's already open
if (this.context.propertyPane.isRenderedByWebPart()) {
this.context.propertyPane.close();
}
// Delay to ensure the pane has closed
await new Promise(resolve => setTimeout(resolve, 10));

// Set the selected container and enter edit mode
this.selectedContainerIndex = index;
this._isEditMode = true;
this.context.propertyPane.refresh();
this.context.propertyPane.open();
},
onEditClick: async (index: number) => {
// Handle edit click by closing and reopening the property pane
this.selectedContainerIndex = index;
this._isEditMode = true;

if (this.context.propertyPane.isRenderedByWebPart()) {
this.context.propertyPane.close();
}
await new Promise(resolve => setTimeout(resolve, 10));

await new Promise(resolve => setTimeout(resolve, 10)); // Delay for smooth reopening
this.context.propertyPane.refresh();
this.context.propertyPane.open();
},
Expand All @@ -73,12 +80,12 @@ export default class BlurbWebPart extends BaseClientSideWebPart<IBlurbWebPartPro
this.properties.containers[index] = this.properties.containers[index + 1];
this.properties.containers[index + 1] = temp;
}
this.render();
this.render(); // Re-render to reflect the new order
},
onRemoveClick: (index: number, updatedCount: number) => {
this.properties.containers.splice(index, 1);
this.properties.containerCount = updatedCount;
this.render();
this.properties.containerCount = updatedCount; // Update the container count
this.render(); // Re-render the component to reflect the changes
},
}
);
Expand All @@ -105,10 +112,10 @@ export default class BlurbWebPart extends BaseClientSideWebPart<IBlurbWebPartPro
borderColor: '#EDEBE9',
borderRadius: '0',
fontColor: '#323130',
title: '',
title: ``,
text: '',
linkUrl: '',
linkTarget: '_self'
linkTarget: '_self',
});
}
} else if (this.properties.containerCount < currentContainerCount) {
Expand All @@ -121,6 +128,15 @@ export default class BlurbWebPart extends BaseClientSideWebPart<IBlurbWebPartPro
return super.onInit();
}

protected onDispose(): void {
ReactDom.unmountComponentAtNode(this.domElement);
}

protected onPropertyPaneConfigurationComplete(): void {
this._isEditMode = false;
this.selectedContainerIndex = -1;
}

private async _getEnvironmentMessage(): Promise<string> {
if (!!this.context.sdks.microsoftTeams) {
const context = await this.context.sdks.microsoftTeams.teamsJs.app.getContext();
Expand All @@ -143,6 +159,34 @@ export default class BlurbWebPart extends BaseClientSideWebPart<IBlurbWebPartPro
return this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentSharePoint : strings.AppSharePointEnvironment;
}

protected onPropertyPaneFieldChanged(propertyPath: string, oldValue: string | number, newValue: string | number): void {
if (propertyPath === 'containerCount' && newValue !== oldValue) {
const newContainerCount = newValue as number;
const currentContainerCount = this.properties.containers.length;

if (newContainerCount > currentContainerCount) {
for (let i = currentContainerCount; i < newContainerCount; i++) {
this.properties.containers.push({
icon: 'CannedChat',
backgroundColor: '#FAF9F8',
borderColor: '#EDEBE9',
borderRadius: '0',
fontColor: '#323130',
title: ``,
text: '',
linkUrl: '',
linkTarget: '_self',
});
}
} else if (newContainerCount < currentContainerCount) {
this.properties.containers.splice(newContainerCount);
}
}

super.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue);
this.render();
}
// The blurb properties pane
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
if (this._isEditMode && this.selectedContainerIndex !== -1) {
const selectedContainer = this.properties.containers[this.selectedContainerIndex] || {};
Expand Down Expand Up @@ -232,7 +276,7 @@ export default class BlurbWebPart extends BaseClientSideWebPart<IBlurbWebPartPro
]
};
}

// The main web part properties pane
return {
pages: [
{
Expand Down
Binary file removed src/webparts/blurb/assets/welcome-dark.png
Binary file not shown.
Binary file removed src/webparts/blurb/assets/welcome-light.png
Binary file not shown.
47 changes: 13 additions & 34 deletions src/webparts/blurb/components/Blurb.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,45 @@ import styles from './Blurb.module.scss';
export const Blurb: React.FunctionComponent<IBlurbProps> = (props) => {
const [selectedBlurbIndex, setSelectedBlurbIndex] = React.useState<number | null>(null);

const handleContainerClick = (index: number): void => {
const handleContainerClick = (index: number, e: React.MouseEvent): void => {
if (props.isEditMode) {
e.preventDefault(); // Prevent link navigation in edit mode
}
props.onContainerClick(index);
setSelectedBlurbIndex(index);
};

const handleMoveClick = (index: number, direction: 'up' | 'down'): void => {
props.onMoveClick(index, direction);
};

const handleRemoveClick = (index: number): void => {
const updatedCount = props.containers.length - 1; // Calculate the updated count
props.onRemoveClick(index, updatedCount); // Pass both index and updated count
setSelectedBlurbIndex(null);
};

React.useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (!document.querySelector(`.${styles.blurbContainer}`)?.contains(event.target as Node)) {
setSelectedBlurbIndex(null);
}
};

document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);

return (
<div className={styles.blurbContainer}>
<div className={styles.containerGrid}>
{props.containers.map((container, index) => {
const isSelected = selectedBlurbIndex === index;

// Determine the wrapper element based on whether the blurb has a link
const WrapperElement = container.linkUrl ? 'a' : 'div';
const wrapperProps = container.linkUrl
? {
href: container.linkUrl,
target: container.linkTarget || '_self',
className: styles.clickableBlurb,
onClick: (e: React.MouseEvent) => handleContainerClick(index, e),
}
: {};
: {
onClick: (e: React.MouseEvent) => handleContainerClick(index, e),
};

return (
<WrapperElement
key={index}
{...wrapperProps}
onClick={() => handleContainerClick(index)}
className={`${styles.container} ${isSelected ? styles.selected : ''}`}
style={{
backgroundColor: container.backgroundColor,
border: `1px solid ${isSelected ? '#333' : container.borderColor}`,
borderRadius: container.borderRadius,
boxShadow: isSelected ? '0 0 5px rgba(0, 0, 0, 0.3)' : 'none',
textDecoration: 'none', // Ensure links don't have underlines
textDecoration: 'none',
}}
>
{/* Secondary Toolbar */}
{isSelected && (
<div
className={`${styles.toolbar} CanvasControlToolbar-item LightTheme`}
Expand All @@ -77,7 +57,7 @@ export const Blurb: React.FunctionComponent<IBlurbProps> = (props) => {
ariaLabel="Move Up"
onClick={(e) => {
e.stopPropagation();
handleMoveClick(index, 'up');
props.onMoveClick(index, 'up');
}}
className={`${styles.toolbarIcon} ToolbarButton`}
/>
Expand All @@ -87,7 +67,7 @@ export const Blurb: React.FunctionComponent<IBlurbProps> = (props) => {
ariaLabel="Move Down"
onClick={(e) => {
e.stopPropagation();
handleMoveClick(index, 'down');
props.onMoveClick(index, 'down');
}}
className={`${styles.toolbarIcon} ToolbarButton`}
/>
Expand All @@ -97,14 +77,13 @@ export const Blurb: React.FunctionComponent<IBlurbProps> = (props) => {
ariaLabel="Remove"
onClick={(e) => {
e.stopPropagation();
handleRemoveClick(index);
props.onRemoveClick(index, props.containers.length - 1);
}}
className={`${styles.toolbarIcon} ToolbarButton`}
/>
</div>
)}

{/* Main Content */}
{container.icon && (
<Icon
iconName={container.icon}
Expand All @@ -120,4 +99,4 @@ export const Blurb: React.FunctionComponent<IBlurbProps> = (props) => {
</div>
</div>
);
};
};
1 change: 1 addition & 0 deletions src/webparts/blurb/components/IBlurbProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export interface IBlurbProps {
linkTarget?: "_self" | "_blank" | string;
}>;
containerCount: number;
isEditMode: boolean;
onContainerClick: (index: number) => void;
onEditClick: (index: number) => void;
onMoveClick: (index: number, direction: 'up' | 'down') => void; // Updated to include direction
Expand Down

0 comments on commit 4d98f05

Please sign in to comment.