fix vti_searchversion

This commit is contained in:
Russell Gove 2024-02-15 13:11:39 -05:00
parent 7d043b9401
commit f6ea2c8d2a
8 changed files with 101 additions and 105 deletions

View File

@ -24,7 +24,7 @@
"officeFabricIconFontName": "Page",
"properties": {
"description": "propertyBagDisplay",
"propertiesToDisplay": "CUSTOMNAVAreaName|AreaName\nCUSTOMNAVBusinessUnit|BusinessUnit\nCUSTOMNAVContinent|Continent\nCUSTOMNAVLocation|Location",
"propertiesToDisplay": "CUSOMNAVAreaName|AreaName\nCUSOMNAVBusinessUnit|BusinessUnit\nCUSOMNAVContinent|Continent\nCUSOMNAVLocation|Location",
"siteTemplatesToInclude": "STS\nPUBLISHING"
}
}

View File

@ -4,7 +4,7 @@ import * as ReactDom from "react-dom";
import { Version } from "@microsoft/sp-core-library";
//import * as strings from "propertyBagDisplayStrings";
import * as strings from "propertyBagDisplayStrings";
import PropertyBagDisplay from "./components/PropertyBagDisplay";
import { IPropertyBagDisplayProps } from "./components/IPropertyBagDisplayProps";
import { IPropertyBagDisplayWebPartProps } from "./IPropertyBagDisplayWebPartProps";
@ -58,17 +58,17 @@ export default class PropertyBagDisplayWebPart extends BaseClientSideWebPart<IPr
},
groups: [
{
groupName: "strings.BasicGroupName",
groupName: strings.BasicGroupName,
groupFields: [
PropertyPaneTextField("description", {
label: "strings.DescriptionFieldLabel"
label: strings.DescriptionFieldLabel
}),
PropertyPaneTextField("propertiesToDisplay", {
label: "strings.PropertiesToDisplayFieldLabel",
label: strings.PropertiesToDisplayFieldLabel,
multiline: true
}),
PropertyPaneTextField("siteTemplatesToInclude", {
label: "strings.SiteTemplatesToIncludeFieldLabel",
label: strings.SiteTemplatesToIncludeFieldLabel,
multiline: true
}),

View File

@ -1,35 +1,26 @@
import * as React from "react";
import pnp from "sp-pnp-js";
import { Web } from "sp-pnp-js";
import * as _ from "lodash";
import utils from "../../shared/utils";
import * as React from "react";
import pnp, { SearchQuery, SearchResults, Web } from "sp-pnp-js";
import DisplayProp from "../../shared/DisplayProp";
import { SearchQuery, SearchResults } from "sp-pnp-js";
import { css } from "office-ui-fabric-react";
import utils from "../../shared/utils";
//import styles from "./PropertyBagDisplay.module.scss";
import { IPropertyBagDisplayProps } from "./IPropertyBagDisplayProps";
import { DefaultButton, PrimaryButton } from "office-ui-fabric-react/lib/Button";
import { CommandBar } from "office-ui-fabric-react/lib/CommandBar";
import {
CheckboxVisibility,
DetailsList, DetailsListLayoutMode, IColumn,
SelectionMode
} from "office-ui-fabric-react/lib/DetailsList";
import { Label } from "office-ui-fabric-react/lib/Label";
import { TextField } from "office-ui-fabric-react/lib/TextField";
import { Toggle } from "office-ui-fabric-react/lib/Toggle";
import { ButtonType, PrimaryButton, DefaultButton } from "office-ui-fabric-react/lib/Button";
import { MessageBar, MessageBarType } from "office-ui-fabric-react/lib/MessageBar";
import * as md from "../../shared/MessageDisplay";
import MessageDisplay from "../../shared/MessageDisplay";
import {
DetailsList, DetailsListLayoutMode, IColumn, IGroupedList, SelectionMode, CheckboxVisibility, IGroup
} from "office-ui-fabric-react/lib/DetailsList";
import {
GroupedList
} from "office-ui-fabric-react/lib/GroupedList";
import {
IViewport
} from "office-ui-fabric-react/lib/utilities/decorators/withViewport";
import MessageDisplay, * as md from "../../shared/MessageDisplay";
import { IPropertyBagDisplayProps } from "./IPropertyBagDisplayProps";
import { IContextualMenuItem, } from "office-ui-fabric-react/lib/ContextualMenu";
import {
Panel, PanelType
} from "office-ui-fabric-react/lib/Panel";
import { IContextualMenuItem, } from "office-ui-fabric-react/lib/ContextualMenu";
export interface IPropertyBagDisplayState {
selectedIndex: number; // the currently selected site
managedToCrawedMapping?: Array<ManagedToCrawledMappingEntry>;// Determines which Carwled propeties are mapped to which Managed Properties
@ -99,7 +90,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
icon: "Edit",
}];
};
}
get ItemIsSelected(): boolean {
if (!this.state) { return false; }
return (this.state.selectedIndex !== -1);
@ -112,7 +103,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
*
* @memberOf PropertyBagDisplay
*/
public renderPopup() {
public renderPopup(): JSX.Element {
if (!this.state.workingStorage) {
return (<div />);
@ -181,11 +172,11 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
*
* @memberOf PropertyBagDisplay
*/
public removeMessage(messageList: Array<md.Message>, messageId: string) {
public removeMessage(messageList: Array<md.Message>, messageId: string): void {
_.remove(messageList, {
Id: messageId
});
this.setState(this.state);
this.setState((current) => ({ ...current, errorMessages: messageList }));
}
/**
* Removes a massage from the main windo
@ -194,7 +185,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
*
* @memberOf PropertyBagDisplay
*/
public removeMainMessage(messageId: string) {
public removeMainMessage(messageId: string): void {
this.removeMessage(this.state.errorMessages, messageId);
}
/**
@ -204,7 +195,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
*
* @memberOf PropertyBagDisplay
*/
public removePanelMessage(messageId: string) {
public removePanelMessage(messageId: string): void {
this.removeMessage(this.state.workingStorage.errorMessages, messageId);
}
/**
@ -247,7 +238,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
*
* @memberOf PropertyBagDisplay
*/
public stopediting() {
public stopediting(): void {
this.setState((current) => ({
...current,
isediting: false,
@ -265,7 +256,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
*
* @memberOf PropertyBagDisplay
*/
private renderSiteUrl(item?: any, index?: number, column?: IColumn): any {
private renderSiteUrl(item?: any, index?: number, column?: IColumn): JSX.Element {
return (<a href={item[column.fieldName]}>{item[column.fieldName]} </a>);
}
/**
@ -331,11 +322,11 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
*
* @memberOf PropertyBagDisplay
*/
public componentWillMount() {
public componentDidMount(): void {
// this.state.columns = this.setupColumns();
// this.state.managedToCrawedMapping = [];
// this.state.managedPropNames = [];
var initState = {
let initState = {
columns: this.setupColumns(),
managedToCrawedMapping: [],
@ -386,7 +377,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
initState.sites.push(obj);
}
debugger;
initState.errorMessages.push(new md.Message("Items Recieved"));
//initState.errorMessages.push(new md.Message("Items Recieved"));
this.setState({ ...initState });
}).catch(err => {
debugger;
@ -403,7 +394,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
*
* @memberOf PropertyBagDisplay
*/
public onActiveItemChanged(item?: any, index?: number) {
public onActiveItemChanged(item?: any, index?: number): void {
//this.state.selectedIndex = index;
this.setState((current) => ({ ...current, selectedIndex: index }));
}
@ -420,7 +411,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
for (const prop of this.state.workingStorage.DisplayProps) {
const promise = utils.setSPProperty(prop.crawledPropertyName, prop.value, this.state.workingStorage.Url)
.then(value => {
this.changeSearchable(this.state.workingStorage.Url, prop.crawledPropertyName, prop.searchable);
return this.changeSearchable(this.state.workingStorage.Url, prop.crawledPropertyName, prop.searchable);
});
promises.push(promise);
}
@ -429,8 +420,7 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
if (this.state.workingStorage.forceCrawl) {
utils.forceCrawl(this.state.workingStorage.Url);
}
// this.state.workingStorage = null;
// this.state.isediting = false;
this.setState((current) => ({ ...current, workingStorage: null, isediting: false }));
this.setState(this.state);
@ -500,20 +490,23 @@ export default class PropertyBagDisplay extends React.Component<IPropertyBagDisp
console.log("in onEditItemClicked");
const selectedSite = this.state.sites[this.state.selectedIndex];
const web = new Web(selectedSite.Url);
web.select("Title", "AllProperties").expand("AllProperties").get().then(r => {
const crawledProps: Array<string> = this.props.propertiesToDisplay.map(item => {
let context = this;
web.select("Title", "AllProperties").expand("AllProperties").get().then((r) => {
console.log(context.context);
const crawledProps: Array<string> = context.props.propertiesToDisplay.map(item => {
return item.split("|")[0];
});
let temp = _.clone(this.state.sites[this.state.selectedIndex]);
let temp = _.clone(selectedSite);
temp.searchableProps = utils.decodeSearchableProps(r.AllProperties["vti_x005f_indexedpropertykeys"]);
temp.DisplayProps = utils.SelectProperties(r.AllProperties, crawledProps, this.state.workingStorage.searchableProps);
// temp.DisplayProps = utils.SelectProperties(r.AllProperties, crawledProps, context.state.workingStorage.searchableProps);
temp.DisplayProps = utils.SelectProperties(r.AllProperties, crawledProps, temp.searchableProps);
temp.errorMessages = new Array<md.Message>();
// now add in the managed Prop
for (const dp of this.state.workingStorage.DisplayProps) {
for (const dp of temp.DisplayProps) {
dp.managedPropertyName =
_.find(this.state.managedToCrawedMapping, mtc => { return mtc.crawledPropertyName === dp.crawledPropertyName; }).managedPropertyName;
_.find(context.state.managedToCrawedMapping, mtc => { return mtc.crawledPropertyName === dp.crawledPropertyName; }).managedPropertyName;
}
this.setState((current) => ({
context.setState((current) => ({
...current,
workingStorage: temp, isediting: true

View File

@ -1,24 +1,24 @@
import * as React from "react";
import { css } from "office-ui-fabric-react"; import { IPropertyBagEditorProps } from "./IPropertyBagEditorProps";
import { Web } from "sp-pnp-js";
import * as _ from "lodash";
import utils from "../../shared/utils";
require("sp-init");
require("microsoft-ajax");
require("sp-runtime");
require("sharepoint");
import { IContextualMenuItem, } from "office-ui-fabric-react/lib/ContextualMenu";
import { DefaultButton, PrimaryButton } from "office-ui-fabric-react/lib/Button";
import { CommandBar } from "office-ui-fabric-react/lib/CommandBar";
import { MessageBar } from "office-ui-fabric-react/lib/MessageBar";
import { IContextualMenuItem, } from "office-ui-fabric-react/lib/ContextualMenu";
import {
DetailsList, DetailsListLayoutMode, IColumn, SelectionMode, CheckboxVisibility,
CheckboxVisibility,
DetailsList, DetailsListLayoutMode, IColumn, SelectionMode,
} from "office-ui-fabric-react/lib/DetailsList";
import { Dialog, DialogType } from "office-ui-fabric-react/lib/Dialog";
import { Label } from "office-ui-fabric-react/lib/Label";
import { TextField } from "office-ui-fabric-react/lib/TextField";
import { Toggle } from "office-ui-fabric-react/lib/Toggle";
import { PrimaryButton, DefaultButton, ButtonType } from "office-ui-fabric-react/lib/Button";
import * as React from "react";
import { Web } from "sp-pnp-js";
import DisplayProp from "../../shared/DisplayProp";
import utils from "../../shared/utils";
import { IPropertyBagEditorProps } from "./IPropertyBagEditorProps";
require("sp-init");
require("microsoft-ajax");
require("sp-runtime");
require("sharepoint");
export interface IPropertyBagEditorState {
displayProps: Array<DisplayProp>; // The list of properties displayed in the webpart
@ -78,7 +78,7 @@ export default class PropertyBagEditor extends React.Component<IPropertyBagEdito
const web = new Web(this.props.siteUrl);
web.select("Title", "AllProperties").expand("AllProperties").get().then(r => {
debugger;
const sp = utils.decodeSearchableProps(r.AllProperties["vti_x005f_indexedpropertykeys"]);
const sp = utils.decodeSearchableProps(r.AllProperties.vti_x005f_indexedpropertykeys);
const dp = utils.SelectProperties(r.AllProperties, this.props.propertiesToEdit, sp);
// this.state.searchableProps = sp;
// this.state.displayProps = dp;

View File

@ -69,7 +69,7 @@ export class UserFilter {
}
export default class PropertyBagFilteredSiteList extends React.Component<IPropertyBagFilteredSiteListProps, IPropertyBagFilteredSiteListState> {
public constructor(props) {
console.log(JSON.stringify("in constructor"));
super(props);
this.state = { sites: [], filteredSites: [], errorMessages: [], userFilters: [], appliedUserFilters: [] };
}
@ -82,10 +82,15 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
* @memberOf PropertyBagFilteredSiteList
*/
public removeMessage(messageId: string) {
_.remove(this.state.errorMessages, {
// _.remove(this.state.errorMessages, {
// Id: messageId
// });
// this.setState(this.state);
const messages = this.state.errorMessages;
_.remove(messages, {
Id: messageId
});
this.setState(this.state);
this.setState((current) => ({ ...current, errorMessages: messages }));
}
/**
@ -96,8 +101,8 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
*
* @memberOf PropertyBagFilteredSiteList
*/
public setupUserFilters(userFilterNames: Array<string>) {
console.log(JSON.stringify("in extractUserFilterValues"));
public setupUserFilters(userFilterNames: Array<string>): void {
console.log("in extractUserFilterValues");
// this.state.userFilters = [];
// for (const userFilterName of userFilterNames) {
// this.state.userFilters.push(new UserFilter(userFilterName));
@ -117,8 +122,8 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
*
* @memberOf PropertyBagFilteredSiteList
*/
public extractUserFilterValues(r) {
console.log(JSON.stringify("in extractUserFilterValues"));
public extractUserFilterValues(r): void {
for (const userFilter of this.state.userFilters) {
const value = r[userFilter.managedPropertyName].trim();
if (_.find(userFilter.values, v => { return v === value; })) {
@ -141,8 +146,8 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
*
* @memberOf PropertyBagFilteredSiteList
*/
public getSites(siteTemplatesToInclude: Array<string>, filters: Array<string>, showQueryText: boolean, userFilters: Array<string>, showSiteDescriptions: boolean) {
console.log(JSON.stringify("in getSites"));
public getSites(siteTemplatesToInclude: Array<string>, filters: Array<string>, showQueryText: boolean, userFilters: Array<string>, showSiteDescriptions: boolean): void {
const userFilterNameArray = [];
if (userFilters) {
for (const userFilter of userFilters) {
@ -226,21 +231,22 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
*
* @memberOf PropertyBagFilteredSiteList
*/
public componentWillMount() {
console.log(JSON.stringify("in componentWillMount"));
public componentDidMount() {
this.getSites(this.props.siteTemplatesToInclude, this.props.filters, this.props.showQueryText, this.props.userFilters, this.props.showSiteDescriptions);
}
/**
* Called whe Properties are changed in the PropertyPane
* Gets the sites and builds the userFilters using the new Properties
*
*
* @param {IPropertyBagFilteredSiteListProps} nextProps
* @param {*} nextContext
*
* @memberOf PropertyBagFilteredSiteList
*/
public componentWillReceiveProps(nextProps: IPropertyBagFilteredSiteListProps, nextContext: any) {
console.log(JSON.stringify("in componentWillReceiveProps"));
public componentDidUpdate(nextProps: IPropertyBagFilteredSiteListProps, nextContext: any): void {
debugger;
this.getSites(nextProps.siteTemplatesToInclude, nextProps.filters, nextProps.showQueryText, nextProps.userFilters, nextProps.showSiteDescriptions);
}
/**
@ -253,8 +259,7 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
*
* @memberOf PropertyBagFilteredSiteList
*/
public conditionallyRenderDescription(site: Site) {
console.log(JSON.stringify("in conditionallyRenderDescription"));
public conditionallyRenderDescription(site: Site): JSX.Element {
if (this.props.showSiteDescriptions) {
return (<Label>{site.description}</Label>);
}
@ -272,7 +277,7 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
* @memberOf PropertyBagFilteredSiteList
*/
private SetupFilters(): Array<IContextualMenuItem> {
console.log(JSON.stringify("in SetupFilters"));
const items = new Array<IContextualMenuItem>();
for (const uf of this.state.userFilters) {
const item: IContextualMenuItem = {
@ -310,8 +315,6 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
* @memberOf PropertyBagFilteredSiteList
*/
public AppliedFilterExists(managedPropertyName: string, value: string): boolean {
console.log(JSON.stringify("in AppliedFilterExists"));
const selectedFilter = _.find(this.state.appliedUserFilters, af => {
return (af.managedPropertyName === managedPropertyName && af.value === value);
});
@ -329,8 +332,7 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
*
* @memberOf PropertyBagFilteredSiteList
*/
public ToggleAppliedUserFilter(item: IContextualMenuItem) {
console.log(JSON.stringify("in ToggleAppliedUserFilter"));
public ToggleAppliedUserFilter(item: IContextualMenuItem): void {
if (this.AppliedFilterExists(item.data.managedPropertyName, item.data.value)) {
// this.state.appliedUserFilters = this.state.appliedUserFilters.filter(af => {
// return (af.managedPropertyName !== item.data.managedPropertyName || af.value !== item.data.value);
@ -361,13 +363,12 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
* @memberOf PropertyBagFilteredSiteList
*/
public filterSites(sites: Site[]): Site[] {
console.log(JSON.stringify("in filterSites"));
if (this.state.appliedUserFilters.length === 0) {
return sites;
}
else {
let filteredSites = sites.filter(site => {
const filteredSites = sites.filter(site => {
debugger;
for (const auf of this.state.appliedUserFilters) {
if (site[auf.managedPropertyName] === auf.value) {
@ -392,7 +393,6 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
* @memberOf PropertyBagFilteredSiteList
*/
public filterOnMetadata(ev?: React.MouseEvent<HTMLElement>, item?: IContextualMenuItem) {
console.log(JSON.stringify("in filterOnMetadata"));
this.ToggleAppliedUserFilter(item);
// this.filterSites();
// this.setState(this.state);
@ -400,7 +400,6 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
}
public doNothing(ev?: React.MouseEvent<HTMLElement>, item?: IContextualMenuItem) {
console.log(JSON.stringify("in doNothing"));
ev.stopPropagation();
return false;
@ -423,8 +422,7 @@ export default class PropertyBagFilteredSiteList extends React.Component<IProper
</li>
);
const commandItems: Array<IContextualMenuItem> = this.SetupFilters();
console.log(JSON.stringify("commandItems follow"));
console.log(JSON.stringify(commandItems));
return (
<div >
<Label>{this.props.description}</Label>

View File

@ -42,9 +42,9 @@ export default class PropertyBagGlobalNav extends React.Component<IPropertyBagGl
}
if (currentItem) { // should have it if site does have this property set
currentItem.subMenuProps.items.push({
key: r['Title'],
name: r['Title'],
href: r['SPSiteUrl']
key: r.Title,
name: r.Title,
href: r.SPSiteUrl
});
}
return items;
@ -59,7 +59,7 @@ export default class PropertyBagGlobalNav extends React.Component<IPropertyBagGl
*
* @memberOf PropertyBagGlobalNav
*/
public getSites(siteTemplatesToInclude: Array<string>, filters: Array<string>, managedProperties: Array<string>) {
public getSites(siteTemplatesToInclude: Array<string>, filters: Array<string>, managedProperties: Array<string>): void {
let querytext = "contentclass:STS_Site ";
if (siteTemplatesToInclude) {
@ -111,11 +111,11 @@ export default class PropertyBagGlobalNav extends React.Component<IPropertyBagGl
});
}
/** react lifecycle */
public componentWillMount() {
public componentDidMount(): void {
this.getSites(this.props.siteTemplatesToInclude, this.props.filters, this.props.managedProperties);
}
public componentWillReceiveProps(nextProps: IPropertyBagGlobalNavProps, nextContext: any) {
public componentDidUpdate(nextProps: IPropertyBagGlobalNavProps, nextContext: any): void {
this.getSites(nextProps.siteTemplatesToInclude, nextProps.filters, nextProps.managedProperties);
}

View File

@ -46,6 +46,7 @@ export default class MessageDisplay extends React.Component<IMessageDisplayProps
{this.props.messages.map((message, y, z) => {
return (
<MessageBar
key={message.Id}
messageBarType={MessageBarType.error}
isMultiline={true}
onDismiss={this.createDismissHandler(message.Id)}>

View File

@ -26,13 +26,13 @@ export default class utils {
*
* @memberOf utils
*/
public static EncodePropertyKey(propKey) {
var bytes = [];
for (var i = 0; i < propKey.length; ++i) {
public static EncodePropertyKey(propKey): string {
let bytes = [];
for (let i = 0; i < propKey.length; ++i) {
bytes.push(propKey.charCodeAt(i));
bytes.push(0);
}
var b64encoded = window.btoa(String.fromCharCode.apply(null, bytes));
const b64encoded = window.btoa(String.fromCharCode.apply(null, bytes));
return b64encoded;
}
@ -46,7 +46,7 @@ export default class utils {
*
* @memberOf utils
*/
public static DecodePropertyKey(propKey) {
public static DecodePropertyKey(propKey): string {
const encoded = window.atob(propKey);
let decoded = "";
for (let x = 0; x < encoded.length; x = x + 2) {
@ -122,7 +122,7 @@ export default class utils {
*
* @memberOf utils
*/
public static setSPProperty(name: string, value: string, siteUrl: string) {
public static setSPProperty(name: string, value: string, siteUrl: string): Promise<any> {
return new Promise((resolve, reject) => {
let webProps;
const clientContext = new SP.ClientContext(siteUrl);
@ -153,7 +153,7 @@ export default class utils {
public static saveSearchablePropertiesToSharePoint(siteUrl: string, propnames: Array<string>): Promise<any> {
const encodedPropNames: Array<string> = [];
for (const propname of propnames) {
if (propname != "") {
if (propname !== "") {
encodedPropNames.push(this.EncodePropertyKey(propname));
}
}
@ -169,14 +169,18 @@ export default class utils {
*
* @memberOf utils
*/
public static forceCrawl(siteUrl: string): Promise<any> {
public static forceCrawl(siteUrl: string): Promise<void> {
const web = new Web(siteUrl);
return web.select("Title", "AllProperties").expand("AllProperties").get().then(r => {
let version: number = r.AllProperties["vti_x005f_searchversion"];
//let version: number = r.AllProperties["vti_x005f_searchversion"];
let version: number = r.AllProperties.vti_x005f_searchversion;
if (version) {
version++;
this.setSPProperty("AllProperties", version.toString(), siteUrl);
return this.setSPProperty("vti_searchversion", version.toString(), siteUrl);
}
else {
return this.setSPProperty("vti_searchversion", "1", siteUrl);
}
});
}
@ -251,6 +255,6 @@ export default class utils {
if (!value) {
return [];
}
return value.split('\n').filter(val => { return val.trim() != ""; });
return value.split('\n').filter(val => { return val.trim() !== ""; });
}
}