import * as React from 'react'; import { observer } from 'mobx-react'; import { observable } from 'mobx'; import arrayMove from 'array-move'; import { getRange, setRange } from 'selection-ranges'; import { Label, Input, Button, Select, Loader, Error, DragBox, Tag, Icon, IconObject } from 'Component'; import { I, C, S, U, J, Relation, keyboard, Storage } from 'Lib'; import Util from '../lib/util'; interface State { error: string; isLoading: boolean; withContent: boolean; collection: any; }; const MAX_LENGTH = 320; const Create = observer(class Create extends React.Component { details: any = { type: '', tag: [], }; node: any = null; refName: any = null; refDescription: any = null; refSpace: any = null; refType: any = null; refCollection: any = null; refComment: any = null; isCreating = false; url = ''; state = { error: '', isLoading: false, withContent: true, collection: null, }; constructor (props: I.PageComponent) { super(props); this.onSubmit = this.onSubmit.bind(this); this.onSpaceChange = this.onSpaceChange.bind(this); this.onTypeChange = this.onTypeChange.bind(this); this.onKeyPress = this.onKeyPress.bind(this); this.onKeyDown = this.onKeyDown.bind(this); this.onKeyUp = this.onKeyUp.bind(this); this.onInput = this.onInput.bind(this); this.onFocus = this.onFocus.bind(this); this.onDragEnd = this.onDragEnd.bind(this); this.onCheckbox = this.onCheckbox.bind(this); this.onCollection = this.onCollection.bind(this); this.focus = this.focus.bind(this); }; render () { const { error, isLoading, withContent } = this.state; const { space } = S.Common; const tags = this.getTagsValue(); const collection = this.state.collection as any; return (
this.node = ref} className="page pageCreate" > {isLoading ? : ''}
); }; componentDidMount (): void { U.Subscription.createAll(() => { this.initSpace(); this.initName(); this.initType(); this.initCollection(); this.setState({ withContent: Boolean(Storage.get('withContent')) }); }); }; componentDidUpdate(): void { this.initType(); this.initCollection(); this.placeholderCheck(); }; initSpace () { const spaces = this.getSpaces(); if (!this.refSpace || !spaces.length) { return; }; let spaceId = S.Common.space || Storage.get('lastSpaceId'); if (!spaceId) { spaceId = spaces[0].id; }; this.refSpace.setOptions(spaces); this.refSpace.setValue(spaceId); this.onSpaceChange(spaceId); }; initType () { const options = this.getTypes().map(it => ({ ...it, id: it.uniqueKey })); if (!this.refType || !options.length) { return; }; this.details.type = this.details.type || J.Constant.typeKey.bookmark; this.refType.setOptions(options); this.refType.setValue(this.details.type); }; initCollection () { const { collection } = this.details; if (!collection) { return; }; U.Object.getById(collection, {}, object => this.setState({ collection: object })); }; initName () { if (!this.refName) { return; }; Util.getCurrentTab(tab => { if (!tab) { return; }; this.refName.setValue(tab.title); this.refName.focus(); this.url = tab.url; }); }; getObjects (subId: string) { return S.Record.getRecords(subId); }; getSpaces () { return U.Space.getList() .filter(it => it && U.Space.canMyParticipantWrite(it.targetSpaceId)) .map(it => ({ ...it, id: it.targetSpaceId, object: it })); }; getTypes () { const layouts = U.Object.getPageLayouts(); return this.getObjects(J.Constant.subId.type). map(Util.optionMapper). filter(this.filter). filter(it => layouts.includes(it.recommendedLayout) && (it.spaceId == S.Common.space) && (it.uniqueKey != J.Constant.typeKey.template)). sort(U.Data.sortByName); }; filter (it: any) { return it && !it.isHidden && !it.isArchived && !it.isDeleted; }; onTypeChange (id: string): void { this.details.type = id; this.forceUpdate(); }; onCollection (): void { const collectionType = S.Record.getCollectionType(); S.Menu.open('searchObject', { className: 'single', element: '#select-collection', data: { filters: [ { relationKey: 'resolvedLayout', condition: I.FilterCondition.In, value: I.ObjectLayout.Collection }, { relationKey: 'type.uniqueKey', condition: I.FilterCondition.NotIn, value: [ J.Constant.typeKey.template ] }, { relationKey: 'isReadonly', condition: I.FilterCondition.NotEqual, value: true }, ], onSelect: (el: any) => { this.setState({ collection: el }); }, canAdd: true, addParam: { name: 'Create new Collection', nameWithFilter: 'Create new Collection "%s"', onClick: (details: any) => { C.ObjectCreate(details, [], '', collectionType?.uniqueKey, S.Common.space, message => { if (message.error.code) { this.setState({ error: message.error.description }); return; }; this.setState({ collection: message.details }); }); }, }, } }); }; onSpaceChange (id: string): void { S.Common.spaceSet(id); U.Subscription.createAll(() => this.forceUpdate()); Storage.set('lastSpaceId', id); }; getTagsValue () { return S.Record.getRecordIds(J.Constant.subId.option, ''). filter(id => this.details.tag.includes(id)). map(id => S.Detail.get(J.Constant.subId.option, id)). filter(it => it && !it._empty_); }; clear () { const node = $(this.node); node.find('#entry').text(' '); this.focus(); }; focus () { const node = $(this.node); const entry = node.find('#entry'); if (entry.length) { window.setTimeout(() => { entry.focus(); setRange(entry.get(0), { start: 0, end: 0 }); this.scrollToBottom(); }); }; }; onValueRemove (id: string) { this.setValue(this.details.tag.filter(it => it != id)); }; onDragEnd (oldIndex: number, newIndex: number) { this.setValue(arrayMove(this.details.tag, oldIndex, newIndex)); }; onKeyDown (e: any) { const node = $(this.node); const entry = node.find('#entry'); keyboard.shortcut('backspace', e, (pressed: string) => { e.stopPropagation(); const range = getRange(entry.get(0)); if (range.start || range.end) { return; }; e.preventDefault(); this.details.tag.pop(); this.setValue(this.details.tag); }); this.placeholderCheck(); this.scrollToBottom(); }; onKeyPress (e: any) { const node = $(this.node); const entry = node.find('#entry'); if (entry.length && (entry.text().length >= MAX_LENGTH)) { e.preventDefault(); }; }; onKeyUp (e: any) { S.Menu.updateData('dataviewOptionList', { filter: this.getValue() }); this.placeholderCheck(); this.resize(); this.scrollToBottom(); }; onInput () { this.placeholderCheck(); }; onFocus () { const relation = S.Record.getRelationByKey('tag'); const element = '#select-tag'; S.Menu.open('dataviewOptionList', { element, horizontal: I.MenuDirection.Center, commonFilter: true, onOpen: () => { window.setTimeout(() => $(element).addClass('isFocused')); }, onClose: () => $(element).removeClass('isFocused'), data: { canAdd: true, canEdit: true, filter: '', value: this.details.tag, maxCount: relation.maxCount, noFilter: true, relation: observable.box(relation), maxHeight: 120, onChange: (value: string[]) => { this.setValue(value); } } }); }; placeholderCheck () { const node = $(this.node); const value = this.getValue(); const list = node.find('#list'); const placeholder = node.find('#placeholder'); const length = this.details.tag.length; length ? list.show() : list.hide(); value || length ? placeholder.hide() : placeholder.show(); }; getValue (): string { const node = $(this.node); const entry = node.find('#entry'); return entry.length ? String(entry.text() || '').trim() : ''; }; setValue (value: string[]) { const relation = S.Record.getRelationByKey('tag'); value = U.Common.arrayUnique(value); const length = value.length; if (relation.maxCount && (length > relation.maxCount)) { value = value.slice(length - relation.maxCount, length); }; this.details.tag = value; this.clear(); this.forceUpdate(); }; onSubmit (e: any) { e.preventDefault(); if (this.isCreating) { return; }; const { withContent } = this.state; const collection = this.state.collection as any; this.isCreating = true; this.setState({ isLoading: true, error: '' }); const details = Object.assign({ name: this.refName?.getValue(), description: this.refDescription?.getValue(), origin: I.ObjectOrigin.Webclipper, }, this.details); const type = S.Record.getTypeByKey(details.type); delete(details.type); C.ObjectCreateFromUrl(details, S.Common.space, type?.uniqueKey, this.url, withContent, type?.defaultTemplateId, (message: any) => { this.setState({ isLoading: false }); if (message.error.code) { this.setState({ error: message.error.description }); return; }; const object = message.details; if (collection) { C.ObjectCollectionAdd(collection.id, [ object.id ], () => { this.setState({ collection: null }); }); }; S.Extension.createdObject = object; U.Router.go('/success', {}); this.isCreating = false; }); }; onCheckbox () { const { withContent } = this.state; Storage.set('withContent', !withContent); this.setState({ withContent: !withContent }); }; scrollToBottom () { const node = $(this.node); const content: any = node.find('.cellContent'); content.scrollTop(content.get(0).scrollHeight + parseInt(content.css('paddingBottom'))); }; resize () { $(window).trigger('resize.menuDataviewOptionList'); }; }); export default Create;