studiokit-scaffolding-js 5.0.0-next.2.9 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/HOC/CollectionComponent.d.ts +4 -3
- package/lib/components/HOC/CollectionComponent.js +3 -1
- package/lib/components/HOC/CollectionFirstItemComponent.d.ts +6 -2
- package/lib/components/HOC/CollectionFirstItemComponent.js +9 -2
- package/lib/components/HOC/CollectionItemComponent.d.ts +3 -2
- package/lib/components/HOC/CollectionItemComponent.js +3 -1
- package/lib/components/HOC/SearchPersistorComponent.js +12 -12
- package/lib/components/ManageTable.d.ts +19 -0
- package/lib/components/ManageTable.js +112 -0
- package/lib/components/UserRoles/index.d.ts +1 -1
- package/lib/constants/index.d.ts +1 -0
- package/lib/constants/index.js +1 -0
- package/lib/constants/table.d.ts +15 -0
- package/lib/constants/table.js +24 -0
- package/lib/hooks/useCollection.d.ts +2 -2
- package/lib/hooks/useCollectionConfiguration.js +10 -2
- package/lib/hooks/useCollectionItem.d.ts +2 -2
- package/lib/types/Collection.d.ts +5 -2
- package/lib/types/Search.d.ts +2 -2
- package/lib/utils/collection.js +14 -12
- package/lib/utils/manageTable.d.ts +2 -0
- package/lib/utils/manageTable.js +28 -0
- package/lib/utils/search.d.ts +12 -9
- package/lib/utils/search.js +34 -22
- package/package.json +2 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import React, { ComponentClass, ComponentType } from 'react';
|
|
2
2
|
import { RouteComponentProps } from 'react-router';
|
|
3
3
|
import { MODEL_STATUS } from '../../constants/modelStatus';
|
|
4
|
-
import { BaseReduxState, Model } from '../../types';
|
|
5
|
-
import { CollectionCommonProps, CollectionCommonState, CollectionCreateParams, CollectionDeleteParams, CollectionLoadParams, CollectionMethodConfiguration, CollectionMethods, CollectionReduxResponse, CollectionUpdateParams } from '../../types/Collection';
|
|
4
|
+
import { BaseReduxState, Model, ModelCollection } from '../../types';
|
|
5
|
+
import { CollectionCommonProps, CollectionCommonState, CollectionCreateParams, CollectionDeleteParams, CollectionDerivedProps, CollectionLoadParams, CollectionMethodConfiguration, CollectionMethods, CollectionReduxResponse, CollectionUpdateParams } from '../../types/Collection';
|
|
6
6
|
import { GuidComponentWrappedProps } from './GuidComponent';
|
|
7
7
|
/** The props passed into `CollectionComponent` from the user and other HOCs. */
|
|
8
8
|
export interface CollectionComponentProps<TModel extends Model> extends CollectionCommonProps, GuidComponentWrappedProps, RouteComponentProps, CollectionReduxResponse<TModel> {
|
|
9
9
|
}
|
|
10
10
|
/** The props passed down to the `WrappedComponent`. */
|
|
11
|
-
export interface CollectionComponentWrappedProps<TModel extends Model> extends Omit<CollectionComponentProps<TModel>, keyof RouteComponentProps>, CollectionMethods, CollectionCommonState {
|
|
11
|
+
export interface CollectionComponentWrappedProps<TModel extends Model> extends Omit<CollectionComponentProps<TModel>, keyof RouteComponentProps>, CollectionDerivedProps<TModel>, CollectionMethods, CollectionCommonState {
|
|
12
12
|
}
|
|
13
13
|
export declare function configureCollectionComponent<TModel extends Model, TOwnProps extends {}>(WrappedComponent: ComponentType<TOwnProps & CollectionComponentWrappedProps<TModel>>, LoaderComponent?: ComponentType): {
|
|
14
14
|
new (props: TOwnProps & CollectionComponentProps<TModel>): {
|
|
@@ -22,6 +22,7 @@ export declare function configureCollectionComponent<TModel extends Model, TOwnP
|
|
|
22
22
|
create: (params: CollectionCreateParams) => void;
|
|
23
23
|
update: (params: CollectionUpdateParams) => void;
|
|
24
24
|
delete: (params: CollectionDeleteParams) => void;
|
|
25
|
+
getModelArray: import("memoize-one").MemoizedFn<(model: ModelCollection<TModel>, guid?: string | undefined) => TModel[]>;
|
|
25
26
|
render(): JSX.Element;
|
|
26
27
|
context: any;
|
|
27
28
|
setState<K extends "modelStatus" | "previousModelStatus" | "fetchingId">(state: CollectionCommonState | ((prevState: Readonly<CollectionCommonState>, props: Readonly<TOwnProps & CollectionComponentProps<TModel>>) => CollectionCommonState | Pick<CollectionCommonState, K> | null) | Pick<CollectionCommonState, K> | null, callback?: (() => void) | undefined): void;
|
|
@@ -58,6 +58,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
58
58
|
};
|
|
59
59
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
60
60
|
exports.configureMapStateToProps = exports.configureCollectionComponent = void 0;
|
|
61
|
+
var memoize_one_1 = __importDefault(require("memoize-one"));
|
|
61
62
|
var react_1 = __importStar(require("react"));
|
|
62
63
|
var react_redux_1 = require("react-redux");
|
|
63
64
|
var react_router_1 = require("react-router");
|
|
@@ -110,6 +111,7 @@ function configureCollectionComponent(WrappedComponent, LoaderComponent) {
|
|
|
110
111
|
_this.delete = function (params) {
|
|
111
112
|
collection_1.deleteItemFromCollection(_this.getCollectionMethodConfig(), params);
|
|
112
113
|
};
|
|
114
|
+
_this.getModelArray = memoize_one_1.default(function (model, guid) { return model_1.getModelArray(model, guid); });
|
|
113
115
|
_this.state = {
|
|
114
116
|
// initializing until model is loaded
|
|
115
117
|
modelStatus: modelStatus_1.MODEL_STATUS.UNINITIALIZED,
|
|
@@ -139,7 +141,7 @@ function configureCollectionComponent(WrappedComponent, LoaderComponent) {
|
|
|
139
141
|
if (modelStatus === modelStatus_1.MODEL_STATUS.UNINITIALIZED) {
|
|
140
142
|
return react_1.default.createElement(LoaderComponent, null);
|
|
141
143
|
}
|
|
142
|
-
return (react_1.default.createElement(WrappedComponent, __assign({}, otherProps, { modelStatus: modelStatus, previousModelStatus: previousModelStatus, fetchingId: fetchingId, load: this.load, stopPeriodicLoad: this.stopPeriodicLoad, create: this.create, update: this.update, delete: this.delete })));
|
|
144
|
+
return (react_1.default.createElement(WrappedComponent, __assign({}, otherProps, { modelArray: this.getModelArray(this.props.model, this.props.guid), modelStatus: modelStatus, previousModelStatus: previousModelStatus, fetchingId: fetchingId, load: this.load, stopPeriodicLoad: this.stopPeriodicLoad, create: this.create, update: this.update, delete: this.delete })));
|
|
143
145
|
};
|
|
144
146
|
return CollectionComponent;
|
|
145
147
|
}(react_1.Component));
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React, { ComponentClass, ComponentType } from 'react';
|
|
2
|
-
import { CollectionItemReduxResponse, Model } from '../../types';
|
|
2
|
+
import { CollectionItemDerivedProps, CollectionItemReduxResponse, Model, ModelCollection } from '../../types';
|
|
3
3
|
import { CollectionComponentWrappedProps } from './CollectionComponent';
|
|
4
4
|
/** The props passed into `WrappedComponent`. */
|
|
5
|
-
export interface CollectionFirstItemComponentWrappedProps<TModel extends Model> extends Omit<CollectionComponentWrappedProps<TModel>, 'model'>, CollectionItemReduxResponse<TModel> {
|
|
5
|
+
export interface CollectionFirstItemComponentWrappedProps<TModel extends Model> extends Omit<CollectionComponentWrappedProps<TModel>, 'model'>, CollectionItemReduxResponse<TModel>, CollectionItemDerivedProps<TModel> {
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* HOC meant to pass the first collection item to the wrapped component as its model.
|
|
@@ -10,6 +10,8 @@ export interface CollectionFirstItemComponentWrappedProps<TModel extends Model>
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function configureCollectionFirstItemComponent<TModel extends Model, TOwnProps extends {}>(WrappedComponent: ComponentType<TOwnProps & CollectionFirstItemComponentWrappedProps<TModel>>): {
|
|
12
12
|
new (props: (TOwnProps & CollectionComponentWrappedProps<TModel>) | Readonly<TOwnProps & CollectionComponentWrappedProps<TModel>>): {
|
|
13
|
+
getModelArray: import("memoize-one").MemoizedFn<(model: ModelCollection<TModel>, guid?: string | undefined) => TModel[]>;
|
|
14
|
+
getModelMinusRelations: import("memoize-one").MemoizedFn<(model: TModel) => Partial<TModel>>;
|
|
13
15
|
getFirstItem: () => TModel;
|
|
14
16
|
render(): JSX.Element;
|
|
15
17
|
context: any;
|
|
@@ -36,6 +38,8 @@ export declare function configureCollectionFirstItemComponent<TModel extends Mod
|
|
|
36
38
|
UNSAFE_componentWillUpdate?(nextProps: Readonly<TOwnProps & CollectionComponentWrappedProps<TModel>>, nextState: Readonly<{}>, nextContext: any): void;
|
|
37
39
|
};
|
|
38
40
|
new (props: TOwnProps & CollectionComponentWrappedProps<TModel>, context: any): {
|
|
41
|
+
getModelArray: import("memoize-one").MemoizedFn<(model: ModelCollection<TModel>, guid?: string | undefined) => TModel[]>;
|
|
42
|
+
getModelMinusRelations: import("memoize-one").MemoizedFn<(model: TModel) => Partial<TModel>>;
|
|
39
43
|
getFirstItem: () => TModel;
|
|
40
44
|
render(): JSX.Element;
|
|
41
45
|
context: any;
|
|
@@ -49,8 +49,12 @@ var __spreadArrays = (this && this.__spreadArrays) || function () {
|
|
|
49
49
|
r[k] = a[j];
|
|
50
50
|
return r;
|
|
51
51
|
};
|
|
52
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
53
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
54
|
+
};
|
|
52
55
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
56
|
exports.configureCollectionFirstItemComponent = void 0;
|
|
57
|
+
var memoize_one_1 = __importDefault(require("memoize-one"));
|
|
54
58
|
var react_1 = __importStar(require("react"));
|
|
55
59
|
var model_1 = require("../../utils/model");
|
|
56
60
|
/**
|
|
@@ -62,8 +66,11 @@ function configureCollectionFirstItemComponent(WrappedComponent) {
|
|
|
62
66
|
__extends(CollectionFirstItemComponent, _super);
|
|
63
67
|
function CollectionFirstItemComponent() {
|
|
64
68
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
|
69
|
+
_this.getModelArray = memoize_one_1.default(function (model, guid) { return model_1.getModelArray(model, guid); });
|
|
70
|
+
_this.getModelMinusRelations = memoize_one_1.default(function (model) { return model_1.getModelMinusRelations(model); });
|
|
65
71
|
_this.getFirstItem = function () {
|
|
66
|
-
var _a = _this.props, model = _a.model,
|
|
72
|
+
var _a = _this.props, model = _a.model, guid = _a.guid;
|
|
73
|
+
var modelArray = _this.getModelArray(model, guid);
|
|
67
74
|
var singleItem = modelArray.length > 0
|
|
68
75
|
? modelArray[0]
|
|
69
76
|
: model[guid]
|
|
@@ -76,7 +83,7 @@ function configureCollectionFirstItemComponent(WrappedComponent) {
|
|
|
76
83
|
CollectionFirstItemComponent.prototype.render = function () {
|
|
77
84
|
var pathParams = this.props.pathParams;
|
|
78
85
|
var firstItem = this.getFirstItem();
|
|
79
|
-
var modelMinusRelations =
|
|
86
|
+
var modelMinusRelations = this.getModelMinusRelations(firstItem);
|
|
80
87
|
var p = __spreadArrays(pathParams);
|
|
81
88
|
if (firstItem.id) {
|
|
82
89
|
p.push(firstItem.id.toString());
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React, { ComponentClass, ComponentType } from 'react';
|
|
2
2
|
import { RouteComponentProps } from 'react-router';
|
|
3
3
|
import { MODEL_STATUS } from '../../constants/modelStatus';
|
|
4
|
-
import { BaseReduxState, CollectionCommonProps, CollectionCommonState, CollectionCreateParams, CollectionItemDeleteParams, CollectionItemLoadParams, CollectionItemMethods, CollectionItemReduxResponse, CollectionItemUpdateParams, CollectionMethodConfiguration, Model } from '../../types';
|
|
4
|
+
import { BaseReduxState, CollectionCommonProps, CollectionCommonState, CollectionCreateParams, CollectionItemDeleteParams, CollectionItemDerivedProps, CollectionItemLoadParams, CollectionItemMethods, CollectionItemReduxResponse, CollectionItemUpdateParams, CollectionMethodConfiguration, Model } from '../../types';
|
|
5
5
|
import { GuidComponentWrappedProps } from './GuidComponent';
|
|
6
6
|
/** The props passed into `CollectionItemComponent` from the user and other HOCs. */
|
|
7
7
|
export interface CollectionItemComponentProps<TModel extends Model> extends CollectionCommonProps, GuidComponentWrappedProps, RouteComponentProps, CollectionItemReduxResponse<TModel> {
|
|
8
8
|
}
|
|
9
9
|
/** The props passed down to the `WrappedComponent`. */
|
|
10
|
-
export interface CollectionItemComponentWrappedProps<TModel extends Model> extends Omit<CollectionItemComponentProps<TModel>, keyof RouteComponentProps>, CollectionItemMethods, CollectionCommonState {
|
|
10
|
+
export interface CollectionItemComponentWrappedProps<TModel extends Model> extends Omit<CollectionItemComponentProps<TModel>, keyof RouteComponentProps>, CollectionItemDerivedProps<TModel>, CollectionItemMethods, CollectionCommonState {
|
|
11
11
|
}
|
|
12
12
|
export declare function configureCollectionItemComponent<TModel extends Model, TOwnProps extends {}>(WrappedComponent: ComponentType<TOwnProps & CollectionItemComponentWrappedProps<TModel>>, LoaderComponent?: ComponentType): {
|
|
13
13
|
new (props: TOwnProps & CollectionItemComponentProps<TModel>): {
|
|
@@ -20,6 +20,7 @@ export declare function configureCollectionItemComponent<TModel extends Model, T
|
|
|
20
20
|
create: (params: CollectionCreateParams) => void;
|
|
21
21
|
update: (params: CollectionItemUpdateParams) => void;
|
|
22
22
|
delete: (params?: CollectionItemDeleteParams) => void;
|
|
23
|
+
getModelMinusRelations: import("memoize-one").MemoizedFn<(model: TModel) => Partial<TModel>>;
|
|
23
24
|
render(): JSX.Element;
|
|
24
25
|
context: any;
|
|
25
26
|
setState<K extends "modelStatus" | "previousModelStatus" | "fetchingId">(state: CollectionCommonState | ((prevState: Readonly<CollectionCommonState>, props: Readonly<TOwnProps & CollectionItemComponentProps<TModel>>) => CollectionCommonState | Pick<CollectionCommonState, K> | null) | Pick<CollectionCommonState, K> | null, callback?: (() => void) | undefined): void;
|
|
@@ -58,6 +58,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
58
58
|
};
|
|
59
59
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
60
60
|
exports.configureMapStateToProps = exports.configureCollectionItemComponent = void 0;
|
|
61
|
+
var memoize_one_1 = __importDefault(require("memoize-one"));
|
|
61
62
|
var react_1 = __importStar(require("react"));
|
|
62
63
|
var react_redux_1 = require("react-redux");
|
|
63
64
|
var react_router_1 = require("react-router");
|
|
@@ -113,6 +114,7 @@ function configureCollectionItemComponent(WrappedComponent, LoaderComponent) {
|
|
|
113
114
|
var model = _this.props.model;
|
|
114
115
|
collection_1.deleteCollectionItem(model, _this.getCollectionMethodConfig(), params);
|
|
115
116
|
};
|
|
117
|
+
_this.getModelMinusRelations = memoize_one_1.default(function (model) { return model_1.getModelMinusRelations(model); });
|
|
116
118
|
_this.state = {
|
|
117
119
|
// initializing until model is loaded, or if no model
|
|
118
120
|
modelStatus: modelStatus_1.MODEL_STATUS.UNINITIALIZED,
|
|
@@ -136,7 +138,7 @@ function configureCollectionItemComponent(WrappedComponent, LoaderComponent) {
|
|
|
136
138
|
if (modelStatus === modelStatus_1.MODEL_STATUS.UNINITIALIZED) {
|
|
137
139
|
return react_1.default.createElement(LoaderComponent, null);
|
|
138
140
|
}
|
|
139
|
-
return (react_1.default.createElement(WrappedComponent, __assign({}, otherProps, { model: this.props.model, modelMinusRelations: this.props.
|
|
141
|
+
return (react_1.default.createElement(WrappedComponent, __assign({}, otherProps, { model: this.props.model, modelMinusRelations: this.getModelMinusRelations(this.props.model), modelStatus: modelStatus, previousModelStatus: previousModelStatus, load: this.load, stopPeriodicLoad: this.stopPeriodicLoad, create: this.create, update: this.update, delete: this.delete })));
|
|
140
142
|
};
|
|
141
143
|
return CollectionItemComponent;
|
|
142
144
|
}(react_1.Component));
|
|
@@ -103,20 +103,20 @@ function configureSearchPersistorComponent(WrappedComponent) {
|
|
|
103
103
|
selectedTab: search.selectedTab,
|
|
104
104
|
sortingRules: search.sortingRules,
|
|
105
105
|
pageSize: search.pageSize,
|
|
106
|
-
|
|
106
|
+
pageByTab: search.pageByTab
|
|
107
107
|
}),
|
|
108
108
|
// do not trigger a re-load unless queryAll is true
|
|
109
109
|
search.queryAll ? _this.doSearch : undefined);
|
|
110
110
|
};
|
|
111
111
|
_this.setSelectedTab = function (selectedTab) {
|
|
112
112
|
var _a, _b;
|
|
113
|
-
var
|
|
113
|
+
var pageByTab = __assign({}, ((_b = (_a = _this.state.search) === null || _a === void 0 ? void 0 : _a.pageByTab) !== null && _b !== void 0 ? _b : {}));
|
|
114
114
|
// if not set, default page to zero when switching tabs
|
|
115
|
-
if (!
|
|
116
|
-
|
|
115
|
+
if (!pageByTab[selectedTab])
|
|
116
|
+
pageByTab[selectedTab] = 0;
|
|
117
117
|
_this.updateAndPersistSearch({
|
|
118
118
|
selectedTab: selectedTab,
|
|
119
|
-
|
|
119
|
+
pageByTab: pageByTab
|
|
120
120
|
});
|
|
121
121
|
};
|
|
122
122
|
_this.setKeywords = function (event) {
|
|
@@ -135,7 +135,7 @@ function configureSearchPersistorComponent(WrappedComponent) {
|
|
|
135
135
|
_this.updateAndPersistSearch({
|
|
136
136
|
queryAll: queryAll,
|
|
137
137
|
requiredMessage: !queryAll ? null : _this.state.search ? _this.state.search.requiredMessage : null
|
|
138
|
-
});
|
|
138
|
+
}, _this.doSearch);
|
|
139
139
|
};
|
|
140
140
|
_this.setSortingRules = function (newSortingRules) {
|
|
141
141
|
_this.updateAndPersistSearch({
|
|
@@ -144,21 +144,21 @@ function configureSearchPersistorComponent(WrappedComponent) {
|
|
|
144
144
|
};
|
|
145
145
|
_this.setPageSize = function (newPageSize, newPage) {
|
|
146
146
|
var _a, _b, _c, _d;
|
|
147
|
-
var
|
|
147
|
+
var pageByTab = __assign({}, ((_b = (_a = _this.state.search) === null || _a === void 0 ? void 0 : _a.pageByTab) !== null && _b !== void 0 ? _b : {}));
|
|
148
148
|
var selectedTab = (_d = (_c = _this.state.search) === null || _c === void 0 ? void 0 : _c.selectedTab) !== null && _d !== void 0 ? _d : 1;
|
|
149
|
-
|
|
149
|
+
pageByTab[selectedTab] = newPage;
|
|
150
150
|
_this.updateAndPersistSearch({
|
|
151
151
|
pageSize: newPageSize,
|
|
152
|
-
|
|
152
|
+
pageByTab: pageByTab
|
|
153
153
|
});
|
|
154
154
|
};
|
|
155
155
|
_this.setPage = function (newPage) {
|
|
156
156
|
var _a, _b, _c, _d;
|
|
157
|
-
var
|
|
157
|
+
var pageByTab = __assign({}, ((_b = (_a = _this.state.search) === null || _a === void 0 ? void 0 : _a.pageByTab) !== null && _b !== void 0 ? _b : {}));
|
|
158
158
|
var selectedTab = (_d = (_c = _this.state.search) === null || _c === void 0 ? void 0 : _c.selectedTab) !== null && _d !== void 0 ? _d : 1;
|
|
159
|
-
|
|
159
|
+
pageByTab[selectedTab] = newPage;
|
|
160
160
|
_this.updateAndPersistSearch({
|
|
161
|
-
|
|
161
|
+
pageByTab: pageByTab
|
|
162
162
|
});
|
|
163
163
|
};
|
|
164
164
|
_this.state = {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { Column, SortingRule } from 'react-table';
|
|
3
|
+
import { Model, Search } from '../types';
|
|
4
|
+
export interface ManageTableProps<TModel, TSearchDataParams> {
|
|
5
|
+
search: Search;
|
|
6
|
+
isFiltered: boolean;
|
|
7
|
+
setSelectedTab: (selectedTab: number) => void;
|
|
8
|
+
setSortingRules: (newSortingRules: SortingRule[]) => void;
|
|
9
|
+
setPageSize: (newPageSize: number, newPage: number) => void;
|
|
10
|
+
setPage: (newPage: number) => void;
|
|
11
|
+
tabs: number[];
|
|
12
|
+
getTabName: (tab?: number) => string;
|
|
13
|
+
searchData: (params: TSearchDataParams) => Record<number, TModel[]>;
|
|
14
|
+
searchDataParams: TSearchDataParams;
|
|
15
|
+
columns: Column<TModel>[];
|
|
16
|
+
entityName: string;
|
|
17
|
+
canQueryAll?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const ManageTable: <TModel extends Model, TSearchDataParams extends {}>({ search: { hasSearched, queryAll, selectedTab, sortingRules, pageSize, pageByTab }, isFiltered, setSelectedTab, setSortingRules, setPageSize, setPage, tabs, getTabName, searchData, searchDataParams, columns, entityName, canQueryAll }: ManageTableProps<TModel, TSearchDataParams>) => JSX.Element;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ManageTable = void 0;
|
|
7
|
+
var lodash_1 = require("lodash");
|
|
8
|
+
var react_1 = require("react");
|
|
9
|
+
var react_2 = __importDefault(require("react"));
|
|
10
|
+
var react_bootstrap_1 = require("react-bootstrap");
|
|
11
|
+
var react_table_1 = __importDefault(require("react-table"));
|
|
12
|
+
var table_1 = require("../constants/table");
|
|
13
|
+
var RefreshIndicator_1 = require("./RefreshIndicator");
|
|
14
|
+
var ManageTable = function (_a) {
|
|
15
|
+
//#region Data
|
|
16
|
+
var _b = _a.search, hasSearched = _b.hasSearched, queryAll = _b.queryAll, selectedTab = _b.selectedTab, sortingRules = _b.sortingRules, pageSize = _b.pageSize, pageByTab = _b.pageByTab, isFiltered = _a.isFiltered, setSelectedTab = _a.setSelectedTab, setSortingRules = _a.setSortingRules, setPageSize = _a.setPageSize, setPage = _a.setPage, tabs = _a.tabs, getTabName = _a.getTabName, searchData = _a.searchData, searchDataParams = _a.searchDataParams, columns = _a.columns, entityName = _a.entityName, canQueryAll = _a.canQueryAll;
|
|
17
|
+
var _c = react_1.useState(), dataByTab = _c[0], setDataByTab = _c[1];
|
|
18
|
+
var isInitialized = dataByTab !== undefined;
|
|
19
|
+
// search and set state, which can be debounced as a single unit of work
|
|
20
|
+
var searchAndSetData = react_1.useCallback(function (params, setDataByTab) {
|
|
21
|
+
setDataByTab(searchData(params));
|
|
22
|
+
}, [searchData]);
|
|
23
|
+
// search is debounced to prevent it being rapidly called
|
|
24
|
+
// useMemo with no dependencies ensures we keep the same debounced function between renders
|
|
25
|
+
var debouncedSearchAndSetData = react_1.useMemo(function () { return lodash_1.debounce(searchAndSetData); }, [searchAndSetData]);
|
|
26
|
+
// search once without debounce to initialize dataByTab state
|
|
27
|
+
react_1.useEffect(function () {
|
|
28
|
+
if (!isInitialized) {
|
|
29
|
+
setDataByTab(searchData(searchDataParams));
|
|
30
|
+
}
|
|
31
|
+
}, [isInitialized, searchData, searchDataParams]);
|
|
32
|
+
// search using debounced method when searchDataParams changes, after initialization
|
|
33
|
+
// use `isMounted` to not call the callback unless the component is mounted
|
|
34
|
+
react_1.useEffect(function () {
|
|
35
|
+
var isMounted = true;
|
|
36
|
+
if (isInitialized) {
|
|
37
|
+
debouncedSearchAndSetData(searchDataParams, function (dataByTab) {
|
|
38
|
+
if (isMounted)
|
|
39
|
+
setDataByTab(dataByTab);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return function () {
|
|
43
|
+
isMounted = false;
|
|
44
|
+
};
|
|
45
|
+
}, [debouncedSearchAndSetData, isInitialized, searchDataParams]);
|
|
46
|
+
//#endregion Data
|
|
47
|
+
var noResultsFound = isFiltered && !!dataByTab && Object.values(dataByTab).every(function (d) { return d.length === 0; });
|
|
48
|
+
var currentTab = selectedTab !== null && selectedTab !== void 0 ? selectedTab : 1;
|
|
49
|
+
var data = dataByTab === null || dataByTab === void 0 ? void 0 : dataByTab[currentTab];
|
|
50
|
+
//#region Tabs
|
|
51
|
+
var onTabSelect = react_1.useCallback(function (eventKey) {
|
|
52
|
+
setSelectedTab(Number(eventKey));
|
|
53
|
+
}, [setSelectedTab]);
|
|
54
|
+
var dataLengthByTab = react_1.useMemo(function () {
|
|
55
|
+
var value = {};
|
|
56
|
+
tabs.forEach(function (tab) {
|
|
57
|
+
var _a;
|
|
58
|
+
value[tab] = (_a = dataByTab === null || dataByTab === void 0 ? void 0 : dataByTab[tab].length) !== null && _a !== void 0 ? _a : 0;
|
|
59
|
+
});
|
|
60
|
+
return value;
|
|
61
|
+
}, [dataByTab, tabs]);
|
|
62
|
+
var SearchTabs = react_1.useMemo(function () { return (react_2.default.createElement(react_bootstrap_1.Tabs, { activeKey: selectedTab, id: "search-tabs", onSelect: onTabSelect }, tabs.map(function (tab) { return (react_2.default.createElement(react_bootstrap_1.Tab, { key: tab, eventKey: tab.toString(), title: getTabName(tab) + " (" + dataLengthByTab[tab] + ")", disabled: noResultsFound })); }))); }, [dataLengthByTab, getTabName, noResultsFound, onTabSelect, selectedTab, tabs]);
|
|
63
|
+
//#endregion Tabs
|
|
64
|
+
//#region Table
|
|
65
|
+
var NoDataComponent = react_1.useMemo(function () {
|
|
66
|
+
return hasSearched ? (react_2.default.createElement("p", { className: "pt4 tc" },
|
|
67
|
+
"No ",
|
|
68
|
+
entityName.toLocaleLowerCase(),
|
|
69
|
+
" matched your search.",
|
|
70
|
+
canQueryAll && !queryAll && (react_2.default.createElement(react_2.default.Fragment, null,
|
|
71
|
+
" You might want to try again with \"Search All ",
|
|
72
|
+
entityName,
|
|
73
|
+
"\" checked.")))) : (react_2.default.createElement("p", { className: "pt4 tc" },
|
|
74
|
+
"No ",
|
|
75
|
+
getTabName(selectedTab).toLowerCase(),
|
|
76
|
+
" ",
|
|
77
|
+
entityName.toLocaleLowerCase(),
|
|
78
|
+
' ',
|
|
79
|
+
isFiltered ? 'matched your search' : 'found',
|
|
80
|
+
"."));
|
|
81
|
+
}, [canQueryAll, entityName, getTabName, hasSearched, isFiltered, queryAll, selectedTab]);
|
|
82
|
+
var NoDataComponentCallback = react_1.useCallback(function () { return NoDataComponent; }, [NoDataComponent]);
|
|
83
|
+
var Table = react_1.useMemo(function () {
|
|
84
|
+
var _a;
|
|
85
|
+
var showPagination = !!data && data.length > table_1.TABLE_DEFAULT_PAGE_SIZE;
|
|
86
|
+
// if pagination is not enabled, or page is not set, ensure page is 0, the first page
|
|
87
|
+
var pageForTab = showPagination && pageByTab && selectedTab ? pageByTab[selectedTab] : 0;
|
|
88
|
+
// if there are less items to display than the page size, shrink the page size so there are not empty rows
|
|
89
|
+
var currentPageSize = Math.min((_a = data === null || data === void 0 ? void 0 : data.length) !== null && _a !== void 0 ? _a : table_1.TABLE_DEFAULT_PAGE_SIZE, pageSize !== null && pageSize !== void 0 ? pageSize : table_1.TABLE_DEFAULT_PAGE_SIZE);
|
|
90
|
+
var pageSizeOptions = table_1.TABLE_PAGE_SIZE_OPTIONS.filter(function (s) { return !(data === null || data === void 0 ? void 0 : data.length) || s <= (data === null || data === void 0 ? void 0 : data.length); });
|
|
91
|
+
return (react_2.default.createElement(react_table_1.default, { "aria-describedby": "search-results-label", className: "manage-table -striped cb" + ((data === null || data === void 0 ? void 0 : data.length) === 1 ? ' single-row-action-button' : ''), data: data, showPagination: showPagination, showPaginationTop: true, sorted: sortingRules, pageSize: currentPageSize, page: pageForTab, pageSizeOptions: pageSizeOptions, columns: columns, onSortedChange: setSortingRules, onPageSizeChange: setPageSize, onPageChange: setPage, NoDataComponent: NoDataComponentCallback }));
|
|
92
|
+
}, [
|
|
93
|
+
NoDataComponentCallback,
|
|
94
|
+
columns,
|
|
95
|
+
data,
|
|
96
|
+
pageByTab,
|
|
97
|
+
pageSize,
|
|
98
|
+
selectedTab,
|
|
99
|
+
setPage,
|
|
100
|
+
setPageSize,
|
|
101
|
+
setSortingRules,
|
|
102
|
+
sortingRules
|
|
103
|
+
]);
|
|
104
|
+
//#endregion Table
|
|
105
|
+
if (!dataByTab)
|
|
106
|
+
return react_2.default.createElement(RefreshIndicator_1.RefreshIndicator, { label: "Loading...", labelClassName: "color-white" });
|
|
107
|
+
return (react_2.default.createElement(react_2.default.Fragment, null,
|
|
108
|
+
react_2.default.createElement("h3", { id: "search-results-label", className: "visually-hidden" }, "Search Results"),
|
|
109
|
+
SearchTabs,
|
|
110
|
+
Table));
|
|
111
|
+
};
|
|
112
|
+
exports.ManageTable = ManageTable;
|
|
@@ -107,5 +107,5 @@ export declare class UserRoles extends Component<UserRolesProps, UserRolesState>
|
|
|
107
107
|
render(): JSX.Element;
|
|
108
108
|
}
|
|
109
109
|
export declare const mapStateToProps: (state: BaseReduxState, ownProps: UserRolesOwnProps) => UserRolesReduxProps;
|
|
110
|
-
declare const _default: import("react-redux").ConnectedComponent<typeof UserRoles, Pick<React.ClassAttributes<UserRoles> & UserRolesProps, "ref" | "queryParams" | "modelName" | "externalProviders" | "model" | "key" | "readOnly" | "guid" | "load" | "pathParams" | "modelStatus" | "disableAutoLoad" | "modelArray" | "stopPeriodicLoad" | "create" | "update" | "delete" | "previousModelStatus" | "fetchingId" | "textForRole" | "
|
|
110
|
+
declare const _default: import("react-redux").ConnectedComponent<typeof UserRoles, Pick<React.ClassAttributes<UserRoles> & UserRolesProps, "ref" | "queryParams" | "modelName" | "externalProviders" | "model" | "key" | "readOnly" | "guid" | "entityName" | "load" | "pathParams" | "modelStatus" | "disableAutoLoad" | "modelArray" | "stopPeriodicLoad" | "create" | "update" | "delete" | "previousModelStatus" | "fetchingId" | "textForRole" | "defaultRole" | "roleDescriptions" | "renderAddDescription" | "isUpdateDisabled" | "isDeleteDisabled" | "allowMultipleRoles" | "requiredRole" | "isAddDisabled" | "modifyUserRoleActivityName" | "deleteOwnUserRoleActivityName" | "addRoleExcludeList" | "entity" | "filterUsers" | "onAdd" | "onUpdate" | "onRemove" | "renderTableDescription" | "lowercaseTextForRole" | "singularArticleForRole"> & UserRolesOwnProps>;
|
|
111
111
|
export default _default;
|
package/lib/constants/index.d.ts
CHANGED
package/lib/constants/index.js
CHANGED
|
@@ -19,5 +19,6 @@ __exportStar(require("./modelStatus"), exports);
|
|
|
19
19
|
__exportStar(require("./notificationType"), exports);
|
|
20
20
|
__exportStar(require("./operatingSystem"), exports);
|
|
21
21
|
__exportStar(require("./shard"), exports);
|
|
22
|
+
__exportStar(require("./table"), exports);
|
|
22
23
|
__exportStar(require("./tier"), exports);
|
|
23
24
|
__exportStar(require("./userRole"), exports);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const TABLE_DEFAULT_PAGE_SIZE = 25;
|
|
2
|
+
export declare const TABLE_PAGE_SIZE_OPTIONS: number[];
|
|
3
|
+
export declare enum MANAGE_TABLE_TAB {
|
|
4
|
+
AVAILABLE = 1,
|
|
5
|
+
DELETED = 2
|
|
6
|
+
}
|
|
7
|
+
/** Iterable array of tabs */
|
|
8
|
+
export declare const MANAGE_TABLE_TABS: MANAGE_TABLE_TAB[];
|
|
9
|
+
export declare enum GROUP_MANAGE_TABLE_TAB {
|
|
10
|
+
CURRENT = 1,
|
|
11
|
+
PAST = 2,
|
|
12
|
+
DELETED = 3
|
|
13
|
+
}
|
|
14
|
+
/** Iterable array of tabs */
|
|
15
|
+
export declare const GROUP_MANAGE_TABLE_TABS: GROUP_MANAGE_TABLE_TAB[];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GROUP_MANAGE_TABLE_TABS = exports.GROUP_MANAGE_TABLE_TAB = exports.MANAGE_TABLE_TABS = exports.MANAGE_TABLE_TAB = exports.TABLE_PAGE_SIZE_OPTIONS = exports.TABLE_DEFAULT_PAGE_SIZE = void 0;
|
|
4
|
+
exports.TABLE_DEFAULT_PAGE_SIZE = 25;
|
|
5
|
+
exports.TABLE_PAGE_SIZE_OPTIONS = [25, 50, 100, 150, 200];
|
|
6
|
+
var MANAGE_TABLE_TAB;
|
|
7
|
+
(function (MANAGE_TABLE_TAB) {
|
|
8
|
+
MANAGE_TABLE_TAB[MANAGE_TABLE_TAB["AVAILABLE"] = 1] = "AVAILABLE";
|
|
9
|
+
MANAGE_TABLE_TAB[MANAGE_TABLE_TAB["DELETED"] = 2] = "DELETED";
|
|
10
|
+
})(MANAGE_TABLE_TAB = exports.MANAGE_TABLE_TAB || (exports.MANAGE_TABLE_TAB = {}));
|
|
11
|
+
/** Iterable array of tabs */
|
|
12
|
+
exports.MANAGE_TABLE_TABS = [MANAGE_TABLE_TAB.AVAILABLE, MANAGE_TABLE_TAB.DELETED];
|
|
13
|
+
var GROUP_MANAGE_TABLE_TAB;
|
|
14
|
+
(function (GROUP_MANAGE_TABLE_TAB) {
|
|
15
|
+
GROUP_MANAGE_TABLE_TAB[GROUP_MANAGE_TABLE_TAB["CURRENT"] = 1] = "CURRENT";
|
|
16
|
+
GROUP_MANAGE_TABLE_TAB[GROUP_MANAGE_TABLE_TAB["PAST"] = 2] = "PAST";
|
|
17
|
+
GROUP_MANAGE_TABLE_TAB[GROUP_MANAGE_TABLE_TAB["DELETED"] = 3] = "DELETED";
|
|
18
|
+
})(GROUP_MANAGE_TABLE_TAB = exports.GROUP_MANAGE_TABLE_TAB || (exports.GROUP_MANAGE_TABLE_TAB = {}));
|
|
19
|
+
/** Iterable array of tabs */
|
|
20
|
+
exports.GROUP_MANAGE_TABLE_TABS = [
|
|
21
|
+
GROUP_MANAGE_TABLE_TAB.CURRENT,
|
|
22
|
+
GROUP_MANAGE_TABLE_TAB.PAST,
|
|
23
|
+
GROUP_MANAGE_TABLE_TAB.DELETED
|
|
24
|
+
];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CollectionCommonProps, CollectionCommonState, CollectionMethods, CollectionReduxResponse, Model } from '../types';
|
|
2
|
-
export interface UseCollectionResponse<TModel extends Model> extends CollectionCommonState, CollectionReduxResponse<TModel>, CollectionMethods {
|
|
1
|
+
import { CollectionCommonProps, CollectionCommonState, CollectionDerivedProps, CollectionMethods, CollectionReduxResponse, Model } from '../types';
|
|
2
|
+
export interface UseCollectionResponse<TModel extends Model> extends CollectionCommonState, CollectionReduxResponse<TModel>, CollectionDerivedProps<TModel>, CollectionMethods {
|
|
3
3
|
guid: string;
|
|
4
4
|
}
|
|
5
5
|
export declare function useCollection<TModel extends Model>(props: CollectionCommonProps): UseCollectionResponse<TModel>;
|
|
@@ -6,6 +6,7 @@ var react_redux_1 = require("react-redux");
|
|
|
6
6
|
var react_router_1 = require("react-router");
|
|
7
7
|
var modelStatus_1 = require("../constants/modelStatus");
|
|
8
8
|
var model_1 = require("../utils/model");
|
|
9
|
+
var route_1 = require("../utils/route");
|
|
9
10
|
var useGuid_1 = require("./useGuid");
|
|
10
11
|
var usePrevious_1 = require("./usePrevious");
|
|
11
12
|
/**
|
|
@@ -23,13 +24,20 @@ function useCollectionConfiguration(props, selectorFunction) {
|
|
|
23
24
|
var _b = react_1.useState(modelStatus_1.MODEL_STATUS.UNINITIALIZED), modelStatus = _b[0], setModelStatus = _b[1];
|
|
24
25
|
var previousModelStatus = usePrevious_1.usePrevious(modelStatus);
|
|
25
26
|
var _c = react_1.useState(), fetchingId = _c[0], setFetchingId = _c[1];
|
|
27
|
+
var pathParams = react_1.useMemo(function () { return propPathParams || route_1.getPathParamsFromRouteMatchParams(routeMatchParams, modelName); }, [
|
|
28
|
+
modelName,
|
|
29
|
+
propPathParams,
|
|
30
|
+
routeMatchParams
|
|
31
|
+
]);
|
|
26
32
|
var _d = react_redux_1.useSelector(function (state) {
|
|
27
|
-
return selectorFunction({ guid: guid, modelName: modelName, pathParams:
|
|
28
|
-
}),
|
|
33
|
+
return selectorFunction({ guid: guid, modelName: modelName, pathParams: pathParams, routeMatchParams: routeMatchParams, state: state });
|
|
34
|
+
}), model = _d.model, isCollectionItem = _d.isCollectionItem;
|
|
29
35
|
var previousModelName = usePrevious_1.usePrevious(modelName);
|
|
30
36
|
var previousModel = usePrevious_1.usePrevious(model);
|
|
31
37
|
var previousPathParams = usePrevious_1.usePrevious(pathParams);
|
|
32
38
|
var previousQueryParams = usePrevious_1.usePrevious(queryParams);
|
|
39
|
+
var modelArray = react_1.useMemo(function () { return (!isCollectionItem ? model_1.getModelArray(model, guid) : undefined); }, [guid, isCollectionItem, model]);
|
|
40
|
+
var modelMinusRelations = react_1.useMemo(function () { return (isCollectionItem ? model_1.getModelMinusRelations(model) : undefined); }, [isCollectionItem, model]);
|
|
33
41
|
var changeModelStatus = function (newModelStatus, newFetchingId) {
|
|
34
42
|
setFetchingId(newFetchingId);
|
|
35
43
|
setModelStatus(newModelStatus);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CollectionCommonProps, CollectionCommonState, CollectionItemMethods, CollectionItemReduxResponse, Model } from '../types';
|
|
2
|
-
export interface UseCollectionItemResponse<TModel extends Model> extends CollectionCommonState, CollectionItemReduxResponse<TModel>, CollectionItemMethods {
|
|
1
|
+
import { CollectionCommonProps, CollectionCommonState, CollectionItemDerivedProps, CollectionItemMethods, CollectionItemReduxResponse, Model } from '../types';
|
|
2
|
+
export interface UseCollectionItemResponse<TModel extends Model> extends CollectionCommonState, CollectionItemReduxResponse<TModel>, CollectionItemDerivedProps<TModel>, CollectionItemMethods {
|
|
3
3
|
guid: string;
|
|
4
4
|
}
|
|
5
5
|
export declare function useCollectionItem<TModel extends Model>(props: CollectionCommonProps): UseCollectionItemResponse<TModel>;
|
|
@@ -30,8 +30,7 @@ export interface CollectionSelectorMethodResponse<TModel extends Model> {
|
|
|
30
30
|
modelName: string;
|
|
31
31
|
pathParams: string[];
|
|
32
32
|
model: TModel | ModelCollection<TModel>;
|
|
33
|
-
|
|
34
|
-
modelMinusRelations?: Partial<TModel>;
|
|
33
|
+
isCollectionItem: boolean;
|
|
35
34
|
}
|
|
36
35
|
/** A method used to select a collection or collection item model from redux. */
|
|
37
36
|
export declare type CollectionSelectorMethod = <TModel extends Model>(params: CollectionSelectorMethodParams) => CollectionSelectorMethodResponse<TModel>;
|
|
@@ -158,6 +157,8 @@ export interface CollectionMethods {
|
|
|
158
157
|
export interface CollectionItemReduxResponse<TModel extends Model> {
|
|
159
158
|
/** The collection item model loaded from redux, or loaded into redux using `load()`. */
|
|
160
159
|
model: TModel;
|
|
160
|
+
}
|
|
161
|
+
export interface CollectionItemDerivedProps<TModel extends Model> {
|
|
161
162
|
/** The collection item model, without any of its nested relations. */
|
|
162
163
|
modelMinusRelations: Partial<TModel>;
|
|
163
164
|
}
|
|
@@ -165,6 +166,8 @@ export interface CollectionItemReduxResponse<TModel extends Model> {
|
|
|
165
166
|
export interface CollectionReduxResponse<TModel extends Model> {
|
|
166
167
|
/** The collection model loaded from redux if available, or loaded into redux using `load()`. */
|
|
167
168
|
model: ModelCollection<TModel>;
|
|
169
|
+
}
|
|
170
|
+
export interface CollectionDerivedProps<TModel extends Model> {
|
|
168
171
|
/** The collection model converted to an array of all collection items. */
|
|
169
172
|
modelArray: TModel[];
|
|
170
173
|
}
|
package/lib/types/Search.d.ts
CHANGED
|
@@ -13,6 +13,6 @@ export interface Search {
|
|
|
13
13
|
sortingRules?: SortingRule[];
|
|
14
14
|
/** react-table page size, for pagination */
|
|
15
15
|
pageSize?: number;
|
|
16
|
-
/** react-table currently selected page, for pagination */
|
|
17
|
-
|
|
16
|
+
/** react-table currently selected page for a given tab, for pagination */
|
|
17
|
+
pageByTab?: Record<string, number | undefined>;
|
|
18
18
|
}
|
package/lib/utils/collection.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.cleanupCollectionGuidKey = exports.handleCollectionParamsChange = exports.handleCollectionItemParamsChange = exports.initializeCollection = exports.initializeCollectionItem = exports.deleteCollectionItem = exports.deleteItemFromCollection = exports.updateCollectionItem = exports.updateItemInCollection = exports.createCollectionItem = exports.createItemInCollection = exports.loadCollectionItem = exports.loadCollection = exports.stopCollectionPeriodicLoad = exports.selectCollectionFromState = exports.selectCollectionItemFromState = void 0;
|
|
4
7
|
var lodash_1 = require("lodash");
|
|
8
|
+
var memoize_one_1 = __importDefault(require("memoize-one"));
|
|
5
9
|
var constants_1 = require("../constants");
|
|
6
10
|
var actionCreator_1 = require("../redux/actionCreator");
|
|
7
11
|
var actions_1 = require("../redux/actions");
|
|
8
|
-
var model_1 = require("./model");
|
|
9
12
|
var route_1 = require("./route");
|
|
10
13
|
//#region Redux Methods
|
|
14
|
+
var getPathParams = memoize_one_1.default(function (pathParams, routeMatchParams, modelName) {
|
|
15
|
+
return pathParams || route_1.getPathParamsFromRouteMatchParams(routeMatchParams, modelName);
|
|
16
|
+
});
|
|
11
17
|
function selectCollectionItemFromState(params) {
|
|
12
18
|
var guid = params.guid, modelName = params.modelName, pathParams = params.pathParams, routeMatchParams = params.routeMatchParams, state = params.state;
|
|
13
19
|
var modelNameLevelCount = route_1.getMinRequiredPathParamsCount(modelName);
|
|
14
|
-
var p = pathParams
|
|
20
|
+
var p = getPathParams(pathParams, routeMatchParams, modelName);
|
|
15
21
|
var reduxModelName = route_1.getReduxModelName(p, modelName);
|
|
16
22
|
var model = {};
|
|
17
23
|
// find `model` using `guid` as its key, to match new item created in `create()`
|
|
@@ -28,31 +34,27 @@ function selectCollectionItemFromState(params) {
|
|
|
28
34
|
else {
|
|
29
35
|
// find `model` using pathParams
|
|
30
36
|
var reduxModel = (lodash_1.get(state.models, reduxModelName) || {});
|
|
31
|
-
model = (Object.keys(reduxModel).length > 0 ?
|
|
37
|
+
model = (Object.keys(reduxModel).length > 0 ? reduxModel : {});
|
|
32
38
|
}
|
|
33
|
-
// convenient way to access model without relations, for use in PUT requests
|
|
34
|
-
var modelMinusRelations = model_1.getModelMinusRelations(model);
|
|
35
39
|
return {
|
|
36
40
|
modelName: modelName,
|
|
37
41
|
pathParams: p,
|
|
38
42
|
model: model,
|
|
39
|
-
|
|
43
|
+
isCollectionItem: true
|
|
40
44
|
};
|
|
41
45
|
}
|
|
42
46
|
exports.selectCollectionItemFromState = selectCollectionItemFromState;
|
|
43
47
|
function selectCollectionFromState(params) {
|
|
44
|
-
var
|
|
45
|
-
var p = pathParams
|
|
48
|
+
var modelName = params.modelName, pathParams = params.pathParams, routeMatchParams = params.routeMatchParams, state = params.state;
|
|
49
|
+
var p = getPathParams(pathParams, routeMatchParams, modelName);
|
|
46
50
|
var reduxModelName = route_1.getReduxModelName(p, modelName);
|
|
47
51
|
var model = lodash_1.get(state.models, reduxModelName);
|
|
48
|
-
model = model && Object.keys(model).length > 0 ?
|
|
49
|
-
// convenient way to access collection as an array
|
|
50
|
-
var modelArray = model_1.getModelArray(model, guid);
|
|
52
|
+
model = model && Object.keys(model).length > 0 ? model : {};
|
|
51
53
|
return {
|
|
52
54
|
modelName: modelName,
|
|
53
55
|
pathParams: p,
|
|
54
56
|
model: model,
|
|
55
|
-
|
|
57
|
+
isCollectionItem: false
|
|
56
58
|
};
|
|
57
59
|
}
|
|
58
60
|
exports.selectCollectionFromState = selectCollectionFromState;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getGroupManageTableTabName = exports.getManageTableTabName = void 0;
|
|
4
|
+
var table_1 = require("../constants/table");
|
|
5
|
+
var getManageTableTabName = function (selectedTab) {
|
|
6
|
+
switch (selectedTab) {
|
|
7
|
+
case table_1.MANAGE_TABLE_TAB.AVAILABLE:
|
|
8
|
+
return 'Available';
|
|
9
|
+
case table_1.MANAGE_TABLE_TAB.DELETED:
|
|
10
|
+
return 'Deleted';
|
|
11
|
+
default:
|
|
12
|
+
return '';
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
exports.getManageTableTabName = getManageTableTabName;
|
|
16
|
+
var getGroupManageTableTabName = function (selectedTab) {
|
|
17
|
+
switch (selectedTab) {
|
|
18
|
+
case table_1.GROUP_MANAGE_TABLE_TAB.CURRENT:
|
|
19
|
+
return 'Current';
|
|
20
|
+
case table_1.GROUP_MANAGE_TABLE_TAB.DELETED:
|
|
21
|
+
return 'Deleted';
|
|
22
|
+
case table_1.GROUP_MANAGE_TABLE_TAB.PAST:
|
|
23
|
+
return 'Past';
|
|
24
|
+
default:
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
exports.getGroupManageTableTabName = getGroupManageTableTabName;
|
package/lib/utils/search.d.ts
CHANGED
|
@@ -14,12 +14,15 @@ export declare const isEntityMatchedByKeywords: (entity: {
|
|
|
14
14
|
export declare const searchEntities: <T extends {
|
|
15
15
|
isDeleted: boolean;
|
|
16
16
|
activities: string[];
|
|
17
|
-
}>(entityArray: T[],
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
}>(entityArray: T[], entityMatchFunction: (entity: T, keywordsList: string[]) => boolean, readActivity: string, canReadAnyGlobally?: boolean | undefined, keywords?: string | undefined) => Record<number, T[]>;
|
|
18
|
+
export interface SearchModelArrayParams<TModel> {
|
|
19
|
+
modelArray: TModel[];
|
|
20
|
+
canReadyAnyGlobally?: boolean;
|
|
21
|
+
keywords?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SearchGroupsParams extends SearchModelArrayParams<Group> {
|
|
24
|
+
groups: ModelCollection<Group>;
|
|
25
|
+
externalTerms: ModelCollection<ExternalTerm>;
|
|
26
|
+
dateString?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare const searchGroups: ({ groups, modelArray: groupsArray, externalTerms, canReadyAnyGlobally, keywords, dateString }: SearchGroupsParams) => Record<number, Group[]>;
|
package/lib/utils/search.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.searchGroups = exports.searchEntities = exports.isEntityMatchedByKeywords = exports.isEntityMatchedByKeyword = exports.isEntityUserMatchedByKeyword = exports.getKeywordsList = void 0;
|
|
4
|
+
var table_1 = require("../constants/table");
|
|
4
5
|
var date_1 = require("./date");
|
|
5
6
|
var groupDates_1 = require("./groupDates");
|
|
6
7
|
var groupRoles_1 = require("./groupRoles");
|
|
@@ -31,30 +32,43 @@ var isEntityMatchedByKeyword = function (entity, keyword) {
|
|
|
31
32
|
exports.isEntityMatchedByKeyword = isEntityMatchedByKeyword;
|
|
32
33
|
var isEntityMatchedByKeywords = function (entity, keywordsList) { return !keywordsList || keywordsList.length === 0 || keywordsList.every(function (k) { return exports.isEntityMatchedByKeyword(entity, k); }); };
|
|
33
34
|
exports.isEntityMatchedByKeywords = isEntityMatchedByKeywords;
|
|
34
|
-
var searchEntities = function (entityArray,
|
|
35
|
+
var searchEntities = function (entityArray, entityMatchFunction, readActivity, canReadAnyGlobally, keywords) {
|
|
36
|
+
var _a;
|
|
35
37
|
var keywordsList = exports.getKeywordsList(keywords);
|
|
36
38
|
var filteredEntities = entityArray.reduce(function (acc, e) {
|
|
39
|
+
var _a;
|
|
37
40
|
// exclude if cannot read any entity and does not have the read activity
|
|
38
41
|
if (!canReadAnyGlobally && !e.activities.includes(readActivity))
|
|
39
42
|
return acc;
|
|
40
43
|
// exclude if does not match, if any
|
|
41
|
-
if (!
|
|
44
|
+
if (!entityMatchFunction(e, keywordsList))
|
|
42
45
|
return acc;
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
// add entity to the corresponding tab filtered array
|
|
47
|
+
var tab = e.isDeleted ? table_1.MANAGE_TABLE_TAB.DELETED : table_1.MANAGE_TABLE_TAB.AVAILABLE;
|
|
48
|
+
var tabArray = (_a = acc[tab]) !== null && _a !== void 0 ? _a : [];
|
|
49
|
+
tabArray.push(e);
|
|
50
|
+
acc[tab] = tabArray;
|
|
48
51
|
return acc;
|
|
49
|
-
}, {
|
|
52
|
+
}, (_a = {}, _a[table_1.MANAGE_TABLE_TAB.AVAILABLE] = [], _a[table_1.MANAGE_TABLE_TAB.DELETED] = [], _a));
|
|
50
53
|
return filteredEntities;
|
|
51
54
|
};
|
|
52
55
|
exports.searchEntities = searchEntities;
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
var getGroupTab = function (group, endDate) {
|
|
57
|
+
if (group.isDeleted) {
|
|
58
|
+
return table_1.GROUP_MANAGE_TABLE_TAB.DELETED;
|
|
59
|
+
}
|
|
60
|
+
else if (!!group.id && date_1.isNowBeforeDate(endDate)) {
|
|
61
|
+
return table_1.GROUP_MANAGE_TABLE_TAB.CURRENT;
|
|
62
|
+
}
|
|
63
|
+
return table_1.GROUP_MANAGE_TABLE_TAB.PAST;
|
|
64
|
+
};
|
|
65
|
+
var searchGroups = function (_a) {
|
|
66
|
+
var _b;
|
|
67
|
+
var groups = _a.groups, groupsArray = _a.modelArray, externalTerms = _a.externalTerms, canReadyAnyGlobally = _a.canReadyAnyGlobally, keywords = _a.keywords, dateString = _a.dateString;
|
|
55
68
|
var keywordsList = exports.getKeywordsList(keywords);
|
|
56
|
-
var visibleGroups =
|
|
69
|
+
var visibleGroups = canReadyAnyGlobally ? groupsArray : groupRoles_1.groupsAsAnythingButLearner(groups);
|
|
57
70
|
var filteredGroups = visibleGroups.reduce(function (acc, g) {
|
|
71
|
+
var _a;
|
|
58
72
|
// exclude if does not match keywords, if any
|
|
59
73
|
if (!exports.isEntityMatchedByKeywords(g, keywordsList))
|
|
60
74
|
return acc;
|
|
@@ -66,18 +80,16 @@ var searchGroups = function (groups, groupsArray, externalTerms, canReadGroupsGl
|
|
|
66
80
|
date_1.getLocalMomentFromUtc(dateString) > date_1.getLocalMomentFromUtc(endDate))) {
|
|
67
81
|
return acc;
|
|
68
82
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
else if (!!g.id && date_1.isNowBeforeDate(endDate)) {
|
|
74
|
-
acc.currentGroups.push(g);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
acc.pastGroups.push(g);
|
|
78
|
-
}
|
|
83
|
+
var tab = getGroupTab(g, endDate);
|
|
84
|
+
var tabArray = (_a = acc[tab]) !== null && _a !== void 0 ? _a : [];
|
|
85
|
+
tabArray.push(g);
|
|
86
|
+
acc[tab] = tabArray;
|
|
79
87
|
return acc;
|
|
80
|
-
},
|
|
88
|
+
}, (_b = {},
|
|
89
|
+
_b[table_1.GROUP_MANAGE_TABLE_TAB.CURRENT] = [],
|
|
90
|
+
_b[table_1.GROUP_MANAGE_TABLE_TAB.PAST] = [],
|
|
91
|
+
_b[table_1.GROUP_MANAGE_TABLE_TAB.DELETED] = [],
|
|
92
|
+
_b));
|
|
81
93
|
return filteredGroups;
|
|
82
94
|
};
|
|
83
95
|
exports.searchGroups = searchGroups;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "studiokit-scaffolding-js",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.1.0",
|
|
4
4
|
"description": "Common scaffolding for Studio apps at Purdue",
|
|
5
5
|
"repository": "https://gitlab.com/purdue-informatics/studiokit/studiokit-scaffolding-js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -126,6 +126,7 @@
|
|
|
126
126
|
"history": "^4.10.1",
|
|
127
127
|
"local-storage-fallback": "^4.1.1",
|
|
128
128
|
"lodash": "^4.17.20",
|
|
129
|
+
"memoize-one": "^6.0.0",
|
|
129
130
|
"moment-timezone": "^0.5.32",
|
|
130
131
|
"parchment": "^1.1.4",
|
|
131
132
|
"pluralize": "^8.0.0",
|