lodash#has JavaScript Examples

The following examples show how to use lodash#has. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RangeFacet.js    From sampo-ui with MIT License 6 votes vote down vote up
constructor (props) {
    super(props)
    let min = ''
    let max = ''
    const { facet } = props
    if (has(facet, 'integerFilter') && facet.integerFilter !== null) {
      const { integerFilter } = facet
      min = integerFilter.start
      max = integerFilter.end
    }
    this.state = { min, max }
  }
Example #2
Source File: imageUpload.js    From gutenberg-forms with GNU General Public License v2.0 6 votes vote down vote up
function ImageUpload(props) {
	const { image } = props;

	let value = image ? image : "";

	function getLeastOneSize(s, media) {
		let { sizes } = media;

		for (const size of s) {
			if (has(sizes, size)) {
				return sizes[size];
				break;
			} else continue;
		}
	}

	return (
		<MediaUploadCheck>
			<MediaUpload
				onSelect={media => {
					let sizes = ["thumbnail", "medium", "large"],
						imageWithDimensions = getLeastOneSize(sizes, media);

					props.onSelect(imageWithDimensions);
				}}
				allowedTypes={["image"]}
				value={value}
				render={({ open }) => (
					<Button isDefault onClick={open}>
						<Icon icon={props.icon} />
					</Button>
				)}
			/>
		</MediaUploadCheck>
	);
}
Example #3
Source File: LeafletConfig.js    From sampo-ui with MIT License 6 votes vote down vote up
createPopUpContentLetterSampo = ({ data, resultClass }) => {
  if (Array.isArray(data.prefLabel)) {
    data.prefLabel = data.prefLabel[0]
  }
  const container = document.createElement('div')
  const h3 = document.createElement('h3')
  if (has(data.prefLabel, 'dataProviderUrl')) {
    const link = document.createElement('a')
    link.addEventListener('click', () => history.push(data.prefLabel.dataProviderUrl))
    link.textContent = data.prefLabel.prefLabel
    link.style.cssText = 'cursor: pointer; text-decoration: underline'
    h3.appendChild(link)
  } else {
    h3.textContent = data.prefLabel.prefLabel
  }
  container.appendChild(h3)
  if (resultClass === 'placesActors') {
    const p = document.createElement('p')
    p.textContent = 'Actors:'
    container.appendChild(p)
    container.appendChild(createInstanceListing(data.related))
  }
  return container
}
Example #4
Source File: index.js    From gutenberg-forms with GNU General Public License v2.0 6 votes vote down vote up
function isDefaultValues(blockAttrs, type, fName, messages) {
	//ensuring that the block values aren't changed!

	if (!has(blockAttrs, "messages")) return;

	let defaultMessage = messages.find((v) => v.fieldName === fName);

	let statics = defaultFieldMessages.find((v) => v.fieldName === fName);

	if (statics[type] === blockAttrs.messages[type]) {
		return true;
	} else if (blockAttrs.messages[type] === defaultMessage[type]) {
		return true;
	}

	return false;
}
Example #5
Source File: ResultClassRoute.js    From sampo-ui with MIT License 6 votes vote down vote up
getVisibleRows = perspectiveState => {
  const { properties, instanceTableData } = perspectiveState
  const visibleRows = []
  const instanceClass = instanceTableData.type ? instanceTableData.type.id : ''
  properties.forEach(row => {
    if ((has(row, 'onlyForClass') && row.onlyForClass === instanceClass) ||
       !has(row, 'onlyForClass')) {
      visibleRows.push(row)
    }
  })
  return visibleRows
}
Example #6
Source File: index.js    From gutenberg-forms with GNU General Public License v2.0 6 votes vote down vote up
export function getGlobalMessages() {
	const globalMessages = cwpGlobal.generalSettings.messages;

	const defaultValidationMessages = defaultFieldMessages.map((v) => {
		if (has(v, "invalid")) {
			return {
				...v,
				invalid: globalMessages[v.fieldName]["value"],
			};
		}

		if (has(v, "invalidName")) {
			return {
				...v,
				invalidName: globalMessages[v.fieldName]["value"],
			};
		}

		if (has(v, "invalidEmail")) {
			return {
				...v,
				invalidEmail: globalMessages[v.fieldName]["value"],
			};
		}

		return v;
	});

	return defaultValidationMessages;
}
Example #7
Source File: VirtualizedTable.js    From sampo-ui with MIT License 6 votes vote down vote up
// _onScrollToRowChange(event) {
  //   const {rowCount} = this.state;
  //   let scrollToIndex = Math.min(
  //     rowCount - 1,
  //     parseInt(event.target.value, 10),
  //   );
  //
  //   if (isNaN(scrollToIndex)) {
  //     scrollToIndex = undefined;
  //   }
  //
  //   this.setState({scrollToIndex});
  // }

  // https://stackoverflow.com/questions/40412114/how-to-do-proper-column-filtering-with-react-virtualized-advice-needed
  _sort ({ sortBy, event, sortDirection }) {
    if (has(event.target, 'className') && event.target.className.startsWith('Mui')) {
      event.stopPropagation()
    } else {
      this.props.clientFSSortResults({ sortBy, sortDirection: sortDirection.toLowerCase() })
    }
  }
Example #8
Source File: index.js    From gutenberg-forms with GNU General Public License v2.0 6 votes vote down vote up
export function detectSimilarFields(clientId, field_id) {
	//this will detect the similar id across fields

	const root = getBlock(getBlockRootClientId(clientId));
	let result = false;

	if (!has(root, "innerBlocks")) return;

	root.innerBlocks.forEach((block) => {
		let { attributes } = block;

		if (layoutBlocks.includes(block.name)) {
			result = detectSimilarFields(block);
		} else {
			if (has(attributes, "field_name")) {
				if (
					isEqual(get(attributes, "field_name"), field_id) &&
					!isEqual(block.clientId, clientId)
				) {
					result = true;
				}
			}
		}
	});

	return result;
}
Example #9
Source File: Utils.js    From sampo-ui with MIT License 5 votes vote down vote up
createExtraResultClassesForJSONConfig = async oldBackendSearchConfig => {
  // const portalConfigJSON = await readFile('src/configs/portalConfig.json')
  // const portalConfig = JSON.parse(portalConfigJSON)
  // const { portalID } = portalConfig
  // const newPerspectiveConfigs = {}
  // // build initial config object
  // for (const newResultClass in oldBackendSearchConfig) {
  //   const resultClassConfig = oldBackendSearchConfig[newResultClass]
  //   if (has(resultClassConfig, 'perspectiveID')) {
  //     const { perspectiveID } = resultClassConfig
  //     if (!has(newPerspectiveConfigs, perspectiveID)) {
  //       const perspectiveConfigJSON = await readFile(`src/configs/${portalID}/search_perspectives/${perspectiveID}.json`)
  //       newPerspectiveConfigs[perspectiveID] = JSON.parse(perspectiveConfigJSON)
  //     }
  //   }
  // }

  // create resultClass configs
  const resultClasses = {}
  for (const resultClass in oldBackendSearchConfig) {
    const resultClassConfig = oldBackendSearchConfig[resultClass]
    if (has(resultClassConfig, 'perspectiveID')) {
      // console.log(resultClass)
      // const { perspectiveID } = resultClassConfig
      const { q, nodes, filterTarget, resultMapper, resultMapperConfig, instance, properties, useNetworkAPI } = resultClassConfig
      if (instance && instance.relatedInstances === '') {
        delete instance.relatedInstances
      }
      let { postprocess } = resultClassConfig
      let resultMapperName = null
      if (resultMapper) {
        resultMapperName = resultMapper.name
      }
      if (postprocess) {
        postprocess = {
          func: postprocess.func.name,
          config: {
            ...postprocess.config
          }
        }
      }
      resultClasses[resultClass] = {
        ...(q && { sparqlQuery: q }),
        ...(nodes && { sparqlQueryNodes: nodes }),
        ...(filterTarget && { filterTarget }),
        ...(resultMapperName && { resultMapper: resultMapperName }),
        ...(resultMapperConfig && { resultMapperConfig }),
        ...(postprocess && { postprocess }),
        ...(instance && { instance }),
        ...(properties && { propertiesQueryBlock: properties }), // for jena text only
        ...(useNetworkAPI && { useNetworkAPI }) // for federated search only
      }
    } else {
      console.log(`no perspectiveID for: ${resultClass}`)
    }
  }
  console.log(JSON.stringify(resultClasses))
}
Example #10
Source File: messages.js    From gutenberg-forms with GNU General Public License v2.0 5 votes vote down vote up
export default function CustomMessages(props) {
	const { val } = props;

	const handleChange = (t, v, i, fieldName) => {
		props.onChange(t, v, i, fieldName);
	};

	return (
		<Fragment>
			{val.map((v, i) => {
				let fieldName = "cwp/".concat(v.fieldName);

				return (
					<Fragment>
						<div className="cwp-option">
							{/* <TextControl
								onChange={value => handleChange("empty", value, i, fieldName)}
								label="Required"
								value={v.empty}
							/> */}
							{has(v, "invalid") && (
								<Fragment>
									<h3 className="cwp-message_header">
										<strong>
											{"Invalid ".concat(firstCapital(v.fieldName))}
										</strong>
										<Icon icon={getFieldIcon(fieldName)} />
									</h3>
									<TextControl
										onChange={value =>
											handleChange("invalid", value, i, fieldName)
										}
										value={v.invalid}
									/>
								</Fragment>
							)}
							{has(v, "invalidEmail") && (
								<Fragment>
									<h3 className="cwp-message_header">
										<strong>
											{"Invalid ".concat(firstCapital(v.fieldName))}
										</strong>
										<Icon icon={getFieldIcon(fieldName)} />
									</h3>
									<TextControl
										onChange={value =>
											handleChange("invalidEmail", value, i, fieldName)
										}
										value={v.invalidEmail}
									/>
								</Fragment>
							)}
							{has(v, "invalidName") && (
								<Fragment>
									<h3 className="cwp-message_header">
										<strong>
											{"Invalid ".concat(firstCapital(v.fieldName))}
										</strong>
										<Icon icon={getFieldIcon(fieldName)} />
									</h3>
									<TextControl
										onChange={value =>
											handleChange("invalidName", value, i, fieldName)
										}
										value={v.invalidName}
									/>
								</Fragment>
							)}
						</div>
					</Fragment>
				);
			})}
		</Fragment>
	);
}
Example #11
Source File: index.js    From hzero-front with Apache License 2.0 5 votes vote down vote up
/**
   * deal field's attribute change
   */
  handleFieldValuesChange(props, changeValues, allValues) {
    // 使用 allValues 重写 field 的属性
    const { field, component, onRefresh } = this.props;
    const { validateFields } = this.editFormRef.current || {};
    if (validateFields) {
      validateFields(err => {
        if (!err) {
          const newConfig = [];
          field[fieldLabelProp] = allValues[fieldLabelProp];
          field[fieldNameProp] = allValues[fieldNameProp];
          // fields's common prop;
          field.requiredFlag = allValues.requiredFlag;
          // 不要 visiableFlag 字段了
          // field.visiableFlag = allValues.visiableFlag;
          // todo 字段的 enabledFlag 不能编辑了
          // field.enabledFlag = allValues.enabledFlag;
          field.description = allValues.description;
          field.align = allValues.align;

          if (has(changeValues, 'autoSize')) {
            // autoSize 有更改才改变 width
            if (allValues.autoSize) {
              field.width = 0; // can set field width in right only when autoSize is 0
            } else {
              field.width = autoSizeWidth;
            }
          }

          const getConfigOfPropValuesFunc = `get${field.componentType}ConfigOfPropValues`;

          if (this[getConfigOfPropValuesFunc]) {
            this[getConfigOfPropValuesFunc](allValues, newConfig);
          }

          const prevFieldConfigs = field.config;
          field.config = newConfig.map(fieldConfig => {
            const prevFieldConfig = find(
              prevFieldConfigs,
              prevC => prevC[attributeNameProp] === fieldConfig[attributeNameProp]
            );
            return { ...prevFieldConfig, ...fieldConfig };
          });
          const newField = field; // { ...field };
          // 更新 feild 在 component 中的引用
          let fieldRefUpdate = false;
          forEach(component.fields, (f, index) => {
            if (f === field) {
              fieldRefUpdate = true;
              component.fields[index] = newField;
              return false;
            }
            return !fieldRefUpdate;
          });
          if (isFunction(onRefresh)) {
            onRefresh();
          }
        }
      });
    }
  }
Example #12
Source File: Filters.js    From sampo-ui with MIT License 5 votes vote down vote up
generateTimespanFilter = ({
  backendSearchConfig,
  facetClass,
  facetID,
  filterTarget,
  values,
  inverse
}) => {
  const facetConfig = backendSearchConfig[facetClass].facets[facetID]
  const { start, end } = values
  let selectionStart = start
  let selectionEnd = end
  const dataType = has(facetConfig, 'dataType') ? facetConfig.dataType : 'xsd:date'
  if (dataType === 'xsd:dateTime') {
    selectionStart = `${selectionStart}T00:00:00Z`
    selectionEnd = `${selectionEnd}T00:00:00Z`
  }
  const filterStr = `
    ?${filterTarget} ${facetConfig.predicate} ?tspan .
    ?tspan ${facetConfig.startProperty} ?startA ;
           ${facetConfig.endProperty} ?endA .       
    BIND("${selectionStart}"^^${dataType} as ?startB)
    BIND("${selectionEnd}"^^${dataType} as ?endB)      
    # Determine whether two date ranges overlap: https://stackoverflow.com/a/325964/6028835
    # Also make sure that starts and ends are in right order in the RDF data.
    FILTER(
      (?startA <= ?endB) && (?endA >= ?startB) && (?startA <= ?endA)
    )
    # Alternative, stricter implementation:
    # Determine whether range B (facet selection) is entirely within range A (timespan in RDF data).
    # Also make sure that starts and ends are in right order in the RDF data.
    # FILTER(
    #  (?startA >= ?startB) && (?endA <= ?endB) && (?startA <= ?endA)
    # )
  `
  if (inverse) {
    return `
    FILTER NOT EXISTS {
        ${filterStr}
    }
    `
  } else {
    return filterStr
  }
}
Example #13
Source File: toolbar.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function BlockToolbar(props) {
	const {
		clientId,
		selectedStep,
		childAttributes,
		setStep,
		refreshAttributes,
	} = props;

	const isStepAvailable = () => {
		// verification function that will confirm if the step is selected and available
		// so we can show actions regarding step

		if (has(childAttributes, selectedStep)) {
			// checking if the child attribute has selected index

			return true;
		}

		return false;
	};

	/**
	 * @param {The index of the required step} index
	 */

	const getStepFromIndex = (index) => {
		if (has(childAttributes, index)) {
			const requiredStep = childAttributes[selectedStep];
			return requiredStep;
		}
		return false;
	};

	const deleteStep = () => {
		const currentStep = getStepFromIndex(selectedStep);
		const stepClientId = get(currentStep, `clientId`);

		removeBlock(stepClientId).then(() => {
			// on success
			let beforeSelectedStep = selectedStep - 1;

			refreshAttributes(); // refreshing the attributes

			if (has(childAttributes, beforeSelectedStep)) {
				setStep(beforeSelectedStep); // setting the current step position to -1 (if available)
			}

			//! after deletion the selection moves to another block therefore
			//! selecting the root block again

			selectBlock(clientId);
		});
	};

	const duplicateStep = () => {
		const currentStep = getStepFromIndex(selectedStep);
		const currentStepClientId = get(currentStep, "clientId");

		duplicateBlocks(
			[currentStepClientId], // client IDS of blocks to duplicate
			clientId // root clientId
		).then(() => {
			refreshAttributes();

			const newStepIndex = selectedStep + 1;

			setStep(newStepIndex);

			//! after duplication the selection moves to another block therefore
			//! selecting the root block again
			selectBlock(clientId);
		});
	};

	const moveStepUp = () => {
		const currentStep = getStepFromIndex(selectedStep);
		const currentStepClientId = get(currentStep, "clientId");
		const newStepIndex = selectedStep - 1; // selecting the before step because this will move to the left

		if (!has(childAttributes, newStepIndex)) {
			return; // breaking if no step are available to move
		}

		moveBlocksUp(
			[currentStepClientId], // client ids of the blocks which will move up
			clientId // client id of root block
		).then(() => {
			// on success

			refreshAttributes(); // finally updating the labels
			setStep(newStepIndex);
		});
	};

	const moveStepDown = () => {
		const currentStep = getStepFromIndex(selectedStep);
		const currentStepClientId = get(currentStep, "clientId");
		const newStepIndex = selectedStep + 1; // selecting the after step because this will move to the right

		if (!has(childAttributes, newStepIndex)) {
			return; // breaking if no step are available to move
		}

		moveBlocksDown(
			[currentStepClientId], // client ids of the blocks which will move up
			clientId // client id of root block
		).then(() => {
			// on success

			refreshAttributes(); // finally updating the labels
			setStep(newStepIndex);
		});
	};

	return (
		<BlockControls>
			<Toolbar>
				{isStepAvailable() && (
					<Fragment>
						<Tooltip text={__("Move Step Up", "cwp-gutenberg-forms")}>
							<IconButton icon="arrow-left-alt2" onClick={moveStepUp} />
						</Tooltip>
						<Tooltip text={__("Move Step Down", "cwp-gutenberg-forms")}>
							<IconButton icon="arrow-right-alt2" onClick={moveStepDown} />
						</Tooltip>
						<Tooltip text={__("Delete Step", "cwp-gutenberg-forms")}>
							<IconButton icon="trash" onClick={deleteStep} />
						</Tooltip>
						<Tooltip text={__("Duplicate Step", "cwp-gutenberg-forms")}>
							<IconButton icon="admin-page" onClick={duplicateStep} />
						</Tooltip>
					</Fragment>
				)}
			</Toolbar>
		</BlockControls>
	);
}
Example #14
Source File: VirtualizedTable.js    From sampo-ui with MIT License 4 votes vote down vote up
render () {
    const { classes, list, perspectiveID } = this.props
    // console.log(list)
    const rowGetter = ({ index }) => this._getDatum(list, index)

    const headerRenderer = ({
      dataKey,
      label,
      sortBy,
      sortDirection
    }) => {
      const showSortIndicator = sortBy === dataKey
      const children = [
        <span
          className='ReactVirtualized__Table__headerTruncatedText'
          style={showSortIndicator ? {} : { marginRight: 16 }}
          key='label'
          title={label}
        >
          {label}
        </span>
      ]
      if (showSortIndicator) {
        children.push(
          <SortIndicator key='SortIndicator' sortDirection={sortDirection} />
        )
      }
      return children
    }

    const labelRenderer = ({ cellData, rowData }) => {
      if (cellData == null) return ''
      const label = <a target='_blank' rel='noopener noreferrer' href={rowData.id}>{cellData}</a>
      let marker = ''
      if (typeof rowData.lat !== 'undefined' || typeof rowData.long !== 'undefined') {
        marker = (
          <IconButton disabled aria-label='Marker' size="large">
            <PlaceIcon />
          </IconButton>
        )
      }
      return (
        <div key={rowData.id}>
          {label}{marker}
        </div>
      )
    }

    const sourceRenderer = ({ cellData, rowData }) => {
      if (cellData == null) return ''
      if (has(rowData, 'namesArchiveLink')) {
        return (
          <div key={rowData.s}>
            <a target='_blank' rel='noopener noreferrer' href={rowData.namesArchiveLink}>{cellData}</a>
          </div>
        )
      } else {
        return (
          <div key={rowData.s}>{cellData}</div>
        )
      }
    }

    return (
      <div className={classes.root}>
        {this.props.list.size > 0 &&
          <AutoSizer>
            {({ height, width }) => (
              <Table
                overscanRowCount={10}
                rowHeight={40}
                rowGetter={rowGetter}
                rowCount={this.props.list.size}
                sort={this._sort}
                sortBy={this.props.clientFSState.sortBy}
                sortDirection={this.props.clientFSState.sortDirection.toUpperCase()}
                width={width}
                height={height}
                headerHeight={50}
                noRowsRenderer={this._noRowsRenderer}
                style={tableStyles.tableRoot}
                rowStyle={calculateRowStyle}
              >
                <Column
                  label={intl.get(`perspectives.${perspectiveID}.properties.prefLabel.label`)}
                  cellDataGetter={({ rowData }) => rowData.prefLabel}
                  dataKey='prefLabel'
                  headerRenderer={headerRenderer}
                  cellRenderer={labelRenderer}
                  width={columnWidth + 70}
                />
                <Column
                  label={intl.get(`perspectives.${perspectiveID}.properties.broaderTypeLabel.label`)}
                  cellDataGetter={({ rowData }) => has(rowData, 'broaderTypeLabel') ? rowData.broaderTypeLabel.toLowerCase() : ''}
                  dataKey='broaderTypeLabel'
                  headerRenderer={headerRenderer}
                  width={columnWidth + 10}
                />
                {/* <Column
                    label="NA type"
                    cellDataGetter={({rowData}) => has(rowData,'typeLabel') ? rowData.typeLabel.toLowerCase() : ''}
                    dataKey="typeLabel"
                    headerRenderer={headerRenderer}
                    width={columnWidth}
                  /> */}
                <Column
                  label={intl.get(`perspectives.${perspectiveID}.properties.broaderAreaLabel.label`)}
                  cellDataGetter={({ rowData }) => rowData.broaderAreaLabel}
                  dataKey='broaderAreaLabel'
                  headerRenderer={headerRenderer}
                  width={columnWidth}
                />
                <Column
                  label={intl.get(`perspectives.${perspectiveID}.properties.modifier.label`)}
                  cellDataGetter={({ rowData }) => rowData.modifier}
                  dataKey='modifier'
                  headerRenderer={headerRenderer}
                  width={columnWidth + 10}
                />
                <Column
                  label={intl.get(`perspectives.${perspectiveID}.properties.basicElement.label`)}
                  cellDataGetter={({ rowData }) => rowData.basicElement}
                  dataKey='basicElement'
                  headerRenderer={headerRenderer}
                  width={columnWidth}
                />
                {/*
                  <Column
                    label="Collector"
                    cellDataGetter={({rowData}) => rowData.collector}
                    dataKey="collector"
                    headerRenderer={headerRenderer}
                    width={columnWidth}
                  /> */}
                <Column
                  label={intl.get(`perspectives.${perspectiveID}.properties.collectionYear.label`)}
                  cellDataGetter={({ rowData }) => rowData.collectionYear}
                  dataKey='collectionYear'
                  headerRenderer={headerRenderer}
                  width={columnWidth}
                />
                <Column
                  label={intl.get(`perspectives.${perspectiveID}.properties.source.label`)}
                  cellDataGetter={({ rowData }) => rowData.source}
                  dataKey='source'
                  headerRenderer={headerRenderer}
                  cellRenderer={sourceRenderer}
                  width={columnWidth}
                />
              </Table>
            )}
          </AutoSizer>}
      </div>
    )
  }
Example #15
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	let {
		options,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		messages,
		messages: { empty },
		condition,
		enableCondition,
		fieldStyle,
		bulkAdd,
		adminId,
		hint,
		showHint,
	} = props.attributes;

	const [checkboxes, setCheckboxes] = useState([]);
	const [focus, setFocus] = useState({
		f: false,
		index: null,
	});

	let checkboxContainer = useRef();

	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {
			const newFieldName = getFieldName("checkbox", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "checkbox"),
					default: extract_admin_id(newFieldName, "checkbox"),
				},
			});

			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"checkbox",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					) +
					"[]",
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"checkbox",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					) +
					"[]",
			});
		}
	};

	useEffect(() => {
		let { options } = props.attributes;

		setCheckboxes(options);
		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	useEffect(() => {
		if (bulkAdd) return;

		let boxes = checkboxContainer.current.querySelectorAll(
			'.cwp-checkbox-option input[type="text"]'
		);

		if (focus.f) {
			if (focus.index === null) {
				boxes[boxes.length - 1].focus();
			} else {
				boxes[focus.index].focus();
			}

			setFocus({ f: false, index: null });
		}
	}, [checkboxes, focus]); //subscribing to any further changes...

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const addCheckbox = () => {
		let newOption = {
			label: "Option " + (checkboxes.length + 1),
			checked: false,
		};

		let new_options = clone(checkboxes);

		new_options.push(newOption);

		props.setAttributes({ options: new_options });
		setCheckboxes(new_options);
	};

	const handleDelete = (index) => {
		let new_options = clone(options);

		let deleted_options = pullAt(new_options, [index]); //dosen't matter :-D

		props.setAttributes({ options: new_options });
		setCheckboxes(new_options);
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};

	const handleChange = (e, index) => {
		let new_options = clone(options);

		new_options[index] = {
			...new_options[index],
			label: e.target.value,
		};

		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
	};

	const handleCheck = (v, index) => {
		let new_options = clone(options);

		new_options[index].checked = v;
		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
	};

	const handleImage = (img, index, action) => {
		let new_options = clone(options);

		if (action === "add") {
			new_options[index] = {
				...new_options[index],
				image: img,
			};
		}

		if (action === "remove") {
			const checkboxToRemove = new_options[index];
			new_options[index] = {
				label: checkboxToRemove.label,
			};
		}

		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleDuplicate = (index) => {
		let new_options = clone(options);

		new_options.splice(index, 0, new_options[index]);

		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleEnter = (index) => {
		let new_options = clone(options);

		new_options.splice(index + 1, 0, { label: "" });

		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
		setFocus({ f: true, index: index + 1 });
	};

	let handleBackspace = (index) => {
		if (checkboxes[index].label === "") {
			handleDelete(index);

			if (checkboxes[index - 1]) {
				setFocus({ f: true, index: index - 1 });
			}
		}
	};

	let clearAll = () => {
		const reset = [
			{
				label: "Option 1",
			},
		];

		setCheckboxes(reset);
		props.setAttributes({
			options: reset,
		});
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	return [
		<InspectorControls>
			<PanelBody
				title={__("Field Settings", "cwp-gutenberg-forms")}
				initialOpen={true}
			>
				<div className="cwp-option">
					<TextControl
						placeholder={adminId.default}
						label={__("Field ID", "cwp-gutenberg-forms")}
						value={adminId.value}
						onChange={handleAdminId}
					/>
				</div>

				{!enableCondition ? (
					<PanelRow>
						<h3 className="cwp-heading">
							{__("Required", "cwp-gutenberg-forms")}
						</h3>
						<FormToggle
							label="Required"
							checked={isRequired}
							onChange={handleRequired}
						/>
					</PanelRow>
				) : (
					<div className="cwp-option">
						<p>
							<Icon icon="info" />{" "}
							{__(
								"You cannot set a conditional field required!",
								"cwp-gutenberg-forms"
							)}
						</p>
					</div>
				)}
				{isRequired && (
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Required Text", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(label) =>
								props.setAttributes({ requiredLabel: label })
							}
							value={requiredLabel}
						/>
					</div>
				)}
				<div className="cwp-option">
					<SelectControl
						label={__("Layout", "cwp-gutenberg-forms")}
						value={fieldStyle}
						options={[
							{ label: __("Block", "cwp-gutenberg-forms"), value: "block" },
							{ label: __("Inline", "cwp-gutenberg-forms"), value: "inline" },
						]}
						onChange={(s) => {
							props.setAttributes({ fieldStyle: s });
						}}
					/>
				</div>
			</PanelBody>
			{isRequired && (
				<PanelBody title="Messages">
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Required Error", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(label) => setMessages("empty", label)}
							value={messages.empty}
						/>
					</div>
				</PanelBody>
			)}
			<PanelBody title={__("Condition", "cwp-gutenberg-forms")}>
				<ConditionalLogic
					condition={condition}
					set={props.setAttributes}
					clientId={props.clientId}
					useCondition={props.attributes.enableCondition}
				/>
			</PanelBody>
			<PanelBody title={__("Show Hint", "cwp-gutenberg-forms")}>
				<div className="cwp-option">
					<FormToggle
						label="Show Hint"
						checked={showHint}
						onChange={() => props.setAttributes({ showHint: !showHint })}
					/>
					{showHint && (
						<Fragment>
							<TextControl
								label={__("Hint Text", "cwp-gutenberg-forms")}
								onChange={(hint) => props.setAttributes({ hint })}
								value={hint}
							/>
						</Fragment>
					)}
				</div>
			</PanelBody>
		</InspectorControls>,
		null,
		<div
			className={`cwp-checkbox cwp-field ${props.className} is-style-${fieldStyle}`}
		>
			{bulkAdd ? (
				<Bulk_Add onChange={(c) => setCheckboxes(c)} data={props} />
			) : (
				<Fragment>
					{!!props.isSelected && !enableCondition && (
						<div className="cwp-required">
							<h3>{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle checked={isRequired} onChange={handleRequired} />
						</div>
					)}

					<div
						ref={checkboxContainer}
						className={`cwp-checkbox-set-backend cwp-checkbox-set ${
							!props.isSelected ? "cwp-checkbox-set-preview" : ""
						}`}
					>
						<div className="cwp-label-wrap">
							<RichText
								placeholder={__("Add a label", "cwp-gutenberg-forms")}
								tag="label"
								value={label}
								onChange={handleLabel}
							/>

							{!props.isSelected && isRequired && !enableCondition && (
								<div className="cwp-required cwp-noticed">
									<h3>{requiredLabel}</h3>
								</div>
							)}
						</div>
						{checkboxes.map((checkbox, index) => {
							const hasImage = has(checkbox, "image"),
								image = hasImage ? checkbox.image.url : "";

							return (
								<Fragment>
									<div className="cwp-checkbox-option">
										<input
											id={id.concat(index.toString())}
											checked={checkbox.checked}
											type="checkbox"
											onClick={() => handleCheck(!checkbox.checked, index)}
										/>
										{!!props.isSelected && (
											<label
												style={{ width: "auto" }}
												for={id.concat(index.toString())}
												onClick={() => handleCheck(!checkbox.checked, index)}
											></label>
										)}
										{!!props.isSelected ? (
											<input
												onChange={(e) => handleChange(e, index)}
												onKeyDown={(e) => {
													e.key === "Enter" && handleEnter(index);
													e.key === "Backspace" && handleBackspace(index);
												}}
												type="text"
												value={checkbox.label}
											/>
										) : (
											<label>
												{checkbox.label}{" "}
												{hasImage && (
													<ImagePreview
														onEdit={(img) => handleImage(img, index, "add")}
														onRemove={() => handleImage(null, index, "remove")}
														isSelected={props.isSelected}
														image={checkbox.image}
													/>
												)}
											</label>
										)}
										{!!props.isSelected && (
											<Fragment>
												<ImageUpload
													icon="format-image"
													value={image}
													onSelect={(img) => handleImage(img, index, "add")}
												/>
												<Button
													isDefault
													onClick={() => handleDuplicate(index)}
												>
													<Icon icon="admin-page" />
												</Button>
												<Button isDefault onClick={() => handleDelete(index)}>
													<Icon icon="no-alt" />
												</Button>
											</Fragment>
										)}
									</div>
									{hasImage && props.isSelected && (
										<ImagePreview
											onEdit={(img) => handleImage(img, index, "add")}
											onRemove={() => handleImage(null, index, "remove")}
											isSelected={props.isSelected}
											image={checkbox.image}
										/>
									)}
								</Fragment>
							);
						})}
						{!!props.isSelected && (
							<div className="cwp-checkbox-controls">
								<div>
									<Button isDefault onClick={addCheckbox}>
										{__("Add Option", "cwp-gutenberg-forms")}
									</Button>
									<Button
										isDefault
										onClick={() => props.setAttributes({ bulkAdd: true })}
									>
										{__("Bulk Add", "cwp-gutenberg-forms")}
									</Button>
								</div>
								<div>
									<Button onClick={clearAll}>
										{__("Clear All", "cwp-gutenberg-forms")}
									</Button>
								</div>
							</div>
						)}
					</div>
				</Fragment>
			)}
			{showHint && <p className="cwp-hint">{hint}</p>}
		</div>,
	];
}
Example #16
Source File: SemanticPortal.js    From sampo-ui with MIT License 4 votes vote down vote up
SemanticPortal = props => {
  const { error } = props
  const location = useLocation()
  const rootUrlWithLang = `${rootUrl}/${props.options.currentLocale}`
  const screenSize = getScreenSize()
  const federatedSearchPerspectives = []
  let noClientFSResults = true
  perspectiveConfig.forEach(perspective => {
    if (perspective.searchMode === 'federated-search') {
      federatedSearchPerspectives.push(perspective)
      noClientFSResults = props.clientFSState && props.clientFSState.results === null
    }
  })

  // trigger a new "page view" event whenever a new page loads
  usePageViews()

  // set HTML title and description dynamically based on translations
  useEffect(() => {
    document.title = intl.get('html.title')
    document.documentElement.lang = props.options.currentLocale
    document.querySelector('meta[name="description"]').setAttribute('content', intl.get('html.description'))
  }, [props.options.currentLocale])

  return (
    <Box
      sx={theme => ({
        backgroundColor: '#bdbdbd',
        overflowX: 'hidden',
        minHeight: '100%',
        [theme.breakpoints.up(layoutConfig.hundredPercentHeightBreakPoint)]: {
          overflow: 'hidden',
          height: '100%'
        }
      })}
    >
      {/* error messages are shown on top of the app */}
      <Message error={error} />
      <>
        {/* no route for TopBar, because it is always visible */}
        <TopBar
          rootUrl={rootUrlWithLang}
          search={props.fullTextSearch}
          fetchFullTextResults={props.fetchFullTextResults}
          clearResults={props.clearResults}
          clientFSClearResults={props.clientFSClearResults}
          perspectives={perspectiveConfig}
          currentLocale={props.options.currentLocale}
          availableLocales={props.options.availableLocales}
          loadLocales={props.loadLocales}
          screenSize={screenSize}
          location={location}
          layoutConfig={layoutConfig}
        />
        {/* enforce a lang tag */}
        <Route exact path={`${rootUrl}/`}>
          <Redirect to={rootUrlWithLang} />
        </Route>
        {/* create a route for portal front page */}
        <Route exact path={`${rootUrlWithLang}`}>
          <>
            <Main
              perspectives={perspectiveConfig}
              screenSize={screenSize}
              rootUrl={rootUrlWithLang}
              layoutConfig={layoutConfig}
            />
            <Footer
              portalConfig={portalConfig}
              layoutConfig={layoutConfig}
            />
          </>
        </Route>
        {/* create a route for full text search results */}
        <Route path={`${rootUrlWithLang}/full-text-search`}>
          <FullTextSearch
            fullTextSearch={props.fullTextSearch}
            resultClass='fullTextSearch'
            sortFullTextResults={props.sortFullTextResults}
            screenSize={screenSize}
            rootUrl={rootUrlWithLang}
            layoutConfig={layoutConfig}
          />
        </Route>
        {/* create routes for faceted search perspectives and corresponding instance pages */}
        {perspectiveConfig.map(perspective => {
          if (!has(perspective, 'externalUrl') && perspective.searchMode === 'faceted-search') {
            return (
              <React.Fragment key={perspective.id}>
                <Route path={`${rootUrlWithLang}/${perspective.id}/faceted-search`}>
                  <FacetedSearchPerspective
                    portalConfig={portalConfig}
                    perspectiveConfig={perspective}
                    layoutConfig={layoutConfig}
                    facetedSearchMode='serverFS'
                    facetState={props[`${perspective.id}Facets`]}
                    facetStateConstrainSelf={props[`${perspective.id}FacetsConstrainSelf`]}
                    perspectiveState={props[perspective.id]}
                    facetClass={perspective.id}
                    resultClass={perspective.id}
                    fetchingResultCount={props[perspective.id].fetchingResultCount}
                    resultCount={props[perspective.id].resultCount}
                    fetchFacet={props.fetchFacet}
                    fetchFacetConstrainSelf={props.fetchFacetConstrainSelf}
                    fetchResults={props.fetchResults}
                    clearFacet={props.clearFacet}
                    clearAllFacets={props.clearAllFacets}
                    fetchResultCount={props.fetchResultCount}
                    updateFacetOption={props.updateFacetOption}
                    showError={props.showError}
                    defaultActiveFacets={perspective.defaultActiveFacets}
                    rootUrl={rootUrlWithLang}
                    screenSize={screenSize}
                    apexChartsConfig={apexChartsConfig}
                    leafletConfig={leafletConfig}
                    networkConfig={networkConfig}
                    leafletMapState={props.leafletMap}
                    fetchPaginatedResults={props.fetchPaginatedResults}
                    fetchInstanceAnalysis={props.fetchInstanceAnalysis}
                    fetchGeoJSONLayers={props.fetchGeoJSONLayers}
                    fetchGeoJSONLayersBackend={props.fetchGeoJSONLayersBackend}
                    clearGeoJSONLayers={props.clearGeoJSONLayers}
                    fetchByURI={props.fetchByURI}
                    updatePage={props.updatePage}
                    updateRowsPerPage={props.updateRowsPerPage}
                    updateMapBounds={props.updateMapBounds}
                    updatePerspectiveHeaderExpanded={props.updatePerspectiveHeaderExpanded}
                    sortResults={props.sortResults}
                    perspective={perspective}
                    animationValue={props.animationValue}
                    animateMap={props.animateMap}
                  />
                </Route>
                {perspective.resultClasses[perspective.id].instanceConfig &&
                  <Switch>
                    <Redirect
                      from={`/${perspective.id}/page/:id`}
                      to={{
                        pathname: `${rootUrlWithLang}/${perspective.id}/page/:id`,
                        hash: location.hash
                      }}
                    />
                    <Route path={`${rootUrlWithLang}/${perspective.id}/page/:id`}>
                      <InstancePagePerspective
                        portalConfig={portalConfig}
                        layoutConfig={layoutConfig}
                        perspectiveConfig={perspective}
                        perspectiveState={props[`${perspective.id}`]}
                        leafletMapState={props.leafletMap}
                        fetchPaginatedResults={props.fetchPaginatedResults}
                        fetchResults={props.fetchResults}
                        fetchInstanceAnalysis={props.fetchInstanceAnalysis}
                        fetchFacetConstrainSelf={props.fetchFacetConstrainSelf}
                        fetchGeoJSONLayers={props.fetchGeoJSONLayers}
                        fetchGeoJSONLayersBackend={props.fetchGeoJSONLayersBackend}
                        clearGeoJSONLayers={props.clearGeoJSONLayers}
                        fetchByURI={props.fetchByURI}
                        updatePage={props.updatePage}
                        updateRowsPerPage={props.updateRowsPerPage}
                        updateFacetOption={props.updateFacetOption}
                        updateMapBounds={props.updateMapBounds}
                        sortResults={props.sortResults}
                        showError={props.showError}
                        perspective={perspective}
                        animationValue={props.animationValue}
                        animateMap={props.animateMap}
                        videoPlayerState={props.videoPlayer}
                        updateVideoPlayerTime={props.updateVideoPlayerTime}
                        updatePerspectiveHeaderExpanded={props.updatePerspectiveHeaderExpanded}
                        screenSize={screenSize}
                        rootUrl={rootUrlWithLang}
                        apexChartsConfig={apexChartsConfig}
                        leafletConfig={leafletConfig}
                        networkConfig={networkConfig}
                      />
                    </Route>
                  </Switch>}
              </React.Fragment>
            )
          }
          return null
        })}
        {/* create routes for perspectives that have only instance pages */}
        {perspectiveConfigOnlyInfoPages.map(perspective =>
          <Switch key={perspective.id}>
            <Redirect
              from={`${rootUrl}/${perspective.id}/page/:id`}
              to={`${rootUrlWithLang}/${perspective.id}/page/:id`}
            />
            <Route path={`${rootUrlWithLang}/${perspective.id}/page/:id`}>
              <InstancePagePerspective
                portalConfig={portalConfig}
                layoutConfig={layoutConfig}
                perspectiveConfig={perspective}
                perspectiveState={props[`${perspective.id}`]}
                leafletMapState={props.leafletMap}
                fetchPaginatedResults={props.fetchPaginatedResults}
                fetchResults={props.fetchResults}
                fetchInstanceAnalysis={props.fetchInstanceAnalysis}
                fetchFacetConstrainSelf={props.fetchFacetConstrainSelf}
                fetchGeoJSONLayers={props.fetchGeoJSONLayers}
                fetchGeoJSONLayersBackend={props.fetchGeoJSONLayersBackend}
                clearGeoJSONLayers={props.clearGeoJSONLayers}
                fetchByURI={props.fetchByURI}
                updatePage={props.updatePage}
                updateRowsPerPage={props.updateRowsPerPage}
                updateFacetOption={props.updateFacetOption}
                updateMapBounds={props.updateMapBounds}
                sortResults={props.sortResults}
                showError={props.showError}
                perspective={perspective}
                animationValue={props.animationValue}
                animateMap={props.animateMap}
                videoPlayerState={props.videoPlayer}
                updateVideoPlayerTime={props.updateVideoPlayerTime}
                updatePerspectiveHeaderExpanded={props.updatePerspectiveHeaderExpanded}
                screenSize={screenSize}
                rootUrl={rootUrlWithLang}
                apexChartsConfig={apexChartsConfig}
                leafletConfig={leafletConfig}
                networkConfig={networkConfig}
              />
            </Route>
          </Switch>
        )}
        {/* optional: create routes for client side faceted search */}
        {federatedSearchPerspectives.length > 0 &&
          federatedSearchPerspectives.map(perspective =>
            <Route key={perspective.id} path={`${rootUrlWithLang}/${perspective.id}/federated-search`}>
              <FederatedSearchPerspective
                portalConfig={portalConfig}
                layoutConfig={layoutConfig}
                facetedSearchMode='clientFS'
                facetClass={perspective.id}
                resultClass={perspective.id}
                facetState={props.clientFSState}
                clientFSFacetValues={props.clientFSFacetValues}
                fetchingResultCount={props.clientFSState.textResultsFetching}
                resultCount={noClientFSResults ? 0 : props.clientFSState.results.length}
                noClientFSResults={noClientFSResults}
                clientFSState={props.clientFSState}
                clientFSToggleDataset={props.clientFSToggleDataset}
                clientFSFetchResults={props.clientFSFetchResults}
                clientFSClearResults={props.clientFSClearResults}
                clientFSUpdateQuery={props.clientFSUpdateQuery}
                clientFSUpdateFacet={props.clientFSUpdateFacet}
                defaultActiveFacets={perspective.defaultActiveFacets}
                updateMapBounds={props.updateMapBounds}
                screenSize={screenSize}
                showError={props.showError}
                rootUrl={rootUrlWithLang}
                location={location}
                apexChartsConfig={apexChartsConfig}
                leafletConfig={leafletConfig}
                networkConfig={networkConfig}
                perspective={perspective}
                clientFSResults={props.clientFSResults}
                clientFSSortResults={props.clientFSSortResults}
                leafletMapState={props.leafletMap}
                fetchGeoJSONLayersBackend={props.fetchGeoJSONLayersBackend}
                fetchGeoJSONLayers={props.fetchGeoJSONLayers}
                clearGeoJSONLayers={props.clearGeoJSONLayers}
              />
            </Route>
          )}
        {/* create routes for top bar info buttons */}
        {!layoutConfig.topBar.externalAboutPage &&
          <Route path={`${rootUrlWithLang}/about`}>
            <TextPage layoutConfig={layoutConfig}>
              {intl.getHTML('aboutThePortalPartOne')}
              {knowledgeGraphMetadataConfig.showTable &&
                <KnowledgeGraphMetadataTable
                  portalConfig={portalConfig}
                  layoutConfig={layoutConfig}
                  perspectiveID={knowledgeGraphMetadataConfig.perspective}
                  resultClass='knowledgeGraphMetadata'
                  fetchKnowledgeGraphMetadata={props.fetchKnowledgeGraphMetadata}
                  knowledgeGraphMetadata={props[knowledgeGraphMetadataConfig.perspective]
                    ? props[knowledgeGraphMetadataConfig.perspective].knowledgeGraphMetadata
                    : null}
                />}
              {intl.getHTML('aboutThePortalPartTwo')}
            </TextPage>
          </Route>}
        {/* create a route for instructions page */}
        {!layoutConfig.topBar.externalInstructions &&
          <Route path={`${rootUrlWithLang}/instructions`}>
            <TextPage layoutConfig={layoutConfig}>
              {intl.getHTML('instructions')}
            </TextPage>
          </Route>}
      </>
    </Box>
  )
}
Example #17
Source File: fieldPlotter.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function FieldPlotter({
	api_fields,
	clientId,
	data,
	name,
	fields,
	title,
	query_fields,
}) {
	const { integrations, actions } = data.attributes;

	const [error, setError] = useState("");

	useEffect(() => {
		if (!has(integrations, name)) {
			integrations[name] = {};
			data.setAttributes({ integrations });
		}
	}, []);

	const getOptions = (field) => {
		const root = getBlock(clientId);
		const child_fields = root.innerBlocks;
		const available_fields = serializeFields(child_fields);

		let options = available_fields.map((f, i) => {
			const fieldName = get(f, "fieldName"),
				blockName = get(f, "blockName"),
				adminId = get(f, "adminId");

			const field_label = isEmpty(fieldName)
				? get(adminId, "value")
				: fieldName;

			const option = {
				label: field_label,
				value: get(adminId, "value"),
				blockName,
			};

			return option;
		});

		const hasRestriction = has(field, "restriction"); // checking for field restrictions..

		if (hasRestriction && !isEmpty(get(field, "restriction"))) {
			const inRestrictionOptions = options.filter((option) =>
				isEqual(option.blockName, get(field, "restriction"))
			);
			return inRestrictionOptions;
		}

		return options;
	};

	const isFieldEmpty = (v, label = null) => {
		if (isEmpty(label)) {
			return isEqual("Select Field", v) || isEmpty(v);
		}

		return isEqual("Select Field", v) || isEmpty(v) || isEqual(label, v);
	};

	const testErrors = (updatedOptions) => {
		const f = Object.assign({}, api_fields, query_fields);

		let has_err = false;

		each(updatedOptions, (option, key) => {
			const hasKey = has(f, key);
			const isFieldRequired = get(get(f, key), "required");

			const field_label = get(get(f, key), "label");
			const fieldEmpty = isFieldEmpty(option, field_label);

			if (hasKey && isFieldRequired === true && fieldEmpty) {
				// this means a required field is not filled
				has_err = true;
			}
		});

		return has_err;
	};

	const handleFieldsChange = (key, val) => {
		// not mutating the original attribute
		const newIntegrations = clone(integrations);

		set(newIntegrations, name, {
			...get(integrations, name),
			[key]: val,
		});

		data.setAttributes({ integrations: newIntegrations });

		if (testErrors(get(newIntegrations, name))) {
			setError(__("Please Map All Required Fields", "cwp-gutenberg-forms"));
		} else {
			setError("");
		}
	};

	return (
		<div className="cwp-fields-plotter">
			{!isEmpty(error) && (
				<Notice status="error" isDismissible={false}>
					{error}
				</Notice>
			)}
			{map(query_fields, (field, key) => {
				const { label, value, type } = field;
				const currentValue = has(integrations[name], key)
					? integrations[name][key]
					: null;
				const field_label = (
					<span>
						{label}
						{has(field, "required") && get(field, "required") == true && (
							<strong color="red"> (Req)</strong>
						)}
					</span>
				);

				if (type === "select") {
					let mappedValues = value.map((v) => {
						return {
							value: v.value,
							label: v.name,
						};
					});

					let values = [
						{
							label,
							value: "",
						},
						...mappedValues,
					];

					return (
						<SelectControl
							label={__(field_label, "cwp-gutenberg-forms")}
							value={currentValue}
							options={values}
							onChange={(v) => handleFieldsChange(key, v)}
						/>
					);
				} else if (type === "text") {
					return (
						<TextControl
							label={__(label, "cwp-gutenberg-forms")}
							value={currentValue}
							onChange={(v) => handleFieldsChange(key, v)}
						/>
					);
				} else if (type === "tags") {
					const suggestions = has(value, "suggestions")
						? value.suggestions
						: [];

					const currentTokens = !isEmpty(currentValue) ? currentValue : [];
					const parsedValue =
						typeof currentTokens === "string"
							? currentTokens.split(",")
							: currentTokens;

					return (
						<FormTokenField
							label={__(field_label, "cwp-gutenberg-forms")}
							value={parsedValue}
							suggestions={suggestions}
							onChange={(tokens) => {
								handleFieldsChange(key, tokens);
							}}
						/>
					);
				}
			})}
			{map(api_fields, (field, key) => {
				const { label } = field;

				const value = has(integrations[name], key)
					? integrations[name][key]
					: null;

				const defaultValue = has(field, "default") ? field.default : "";

				const field_label = (
					<span>
						{label}
						{has(field, "required") && get(field, "required") == true && (
							<strong color="red"> (Req)</strong>
						)}
					</span>
				);

				return (
					<div className="cwp_field_plot">
						<SelectControl
							onChange={(val) => handleFieldsChange(key, val)}
							label={__(field_label, "cwp-gutenberg-forms")}
							value={value}
							options={[
								{
									label: "Select Field",
									value: defaultValue,
								},
								...getOptions(field),
							]}
						/>
					</div>
				);
			})}
		</div>
	);
}
Example #18
Source File: FacetResults.js    From sampo-ui with MIT License 4 votes vote down vote up
FacetResults = props => {
  const {
    rootUrl, perspective
  } = props
  const { searchMode } = perspective
  const perspectiveID = perspective.id
  return (
    <>
      <PerspectiveTabs
        tabs={perspective.tabs}
        screenSize={props.screenSize}
        layoutConfig={props.layoutConfig}
      />
      <Route
        exact path={`${rootUrl}/${perspective.id}/faceted-search`}
        render={() => <Redirect to={`${rootUrl}/${perspective.id}/faceted-search/table`} />}
      />
      {Object.keys(perspective.resultClasses).map(resultClass => {
        let resultClassConfig = perspective.resultClasses[resultClass]
        if (has(resultClassConfig, 'paginatedResultsConfig')) {
          resultClassConfig = resultClassConfig.paginatedResultsConfig
        }
        if (!has(resultClassConfig, 'component')) {
          return null
        }
        const { tabPath } = resultClassConfig
        const facetClass = resultClassConfig.facetClass ? resultClassConfig.facetClass : resultClass
        const path = [`${rootUrl}/${perspectiveID}/${searchMode}/${tabPath}`, '/iframe.html']
        return (
          <ResultClassRoute
            key={resultClass}
            path={path}
            resultClass={resultClass}
            facetClass={facetClass}
            resultClassConfig={resultClassConfig}
            {...props}
          />
        )
      })}
      {/*
      <Route
        path={`${rootUrl}/${perspective.id}/faceted-search/choropleth_map`}
        render={() =>
          <Deck
            portalConfig={portalConfig}
            center={props.perspectiveState.maps.casualtiesByMunicipality.center}
            zoom={props.perspectiveState.maps.casualtiesByMunicipality.zoom}
            results={props.perspectiveState.results}
            facetUpdateID={props.facetState.facetUpdateID}
            instanceAnalysisData={props.perspectiveState.instanceAnalysisData}
            instanceAnalysisDataUpdateID={props.perspectiveState.instanceAnalysisDataUpdateID}
            resultClass='casualtiesByMunicipality'
            facetClass='perspective1'
            fetchResults={props.fetchResults}
            fetchInstanceAnalysis={props.fetchInstanceAnalysis}
            fetching={props.perspectiveState.fetching}
            fetchingInstanceAnalysisData={props.perspectiveState.fetchingInstanceAnalysisData}
            layerType='polygonLayer'
            mapBoxAccessToken={props.mapBoxAccessToken}
            layoutConfig={props.layoutConfig}
          />}
      />
      <Route
        path={`${rootUrl}/${perspective.id}/faceted-search/bar_chart_race_ms_productions`}
        render={() =>
          <BarChartRace
            portalConfig={portalConfig}
            fetchData={props.fetchResults}
            resultClass='productionsByDecadeAndCountry'
            facetClass='perspective1'
            resultUpdateID={props.perspectiveState.resultUpdateID}
            results={props.perspectiveState.results}
            stepBegin={1000}
            stepEnd={1900}
            stepIncrement={10}
            stepDuration={1000}
          />}
      />
      <Route
        path={`${rootUrl}/${perspective.id}/faceted-search/bar_chart_race_speeches`}
        render={() =>
          <BarChartRace
            portalConfig={portalConfig}
            fetchData={props.fetchResults}
            resultClass='speechesByYearAndParty'
            facetClass='perspective1'
            resultUpdateID={props.perspectiveState.resultUpdateID}
            results={props.perspectiveState.results}
            stepBegin={1907}
            stepEnd={2021}
            stepIncrement={1}
            stepDuration={1000}
          />}
      />
       */}
    </>
  )
}
Example #19
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	let {
		options,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		messages: { empty },
		messages,
		condition,
		enableCondition,
		fieldStyle,
		bulkAdd,
		adminId,
		hint,
		showHint,
	} = props.attributes;

	const radiosContainer = useRef();

	const [radios, setRadios] = useState([]);

	const [focus, setFocus] = useState({
		f: false,
		index: null,
	});

	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {
			const newFieldName = getFieldName("radio", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "radio"),
					default: extract_admin_id(newFieldName, "radio"),
				},
			});
			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"radio",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					),
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"radio",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					),
			});
		}
	};

	useEffect(() => {
		let rootMessages = getRootMessages(props.clientId, "radio");

		if (rootMessages) {
			const newMessages = clone(messages);

			assign(newMessages, rootMessages);

			props.setAttributes({ messages: newMessages });
		}

		let { options } = props.attributes;

		const checked = options.find((c) => c.checked);

		if (checked) {
			let opt = clone(options);

			let remove_extra_checked = opt.map((v) => {
				if (!isEqual(v, checked)) {
					return {
						...v,
						checked: false,
					};
				} else return v;
			});
			setRadios(remove_extra_checked);
		} else {
			setRadios(options);
		}

		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	useEffect(() => {
		if (bulkAdd) return;

		let boxes = radiosContainer.current.querySelectorAll(
			'.cwp-radios-option input[type="text"]'
		);

		if (focus.f) {
			if (focus.index === null) {
				boxes[boxes.length - 1].focus();
			} else {
				boxes[focus.index].focus();
			}

			setFocus({ f: false, index: null });
		}
	}, [radios, focus]); //subscribing to any further changes...

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const addRadio = () => {
		let newOption = {
			label: "Option " + (radios.length + 1),
			checked: false,
		};

		let new_options = clone(radios);

		new_options.push(newOption);

		props.setAttributes({ options: new_options });
		setRadios(new_options);
	};

	const handleDelete = (index) => {
		let new_options = clone(options);

		let deleted_options = pullAt(new_options, [index]); //dosen't matter :-D

		props.setAttributes({ options: new_options });
		setRadios(new_options);
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};

	const handleChange = (e, index) => {
		let new_options = clone(options);

		new_options[index] = {
			...new_options[index],
			label: e.target.value,
		};

		setRadios(new_options);
		props.setAttributes({ options: new_options });
	};

	const handleCheck = (c, index) => {
		let new_options = clone(options);

		new_options.forEach((v) => (v.checked = false));

		new_options[index].checked = c;

		setRadios(new_options);
		props.setAttributes({ options: new_options });
	};

	const handleImage = (img, index, action) => {
		let new_options = clone(options);

		if (action === "add") {
			new_options[index] = {
				...new_options[index],
				image: img,
			};
		}

		if (action === "remove") {
			const RadioToRemove = new_options[index];
			new_options[index] = {
				label: RadioToRemove.label,
			};
		}

		setRadios(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleDuplicate = (index) => {
		let new_options = clone(options);

		new_options.splice(index, 0, new_options[index]);

		setRadios(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleEnter = (index) => {
		let new_options = clone(options);

		new_options.splice(index + 1, 0, { label: "" });

		setRadios(new_options);
		props.setAttributes({ options: new_options });
		setFocus({ f: true, index: index + 1 });
	};

	let handleBackspace = (index) => {
		if (radios[index].label === "") {
			handleDelete(index);

			if (radios[index - 1]) {
				setFocus({ f: true, index: index - 1 });
			}
		}
	};

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	let clearAll = () => {
		const reset = [
			{
				label: "Option 1",
			},
		];

		setRadios(reset);
		props.setAttributes({
			options: reset,
		});
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	return [
		<InspectorControls>
			<PanelBody title="Field Settings" initialOpen={true}>
				<div className="cwp-option">
					<TextControl
						placeholder={adminId.default}
						label={__("Field ID", "cwp-gutenberg-forms")}
						value={adminId.value}
						onChange={handleAdminId}
					/>
				</div>

				{!enableCondition ? (
					<PanelRow>
						<h3 className="cwp-heading">
							{__("Required", "cwp-gutenberg-forms")}
						</h3>
						<FormToggle
							label="Required"
							checked={isRequired}
							onChange={handleRequired}
						/>
					</PanelRow>
				) : (
					<div className="cwp-option">
						<p>
							<Icon icon="info" />{" "}
							{__(
								"You cannot set a conditional field required!",
								"cwp-gutenberg-forms"
							)}
						</p>
					</div>
				)}
				{isRequired && (
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Required Text", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(label) =>
								props.setAttributes({ requiredLabel: label })
							}
							value={requiredLabel}
						/>
					</div>
				)}
				<div className="cwp-option">
					<SelectControl
						label={__("Layout", "cwp-gutenberg-forms")}
						value={fieldStyle}
						options={[
							{ label: __("Block", "cwp-gutenberg-forms"), value: "block" },
							{ label: __("Inline", "cwp-gutenberg-forms"), value: "inline" },
						]}
						onChange={(s) => {
							props.setAttributes({ fieldStyle: s });
						}}
					/>
				</div>
			</PanelBody>
			<PanelBody title={__("Show Hint", "cwp-gutenberg-forms")}>
				<div className="cwp-option">
					<FormToggle
						label="Show Hint"
						checked={showHint}
						onChange={() => props.setAttributes({ showHint: !showHint })}
					/>
					{showHint && (
						<Fragment>
							<TextControl
								label={__("Hint Text", "cwp-gutenberg-forms")}
								onChange={(hint) => props.setAttributes({ hint })}
								value={hint}
							/>
						</Fragment>
					)}
				</div>
			</PanelBody>
			<PanelBody title="Condition">
				<ConditionalLogic
					condition={condition}
					set={props.setAttributes}
					clientId={props.clientId}
					useCondition={props.attributes.enableCondition}
				/>
			</PanelBody>

			{isRequired && (
				<PanelBody title={__("Messages", "cwp-gutenberg-forms")}>
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Required Error", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(label) => setMessages("empty", label)}
							value={empty}
						/>
					</div>
				</PanelBody>
			)}
		</InspectorControls>,
		null,
		<div
			className={`cwp-radios cwp-field ${props.className} is-style-${fieldStyle}`}
		>
			{bulkAdd ? (
				<Bulk_Add onChange={(c) => setRadios(c)} data={props} />
			) : (
				<Fragment>
					{!!props.isSelected && !enableCondition && (
						<div className="cwp-required">
							<h3>{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle checked={isRequired} onChange={handleRequired} />
						</div>
					)}

					<div
						ref={radiosContainer}
						className={`cwp-radios-set ${
							!props.isSelected ? "cwp-radio-set-preview" : ""
						}`}
					>
						<div className="cwp-label-wrap">
							<RichText
								placeholder={__("Add a label", "cwp-gutenberg-forms")}
								tag="label"
								value={label}
								onChange={handleLabel}
							/>
							{!props.isSelected && isRequired && !enableCondition && (
								<div className="cwp-required cwp-noticed">
									<h3>{requiredLabel}</h3>
								</div>
							)}
						</div>
						{radios.map((radio, index) => {
							const hasImage = has(radio, "image"),
								image = hasImage ? radio.image.url : "";

							return (
								<Fragment>
									<div className="cwp-radios-option">
										<input
											id={id.concat(index.toString())}
											checked={radio.checked}
											onClick={() => handleCheck(!radio.checked, index)}
											type="radio"
										/>
										{!!props.isSelected && (
											<label
												style={{ width: "auto" }}
												onClick={() => handleCheck(!radio.checked, index)}
												for={id.concat(index.toString())}
											></label>
										)}
										{!!props.isSelected ? (
											<input
												onKeyDown={(e) => {
													e.key === "Enter" && handleEnter(index);
													e.key === "Backspace" && handleBackspace(index);
												}}
												onChange={(e) => handleChange(e, index)}
												type="text"
												value={radio.label}
											/>
										) : (
											<label>
												{radio.label}{" "}
												{hasImage && !props.isSelected && (
													<ImagePreview
														onEdit={(img) => handleImage(img, index, "add")}
														onRemove={() => handleImage(null, index, "remove")}
														isSelected={props.isSelected}
														image={radio.image}
													/>
												)}
											</label>
										)}
										{!!props.isSelected && (
											<Fragment>
												<ImageUpload
													icon="format-image"
													value={image}
													onSelect={(img) => handleImage(img, index, "add")}
												/>
												<Button
													isDefault
													onClick={() => handleDuplicate(index)}
												>
													<Icon icon="admin-page" />
												</Button>
												<Button isDefault onClick={() => handleDelete(index)}>
													<Icon icon="no-alt" />
												</Button>
											</Fragment>
										)}
									</div>
									{hasImage && !!props.isSelected && (
										<ImagePreview
											onEdit={(img) => handleImage(img, index, "add")}
											onRemove={() => handleImage(null, index, "remove")}
											isSelected={props.isSelected}
											image={radio.image}
										/>
									)}
								</Fragment>
							);
						})}
						{!!props.isSelected && (
							<div className="cwp-radios-controls">
								<div>
									<Button isDefault onClick={addRadio}>
										{__("Add Option", "cwp-gutenberg-forms")}
									</Button>
									<Button
										isDefault
										onClick={() => props.setAttributes({ bulkAdd: true })}
									>
										{__("Bulk Add", "cwp-gutenberg-forms")}
									</Button>
								</div>
								<div>
									<Button onClick={clearAll}>
										{__("Clear All", "cwp-gutenberg-forms")}
									</Button>
								</div>
							</div>
						)}
					</div>
				</Fragment>
			)}
			{showHint && (
                <p className="cwp-hint">{hint}</p>
            )}
		</div>,
	];
}
Example #20
Source File: FacetInfo.js    From sampo-ui with MIT License 4 votes vote down vote up
render () {
    const { facetClass, resultClass, resultCount, someFacetIsFetching, screenSize } = this.props
    const mobileMode = screenSize === 'xs' || screenSize === 'sm'
    const { facets } = this.props.facetState
    const uriFilters = {}
    const spatialFilters = {}
    const textFilters = {}
    const timespanFilters = {}
    const dateNoTimespanFilters = {}
    const integerFilters = {}
    let activeUriFilters = false
    let activeSpatialFilters = false
    let activeTextFilters = false
    let activeTimespanFilters = false
    let activeDateNoTimespanFilters = false
    let activeIntegerFilters = false
    Object.entries(facets).forEach(entry => {
      const [key, value] = entry
      if (has(value, 'uriFilter') && value.uriFilter !== null) {
        activeUriFilters = true
        uriFilters[key] = value.uriFilter
      }
      if (has(value, 'spatialFilter') && value.spatialFilter !== null) {
        activeSpatialFilters = true
        spatialFilters[key] = value.spatialFilter._bounds
      }
      if (has(value, 'textFilter') && value.textFilter !== null) {
        activeTextFilters = true
        textFilters[key] = value.textFilter
      }
      if (has(value, 'timespanFilter') && value.timespanFilter !== null) {
        activeTimespanFilters = true
        timespanFilters[key] = value.timespanFilter
      }
      if (has(value, 'dateNoTimespanFilter') && value.dateNoTimespanFilter !== null) {
        activeDateNoTimespanFilters = true
        dateNoTimespanFilters[key] = value.dateNoTimespanFilter
      }
      if (has(value, 'integerFilter') && value.integerFilter !== null) {
        activeIntegerFilters = true
        integerFilters[key] = value.integerFilter
      }
    })
    return (
      <>
        {this.props.fetchingResultCount
          ? <CircularProgress size={26} />
          : (
            <Typography
              component='h2'
              variant={this.getTypographyVariant()}
              sx={{
                fontWeight: 'bold',
                fontSize: '1rem'
              }}
            >
              {intl.get('facetBar.results')}: {resultCount} {intl.get(`perspectives.${resultClass}.facetResultsType`)}
            </Typography>
            )}
        {!mobileMode &&
          <Divider
            sx={theme => ({
              marginTop: theme.spacing(0.5),
              marginBottom: theme.spacing(0.5)
            })}
          />}
        {(activeUriFilters ||
          activeSpatialFilters ||
          activeTextFilters ||
          activeTimespanFilters ||
          activeDateNoTimespanFilters ||
          activeIntegerFilters
        ) &&
          <>
            <Box
              sx={{
                display: 'flex',
                justifyContent: 'space-between'
              }}
            >
              <Typography component='h2' variant={this.getTypographyVariant()}>{intl.get('facetBar.activeFilters')}</Typography>
              <Button
                variant='contained'
                color='secondary'
                size='small'
                startIcon={<DeleteIcon />}
                onClick={this.handleRemoveAllFiltersOnClick}
                disabled={someFacetIsFetching}
                sx={theme => ({
                  margin: theme.spacing(1)
                })}
              >{intl.get('facetBar.removeAllFilters')}
              </Button>
            </Box>
            <ActiveFilters
              facetClass={facetClass}
              uriFilters={uriFilters}
              spatialFilters={spatialFilters}
              textFilters={textFilters}
              timespanFilters={timespanFilters}
              dateNoTimespanFilters={dateNoTimespanFilters}
              integerFilters={integerFilters}
              updateFacetOption={this.props.updateFacetOption}
              someFacetIsFetching={someFacetIsFetching}
              fetchingResultCount={this.props.fetchingResultCount}
              fetchFacet={this.props.fetchFacet}
              propertiesTranslationsID={this.props.propertiesTranslationsID}
            />
            <Divider
              sx={theme => ({
                marginTop: theme.spacing(0.5),
                marginBottom: theme.spacing(0.5)
              })}
            />
          </>}
        {!mobileMode &&
          <Typography
            component='h2'
            variant={this.getTypographyVariant()}
            sx={{
              fontWeight: 'bold',
              fontSize: '1rem'
            }}
          >
            {intl.get('facetBar.narrowDownBy')}:
          </Typography>}
      </>
    )
  }
Example #21
Source File: condition.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function Condition(props) {
	let currentField = props.fieldName,
		{ clientId, condition } = props; // where props.set === props.setAttributes

	useEffect(() => {
		let first_field = getOptions()[1];

		if (
			!isEmpty(first_field) &&
			has(first_field, "value") &&
			isEmpty(condition.value)
		) {
			handleConditionChange(first_field.value, "field");
		}
	}, []);

	const getOptions = () => {
		let fields = [
			{
				value: null,
				label: __("Select Field", 'cwp-gutenberg-forms'),
			},
		];

		// function getSiblings( clientId ) => return the relatives of the particular field inside a parent/root block

		getSiblings(clientId).forEach((sibling) => {
			if (!has(sibling, "label") && !has(sibling, "field_name")) return;
			const { label, field_name } = sibling; //destructuring the label attribute from the sibling field..

			fields.push({ value: field_name, label: label }); //pushing the option to the select field
			//where field_name is the unique id of the field;
		});

		return fields;
	};

	const handleConditionChange = (value, type) => {
		const newCondition = clone(condition); //creating a copy of the existing condition;

		set(newCondition, type, value); //modifying the condition copy;

		props.set({ condition: newCondition }); //props.setAttributes()
	};

	let operators = [
		{
			value: "===",
			label: __("Is Equal To", 'cwp-gutenberg-forms'),
		},
		{
			value: "!==",
			label: __("Not Equal To", 'cwp-gutenberg-forms'),
		},
	];

	const getValueType = () => {
		if (isEmpty(condition.field)) return null;

		const splitted_fieldName = condition.field.split("-"),
			fieldName = splitted_fieldName[0];

		const siblings = getSiblings(clientId);

		let currentSibling = siblings.filter(
				(v) => v.field_name === condition.field
			),
			selectOptions;

		if (
			fieldName === "select" ||
			fieldName === "radio" ||
			fieldName === "checkbox"
		) {
			if (has(currentSibling[0], "options")) {
				const generatedOptions = currentSibling[0].options.map((v) => {
					return {
						...v,
						value: v.label,
					};
				});

				generatedOptions.unshift({
					label: __( "Select Value", 'cwp-gutenberg-forms'),
					value: "",
				});

				selectOptions = generatedOptions;
			}
		}

		switch (fieldName) {
			case "radio":
				return (
					<SelectControl
						value={condition.value}
						onChange={(val) => {
							handleConditionChange(val, "value");
						}}
						options={selectOptions}
					/>
				);

			case "checkbox":
				return (
					<SelectControl
						multiple
						value={condition.value}
						onChange={(val) => {
							handleConditionChange(val, "value");
						}}
						options={selectOptions}
					/>
				);

			case "select":
				return (
					<SelectControl
						value={condition.value}
						onChange={(val) => {
							handleConditionChange(val, "value");
						}}
						options={selectOptions}
					/>
				);

			default: {
				return (
					<TextControl
						value={condition.value}
						placeholder={__("value", 'cwp-gutenberg-forms')}
						onChange={(val) => handleConditionChange(val, "value")}
					/>
				);
			}
		}
	};

	return (
		<div className="cwp-form-condition-component">
			<div className="cwp-option">
				<PanelRow>
					<h3>Use Condition</h3>
					<FormToggle
						checked={props.useCondition}
						onChange={() => {
							if (props.useCondition === false) {
								props.set({ isRequired: false });
							}
							props.set({
								enableCondition: !props.useCondition,
							});
						}}
					/>
				</PanelRow>
			</div>

			{props.useCondition && (
				<Fragment>
					<h3>Show if</h3>
					<SelectControl
						value={condition.field}
						options={getOptions()}
						onChange={(field) => {
							handleConditionChange(field, "field");
						}}
					/>
					<SelectControl
						onChange={(operator) => {
							handleConditionChange(operator, "condition");
						}}
						value={condition.condition}
						options={operators}
					/>
					{getValueType()}
				</Fragment>
			)}
		</div>
	);
}
Example #22
Source File: DemarcheSectionSelect.js    From datapass with GNU Affero General Public License v3.0 4 votes vote down vote up
DemarcheSectionSelect = ({ body, scrollableId }) => {
  const { disabled, onChange, enrollment, demarches } = useContext(FormContext);
  const { demarche: selectedDemarcheId } = enrollment;

  const [isLoading, setIsLoading] = useState(false);
  const [confirmNewDemarcheId, setConfirmNewDemarcheId] = useState(false);

  // reducer expects onChange events from HTML Element
  const selectNewDemarche = useCallback(
    (newDemarcheId) => {
      onChange({ target: { value: newDemarcheId, name: 'demarche' } });
    },
    [onChange]
  );

  const filteredDemarches = useMemo(
    () =>
      pickBy(demarches, function (value, key) {
        return (
          !value.state?.technical_team_value ||
          !enrollment.technical_team_value ||
          value.state.technical_team_value ===
            enrollment.technical_team_value ||
          key === selectedDemarcheId
        );
      }),
    [demarches, enrollment.technical_team_value, selectedDemarcheId]
  );

  const onSelectDemarche = (event) => {
    let newDemarcheId = event.target.value || 'default';

    const preFilledEnrollment = merge(
      {},
      get(demarches, 'default', {}).state,
      get(demarches, selectedDemarcheId, {}).state
    );

    // we compare current enrollment with prefilled associated with selectedDemarcheId
    // if modifications, it means any change to selectedDemarcheId could overwrite the user's changes.
    const modifications = findModifiedFields(preFilledEnrollment, enrollment);

    if (!isEmpty(modifications)) {
      // trigger confirmation modal before updating Enrollment
      setConfirmNewDemarcheId(newDemarcheId);
    } else {
      // update Enrollment Context with new demarche
      selectNewDemarche(newDemarcheId);
    }
  };

  useEffect(() => {
    if (selectedDemarcheId !== 'default') {
      setIsLoading(true);
      const timer = setTimeout(() => setIsLoading(false), 900);
      return () => clearTimeout(timer);
    }
  }, [selectedDemarcheId]);

  const displayNotification = useMemo(
    () =>
      has(demarches, selectedDemarcheId) && selectedDemarcheId !== 'default',
    [demarches, selectedDemarcheId]
  );

  return (
    <>
      <ScrollablePanel scrollableId={scrollableId}>
        <h2>Les modèles pré-remplis</h2>
        {body || (
          <p>
            Nous avons identifié plusieurs cas d’usage de cette API. Si votre
            demande d’habilitation s’inscrit dans un des cas ci-dessous,
            sélectionnez-le pour gagner du temps.
          </p>
        )}
        <SelectInput
          label="Sélectionnez le modèle correspondant à votre projet"
          name="demarche"
          options={Object.keys(filteredDemarches).map((demarcheId) => ({
            id: demarcheId,
            label: get(demarches, demarcheId, {}).label,
          }))}
          value={selectedDemarcheId}
          disabled={disabled}
          onChange={onSelectDemarche}
        />
        {confirmNewDemarcheId && (
          <ConfirmationModal
            title="Attention, vous allez écraser certains de vos changements"
            handleCancel={() => setConfirmNewDemarcheId(false)}
            handleConfirm={() => {
              setConfirmNewDemarcheId(false);
              selectNewDemarche(confirmNewDemarcheId);
            }}
            confirmLabel="Changer tout de même"
          >
            <p>
              En changeant de cas d’usage, certains des champs que vous avez
              édités vont être écrasés.
            </p>
          </ConfirmationModal>
        )}
        {displayNotification && (
          <DemarcheSectionSelectNotification
            isLoading={isLoading}
            selectedDemarcheId={selectedDemarcheId}
            demarches={demarches}
          />
        )}
      </ScrollablePanel>
    </>
  );
}
Example #23
Source File: Utils.js    From sampo-ui with MIT License 4 votes vote down vote up
mergeFacetConfigs = (clientFacets, serverFacets) => {
  const mergedFacets = {}
  for (const clientFacetID in clientFacets) {
    if (!has(serverFacets, clientFacetID)) {
      console.log(clientFacetID + ' missing from serverFacets')
      continue
    }
    const clientFacet = clientFacets[clientFacetID]
    const serverFacet = serverFacets[clientFacetID]
    // strip new lines
    if (serverFacet.facetValueFilter && serverFacet.facetValueFilter !== '') {
      serverFacet.facetValueFilter = serverFacet.facetValueFilter.replace(/\s+/g, ' ').trim()
    }
    if (serverFacet.facetLabelFilter && serverFacet.facetLabelFilter !== '') {
      serverFacet.facetLabelFilter = serverFacet.facetLabelFilter.replace(/\s+/g, ' ').trim()
    }
    if (serverFacet.predicate && serverFacet.predicate !== '') {
      serverFacet.predicate = serverFacet.predicate.replace(/\s+/g, ' ').trim()
    }
    if (serverFacet.labelPath && serverFacet.labelPath !== '') {
      serverFacet.labelPath = serverFacet.labelPath.replace(/\s+/g, ' ').trim()
    }
    if (serverFacet.orderByPattern && serverFacet.orderByPattern !== '') {
      serverFacet.orderByPattern = serverFacet.orderByPattern.replace(/\s+/g, ' ').trim()
    }
    if (serverFacet.textQueryPredicate && serverFacet.textQueryPredicate !== '') {
      serverFacet.textQueryPredicate = serverFacet.textQueryPredicate.replace(/\s+/g, ' ').trim()
    }

    // start building new facet config object
    const mergedFacet = {
      containerClass: clientFacet.containerClass,
      filterType: clientFacet.filterType
    }
    if (clientFacet.searchField) {
      mergedFacet.searchField = clientFacet.searchField
    }
    if (clientFacet.sortButton) {
      mergedFacet.sortButton = clientFacet.sortButton
    }
    if (clientFacet.spatialFilterButton) {
      mergedFacet.spatialFilterButton = clientFacet.spatialFilterButton
    }
    if (clientFacet.pieChartButton) {
      mergedFacet.pieChartButton = clientFacet.pieChartButton
    }
    if (clientFacet.lineChartButton) {
      mergedFacet.lineChartButton = clientFacet.lineChartButton
    }

    // labelPath --> sortByPredicate
    if (serverFacet.labelPath) {
      mergedFacet.sortByPredicate = serverFacet.labelPath
    }
    if (serverFacet.orderByPattern) {
      mergedFacet.sortByPattern = serverFacet.orderByPattern
    }

    if (serverFacet.type === 'text') {
      mergedFacet.facetType = 'text'
      if (serverFacet.textQueryPredicate && serverFacet.textQueryPredicate !== '') {
        mergedFacet.textQueryPredicate = serverFacet.textQueryPredicate
      }
      if (serverFacet.textQueryProperty && serverFacet.textQueryProperty !== '') {
        mergedFacet.textQueryProperty = serverFacet.textQueryProperty
      }
    }

    if (serverFacet.type === 'list') {
      if (serverFacet.facetValueFilter && serverFacet.facetValueFilter !== '') {
        mergedFacet.facetValueFilter = serverFacet.facetValueFilter
      }
      if (serverFacet.facetLabelFilter && serverFacet.facetLabelFilter !== '') {
        mergedFacet.facetLabelFilter = serverFacet.facetLabelFilter
      }
      if (has(serverFacet, 'literal')) {
        mergedFacet.literal = serverFacet.literal
      }
      mergedFacet.facetType = 'list'
      mergedFacet.predicate = serverFacet.predicate
      mergedFacet.sortBy = clientFacet.sortBy
      mergedFacet.sortDirection = clientFacet.sortDirection
    }

    if (serverFacet.type === 'hierarchical') {
      if (serverFacet.facetValueFilter && serverFacet.facetValueFilter !== '') {
        mergedFacet.facetValueFilter = serverFacet.facetValueFilter
      }
      if (serverFacet.facetLabelFilter && serverFacet.facetLabelFilter !== '') {
        mergedFacet.facetLabelFilter = serverFacet.facetLabelFilter
      }
      mergedFacet.facetType = 'hierarchical'
      mergedFacet.predicate = serverFacet.predicate
      mergedFacet.parentProperty = serverFacet.parentProperty
    }

    if (serverFacet.type === 'timespan') {
      mergedFacet.facetType = 'timespan'
      if (serverFacet.sortByAscPredicate) {
        mergedFacet.sortByAscPredicate = serverFacet.sortByAscPredicate
      }
      if (serverFacet.sortByDescPredicate) {
        mergedFacet.sortByDescPredicate = serverFacet.sortByDescPredicate
      }
      mergedFacet.predicate = serverFacet.predicate
      mergedFacet.startProperty = serverFacet.startProperty
      mergedFacet.endProperty = serverFacet.endProperty
      mergedFacet.max = clientFacet.max
      mergedFacet.min = clientFacet.min
    }

    if (serverFacet.type === 'integer') {
      mergedFacet.predicate = serverFacet.predicate
      mergedFacet.typecasting = serverFacet.typecasting
      mergedFacet.facetType = 'integer'
    }

    mergedFacets[clientFacetID] = mergedFacet
  }
  for (const facetID in mergedFacets) {
    const unorderedFacet = mergedFacets[facetID]
    const orderedFacet = Object.keys(unorderedFacet).sort().reduce(
      (obj, key) => {
        obj[key] = unorderedFacet[key]
        return obj
      },
      {}
    )
    mergedFacets[facetID] = orderedFacet
  }
  // console.log(mergedFacets)
  console.log(JSON.stringify(mergedFacets))
}