1
0
Fork 0
mirror of https://github.com/anyproto/anytype-ts.git synced 2025-06-11 10:18:07 +09:00

JS-3362: dictionary relations filters + bugfixes

This commit is contained in:
Andrew Simachev 2023-11-15 14:37:19 +01:00
parent 5aec6900cf
commit 2a681b8a7d
No known key found for this signature in database
GPG key ID: 49A163D0D14E6FD8
6 changed files with 130 additions and 46 deletions

View file

@ -35,7 +35,7 @@ const forceProps = {
},
charge: {
strength: -250,
distanceMax: 200,
distanceMax: 300,
},
link: {
distance: 50,

View file

@ -1573,13 +1573,13 @@
"errorAccountRecover109": "Account has been deleted",
"errorObjectImport7": "Import has not been completed. CSV import supports up to 1000 rows and 10 columns.",
"objectOrigin0": "User",
"objectOrigin1": "Clipboard",
"objectOrigin2": "Drag'n'Drop",
"objectOrigin3": "Import",
"objectOrigin4": "Webclipper",
"objectOrigin5": "Sharing Extension",
"objectOrigin6": "Usecase",
"objectOrigin7": "Built-in"
"origin0": "User",
"origin1": "Clipboard",
"origin2": "Drag'n'Drop",
"origin3": "Import",
"origin4": "Webclipper",
"origin5": "Sharing Extension",
"origin6": "Usecase",
"origin7": "Built-in"
}

View file

@ -77,7 +77,7 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
switch (relation.format) {
case I.RelationType.Tag:
case I.RelationType.Status:
case I.RelationType.Status: {
Item = (element: any) => {
return (
<div
@ -113,8 +113,9 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
</React.Fragment>
);
break;
};
case I.RelationType.Object:
case I.RelationType.Object: {
Item = (element: any) => {
const type = dbStore.getTypeById(element.type);
@ -150,8 +151,9 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
</React.Fragment>
);
break;
};
case I.RelationType.Checkbox:
case I.RelationType.Checkbox: {
value = (
<div className="item">
<Select
@ -160,13 +162,14 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
arrowClassName="light"
options={checkboxOptions}
value={item.value ? '1' : '0'}
onChange={(v: string) => { this.onChange('value', Boolean(Number(v)), true); }}
onChange={v => this.onChange('value', Boolean(Number(v)), true)}
/>
</div>
);
break;
};
case I.RelationType.Date:
case I.RelationType.Date: {
if ([ I.FilterQuickOption.NumberOfDaysAgo, I.FilterQuickOption.NumberOfDaysNow ].includes(item.quickOption)) {
value = (
<div key="filter-value-date-days" className="item">
@ -201,10 +204,10 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
);
onSubmit = (e: any) => { this.onSubmitDate(e); };
};
break;
};
default:
default: {
value = (
<div className="item">
<Input
@ -212,13 +215,29 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
value={item.value}
placeholder={translate('commonValue')}
onFocus={this.onFocusText}
onKeyUp={(e: any, v: string) => { this.onChange('value', v, true); }}
onSelect={(e: any) => { this.onSelect(e); }}
onKeyUp={(e: any, v: string) => this.onChange('value', v, true)}
onSelect={e => this.onSelect(e)}
/>
<Icon className="clear" onClick={this.onClear} />
</div>
);
break;
};
};
if (Relation.isDictionary(item.relationKey)) {
value = (
<div className="item">
<Select
id={[ 'filter', 'dictionary', item.id ].join('-')}
className="checkboxValue"
arrowClassName="light"
options={Relation.getDictionaryOptions(item.relationKey)}
value={item.value}
onChange={v => this.onChange('value', Number(v), true)}
/>
</div>
);
};
if ([ I.FilterCondition.None, I.FilterCondition.Empty, I.FilterCondition.NotEmpty ].includes(item.condition)) {
@ -333,12 +352,18 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
const relationOptions = this.getRelationOptions();
const relationOption: any = relationOptions.find(it => it.id == item.relationKey) || {};
const conditionOptions = Relation.filterConditionsByType(relation.format);
const conditionOption: any = conditionOptions.find(it => it.id == item.condition) || {};
const filterQuickOptions = Relation.filterQuickOptions(relation.format, item.condition);
const filterOption: any = filterQuickOptions.find(it => it.id == item.quickOption) || {};
let conditionOptions = [];
if (Relation.isDictionary(item.relationKey)) {
conditionOptions = Relation.filterConditionsDictionary();
} else {
conditionOptions = Relation.filterConditionsByType(relation.format);
};
const conditionOption: any = conditionOptions.find(it => it.id == item.condition) || {};
const ret: any[] = [
{ id: 'relation', icon: relationOption.icon, name: relationOption.name, arrow: true },
{ id: 'condition', icon: '', name: conditionOption.name, format: relation.format, arrow: true },
@ -352,7 +377,11 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
};
onOver (e: any, item: any) {
const { getId, getSize, setActive } = this.props;
const { getId, getSize, setActive, param } = this.props;
const { data } = param;
const { getView, itemId } = data;
const view = getView();
const filter = view.getFilter(itemId);
if (!keyboard.isMouseDisabled) {
setActive(item, false);
@ -369,7 +398,11 @@ const MenuDataviewFilterValues = observer(class MenuDataviewFilterValues extends
};
case 'condition': {
options = Relation.filterConditionsByType(item.format);
if (Relation.isDictionary(filter.relationKey)) {
options = Relation.filterConditionsDictionary();
} else {
options = Relation.filterConditionsByType(item.format);
};
break;
};

View file

@ -23,7 +23,15 @@ const MenuItemFilter = observer(class MenuItemFilter extends React.Component<Pro
render () {
const { id, index, relation, condition, quickOption, subId, readonly, style, onOver, onClick, onRemove } = this.props;
const conditionOptions = Relation.filterConditionsByType(relation.format);
const isDictionary = Relation.isDictionary(relation.relationKey);
let conditionOptions = [];
if (isDictionary) {
conditionOptions = Relation.filterConditionsDictionary();
} else {
conditionOptions = Relation.filterConditionsByType(relation.format);
};
const conditionOption: any = conditionOptions.find(it => it.id == condition) || {};
const filterOptions = Relation.filterQuickOptions(relation.format, conditionOption.id);
const filterOption: any = filterOptions.find(it => it.id == quickOption) || {};
@ -124,6 +132,15 @@ const MenuItemFilter = observer(class MenuItemFilter extends React.Component<Pro
};
};
if (isDictionary) {
const options = Relation.getDictionaryOptions(relation.relationKey);
const option = options.find(it => it.id == v);
if (option) {
v = option.name;
};
};
if ([ I.FilterCondition.None, I.FilterCondition.Empty, I.FilterCondition.NotEmpty ].includes(condition)) {
v = null;
};

View file

@ -1,32 +1,31 @@
import Struct from 'google-protobuf/google/protobuf/struct_pb.js';
const prepare = (o: any) => {
if (typeof o === 'undefined') {
o = null;
} else
if (typeof o === 'object') {
for (const k in o) {
if (typeof o[k] === 'object') {
o[k] = prepare(o[k]);
} else
if (typeof o[k] === 'undefined') {
o[k] = null;
};
};
};
return o;
};
export class Encode {
public static struct (obj: any) {
return Struct.Struct.fromJavaScript(this.prepare(obj));
return Struct.Struct.fromJavaScript(prepare(obj));
};
public static value (value: any) {
return Struct.Value.fromJavaScript(this.prepare(value));
return Struct.Value.fromJavaScript(prepare(value));
};
private static prepare (o: any) {
if (typeof o === 'undefined') {
o = null;
} else
if (typeof o === 'object') {
for (const k in o) {
if (typeof o[k] === 'object') {
o[k] = this.prepare(o[k]);
} else
if (typeof o[k] === 'undefined') {
o[k] = null;
};
};
};
return o;
};
};
export class Decode {

View file

@ -99,6 +99,15 @@ class Relation {
return ret;
};
public filterConditionsDictionary () {
return [
{ id: I.FilterCondition.Equal, name: translate('filterConditionEqual') },
{ id: I.FilterCondition.NotEqual, name: translate('filterConditionNotEqual') },
{ id: I.FilterCondition.Empty, name: translate('filterConditionEmpty') },
{ id: I.FilterCondition.NotEmpty, name: translate('filterConditionNotEmpty') },
];
};
public filterQuickOptions (type: I.RelationType, condition: I.FilterCondition) {
if ([ I.FilterCondition.Empty, I.FilterCondition.NotEmpty ].includes(condition)) {
return [];
@ -263,7 +272,7 @@ class Relation {
case 'origin': {
value = Number(value) || I.ObjectOrigin.None;
return (value == I.ObjectOrigin.None) ? null : translate(`objectOrigin${value}`);
return (value == I.ObjectOrigin.None) ? null : translate(`origin${value}`);
};
};
return null;
@ -385,6 +394,24 @@ class Relation {
return options.map(it => ({ id: it, name: it }));
};
public getDictionaryOptions (relationKey: string) {
const options = [];
const dictionary = {
layout: I.ObjectLayout,
origin: I.ObjectOrigin,
};
const item = dictionary[relationKey];
if (item) {
const keys = Object.keys(item).filter(v => !isNaN(Number(v)));
keys.forEach((key, index) => {
options.push({ id: index, name: translate(`${relationKey}${index}`) });
});
};
return options;
};
public getStringValue (value: any) {
if ((typeof value === 'object') && value && UtilCommon.hasProperty(value, 'length')) {
return String(value.length ? value[0] : '');
@ -551,9 +578,17 @@ class Relation {
return this.systemKeys().filter(it => !skipKeys.includes(it));
};
isSystem (relationKey: string) {
isSystem (relationKey: string): boolean {
return this.systemKeys().includes(relationKey);
};
dictionaryKeys () {
return [ 'layout', 'origin' ];
};
isDictionary (relationKey: string): boolean {
return this.dictionaryKeys().includes(relationKey);
};
};