Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to properly use the adaptive card designer control in spfx 1.16.1 #1825

Open
JonoSuave opened this issue May 31, 2024 · 1 comment
Open

Comments

@JonoSuave
Copy link

Thank you for reporting an issue, suggesting an enhancement, or asking a question. We appreciate your feedback - to help the team understand your
needs please complete the below template to ensure we have the details to help. Thanks!

Please check out the documentation to see if your question is already addressed there. This will help us ensure our documentation is up to date.

Category

[ ] Enhancement

[ ] Bug

[ x] Question

Version

spfx 1.16.1

Please specify what version of the library you are using: [ ]
v3
If you are not using the latest release, please update and see if the issue is resolved before submitting an issue.

Question

I'm trying to update a previous solution from Angular to React. I've gotten pretty far but am now stuck on the Adaptive Card portion. I'm thinking I need to be referencing a different adaptive card node module, but would like guidance on which pnp control to pull from and how to properly convert it.

Observed Behavior

import * as ACDesigner from "@pnp/spfx-controls-react/node_modules/adaptivecards-designer" doesn't appear to be the correct module to reference, nor is import * as AC from "@pnp/spfx-controls-react/node_modules/adaptivecards".

Steps to Reproduce

Here's what my current AdaptiveCardIcon.tsx file looks:

import * as ACDesigner from "@pnp/spfx-controls-react/node_modules/adaptivecards-designer";
import * as AC from "@pnp/spfx-controls-react/node_modules/adaptivecards";
import * as ReactDOM from "react-dom";
import * as React from "react";
import { ActionButton } from "office-ui-fabric-react/lib/Button";
import { UserSearchService } from "../../services/UserSearchService/UserSearchService";

const internalRender = (renderReact: () => JSX.Element): HTMLElement => {
	const div = document.createElement("div");
	ReactDOM.render(renderReact(), div); // eslint-disable-line @microsoft/spfx/pair-react-dom-render-unmount
	return div;
};

export class AdaptiveCardIconPeer extends ACDesigner.TypedCardElementPeer<AdaptiveCardIcon> {
	public static readonly iconNameProperty = new ACDesigner.StringPropertyEditor(
		AC.Versions.v1_0,
		"iconName",
		"Icon Name"
	);

	public static readonly textProperty = new ACDesigner.StringPropertyEditor(
		AC.Versions.v1_0,
		"text",
		"Text",
		true
	);

	public static readonly urlProperty = new ACDesigner.StringPropertyEditor(
		AC.Versions.v1_0,
		"url",
		"URL",
		true
	);

	public static readonly formatAsPhoneProperty = new ACDesigner.BooleanPropertyEditor(
		AC.Versions.v1_0,
		"formatAsPhone",
		"Format as Phone Number",
		true
	);

	public populatePropertySheet(
		propertySheet: ACDesigner.PropertySheet,
		defaultCategory: string = "Action Link"
	): void {
		super.populatePropertySheet(propertySheet, defaultCategory);
		propertySheet.add(defaultCategory, AdaptiveCardIconPeer.textProperty);
		propertySheet.add(defaultCategory, AdaptiveCardIconPeer.urlProperty);
		propertySheet.add(defaultCategory, AdaptiveCardIconPeer.iconNameProperty);
		propertySheet.add(defaultCategory, AdaptiveCardIconPeer.formatAsPhoneProperty);
	}
	public initializeCardElement(): void {
		//super.initializeCardElement();
		console.log(this);
		const el = this.cardElement;
		el.iconName = "Link";
	}
}

export class AdaptiveCardIcon extends AC.CardElement {
	static readonly JsonTypeName = "ActionLink";
	static readonly iconNameProperty = new AC.StringProperty(AC.Versions.v1_0, "iconName", true);
	static readonly textProperty = new AC.StringProperty(AC.Versions.v1_0, "text", true);
	static readonly urlProperty = new AC.StringProperty(AC.Versions.v1_0, "url", true);
	static readonly formatAsPhoneProperty = new AC.BoolProperty(
		AC.Versions.v1_0,
		"formatAsPhone",
		false
	);
	@AC.property(AdaptiveCardIcon.iconNameProperty)
	get iconName(): string {
		return this.getValue(AdaptiveCardIcon.iconNameProperty);
	}

	set iconName(value: string) {
		if (this.iconName !== value) {
			this.setValue(AdaptiveCardIcon.iconNameProperty, value);

			this.updateLayout();
		}
	}

	@AC.property(AdaptiveCardIcon.textProperty)
	get text(): string {
		return this.getValue(AdaptiveCardIcon.textProperty);
	}
	set text(value: string) {
		if (this.text !== value) {
			this.setValue(AdaptiveCardIcon.textProperty, value);
			this.updateLayout();
		}
	}

	@AC.property(AdaptiveCardIcon.formatAsPhoneProperty)
	get url(): string {
		return this.getValue(AdaptiveCardIcon.urlProperty);
	}
	set url(value: string) {
		if (this.url !== value) {
			this.setValue(AdaptiveCardIcon.urlProperty, value);
			this.updateLayout();
		}
	}

	@AC.property(AdaptiveCardIcon.formatAsPhoneProperty)
	get formatAsPhone(): boolean {
		return this.getValue(AdaptiveCardIcon.formatAsPhoneProperty);
	}
	set formatAsPhone(value: boolean) {
		if (this.formatAsPhone !== value) {
			this.setValue(AdaptiveCardIcon.formatAsPhoneProperty, value);
			this.updateLayout();
		}
	}
	protected internalRender(): HTMLElement {
		const text = this.formatAsPhone ? UserSearchService.formatPhoneNumber(this.text) : this.text;
		const control = () => (
			<div onClick={(ev) => ev.stopPropagation()}>
				<ActionButton
					styles={{ root: { height: "auto" } }}
					iconProps={{ iconName: this.iconName }}
					text={text}
					href={this.url}
				/>
			</div>
		);
		const el = internalRender(control);
		return el;
	}

	getJsonTypeName(): string {
		return AdaptiveCardIcon.JsonTypeName;
	}
}

Here's my package.json:

{
  "name": "jt-sp-directory",
  "version": "0.0.1",
  "private": true,
  "engines": {
    "node": ">=16.13.0 <17.0.0"
  },
  "main": "lib/index.js",
  "scripts": {
    "build": "gulp bundle",
    "clean": "gulp clean",
    "test": "gulp test",
    "ship": "gulp clean && gulp --ship && gulp package-solution --ship",
    "serve": "gulp bundle --custom-serve --max_old_space_size=4096 && fast-serve"
  },
  "dependencies": {
    "@journeyteam/directory-extensions": "0.0.6",
    "@microsoft/microsoft-graph-types": "^2.26.0",
    "@microsoft/sp-client-base": "^1.0.0",
    "@microsoft/sp-component-base": "^1.16.1",
    "@microsoft/sp-core-library": "1.16.1",
    "@microsoft/sp-dynamic-data": "^1.16.1",
    "@microsoft/sp-http": "^1.16.1",
    "@microsoft/sp-loader": "^1.16.1",
    "@microsoft/sp-lodash-subset": "1.16.1",
    "@microsoft/sp-office-ui-fabric-core": "1.16.1",
    "@microsoft/sp-page-context": "1.16.1",
    "@microsoft/sp-property-pane": "1.16.1",
    "@microsoft/sp-webpart-base": "1.16.1",
    "@monaco-editor/loader": "^1.3.1",
    "@pnp/graph": "^3.11.0",
    "@pnp/sp": "^3.11.0",
    "@pnp/spfx-controls-react": "^3.12.0",
    "@pnp/spfx-property-controls": "^3.11.0",
    "@types/lodash": "^4.14.191",
    "handlebars": "^4.7.7",
    "libphonenumber-js": "^1.10.18",
    "lodash": "^4.17.21",
    "office-ui-fabric-react": "^7.204.0",
    "pnpm": "^9.1.4",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "tslib": "2.3.1"
  },
  "devDependencies": {
    "@microsoft/eslint-config-spfx": "1.16.1",
    "@microsoft/eslint-plugin-spfx": "1.16.1",
    "@microsoft/rush-stack-compiler-4.5": "0.2.2",
    "@microsoft/sp-build-web": "1.16.1",
    "@microsoft/sp-module-interfaces": "1.16.1",
    "@rushstack/eslint-config": "2.5.1",
    "@types/react": "17.0.45",
    "@types/react-dom": "17.0.17",
    "@types/webpack-env": "~1.15.2",
    "ajv": "^6.12.5",
    "eslint-plugin-react-hooks": "4.3.0",
    "gulp": "4.0.2",
    "spfx-fast-serve-helpers": "^1.16.1",
    "typescript": "4.5.5"
  },
  "volta": {
    "node": "16.19.0"
  }
}

Attached are the errors I'm getting.
Screenshot 2024-05-30 at 6 07 07 PM
Screenshot 2024-05-30 at 6 07 45 PM
Screenshot 2024-05-30 at 6 07 57 PM

Copy link

Thank you for submitting your first issue to this project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant