Skip to content

Commit

Permalink
Locale strings + TermSet selection (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
estruyf committed Apr 17, 2018
1 parent 6461e31 commit d15d356
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 56 deletions.
9 changes: 8 additions & 1 deletion src/controls/taxonomyPicker/ITaxonomyPicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ export interface ITaxonomyPickerProps {
* Id of a child term in the termset where to be able to selected and search the terms from
*/
ancoreId?: string;
/**
* Specify if the term set itself is selectable in the tree view
*/
isTermSetSelectable?: boolean;
/**
* Whether the property pane field is enabled or not.
*/
Expand Down Expand Up @@ -80,9 +84,12 @@ export interface ITermChanges {

export interface ITermParentProps extends ITermChanges {
termset: ITermSet;
autoExpand: () => void;
multiSelection: boolean;
anchorId? : string;
isTermSetSelectable?: boolean;

autoExpand: () => void;
termSetSelectedChange?: (termSet: ITermSet, isChecked: boolean) => void;
}

export interface ITermParentState {
Expand Down
17 changes: 14 additions & 3 deletions src/controls/taxonomyPicker/TaxonomyPicker.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@
margin-left: 15px;
}

.termSetSelectable {
height: 50px;
line-height: 50px;
}

.termSetSelector {
display: inline-block;
margin: 0 8px 0 4px;
vertical-align: middle;
}

.term {
padding-left: 20px;

Expand Down Expand Up @@ -72,8 +83,8 @@
width: 100%;
text-align: left;
cursor: pointer;


.termSuggestionSubTitle
{
font-size: 12px;
Expand Down Expand Up @@ -129,7 +140,7 @@
display: flex;
align-items: center;
}

.errorIcon {
font-size: 14px;
margin-right: 5px;
Expand Down
33 changes: 25 additions & 8 deletions src/controls/taxonomyPicker/TaxonomyPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as React from 'react';
import { IWebPartContext } from '@microsoft/sp-webpart-base';
import { Async } from 'office-ui-fabric-react/lib/Utilities';
import { PrimaryButton, DefaultButton, IconButton, IButtonProps } from 'office-ui-fabric-react/lib/Button';
import { Panel, PanelType } from 'office-ui-fabric-react/lib/Panel';
import { Spinner, SpinnerType } from 'office-ui-fabric-react/lib/Spinner';
Expand Down Expand Up @@ -32,7 +31,6 @@ export const TERM_IMG = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQC
* Renders the controls for PropertyFieldTermPicker component
*/
export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxonomyPickerState> {
private async: Async;
private delayedValidate: (value: IPickerTerms) => void;
private termsService: SPTermStorePickerService;
private previousValues: IPickerTerms = [];
Expand All @@ -58,7 +56,6 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
this.onClosePanel = this.onClosePanel.bind(this);
this.onSave = this.onSave.bind(this);
this.termsChanged = this.termsChanged.bind(this);
this.async = new Async(this);
this.termsFromPickerChanged = this.termsFromPickerChanged.bind(this);
}

Expand Down Expand Up @@ -202,12 +199,29 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
}

/**
* Called when the component will unmount
* TermSet selection handler
* @param termSet
* @param isChecked
*/
public componentWillUnmount() {
if (typeof this.async !== 'undefined') {
this.async.dispose();
}
private termSetSelectedChange = (termSet: ITermSet, isChecked: boolean) => {
const ts: ITermSet = {...termSet};
// Clean /Guid.../ from the ID
ts.Id = this.termsService.cleanGuid(ts.Id);
// Create a term for the termset
const term: ITerm = {
Name: ts.Name,
Id: ts.Id,
TermSet: ts,
PathOfTerm: "",
_ObjectType_: ts._ObjectType_,
_ObjectIdentity_: ts._ObjectIdentity_,
Description: ts.Description,
IsDeprecated: null,
IsRoot: null
};

// Trigger the normal change event
this.termsChanged(term, isChecked);
}

/**
Expand All @@ -227,6 +241,7 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
termPickerHostProps={this.props}
disabled={this.props.disabled}
value={this.state.activeNodes}
isTermSetSelectable={this.props.isTermSetSelectable}
onChanged={this.termsFromPickerChanged}
allowMultipleSelections={this.props.allowMultipleSelections}
/>
Expand Down Expand Up @@ -268,6 +283,8 @@ export class TaxonomyPicker extends React.Component<ITaxonomyPickerProps, ITaxon
<TermParent anchorId={this.props.ancoreId}
autoExpand={null}
termset={this.state.termSetAndTerms}
isTermSetSelectable={this.props.isTermSetSelectable}
termSetSelectedChange={this.termSetSelectedChange}
activeNodes={this.state.activeNodes}
changedCallback={this.termsChanged}
multiSelection={this.props.allowMultipleSelections} />
Expand Down
61 changes: 41 additions & 20 deletions src/controls/taxonomyPicker/TermParent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { EXPANDED_IMG, COLLAPSED_IMG, TERMSET_IMG, TERM_IMG } from './TaxonomyPi
import Term from './Term';

import styles from './TaxonomyPicker.module.scss';
import { Checkbox } from 'office-ui-fabric-react';
import * as strings from 'ControlStrings';

/**
* Term Parent component, represents termset or term if anchorId
Expand All @@ -17,6 +19,7 @@ export default class TermParent extends React.Component<ITermParentProps, ITermP

constructor(props: ITermParentProps) {
super(props);

this._terms = this.props.termset.Terms;
this.state = {
loaded: true,
Expand All @@ -25,19 +28,7 @@ export default class TermParent extends React.Component<ITermParentProps, ITermP
this._handleClick = this._handleClick.bind(this);
}



/**
* Handle the click event: collapse or expand
*/
private _handleClick() {
this.setState({
expanded: !this.state.expanded
});
}


/**
* componentWillMount
*/
public componentWillMount()
Expand All @@ -51,10 +42,10 @@ export default class TermParent extends React.Component<ITermParentProps, ITermP
const anchorDepth = anchorTerm.PathDepth;
this._anchorName = anchorTerm.Name;
var anchorTerms : ITerm[] = this._terms.filter(t => t.PathOfTerm.substring(0, anchorTerm.PathOfTerm.length) === anchorTerm.PathOfTerm && t.Id !== anchorTerm.Id);

anchorTerms = anchorTerms.map(term => {
term.PathDepth = term.PathDepth - anchorTerm.PathDepth;

return term;
});

Expand All @@ -64,6 +55,24 @@ export default class TermParent extends React.Component<ITermParentProps, ITermP
}


/**
* Handle the click event: collapse or expand
*/
private _handleClick() {
this.setState({
expanded: !this.state.expanded
});
}


/**
* The term set selection changed
*/
private termSetSelectionChange = (ev: React.FormEvent<HTMLElement>, isChecked: boolean): void => {
this.props.termSetSelectedChange(this.props.termset, isChecked);
}


public render(): JSX.Element {
// Specify the inline styling to show or hide the termsets
const styleProps: React.CSSProperties = {
Expand All @@ -72,7 +81,7 @@ export default class TermParent extends React.Component<ITermParentProps, ITermP

let termElm: JSX.Element = <div />;
// Check if the terms have been loaded

if (this.state.loaded) {
if (this._terms.length > 0) {
termElm = (
Expand All @@ -85,18 +94,30 @@ export default class TermParent extends React.Component<ITermParentProps, ITermP
</div>
);
} else {
termElm = <div className={`${styles.listItem} ${styles.term}`}>Term set does not contain any terms</div>;
termElm = <div className={`${styles.listItem} ${styles.term}`}>{strings.TaxonomyPickerNoTerms}</div>;
}
} else {
termElm = <Spinner type={SpinnerType.normal} />;
}


return (
<div>
<div className={`${styles.listItem} ${styles.termset}`} onClick={this._handleClick}>
<img src={this.state.expanded ? EXPANDED_IMG : COLLAPSED_IMG} alt='Expand This Term Set' title='Expand This Term Set' />
<img src={this.props.anchorId ? TERM_IMG : TERMSET_IMG} title='Menu for Term Set' alt='Menu for Term Set' /> {this.props.anchorId ? this._anchorName : this.props.termset.Name}
<div className={`${styles.listItem} ${styles.termset} ${(!this.props.anchorId && this.props.isTermSetSelectable) ? styles.termSetSelectable : ""}`} onClick={this._handleClick}>
<img src={this.state.expanded ? EXPANDED_IMG : COLLAPSED_IMG} alt={strings.TaxonomyPickerExpandTitle} title={strings.TaxonomyPickerExpandTitle} />
{
// Show the termset selection box
(!this.props.anchorId && this.props.isTermSetSelectable) &&
<Checkbox className={styles.termSetSelector}
checked={this.props.activeNodes.filter(a => a.path === "" && a.key === a.termSet).length >= 1}
onChange={this.termSetSelectionChange} />
}
<img src={this.props.anchorId ? TERM_IMG : TERMSET_IMG} alt={strings.TaxonomyPickerMenuTermSet} title={strings.TaxonomyPickerMenuTermSet} />
{
this.props.anchorId ?
this._anchorName :
this.props.termset.Name
}
</div>
<div style={styleProps}>
{termElm}
Expand Down
23 changes: 20 additions & 3 deletions src/controls/taxonomyPicker/TermPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import SPTermStorePickerService from './../../services/SPTermStorePickerService'
import styles from './TaxonomyPicker.module.scss';
import { ITaxonomyPickerProps } from './ITaxonomyPicker';
import { IWebPartContext } from '@microsoft/sp-webpart-base';
import * as strings from 'ControlStrings';

export class TermBasePicker extends BasePicker<IPickerTerm, IBasePickerProps<IPickerTerm>>
{
Expand All @@ -20,8 +21,9 @@ export interface ITermPickerProps {
context: IWebPartContext;
disabled: boolean;
value: IPickerTerms;
onChanged: (items: IPickerTerm[]) => void;
allowMultipleSelections : boolean;
isTermSetSelectable?: boolean;
onChanged: (items: IPickerTerm[]) => void;
}

export default class TermPicker extends React.Component<ITermPickerProps, ITermPickerState> {
Expand Down Expand Up @@ -91,7 +93,7 @@ export default class TermPicker extends React.Component<ITermPickerProps, ITermP
return (
<div className={styles.termSuggestion} title={termTitle}>
<div>{term.name}</div>
<div className={styles.termSuggestionSubTitle}> in {termParent}</div>
<div className={styles.termSuggestionSubTitle}> {strings.TaxonomyPickerInLabel} {termParent ? termParent : strings.TaxonomyPickerTermSetLabel}</div>
</div>
);
}
Expand All @@ -102,7 +104,22 @@ export default class TermPicker extends React.Component<ITermPickerProps, ITermP
private async onFilterChanged(filterText: string, tagList: IPickerTerm[]): Promise<IPickerTerm[]> {
if (filterText !== "") {
let termsService = new SPTermStorePickerService(this.props.termPickerHostProps, this.props.context);
let terms = await termsService.searchTermsByName(filterText);
let terms: IPickerTerm[] = await termsService.searchTermsByName(filterText);
// Check if the termset can be selected
if (this.props.isTermSetSelectable) {
// Retrieve the current termset
const termSet = await termsService.getTermSet();
// Check if termset was retrieved and if it contains the filter value
if (termSet && termSet.Name.toLowerCase().indexOf(filterText.toLowerCase()) === 0) {
// Add the termset to the suggestion list
terms.push({
key: termsService.cleanGuid(termSet.Id),
name: termSet.Name,
path: "",
termSet: termsService.cleanGuid(termSet.Id)
});
}
}
// Filter out the terms which are already set
const filteredTerms = [];
for (const term of terms) {
Expand Down
8 changes: 7 additions & 1 deletion src/loc/en-us.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ define([], () => {
"SendEmailTo": "Send an email to {0}",
"StartChatWith": "Start a chat with {0}",
"Contact": "Contact",
"UpdateProfile": "Update your profile"
"UpdateProfile": "Update your profile",

"TaxonomyPickerNoTerms": "Term set does not contain any terms",
"TaxonomyPickerExpandTitle": "Expand This Term Set",
"TaxonomyPickerMenuTermSet": "Menu for Term Set",
"TaxonomyPickerInLabel": "in",
"TaxonomyPickerTermSetLabel": "Term Set"
};
});
7 changes: 7 additions & 0 deletions src/loc/mystrings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ declare interface IControlStrings {
StartChatWith: string;
Contact: string;
UpdateProfile: string;

// Taxonomy picker
TaxonomyPickerNoTerms: string;
TaxonomyPickerExpandTitle: string;
TaxonomyPickerMenuTermSet: string;
TaxonomyPickerInLabel: string;
TaxonomyPickerTermSetLabel: string;
}

declare module 'ControlStrings' {
Expand Down
Loading

0 comments on commit d15d356

Please sign in to comment.