aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoreperelm2 <emily_perelman@brown.edu>2023-08-10 18:46:04 -0400
committereperelm2 <emily_perelman@brown.edu>2023-08-10 18:46:04 -0400
commit1c5bb5390ab9f198acde7d48aaa7d7d536f432cd (patch)
treeb80984ea3b07d79925eeb7194ff6dedb6d38cf87 /src
parent082a280ed989007d84c8619438889c64a6fedb14 (diff)
need to pull
Diffstat (limited to 'src')
-rw-r--r--src/.DS_Storebin10244 -> 10244 bytes
-rw-r--r--src/client/documents/Documents.ts11
-rw-r--r--src/client/util/.ClientUtils.ts.icloudbin0 -> 161 bytes
-rw-r--r--src/client/util/.ReportManager.scss.icloudbin0 -> 168 bytes
-rw-r--r--src/client/util/.ReportManager.tsx.icloudbin0 -> 167 bytes
-rw-r--r--src/client/views/.Palette.scss.icloudbin0 -> 160 bytes
-rw-r--r--src/client/views/DashboardView.tsx78
-rw-r--r--src/client/views/FilterPanel.tsx371
-rw-r--r--src/client/views/Palette.tsx69
-rw-r--r--src/client/views/nodes/.QueryBox.scss.icloudbin0 -> 160 bytes
-rw-r--r--src/client/views/nodes/.QueryBox.tsx.icloudbin0 -> 160 bytes
-rw-r--r--src/fields/.ListSpec.ts.icloudbin0 -> 158 bytes
-rw-r--r--src/fields/IconField.ts26
-rw-r--r--src/fields/PresField.ts6
-rw-r--r--src/mobile/MobileInterface.tsx1
-rw-r--r--src/server/stats/.userLoginStats.csv.icloudbin0 -> 168 bytes
16 files changed, 329 insertions, 233 deletions
diff --git a/src/.DS_Store b/src/.DS_Store
index 06389d6ae..946e85928 100644
--- a/src/.DS_Store
+++ b/src/.DS_Store
Binary files differ
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 5d8ae19fc..533df5c11 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -74,6 +74,8 @@ export class FInfo {
readOnly: boolean = false;
fieldType?: string = '';
values?: Field[];
+
+ filterable?: boolean = true;
// format?: string; // format to display values (e.g, decimal places, $, etc)
// parse?: ScriptField; // parse a value from a string
constructor(d: string, readOnly?: boolean) {
@@ -88,7 +90,7 @@ class BoolInfo extends FInfo {
class NumInfo extends FInfo {
fieldType? = 'number';
values?: number[] = [];
- constructor(d: string, readOnly?: boolean, values?: number[], filterable?:boolean) {
+ constructor(d: string, readOnly?: boolean, values?: number[], filterable?: boolean) {
super(d, readOnly);
this.values = values;
}
@@ -96,15 +98,16 @@ class NumInfo extends FInfo {
class StrInfo extends FInfo {
fieldType? = 'string';
values?: string[] = [];
- constructor(d: string, readOnly?: boolean, values?: string[], filterable?:boolean) {
+ constructor(d: string, filterable?: boolean, readOnly?: boolean, values?: string[]) {
super(d, readOnly);
this.values = values;
+ this.filterable = filterable;
}
}
class DocInfo extends FInfo {
fieldType? = 'Doc';
values?: Doc[] = [];
- constructor(d: string, filterable?:boolean, values?: Doc[] ) {
+ constructor(d: string, filterable?: boolean, values?: Doc[]) {
super(d, true);
this.values = values;
}
@@ -184,7 +187,7 @@ export class DocumentOptions {
author?: string; // STRt = new StrInfo('creator of document'); // bcz: don't change this. Otherwise, the userDoc's field Infos will have a FieldInfo assigned to its author field which will render it unreadable
author_date?: DATEt = new DateInfo('date the document was created', true);
annotationOn?: DOCt = new DocInfo('document annotated by this document', false);
- color?: STRt = new StrInfo('foreground color data doc');
+ color?: STRt = new StrInfo('foreground color data doc', true);
hidden?: BOOLt = new BoolInfo('whether the document is not rendered by its collection');
backgroundColor?: STRt = new StrInfo('background color for data doc');
opacity?: NUMt = new NumInfo('document opacity');
diff --git a/src/client/util/.ClientUtils.ts.icloud b/src/client/util/.ClientUtils.ts.icloud
new file mode 100644
index 000000000..e5e477586
--- /dev/null
+++ b/src/client/util/.ClientUtils.ts.icloud
Binary files differ
diff --git a/src/client/util/.ReportManager.scss.icloud b/src/client/util/.ReportManager.scss.icloud
new file mode 100644
index 000000000..f5d34d292
--- /dev/null
+++ b/src/client/util/.ReportManager.scss.icloud
Binary files differ
diff --git a/src/client/util/.ReportManager.tsx.icloud b/src/client/util/.ReportManager.tsx.icloud
new file mode 100644
index 000000000..72924c53a
--- /dev/null
+++ b/src/client/util/.ReportManager.tsx.icloud
Binary files differ
diff --git a/src/client/views/.Palette.scss.icloud b/src/client/views/.Palette.scss.icloud
new file mode 100644
index 000000000..49a2ac2da
--- /dev/null
+++ b/src/client/views/.Palette.scss.icloud
Binary files differ
diff --git a/src/client/views/DashboardView.tsx b/src/client/views/DashboardView.tsx
index ae55c8ebf..d6c7b43d5 100644
--- a/src/client/views/DashboardView.tsx
+++ b/src/client/views/DashboardView.tsx
@@ -43,7 +43,7 @@ export class DashboardView extends React.Component {
@observable private selectedDashboardGroup = DashboardGroup.MyDashboards;
@observable private newDashboardName: string | undefined = undefined;
- @observable private newDashboardColor: string | undefined = "#AFAFAF";
+ @observable private newDashboardColor: string | undefined = '#AFAFAF';
@action abortCreateNewDashboard = () => {
this.newDashboardName = undefined;
};
@@ -100,24 +100,17 @@ export class DashboardView extends React.Component {
const dashboardCount = DocListCast(Doc.MyDashboards.data).length + 1;
const placeholder = `Dashboard ${dashboardCount}`;
return (
- <div className="new-dashboard"
- style={{
+ <div
+ className="new-dashboard"
+ style={{
background: StrCast(Doc.UserDoc().userBackgroundColor),
- color: StrCast(Doc.UserDoc().userColor)
- }}
- >
+ color: StrCast(Doc.UserDoc().userColor),
+ }}>
<div className="header">Create New Dashboard</div>
- <EditableText
- formLabel='Title'
- placeholder={placeholder}
- type={Type.SEC}
- color={StrCast(Doc.UserDoc().userColor)}
- setVal={val => this.setNewDashboardName(val as string)}
- fillWidth
- />
+ <EditableText formLabel="Title" placeholder={placeholder} type={Type.SEC} color={StrCast(Doc.UserDoc().userColor)} setVal={val => this.setNewDashboardName(val as string)} fillWidth />
<ColorPicker
- formLabel='Background'
- colorPickerType='github'
+ formLabel="Background"
+ colorPickerType="github"
type={Type.TERT}
selectedColor={this.newDashboardColor}
setSelectedColor={color => {
@@ -165,21 +158,14 @@ export class DashboardView extends React.Component {
};
render() {
- const color = StrCast(Doc.UserDoc().userColor)
- const variant = StrCast(Doc.UserDoc().userVariantColor)
+ const color = StrCast(Doc.UserDoc().userColor);
+ const variant = StrCast(Doc.UserDoc().userVariantColor);
return (
<>
<div className="dashboard-view">
<div className="left-menu">
- <Button
- text={'My Dashboards'}
- active={this.selectedDashboardGroup === DashboardGroup.MyDashboards}
- color={color}
- align={'flex-start'}
- onClick={() => this.selectDashboardGroup(DashboardGroup.MyDashboards)}
- fillWidth
- />
- <Button
+ <Button text={'My Dashboards'} active={this.selectedDashboardGroup === DashboardGroup.MyDashboards} color={color} align={'flex-start'} onClick={() => this.selectDashboardGroup(DashboardGroup.MyDashboards)} fillWidth />
+ <Button
text={'Shared Dashboards' + ' (' + this.getDashboards(DashboardGroup.SharedDashboards).length + ')'}
active={this.selectedDashboardGroup === DashboardGroup.SharedDashboards}
color={this.getDashboards(DashboardGroup.SharedDashboards).some(dash => !DocListCast(Doc.MySharedDocs.viewed).includes(dash)) ? 'green' : color}
@@ -196,11 +182,11 @@ export class DashboardView extends React.Component {
.filter(key => key !== `acl-${Doc.CurrentUserEmailNormalized}` && !['acl-Me', 'acl-Guest'].includes(key))
.some(key => dashboard[DocAcl][key] !== AclPrivate);
return (
- <div
- className="dashboard-container"
- key={dashboard[Id]}
+ <div
+ className="dashboard-container"
+ key={dashboard[Id]}
style={{ background: this.isUnviewedSharedDashboard(dashboard) && this.selectedDashboardGroup === DashboardGroup.SharedDashboards ? '#6CB982' : shared ? variant : '' }}
- onContextMenu={e => this.onContextMenu(dashboard, e)}
+ onContextMenu={e => this.onContextMenu(dashboard, e)}
onClick={e => this.clickDashboard(e, dashboard)}>
<img
src={
@@ -208,12 +194,7 @@ export class DashboardView extends React.Component {
}
/>
<div className="info">
- <EditableText
- type={Type.PRIM}
- color={color}
- val={StrCast(dashboard.title)}
- setVal={val => (Doc.GetProto(dashboard).title = val)}
- />
+ <EditableText type={Type.PRIM} color={color} val={StrCast(dashboard.title)} setVal={val => (Doc.GetProto(dashboard).title = val)} />
{this.selectedDashboardGroup === DashboardGroup.SharedDashboards && this.isUnviewedSharedDashboard(dashboard) ? <div>unviewed</div> : <div></div>}
<div
className="more"
@@ -229,10 +210,13 @@ export class DashboardView extends React.Component {
<Button size={Size.SMALL} color={color} icon={<FontAwesomeIcon color={color} icon="bars" />} />
</div>
</div>
- <div className={`background`} style={{
- background: StrCast(Doc.UserDoc().userColor),
- filter: 'opacity(0.2)'
- }}/>
+ <div
+ className={`background`}
+ style={{
+ background: StrCast(Doc.UserDoc().userColor),
+ filter: 'opacity(0.2)',
+ }}
+ />
<div className={'dashboard-status' + (shared ? '-shared' : '')}>{shared ? 'shared' : ''}</div>
</div>
);
@@ -243,10 +227,13 @@ export class DashboardView extends React.Component {
this.setNewDashboardName('');
}}>
+
- <div className={`background`} style={{
- background: StrCast(Doc.UserDoc().userColor),
- filter: 'opacity(0.2)'
- }}/>
+ <div
+ className={`background`}
+ style={{
+ background: StrCast(Doc.UserDoc().userColor),
+ filter: 'opacity(0.2)',
+ }}
+ />
</div>
</div>
</div>
@@ -416,6 +403,7 @@ export class DashboardView extends React.Component {
backgroundColor: background,
title: `Untitled Tab 1`,
};
+
const title = name ? name : `Dashboard ${dashboardCount}`;
const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: title }, id, 'row');
diff --git a/src/client/views/FilterPanel.tsx b/src/client/views/FilterPanel.tsx
index 127708ca3..1a923a995 100644
--- a/src/client/views/FilterPanel.tsx
+++ b/src/client/views/FilterPanel.tsx
@@ -15,11 +15,12 @@ import { AiOutlineMinusSquare, AiOutlinePlusSquare } from 'react-icons/ai';
import { CiCircleRemove } from 'react-icons/ci';
import { Slider, Rail, Handles, Tracks, Ticks } from 'react-compound-slider';
import { TooltipRail, Handle, Tick, Track } from './nodes/SliderBox-components';
+import { DocumentOptions } from '../documents/Documents';
-//slight bug when you don't click on background canvas before creating filter and the you click on the canvas
+//slight bug when you don't click on background canvas before creating filter and the you click on the canvas
- //use to -- & determine amount of sigfinict digits -- make all sections blue evn when collapsed
- // transform switch to x and y not x coordinate and y coordinate
+//use to -- & determine amount of sigfinict digits -- make all sections blue evn when collapsed
+// transform switch to x and y not x coordinate and y coordinate
interface filterProps {
rootDoc: Doc;
@@ -51,6 +52,7 @@ export class FilterPanel extends React.Component<filterProps> {
if (targetDoc) {
SearchBox.foreachRecursiveDoc([this.targetDoc], (depth, doc) => allDocs.add(doc));
}
+ console.log('this is all Docs' + Array.from(allDocs));
return Array.from(allDocs);
}
@@ -66,12 +68,17 @@ export class FilterPanel extends React.Component<filterProps> {
.filter(key => key[0])
.filter(key => key.indexOf('modificationDate') !== -1 || (key[0] === key[0].toUpperCase() && !key.startsWith('_')) || noviceFields.includes(key) || !Doc.noviceMode)
.sort();
+
+ // console.log('THIS IS HERE ' + Doc.UserDoc().color + 'space ' + Doc.UserDoc().color);
noviceFields.forEach(key => sortedKeys.splice(sortedKeys.indexOf(key), 1));
+
+ console.log('this is novice fields ' + noviceFields + 'and this is sorted Keys ' + sortedKeys);
+
return [...noviceFields, ...sortedKeys];
}
@computed get rangeFilters() {
- return StrListCast(this.targetDoc?._childFiltersByRanges).filter((filter, i) => !( i % 3) )
+ return StrListCast(this.targetDoc?._childFiltersByRanges).filter((filter, i) => !(i % 3));
}
/**
@@ -85,25 +92,24 @@ export class FilterPanel extends React.Component<filterProps> {
@computed get mapActiveFiltersToFacets() {
const filters = new Map<string, string>();
//this.targetDoc.docFilters
- this.activeFilters.map(filter => filters.set(filter.split(Doc.FilterSep)[1] ,filter.split(Doc.FilterSep)[0] ))
- return filters
+ this.activeFilters.map(filter => filters.set(filter.split(Doc.FilterSep)[1], filter.split(Doc.FilterSep)[0]));
+ return filters;
}
- //
+ //
// activeFacetHeaders() - just the facet names, not the rest of the filter
//
// this wants to return all the filter facets that have an existing filter set on them in order to show them in the rendered panel
- // this set may overlap the selectedFilters
+ // this set may overlap the selectedFilters
// if the components reloads, these will still exist and be shown
// ["#tags", "width", "height"]
//
@computed get activeFacetHeaders() {
- const activeHeaders = new Array()
- this.activeFilters.map(filter => activeHeaders.push(filter.split(Doc.FilterSep)[0]) )
+ const activeHeaders = new Array();
+ this.activeFilters.map(filter => activeHeaders.push(filter.split(Doc.FilterSep)[0]));
-
return activeHeaders;
}
/**
@@ -123,7 +129,7 @@ export class FilterPanel extends React.Component<filterProps> {
newarray = [];
subDocs.forEach(t => {
const facetVal = t[facetKey];
- // console.log("facetVal " + facetVal)
+ // console.log("facetVal " + facetVal)
if (facetVal instanceof RichTextField || typeof facetVal === 'string') rtFields++;
facetVal !== undefined && valueSet.add(Field.toString(facetVal as Field));
(facetVal === true || facetVal == false) && valueSet.add(Field.toString(!facetVal));
@@ -137,12 +143,10 @@ export class FilterPanel extends React.Component<filterProps> {
}
// }
// });
-
+
return { strings: Array.from(valueSet.keys()), rtFields };
}
-
-
public removeFilter = (filterName: string) => {
Doc.setDocFilter(this.targetDoc, filterName, undefined, 'remove');
Doc.setDocRangeFilter(this.targetDoc, filterName, undefined);
@@ -152,97 +156,85 @@ export class FilterPanel extends React.Component<filterProps> {
@observable _chosenFacetsCollapse = new ObservableMap<string, boolean>();
@observable _collapseReturnKeys = new Array();
-
// this computed function gets the active filters and maps them to their headers
//
// activeRenderedFacetInfos()
// returns renderInfo for all user selected filters and for all existing filters set on the document
// Map("tags" => {"checkbox"},
- // "width" => {"rangs", domain:[1978,1992]})
+ // "width" => {"rangs", domain:[1978,1992]})
//
- @computed get activeRenderedFacetInfos(){
-
+ @computed get activeRenderedFacetInfos() {
return new Set(
- Array.from(new Set(Array.from(this._selectedFacetHeaders).concat(this.activeFacetHeaders))).map(
- facetHeader => {
-
- const facetValues = this.gatherFieldValues(this.targetDocChildren, facetHeader);
-
- let nonNumbers = 0;
- let minVal = Number.MAX_VALUE,
- maxVal = -Number.MAX_VALUE;
- facetValues.strings.map(val => {
- const num = val ? Number(val) : Number.NaN;
- if (Number.isNaN(num)) {
- val && nonNumbers++;
- } else {
- minVal = Math.min(num, minVal);
- maxVal = Math.max(num, maxVal);
- }
- });
-
-
- if (facetHeader === 'text' ){
- return {facetHeader: facetHeader, renderType: 'text'}
-
- } else if (facetHeader !== 'tags' && nonNumbers / facetValues.strings.length < 0.1){
-
- const extendedMinVal = minVal - Math.min(1, Math.floor(Math.abs(maxVal - minVal) * 0.1));
- const extendedMaxVal = Math.max(minVal + 1, maxVal + Math.min(1, Math.ceil(Math.abs(maxVal - minVal) * 0.05)));
- const ranged = Doc.readDocRangeFilter(this.targetDoc, facetHeader); // not the filter range, but the zooomed in range on the filter
- return {facetHeader: facetHeader, renderType: 'range', domain: [extendedMinVal, extendedMaxVal], range: ranged ? ranged: [extendedMinVal, extendedMaxVal]}
-
- } else{
- return {facetHeader: facetHeader, renderType: 'checkbox'}
+ Array.from(new Set(Array.from(this._selectedFacetHeaders).concat(this.activeFacetHeaders))).map(facetHeader => {
+ const facetValues = this.gatherFieldValues(this.targetDocChildren, facetHeader);
+
+ let nonNumbers = 0;
+ let minVal = Number.MAX_VALUE,
+ maxVal = -Number.MAX_VALUE;
+ facetValues.strings.map(val => {
+ const num = val ? Number(val) : Number.NaN;
+ if (Number.isNaN(num)) {
+ val && nonNumbers++;
+ } else {
+ minVal = Math.min(num, minVal);
+ maxVal = Math.max(num, maxVal);
}
+ });
+
+ if (facetHeader === 'text') {
+ return { facetHeader: facetHeader, renderType: 'text' };
+ } else if (facetHeader !== 'tags' && nonNumbers / facetValues.strings.length < 0.1) {
+ const extendedMinVal = minVal - Math.min(1, Math.floor(Math.abs(maxVal - minVal) * 0.1));
+ const extendedMaxVal = Math.max(minVal + 1, maxVal + Math.min(1, Math.ceil(Math.abs(maxVal - minVal) * 0.05)));
+ const ranged = Doc.readDocRangeFilter(this.targetDoc, facetHeader); // not the filter range, but the zooomed in range on the filter
+ return { facetHeader: facetHeader, renderType: 'range', domain: [extendedMinVal, extendedMaxVal], range: ranged ? ranged : [extendedMinVal, extendedMaxVal] };
+ } else {
+ return { facetHeader: facetHeader, renderType: 'checkbox' };
}
- ))
+ })
+ );
}
@observable _selectedFacetHeaders = new Set<string>();
/**
- * user clicks on a filter facet because they want to see it.
+ * user clicks on a filter facet because they want to see it.
* this adds this chosen filter to a set of user selected filters called: selectedFilters
* if this component reloads, then these filters will go away since they haven't been written to any Doc anywhere
- *
+ *
* // this._selectedFacets.add(facetHeader); .. add to Set() not array
*/
@action
- facetClick = (facetHeader: string) => { // just when someone chooses a facet
+ facetClick = (facetHeader: string) => {
+ // just when someone chooses a facet
this._selectedFacetHeaders.add(facetHeader);
- return
+ return;
};
-
@action
- sortingCurrentFacetValues = (facetHeader:string) => {
- this._collapseReturnKeys.splice(0)
+ sortingCurrentFacetValues = (facetHeader: string) => {
+ this._collapseReturnKeys.splice(0);
Array.from(this.activeRenderedFacetInfos.keys()).map(renderInfo => {
- if ( renderInfo.renderType === "range" && renderInfo.facetHeader === facetHeader) {
- this._collapseReturnKeys.push(renderInfo.range)
-
- }
- })
-
- for (var key of this.facetValues(facetHeader)){
- if (this.mapActiveFiltersToFacets.get(key)){
- this._collapseReturnKeys.push(key)
- }}
-
- return (
- <div className = " filterbox-collpasedAndActive">
- {this._collapseReturnKeys.join(', ') }
- </div>)
- }
-
-
+ if (renderInfo.renderType === 'range' && renderInfo.facetHeader === facetHeader) {
+ this._collapseReturnKeys.push(renderInfo.range);
+ }
+ });
+
+ for (var key of this.facetValues(facetHeader)) {
+ if (this.mapActiveFiltersToFacets.get(key)) {
+ this._collapseReturnKeys.push(key);
+ }
+ }
+
+ return <div className=" filterbox-collpasedAndActive">{this._collapseReturnKeys.join(', ')}</div>;
+ };
+
facetValues = (facetHeader: string) => {
const allCollectionDocs = new Set<Doc>();
SearchBox.foreachRecursiveDoc(this.targetDocChildren, (depth: number, doc: Doc) => allCollectionDocs.add(doc));
@@ -267,9 +259,15 @@ export class FilterPanel extends React.Component<filterProps> {
return nonNumbers / facetValues.length > 0.1 ? facetValues.sort() : facetValues.sort((n1: string, n2: string) => Number(n1) - Number(n2));
};
-
render() {
+ // console.log('this is frist one today ' + this._allFacets);
+ this._allFacets.forEach(element => console.log(element));
const options = this._allFacets.filter(facet => this.activeFacetHeaders.indexOf(facet) === -1).map(facet => ({ value: facet, label: facet }));
+ // console.log('HEELLLLLL ' + DocumentOptions);
+
+ const freeformOptions: DocumentOptions = {};
+
+ console.log('wht is this ' + freeformOptions.author);
return (
<div className="filterBox-treeView">
@@ -290,50 +288,57 @@ export class FilterPanel extends React.Component<filterProps> {
</div>
<div className="filterBox-tree" key="tree">
- {Array.from(this.activeRenderedFacetInfos.keys()).map(renderInfo => ( // iterato over activeFacetRenderInfos ==> renderInfo which you can renderInfo.facetHeader
- <div>
- <div className = "filterBox-facetHeader">
- <div className = "filterBox-facetHeader-Header"> </div>
- {renderInfo.facetHeader.charAt(0).toUpperCase() + renderInfo.facetHeader.slice(1)}
-
- <div className = "filterBox-facetHeader-collapse"
- onClick = {action((e) => {
- const collapseBoolValue = this._chosenFacetsCollapse.get(renderInfo.facetHeader)
- this._chosenFacetsCollapse.set(renderInfo.facetHeader, !collapseBoolValue )})}>
- {this._chosenFacetsCollapse.get(renderInfo.facetHeader) ? <AiOutlinePlusSquare/> : <AiOutlineMinusSquare/> }
-
- </div>
-
- <div className='filterBox-facetHeader-remove'
- onClick = {action((e) => {
-
- for (var key of this.facetValues(renderInfo.facetHeader)){
- if (this.mapActiveFiltersToFacets.get(key)){
- Doc.setDocFilter(this.targetDoc, renderInfo.facetHeader, key, 'remove')
- }}
- this._selectedFacetHeaders.delete(renderInfo.facetHeader)
- this._chosenFacetsCollapse.delete(renderInfo.facetHeader)
-
- if (renderInfo.domain){
- Doc.setDocRangeFilter(this.targetDoc, renderInfo.facetHeader, renderInfo.domain, 'remove')
- }})} >
-
- <CiCircleRemove/> </div>
+ {Array.from(this.activeRenderedFacetInfos.keys()).map(
+ (
+ renderInfo // iterato over activeFacetRenderInfos ==> renderInfo which you can renderInfo.facetHeader
+ ) => (
+ <div>
+ <div className="filterBox-facetHeader">
+ <div className="filterBox-facetHeader-Header"> </div>
+ {renderInfo.facetHeader.charAt(0).toUpperCase() + renderInfo.facetHeader.slice(1)}
+
+ <div
+ className="filterBox-facetHeader-collapse"
+ onClick={action(e => {
+ const collapseBoolValue = this._chosenFacetsCollapse.get(renderInfo.facetHeader);
+ this._chosenFacetsCollapse.set(renderInfo.facetHeader, !collapseBoolValue);
+ })}>
+ {this._chosenFacetsCollapse.get(renderInfo.facetHeader) ? <AiOutlinePlusSquare /> : <AiOutlineMinusSquare />}
+ </div>
+
+ <div
+ className="filterBox-facetHeader-remove"
+ onClick={action(e => {
+ for (var key of this.facetValues(renderInfo.facetHeader)) {
+ if (this.mapActiveFiltersToFacets.get(key)) {
+ Doc.setDocFilter(this.targetDoc, renderInfo.facetHeader, key, 'remove');
+ }
+ }
+ this._selectedFacetHeaders.delete(renderInfo.facetHeader);
+ this._chosenFacetsCollapse.delete(renderInfo.facetHeader);
+
+ if (renderInfo.domain) {
+ Doc.setDocRangeFilter(this.targetDoc, renderInfo.facetHeader, renderInfo.domain, 'remove');
+ }
+ })}>
+ <CiCircleRemove />{' '}
+ </div>
+ </div>
+
+ {this._chosenFacetsCollapse.get(renderInfo.facetHeader)
+ ? this.sortingCurrentFacetValues(renderInfo.facetHeader)
+ : this.displayFacetValueFilterUIs(renderInfo.renderType, renderInfo.facetHeader, renderInfo.domain, renderInfo.range)}
+ {/* */}
</div>
-
- { this._chosenFacetsCollapse.get(renderInfo.facetHeader) ?
- this.sortingCurrentFacetValues(renderInfo.facetHeader)
- : this.displayFacetValueFilterUIs(renderInfo.renderType, renderInfo.facetHeader, renderInfo.domain, renderInfo.range ) }
- {/* */}
- </div>
- ))}
+ )
+ )}
</div>
</div>
);
}
- private displayFacetValueFilterUIs(type: string | undefined, facetHeader: string, renderInfoDomain?: number[] | undefined, renderInfoRange?: number[] ): React.ReactNode {
- switch (type /* renderInfo.type */ ) {
+ private displayFacetValueFilterUIs(type: string | undefined, facetHeader: string, renderInfoDomain?: number[] | undefined, renderInfoRange?: number[]): React.ReactNode {
+ switch (type /* renderInfo.type */) {
case 'text': // if (this.chosenFacets.get(facetHeader) === 'text')
return (
<input
@@ -353,82 +358,80 @@ export class FilterPanel extends React.Component<filterProps> {
<div>
<input
style={{ width: 20, marginLeft: 20 }}
- checked={
- StrListCast(this.targetDoc._childFilters)
- .find(filter => filter.split(Doc.FilterSep)[0] === facetHeader && filter.split(Doc.FilterSep)[1] == facetValue)
- ?.split(Doc.FilterSep)[2] === 'check'
+ checked={
+ StrListCast(this.targetDoc._childFilters)
+ .find(filter => filter.split(Doc.FilterSep)[0] === facetHeader && filter.split(Doc.FilterSep)[1] == facetValue)
+ ?.split(Doc.FilterSep)[2] === 'check'
}
type={type}
- onChange={undoable(e => Doc.setDocFilter(this.targetDoc, facetHeader, fval, e.target.checked ? 'check' : 'remove'), 'set filter')}
+ onChange={undoable(e => Doc.setDocFilter(this.targetDoc, facetHeader, fval, e.target.checked ? 'check' : 'remove'), 'set filter')}
/>
{facetValue}
</div>
);
- })
-
- case 'range':
- const domain = renderInfoDomain;
- if (domain){
- return(
- <div className = "sliderBox-outerDiv" style = {{width: "95%", height: 45 }}>
- <Slider mode={2} step={Math.min(1, 0.1 * (domain[1] - domain[0]))} domain={[-1000, 1000]} rootStyle={{ position: 'relative', width: '100%' }}
- onChange={ values => Doc.setDocRangeFilter(this.targetDoc, facetHeader, values)} values={renderInfoRange!} >
- <Rail>{railProps => <TooltipRail {...railProps} />}</Rail>
- <Handles>
- {({ handles, activeHandleID, getHandleProps }) => (
- <div className="slider-handles">
- {handles.map((handle, i) => {
- // const value = i === 0 ? defaultValues[0] : defaultValues[1];
- return (
- <div >
- <Handle key={handle.id} handle={handle} domain={domain} isActive={handle.id === activeHandleID} getHandleProps={getHandleProps} />
- </div>
- );
- })}
- </div>
- )}
- </Handles>
- <Tracks left={false} right={false}>
- {({ tracks, getTrackProps }) => (
- <div className="slider-tracks">
- {tracks.map(({ id, source, target }) => (
- <Track key={id} source={source} target={target} disabled={false} getTrackProps={getTrackProps} />
- ))}
- </div>
- )}
- </Tracks>
- <Ticks count={5}>
- {({ ticks }) => (
- <div className="slider-ticks">
- {ticks.map(tick => (
- <Tick key={tick.id} tick={tick} count={ticks.length} format={(val: number) => val.toString()} />
- ))}
- </div>
- )}
- </Ticks>
- </Slider>
- </div>
-
- )
- }
+ });
+
+ case 'range':
+ const domain = renderInfoDomain;
+ if (domain) {
+ return (
+ <div className="sliderBox-outerDiv" style={{ width: '95%', height: 45 }}>
+ <Slider
+ mode={2}
+ step={Math.min(1, 0.1 * (domain[1] - domain[0]))}
+ domain={[-1000, 1000]}
+ rootStyle={{ position: 'relative', width: '100%' }}
+ onChange={values => Doc.setDocRangeFilter(this.targetDoc, facetHeader, values)}
+ values={renderInfoRange!}>
+ <Rail>{railProps => <TooltipRail {...railProps} />}</Rail>
+ <Handles>
+ {({ handles, activeHandleID, getHandleProps }) => (
+ <div className="slider-handles">
+ {handles.map((handle, i) => {
+ // const value = i === 0 ? defaultValues[0] : defaultValues[1];
+ return (
+ <div>
+ <Handle key={handle.id} handle={handle} domain={domain} isActive={handle.id === activeHandleID} getHandleProps={getHandleProps} />
+ </div>
+ );
+ })}
+ </div>
+ )}
+ </Handles>
+ <Tracks left={false} right={false}>
+ {({ tracks, getTrackProps }) => (
+ <div className="slider-tracks">
+ {tracks.map(({ id, source, target }) => (
+ <Track key={id} source={source} target={target} disabled={false} getTrackProps={getTrackProps} />
+ ))}
+ </div>
+ )}
+ </Tracks>
+ <Ticks count={5}>
+ {({ ticks }) => (
+ <div className="slider-ticks">
+ {ticks.map(tick => (
+ <Tick key={tick.id} tick={tick} count={ticks.length} format={(val: number) => val.toString()} />
+ ))}
+ </div>
+ )}
+ </Ticks>
+ </Slider>
+ </div>
+ );
+ }
-
-
- // case 'range'
- // return <Slider ...
- // return <slider domain={renderInfo.domain}> domain is number[] for min and max
- // onChange = { ... Doc.setDocRangeFilter(this.targetDoc, facetHeader, [extendedMinVal, extendedMaxVal] ) }
- //
- // OR
-
- // return <div>
- // <slider domain={renderInfo.domain}> // domain is number[] for min and max
- // <dimain changing handles >
- // <?div
-
- ;
+ // case 'range'
+ // return <Slider ...
+ // return <slider domain={renderInfo.domain}> domain is number[] for min and max
+ // onChange = { ... Doc.setDocRangeFilter(this.targetDoc, facetHeader, [extendedMinVal, extendedMaxVal] ) }
+ //
+ // OR
+
+ // return <div>
+ // <slider domain={renderInfo.domain}> // domain is number[] for min and max
+ // <dimain changing handles >
+ // <?div
}
}
}
-
-
diff --git a/src/client/views/Palette.tsx b/src/client/views/Palette.tsx
new file mode 100644
index 000000000..3ad28c418
--- /dev/null
+++ b/src/client/views/Palette.tsx
@@ -0,0 +1,69 @@
+import { IReactionDisposer, observable, reaction } from 'mobx';
+import { observer } from 'mobx-react';
+import * as React from 'react';
+import { Doc } from '../../fields/Doc';
+import { NumCast } from '../../fields/Types';
+import { emptyFunction, returnEmptyDoclist, returnEmptyFilter, returnEmptyString, returnFalse, returnTrue, emptyPath } from '../../Utils';
+import { Transform } from '../util/Transform';
+import { DocumentView } from './nodes/DocumentView';
+import './Palette.scss';
+
+export interface PaletteProps {
+ x: number;
+ y: number;
+ thumb: number[];
+ thumbDoc: Doc;
+}
+
+@observer
+export default class Palette extends React.Component<PaletteProps> {
+ private _selectedDisposer?: IReactionDisposer;
+ @observable private _selectedIndex: number = 0;
+
+ componentDidMount = () => {
+ this._selectedDisposer = reaction(
+ () => NumCast(this.props.thumbDoc.selectedIndex),
+ i => (this._selectedIndex = i),
+ { fireImmediately: true }
+ );
+ };
+
+ componentWillUnmount = () => {
+ this._selectedDisposer?.();
+ };
+
+ render() {
+ return (
+ <div className="palette-container" style={{ transform: `translate(${this.props.x}px, ${this.props.y}px)` }}>
+ <div className="palette-thumb" style={{ transform: `translate(${this.props.thumb[0] - this.props.x}px, ${this.props.thumb[1] - this.props.y}px)` }}>
+ <div className="palette-thumbContent" style={{ transform: `translate(-${this._selectedIndex * 50 + 10}px, 0px)` }}>
+ <DocumentView
+ Document={this.props.thumbDoc}
+ DataDoc={undefined}
+ addDocument={undefined}
+ addDocTab={returnFalse}
+ rootSelected={returnTrue}
+ pinToPres={emptyFunction}
+ removeDocument={undefined}
+ ScreenToLocalTransform={Transform.Identity}
+ PanelWidth={() => window.screen.width}
+ PanelHeight={() => window.screen.height}
+ renderDepth={0}
+ isDocumentActive={returnTrue}
+ isContentActive={emptyFunction}
+ focus={emptyFunction}
+ docViewPath={returnEmptyDoclist}
+ styleProvider={returnEmptyString}
+ whenChildContentsActiveChanged={emptyFunction}
+ bringToFront={emptyFunction}
+ docFilters={returnEmptyFilter}
+ docRangeFilters={returnEmptyFilter}
+ searchFilterDocs={returnEmptyDoclist}
+ />
+ <div className="palette-cover" style={{ transform: `translate(${Math.max(0, this._selectedIndex) * 50.75 + 23}px, 0px)` }}></div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
diff --git a/src/client/views/nodes/.QueryBox.scss.icloud b/src/client/views/nodes/.QueryBox.scss.icloud
new file mode 100644
index 000000000..26ba46a75
--- /dev/null
+++ b/src/client/views/nodes/.QueryBox.scss.icloud
Binary files differ
diff --git a/src/client/views/nodes/.QueryBox.tsx.icloud b/src/client/views/nodes/.QueryBox.tsx.icloud
new file mode 100644
index 000000000..5930b1e0e
--- /dev/null
+++ b/src/client/views/nodes/.QueryBox.tsx.icloud
Binary files differ
diff --git a/src/fields/.ListSpec.ts.icloud b/src/fields/.ListSpec.ts.icloud
new file mode 100644
index 000000000..2fbd1858e
--- /dev/null
+++ b/src/fields/.ListSpec.ts.icloud
Binary files differ
diff --git a/src/fields/IconField.ts b/src/fields/IconField.ts
new file mode 100644
index 000000000..76c4ddf1b
--- /dev/null
+++ b/src/fields/IconField.ts
@@ -0,0 +1,26 @@
+import { Deserializable } from "../client/util/SerializationHelper";
+import { serializable, primitive } from "serializr";
+import { ObjectField } from "./ObjectField";
+import { Copy, ToScriptString, ToString } from "./FieldSymbols";
+
+@Deserializable("icon")
+export class IconField extends ObjectField {
+ @serializable(primitive())
+ readonly icon: string;
+
+ constructor(icon: string) {
+ super();
+ this.icon = icon;
+ }
+
+ [Copy]() {
+ return new IconField(this.icon);
+ }
+
+ [ToScriptString]() {
+ return "invalid";
+ }
+ [ToString]() {
+ return "ICONfield";
+ }
+}
diff --git a/src/fields/PresField.ts b/src/fields/PresField.ts
new file mode 100644
index 000000000..f236a04fd
--- /dev/null
+++ b/src/fields/PresField.ts
@@ -0,0 +1,6 @@
+//insert code here
+import { ObjectField } from "./ObjectField";
+
+export abstract class PresField extends ObjectField {
+
+} \ No newline at end of file
diff --git a/src/mobile/MobileInterface.tsx b/src/mobile/MobileInterface.tsx
index 584a7b432..c16a1c124 100644
--- a/src/mobile/MobileInterface.tsx
+++ b/src/mobile/MobileInterface.tsx
@@ -584,6 +584,7 @@ export class MobileInterface extends React.Component {
y: 400,
title: 'Collection ' + dashboardCount,
};
+
const freeformDoc = Doc.GuestTarget || Docs.Create.FreeformDocument([], freeformOptions);
const dashboardDoc = Docs.Create.StandardCollectionDockingDocument([{ doc: freeformDoc, initialWidth: 600 }], { title: `Dashboard ${dashboardCount}` }, id, 'row');
diff --git a/src/server/stats/.userLoginStats.csv.icloud b/src/server/stats/.userLoginStats.csv.icloud
new file mode 100644
index 000000000..4a95297e8
--- /dev/null
+++ b/src/server/stats/.userLoginStats.csv.icloud
Binary files differ