Skip to content

Commit

Permalink
Improvements to document template selector component #251 (#252)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ole Martin Pettersen authored and Ole Martin Pettersen committed Mar 7, 2020
1 parent ceedf44 commit 3d9bdd9
Show file tree
Hide file tree
Showing 15 changed files with 322 additions and 305 deletions.
4 changes: 2 additions & 2 deletions SharePointFramework/ProjectExtensions/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
"scripts": {
"serve": "gulp serve --locale=nb-no",
"serveNoBrowser": "gulp serve --locale=nb-no --nobrowser",
"serveTemplateSelector": "gulp serve --locale=nb-no --config=templateSelector",
"serveProjectSetup": "gulp serve --locale=nb-no --config=projectSetup",
"serveTemplateSelector": "gulp serve --locale=nb-no --config=TemplateSelectorCommand",
"serveProjectUpgrade": "gulp serve --locale=nb-no --config=ProjectUpgrade",
"package": "gulp clean && gulp default --ship && gulp package-solution --ship",
"deploy": "gulp uploadAppPkg && gulp deploySppkg",
"packageAndDeploy": "npm run package && npm run deploy",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,29 @@
.documentTemplateDialogScreenEditCopy {
.item {
margin: 0 0 20px 0;

.header {
position: relative;
cursor: pointer;
position: relative;
cursor: pointer;

.title {
font-size: 18px;
font-weight: 100;
}

.icon {
position: absolute;
top: 0;
right: 0;
position: absolute;
top: 0;
right: 0;
}
}

.nameInput {
margin: 5px 0 0 0;
}

.titleInput {
margin: 5px 0 0 0;
}
}
.copyAction {
margin: 20px 0 0 0;
button {
width: 100%;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,63 +1,19 @@
import { getId } from '@uifabric/utilities';
import { SPDataAdapter } from 'data';
import { Icon } from 'office-ui-fabric-react/lib/Icon';
import { TextField } from 'office-ui-fabric-react/lib/TextField';
import * as strings from 'ProjectExtensionsStrings';
import * as React from 'react';
import styles from './DocumentTemplateItem.module.scss';
import { IDocumentTemplateItemProps } from './IDocumentTemplateItemProps';
import { IDocumentTemplateItemState } from './IDocumentTemplateItemState';
import { getId } from '@uifabric/utilities';
import { SPDataAdapter } from 'data';

export class DocumentTemplateItem extends React.Component<IDocumentTemplateItemProps, IDocumentTemplateItemState> {
private _nameId = getId('name');
private _titleId = getId('title');
private _changeTimeout: number;

constructor(props: IDocumentTemplateItemProps) {
super(props);
this.state = { isExpanded: false };
}
// tslint:disable-next-line: naming-convention
export const DocumentTemplateItem = (props: IDocumentTemplateItemProps) => {
const nameId = getId('name');
const titleId = getId('title');
let changeTimeout: number;
const [isExpanded, setIsExpanded] = React.useState(false);

public async componentDidMount() {
let errorMessage = await SPDataAdapter.isFilenameValid(this.props.folderServerRelativeUrl, this.props.model.name);
if (errorMessage) {
this.props.onInputChanged(this.props.model.id, {}, errorMessage);
this.setState({ isExpanded: true });
}
}

public render(): React.ReactElement<IDocumentTemplateItemProps> {
return (
<div className={styles.documentTemplateItem}>
<div className={styles.header} onClick={this._onExpandCollapse.bind(this)}>
<div className={styles.title}>{this.props.model.name}</div>
<div className={styles.icon}>
<Icon iconName={this.state.isExpanded ? 'ChevronDown' : 'ChevronUp'} />
</div>
</div>
<div hidden={!this.state.isExpanded}>
<div className={styles.inputField}>
<TextField
id={this._nameId}
label={strings.NameLabel}
placeholder={strings.NameLabel}
defaultValue={this.props.model.nameWithoutExtension}
suffix={`.${this.props.model.fileExtension}`}
errorMessage={this.props.model.errorMessage}
onChange={this._onInputChange.bind(this)} />
</div>
<div className={styles.inputField}>
<TextField
id={this._titleId}
label={strings.TitleLabel}
placeholder={strings.TitleLabel}
defaultValue={this.props.model.title}
onChange={this._onInputChange.bind(this)} />
</div>
</div>
</div>
);
}

/**
* On input change
Expand All @@ -66,28 +22,61 @@ export class DocumentTemplateItem extends React.Component<IDocumentTemplateItemP
* @param {string} newValue New value
* @param {number} resolveDelay Resolve delay
*/
private _onInputChange(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue: string, resolveDelay: number = 400) {
clearTimeout(this._changeTimeout);
this._changeTimeout = setTimeout(async () => {
function onInputChange(event: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, newValue: string, resolveDelay: number = 400) {
clearTimeout(changeTimeout);
changeTimeout = setTimeout(async () => {
switch ((event.target as HTMLInputElement).id) {
case this._nameId: {
let newName = `${newValue}.${this.props.model.fileExtension}`;
let errorMessage = await SPDataAdapter.isFilenameValid(this.props.folderServerRelativeUrl, newName);
this.props.onInputChanged(this.props.model.id, { newName }, errorMessage);
case nameId: {
let newName = `${newValue}.${props.model.fileExtension}`;
let errorMsg = await SPDataAdapter.isFilenameValid(props.folderServerRelativeUrl, newName);
props.onInputChanged(props.model.id, { newName }, errorMsg);
}
break;
case this._titleId: {
this.props.onInputChanged(this.props.model.id, { newTitle: newValue });
case titleId: {
props.onInputChanged(props.model.id, { newTitle: newValue });
}
break;
}
}, resolveDelay);
}

/**
* On expand collapse
*/
private _onExpandCollapse(): void {
this.setState(({ isExpanded }) => ({ isExpanded: !isExpanded }));
}
}
React.useEffect(() => {
SPDataAdapter.isFilenameValid(props.folderServerRelativeUrl, props.model.name).then(errorMessage => {
if (errorMessage) {
props.onInputChanged(props.model.id, {}, errorMessage);
setIsExpanded(true);
}
});
}, [props.folderServerRelativeUrl]);

return (
<div className={styles.documentTemplateItem}>
<div className={styles.header} onClick={_ => setIsExpanded(!isExpanded)}>
<div className={styles.title}>{props.model.name}</div>
<div className={styles.icon}>
<Icon iconName={isExpanded ? 'ChevronDown' : 'ChevronUp'} />
</div>
</div>
<div hidden={!isExpanded}>
<div className={styles.inputField}>
<TextField
id={nameId}
label={strings.NameLabel}
placeholder={strings.NameLabel}
defaultValue={props.model.nameWithoutExtension}
suffix={`.${props.model.fileExtension}`}
errorMessage={props.model.errorMessage}
onChange={onInputChange} />
</div>
<div className={styles.inputField}>
<TextField
id={titleId}
label={strings.TitleLabel}
placeholder={strings.TitleLabel}
defaultValue={props.model.title}
onChange={onInputChange} />
</div>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IDocumentLibrary, TemplateFile } from '../../../models';
import { DocumentTemplateDialogScreen } from '../DocumentTemplateDialogScreen';

export interface IDocumentTemplateDialogScreenEditCopyProps {
/**
Expand All @@ -15,4 +16,9 @@ export interface IDocumentTemplateDialogScreenEditCopyProps {
* On start copy callback
*/
onStartCopy: (templates: TemplateFile[], selectedFolderServerRelativeUrl: string) => void;

/**
* On change screen
*/
onChangeScreen: (screen: DocumentTemplateDialogScreen) => void;
}

This file was deleted.

Loading

0 comments on commit 3d9bdd9

Please sign in to comment.