@plusscommunities/pluss-feature-builder-app-c 1.0.1-beta.3
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/dist/module/actions/featureBuilderActions.js +106 -0
- package/dist/module/actions/featureBuilderActions.js.map +1 -0
- package/dist/module/actions/featureBuilderStringsActions.js +106 -0
- package/dist/module/actions/featureBuilderStringsActions.js.map +1 -0
- package/dist/module/actions/index.js +12 -0
- package/dist/module/actions/index.js.map +1 -0
- package/dist/module/actions/types.js +7 -0
- package/dist/module/actions/types.js.map +1 -0
- package/dist/module/components/FeatureDetailScreen.js +725 -0
- package/dist/module/components/FeatureDetailScreen.js.map +1 -0
- package/dist/module/components/FeatureListItem.js +174 -0
- package/dist/module/components/FeatureListItem.js.map +1 -0
- package/dist/module/components/FeatureListScreen.js +159 -0
- package/dist/module/components/FeatureListScreen.js.map +1 -0
- package/dist/module/components/FieldRenderer.js +218 -0
- package/dist/module/components/FieldRenderer.js.map +1 -0
- package/dist/module/components/FileDownload.js +74 -0
- package/dist/module/components/FileDownload.js.map +1 -0
- package/dist/module/components/WidgetGrid.js +158 -0
- package/dist/module/components/WidgetGrid.js.map +1 -0
- package/dist/module/components/WidgetLarge.js +274 -0
- package/dist/module/components/WidgetLarge.js.map +1 -0
- package/dist/module/components/WidgetSmall.js +315 -0
- package/dist/module/components/WidgetSmall.js.map +1 -0
- package/dist/module/components/common/index.js +25 -0
- package/dist/module/components/common/index.js.map +1 -0
- package/dist/module/components/layouts/CondensedList.js +195 -0
- package/dist/module/components/layouts/CondensedList.js.map +1 -0
- package/dist/module/components/layouts/FeatureImageList.js +172 -0
- package/dist/module/components/layouts/FeatureImageList.js.map +1 -0
- package/dist/module/components/layouts/RoundImageList.js +198 -0
- package/dist/module/components/layouts/RoundImageList.js.map +1 -0
- package/dist/module/components/layouts/SquareImageList.js +185 -0
- package/dist/module/components/layouts/SquareImageList.js.map +1 -0
- package/dist/module/config/index.js +10 -0
- package/dist/module/config/index.js.map +1 -0
- package/dist/module/core.config.js +17 -0
- package/dist/module/core.config.js.map +1 -0
- package/dist/module/feature.config.js +113 -0
- package/dist/module/feature.config.js.map +1 -0
- package/dist/module/index.js +24 -0
- package/dist/module/index.js.map +1 -0
- package/dist/module/js/Colors.js +25 -0
- package/dist/module/js/Colors.js.map +1 -0
- package/dist/module/js/FieldTypes.js +123 -0
- package/dist/module/js/FieldTypes.js.map +1 -0
- package/dist/module/js/NavigationService.js +10 -0
- package/dist/module/js/NavigationService.js.map +1 -0
- package/dist/module/js/Styles.js +3 -0
- package/dist/module/js/Styles.js.map +1 -0
- package/dist/module/js/helpers.js +29 -0
- package/dist/module/js/helpers.js.map +1 -0
- package/dist/module/js/index.js +24 -0
- package/dist/module/js/index.js.map +1 -0
- package/dist/module/js/spacing.js +29 -0
- package/dist/module/js/spacing.js.map +1 -0
- package/dist/module/js/types.js +254 -0
- package/dist/module/js/types.js.map +1 -0
- package/dist/module/reducers/featureBuilderReducer.js +75 -0
- package/dist/module/reducers/featureBuilderReducer.js.map +1 -0
- package/dist/module/utils/featureSelectors.js +9 -0
- package/dist/module/utils/featureSelectors.js.map +1 -0
- package/dist/module/values.config.a.js +96 -0
- package/dist/module/values.config.a.js.map +1 -0
- package/dist/module/values.config.b.js +96 -0
- package/dist/module/values.config.b.js.map +1 -0
- package/dist/module/values.config.c.js +96 -0
- package/dist/module/values.config.c.js.map +1 -0
- package/dist/module/values.config.d.js +96 -0
- package/dist/module/values.config.d.js.map +1 -0
- package/dist/module/values.config.js +96 -0
- package/dist/module/values.config.js.map +1 -0
- package/dist/module/webapi/featureBuilderAPI.js +59 -0
- package/dist/module/webapi/featureBuilderAPI.js.map +1 -0
- package/dist/module/webapi/helper.js +4 -0
- package/dist/module/webapi/helper.js.map +1 -0
- package/dist/module/webapi/index.js +8 -0
- package/dist/module/webapi/index.js.map +1 -0
- package/package.json +62 -0
- package/src/actions/featureBuilderActions.js +112 -0
- package/src/actions/featureBuilderStringsActions.js +114 -0
- package/src/actions/index.js +12 -0
- package/src/actions/types.js +7 -0
- package/src/components/FeatureDetailScreen.js +817 -0
- package/src/components/FeatureListItem.js +198 -0
- package/src/components/FeatureListScreen.js +160 -0
- package/src/components/FieldRenderer.js +272 -0
- package/src/components/FileDownload.js +79 -0
- package/src/components/WidgetGrid.js +181 -0
- package/src/components/WidgetLarge.js +305 -0
- package/src/components/WidgetSmall.js +344 -0
- package/src/components/common/index.js +25 -0
- package/src/components/layouts/CondensedList.js +230 -0
- package/src/components/layouts/FeatureImageList.js +193 -0
- package/src/components/layouts/RoundImageList.js +219 -0
- package/src/components/layouts/SquareImageList.js +205 -0
- package/src/config/index.js +10 -0
- package/src/core.config.js +29 -0
- package/src/feature.config.js +127 -0
- package/src/index.js +27 -0
- package/src/js/Colors.js +30 -0
- package/src/js/FieldTypes.js +131 -0
- package/src/js/NavigationService.js +12 -0
- package/src/js/Styles.js +3 -0
- package/src/js/helpers.js +30 -0
- package/src/js/index.js +24 -0
- package/src/js/spacing.js +30 -0
- package/src/js/types.js +253 -0
- package/src/reducers/featureBuilderReducer.js +64 -0
- package/src/utils/featureSelectors.js +8 -0
- package/src/values.config.a.js +104 -0
- package/src/values.config.b.js +104 -0
- package/src/values.config.c.js +104 -0
- package/src/values.config.d.js +104 -0
- package/src/values.config.js +104 -0
- package/src/webapi/featureBuilderAPI.js +65 -0
- package/src/webapi/helper.js +4 -0
- package/src/webapi/index.js +8 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { getUrl } from "./helper";
|
|
2
|
+
import { authedFunction } from "../js";
|
|
3
|
+
import { values } from "../values.config";
|
|
4
|
+
|
|
5
|
+
// Helper function for constructing URLs
|
|
6
|
+
const getFeatureBuilderUrl = (action, query = null) => {
|
|
7
|
+
return getUrl(values.apiNamespace, action, query);
|
|
8
|
+
};
|
|
9
|
+
export const featureBuilderAPI = {
|
|
10
|
+
// Fetch all feature definitions
|
|
11
|
+
getFeatureDefinitions: site => {
|
|
12
|
+
const url = getFeatureBuilderUrl(values.api.getDefinitions, {
|
|
13
|
+
site
|
|
14
|
+
});
|
|
15
|
+
const request = {
|
|
16
|
+
method: "GET",
|
|
17
|
+
url
|
|
18
|
+
};
|
|
19
|
+
return authedFunction(request).then(response => {
|
|
20
|
+
return response;
|
|
21
|
+
}).catch(error => {
|
|
22
|
+
throw error;
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
// Fetch listings for all features or specific feature
|
|
26
|
+
getFeatureListings: (site, featureDefinitionId = null) => {
|
|
27
|
+
const queryParams = {
|
|
28
|
+
site
|
|
29
|
+
};
|
|
30
|
+
if (featureDefinitionId) {
|
|
31
|
+
queryParams.featureDefinitionId = featureDefinitionId;
|
|
32
|
+
}
|
|
33
|
+
const url = getFeatureBuilderUrl(values.api.getListings, queryParams);
|
|
34
|
+
const request = {
|
|
35
|
+
method: "GET",
|
|
36
|
+
url
|
|
37
|
+
};
|
|
38
|
+
return authedFunction(request).then(response => {
|
|
39
|
+
return response;
|
|
40
|
+
}).catch(error => {
|
|
41
|
+
throw error;
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
// Fetch a single listing by ID
|
|
45
|
+
getSingleListing: (site, listingId) => {
|
|
46
|
+
if (!listingId) {
|
|
47
|
+
return Promise.reject(new Error("Listing ID is required"));
|
|
48
|
+
}
|
|
49
|
+
const url = getFeatureBuilderUrl(values.api.getSingleListing, {
|
|
50
|
+
site,
|
|
51
|
+
id: listingId
|
|
52
|
+
});
|
|
53
|
+
return authedFunction({
|
|
54
|
+
method: "GET",
|
|
55
|
+
url
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=featureBuilderAPI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["getUrl","authedFunction","values","getFeatureBuilderUrl","action","query","apiNamespace","featureBuilderAPI","getFeatureDefinitions","site","url","api","getDefinitions","request","method","then","response","catch","error","getFeatureListings","featureDefinitionId","queryParams","getListings","getSingleListing","listingId","Promise","reject","Error","id"],"sources":["featureBuilderAPI.js"],"sourcesContent":["import { getUrl } from \"./helper\";\nimport { authedFunction } from \"../js\";\nimport { values } from \"../values.config\";\n\n// Helper function for constructing URLs\nconst getFeatureBuilderUrl = (action, query = null) => {\n\treturn getUrl(values.apiNamespace, action, query);\n};\n\nexport const featureBuilderAPI = {\n\t// Fetch all feature definitions\n\tgetFeatureDefinitions: (site) => {\n\t\tconst url = getFeatureBuilderUrl(values.api.getDefinitions, { site });\n\n\t\tconst request = {\n\t\t\tmethod: \"GET\",\n\t\t\turl,\n\t\t};\n\n\t\treturn authedFunction(request)\n\t\t\t.then((response) => {\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthrow error;\n\t\t\t});\n\t},\n\n\t// Fetch listings for all features or specific feature\n\tgetFeatureListings: (site, featureDefinitionId = null) => {\n\t\tconst queryParams = { site };\n\t\tif (featureDefinitionId) {\n\t\t\tqueryParams.featureDefinitionId = featureDefinitionId;\n\t\t}\n\t\tconst url = getFeatureBuilderUrl(values.api.getListings, queryParams);\n\n\t\tconst request = {\n\t\t\tmethod: \"GET\",\n\t\t\turl,\n\t\t};\n\n\t\treturn authedFunction(request)\n\t\t\t.then((response) => {\n\t\t\t\treturn response;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tthrow error;\n\t\t\t});\n\t},\n\n\t// Fetch a single listing by ID\n\tgetSingleListing: (site, listingId) => {\n\t\tif (!listingId) {\n\t\t\treturn Promise.reject(new Error(\"Listing ID is required\"));\n\t\t}\n\t\tconst url = getFeatureBuilderUrl(values.api.getSingleListing, {\n\t\t\tsite,\n\t\t\tid: listingId,\n\t\t});\n\t\treturn authedFunction({\n\t\t\tmethod: \"GET\",\n\t\t\turl,\n\t\t});\n\t},\n};\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,UAAU;AACjC,SAASC,cAAc,QAAQ,OAAO;AACtC,SAASC,MAAM,QAAQ,kBAAkB;;AAEzC;AACA,MAAMC,oBAAoB,GAAGA,CAACC,MAAM,EAAEC,KAAK,GAAG,IAAI,KAAK;EACtD,OAAOL,MAAM,CAACE,MAAM,CAACI,YAAY,EAAEF,MAAM,EAAEC,KAAK,CAAC;AAClD,CAAC;AAED,OAAO,MAAME,iBAAiB,GAAG;EAChC;EACAC,qBAAqB,EAAGC,IAAI,IAAK;IAChC,MAAMC,GAAG,GAAGP,oBAAoB,CAACD,MAAM,CAACS,GAAG,CAACC,cAAc,EAAE;MAAEH;IAAK,CAAC,CAAC;IAErE,MAAMI,OAAO,GAAG;MACfC,MAAM,EAAE,KAAK;MACbJ;IACD,CAAC;IAED,OAAOT,cAAc,CAACY,OAAO,CAAC,CAC5BE,IAAI,CAAEC,QAAQ,IAAK;MACnB,OAAOA,QAAQ;IAChB,CAAC,CAAC,CACDC,KAAK,CAAEC,KAAK,IAAK;MACjB,MAAMA,KAAK;IACZ,CAAC,CAAC;EACJ,CAAC;EAED;EACAC,kBAAkB,EAAEA,CAACV,IAAI,EAAEW,mBAAmB,GAAG,IAAI,KAAK;IACzD,MAAMC,WAAW,GAAG;MAAEZ;IAAK,CAAC;IAC5B,IAAIW,mBAAmB,EAAE;MACxBC,WAAW,CAACD,mBAAmB,GAAGA,mBAAmB;IACtD;IACA,MAAMV,GAAG,GAAGP,oBAAoB,CAACD,MAAM,CAACS,GAAG,CAACW,WAAW,EAAED,WAAW,CAAC;IAErE,MAAMR,OAAO,GAAG;MACfC,MAAM,EAAE,KAAK;MACbJ;IACD,CAAC;IAED,OAAOT,cAAc,CAACY,OAAO,CAAC,CAC5BE,IAAI,CAAEC,QAAQ,IAAK;MACnB,OAAOA,QAAQ;IAChB,CAAC,CAAC,CACDC,KAAK,CAAEC,KAAK,IAAK;MACjB,MAAMA,KAAK;IACZ,CAAC,CAAC;EACJ,CAAC;EAED;EACAK,gBAAgB,EAAEA,CAACd,IAAI,EAAEe,SAAS,KAAK;IACtC,IAAI,CAACA,SAAS,EAAE;MACf,OAAOC,OAAO,CAACC,MAAM,CAAC,IAAIC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3D;IACA,MAAMjB,GAAG,GAAGP,oBAAoB,CAACD,MAAM,CAACS,GAAG,CAACY,gBAAgB,EAAE;MAC7Dd,IAAI;MACJmB,EAAE,EAAEJ;IACL,CAAC,CAAC;IACF,OAAOvB,cAAc,CAAC;MACrBa,MAAM,EAAE,KAAK;MACbJ;IACD,CAAC,CAAC;EACH;AACD,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Helper","getUrl","getAuthTokenHeader"],"sources":["helper.js"],"sourcesContent":["import { Helper } from \"../core.config\";\n\nexport const getUrl = Helper.getUrl;\nexport const getAuthTokenHeader = Helper.getAuthTokenHeader;\n"],"mappings":"AAAA,SAASA,MAAM,QAAQ,gBAAgB;AAEvC,OAAO,MAAMC,MAAM,GAAGD,MAAM,CAACC,MAAM;AACnC,OAAO,MAAMC,kBAAkB,GAAGF,MAAM,CAACE,kBAAkB","ignoreList":[]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Apis } from "../core.config";
|
|
2
|
+
export const userActions = Apis.userActions;
|
|
3
|
+
export const contactActions = Apis.contactActions;
|
|
4
|
+
export const eventActions = Apis.eventActions;
|
|
5
|
+
|
|
6
|
+
// TODO: Add custom web apis below for example,
|
|
7
|
+
// export * from './activityActions';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Apis","userActions","contactActions","eventActions"],"sources":["index.js"],"sourcesContent":["import { Apis } from \"../core.config\";\n\nexport const userActions = Apis.userActions;\nexport const contactActions = Apis.contactActions;\nexport const eventActions = Apis.eventActions;\n\n// TODO: Add custom web apis below for example,\n// export * from './activityActions';\n"],"mappings":"AAAA,SAASA,IAAI,QAAQ,gBAAgB;AAErC,OAAO,MAAMC,WAAW,GAAGD,IAAI,CAACC,WAAW;AAC3C,OAAO,MAAMC,cAAc,GAAGF,IAAI,CAACE,cAAc;AACjD,OAAO,MAAMC,YAAY,GAAGH,IAAI,CAACG,YAAY;;AAE7C;AACA","ignoreList":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@plusscommunities/pluss-feature-builder-app-c",
|
|
3
|
+
"version": "1.0.1-beta.3",
|
|
4
|
+
"description": "Feature Builder mobile extension for displaying custom features",
|
|
5
|
+
"main": "dist/module/index.js",
|
|
6
|
+
"module": "dist/module/index.js",
|
|
7
|
+
"react-native": "src/index.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist/",
|
|
10
|
+
"src/"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "npm i --legacy-peer-deps && bob build",
|
|
14
|
+
"betapatch": "npm version prepatch --preid=beta",
|
|
15
|
+
"patch": "npm version patch",
|
|
16
|
+
"betaupload": "npm run build && npm publish --access public --tag beta",
|
|
17
|
+
"betaupload:p": "npm run betapatch && npm run betaupload",
|
|
18
|
+
"upload": "npm run build && npm publish --access public",
|
|
19
|
+
"upload:p": "npm run patch && npm run upload",
|
|
20
|
+
"copy:add": "run(){ ext=${1:-default}; test -f src/values.config.$ext.js || cp src/values.config.default.js src/values.config.$ext.js; }; run",
|
|
21
|
+
"copy:get": "echo $npm_package_name",
|
|
22
|
+
"copy:set": "run(){ target='@plusscommunities/pluss-feature-builder-app-a'; ext=${1:-default}; [ $ext == 'default' ] && replace=$target || replace=$target'-'$ext; echo 'Setting target to '$replace; test -f src/values.config.$ext.js && cp -f src/values.config.$ext.js src/values.config.js; sed -i '' -e 's/'$target'.*\"/'$replace'\"/g' package.json; }; run",
|
|
23
|
+
"copy:upload": "npm run patch; for file in `ls ./src/values.config.*.js`; do dup=`echo $file | sed 's/.*values\\.config\\.\\(.*\\)\\.js/\\1/'`; npm run copy:set $dup; npm run upload; done; npm run copy:set;",
|
|
24
|
+
"copy:betaupload": "npm run betapatch; for file in `ls ./src/values.config.*.js`; do dup=`echo $file | sed 's/.*values\\.config\\.\\(.*\\)\\.js/\\1/'`; npm run copy:set $dup; npm run betaupload; done; npm run copy:set;"
|
|
25
|
+
},
|
|
26
|
+
"author": "Thorbjorn Kappel Davis",
|
|
27
|
+
"license": "ISC",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"axios": "^1.6.8",
|
|
30
|
+
"lodash": "^4.17.4",
|
|
31
|
+
"moment": "^2.30.1"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@plusscommunities/pluss-core-app": "*",
|
|
35
|
+
"expo-constants": "*",
|
|
36
|
+
"expo-linear-gradient": "*",
|
|
37
|
+
"react": "*",
|
|
38
|
+
"react-native": "*",
|
|
39
|
+
"react-native-elements": "*",
|
|
40
|
+
"react-native-iphone-x-helper": "*",
|
|
41
|
+
"react-native-webview": "*",
|
|
42
|
+
"react-redux": "*",
|
|
43
|
+
"redux-persist": "*"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@plusscommunities/pluss-core-app": "^6.1.13",
|
|
47
|
+
"react": "18.2.0",
|
|
48
|
+
"react-native": "0.73.6",
|
|
49
|
+
"react-native-builder-bob": "^0.18.2",
|
|
50
|
+
"react-native-elements": "^0.17.0",
|
|
51
|
+
"react-native-iphone-x-helper": "^1.3.1",
|
|
52
|
+
"react-native-webview": "13.6.4",
|
|
53
|
+
"react-redux": "^7.2.6"
|
|
54
|
+
},
|
|
55
|
+
"react-native-builder-bob": {
|
|
56
|
+
"source": "src",
|
|
57
|
+
"output": "dist",
|
|
58
|
+
"targets": [
|
|
59
|
+
"module"
|
|
60
|
+
]
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { values } from "../values.config";
|
|
2
|
+
import { featureBuilderAPI } from "../webapi/featureBuilderAPI";
|
|
3
|
+
import { updateFeatureBuilderStringAndIconFromDefinition } from "./featureBuilderStringsActions";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Action types for feature builder Redux actions
|
|
7
|
+
* These are pulled from values.config.actions to ensure unique action types per instance
|
|
8
|
+
* @readonly
|
|
9
|
+
* @enum {string}
|
|
10
|
+
*/
|
|
11
|
+
export const FeatureBuilderActionTypes = {
|
|
12
|
+
/** Indicates loading state for feature data fetch */
|
|
13
|
+
LOADING: values.actions.LOADING,
|
|
14
|
+
/** Indicates successful fetch of feature definition and listings */
|
|
15
|
+
LOAD_SUCCESS: values.actions.LOAD_SUCCESS,
|
|
16
|
+
/** Indicates failure in fetching feature data */
|
|
17
|
+
FAILURE: values.actions.FAILURE,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Loads the target feature definition and its listings from the API
|
|
22
|
+
* This function fetches the feature definition configured in values.config
|
|
23
|
+
* and loads all associated listings for display
|
|
24
|
+
*
|
|
25
|
+
* @function
|
|
26
|
+
* @returns {Function} Redux thunk function that handles the async loading
|
|
27
|
+
* @throws {Error} When no feature definitions are found or API calls fail
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // In component
|
|
31
|
+
* useEffect(() => {
|
|
32
|
+
* props.loadTargetFeature();
|
|
33
|
+
* }, []);
|
|
34
|
+
*
|
|
35
|
+
* // Dispatch directly
|
|
36
|
+
* dispatch(loadTargetFeature());
|
|
37
|
+
*/
|
|
38
|
+
export const loadTargetFeature = () => {
|
|
39
|
+
return async (dispatch, getState) => {
|
|
40
|
+
dispatch({ type: FeatureBuilderActionTypes.LOADING });
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const state = getState();
|
|
44
|
+
const site = state.user?.site;
|
|
45
|
+
const targetId = values.targetFeatureDefinitionId;
|
|
46
|
+
const defResponse = await featureBuilderAPI.getFeatureDefinitions(site);
|
|
47
|
+
const allDefinitions = defResponse.data.featureDefinitions || [];
|
|
48
|
+
|
|
49
|
+
// Find the specific target definition - throw if not found
|
|
50
|
+
const rawTarget = allDefinitions.find((d) => d.id === targetId);
|
|
51
|
+
|
|
52
|
+
if (!rawTarget) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`Target feature definition with ID '${targetId}' not found.`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const flattenedFeature = {
|
|
59
|
+
id: rawTarget.id,
|
|
60
|
+
...rawTarget.definition,
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const listResponse = await featureBuilderAPI.getFeatureListings(
|
|
64
|
+
site,
|
|
65
|
+
rawTarget.id,
|
|
66
|
+
);
|
|
67
|
+
const rawListings = listResponse.data.listings || [];
|
|
68
|
+
|
|
69
|
+
// Filter out soft-deleted items at the Redux level
|
|
70
|
+
const listings = rawListings.filter((listing) => !listing.deletedAt);
|
|
71
|
+
|
|
72
|
+
dispatch({
|
|
73
|
+
type: FeatureBuilderActionTypes.LOAD_SUCCESS,
|
|
74
|
+
payload: {
|
|
75
|
+
feature: flattenedFeature,
|
|
76
|
+
listings: listings,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Update strings store with feature definition title and icon
|
|
81
|
+
dispatch(updateFeatureBuilderStringAndIconFromDefinition());
|
|
82
|
+
} catch (error) {
|
|
83
|
+
dispatch({
|
|
84
|
+
type: FeatureBuilderActionTypes.FAILURE,
|
|
85
|
+
payload: error.message || "Failed to load feature.",
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// Aliases for compatibility with any lingering imports
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Alias for loadTargetFeature - initializes feature builder with target feature
|
|
95
|
+
* @function
|
|
96
|
+
* @see loadTargetFeature
|
|
97
|
+
*/
|
|
98
|
+
export const initializeFeatureBuilder = loadTargetFeature;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Alias for loadTargetFeature - refreshes current feature data
|
|
102
|
+
* @function
|
|
103
|
+
* @see loadTargetFeature
|
|
104
|
+
*/
|
|
105
|
+
export const refreshFeature = loadTargetFeature;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Alias for loadTargetFeature - fetches listings for target feature
|
|
109
|
+
* @function
|
|
110
|
+
* @see loadTargetFeature
|
|
111
|
+
*/
|
|
112
|
+
export const fetchTargetFeatureListings = loadTargetFeature;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { selectFeatureDefinition } from "../reducers/featureBuilderReducer";
|
|
2
|
+
import { values } from "../values.config";
|
|
3
|
+
|
|
4
|
+
// IMPORTANT: Using local UPDATE_STRINGS action type to make extension self-contained
|
|
5
|
+
// The main app's StringsReducer will handle this action type the same way
|
|
6
|
+
export const UPDATE_STRINGS = "UPDATE_STRINGS";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Updates the feature builder's menu text in the global strings store
|
|
10
|
+
* This ensures UI components use the dynamic title from feature definition
|
|
11
|
+
*/
|
|
12
|
+
export const updateFeatureBuilderString = (title) => (dispatch, getState) => {
|
|
13
|
+
const currentStrings = getState().strings?.config || {};
|
|
14
|
+
|
|
15
|
+
const updatedStrings = {
|
|
16
|
+
...currentStrings,
|
|
17
|
+
featureTitles: {
|
|
18
|
+
...currentStrings.featureTitles,
|
|
19
|
+
[values.featureKey]: title || values.featureName,
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
dispatch({
|
|
24
|
+
type: UPDATE_STRINGS,
|
|
25
|
+
payload: updatedStrings,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Updates the feature builder string using the current title from feature definition
|
|
31
|
+
* This is useful when the feature definition has been updated
|
|
32
|
+
*/
|
|
33
|
+
export const updateFeatureBuilderStringFromDefinition =
|
|
34
|
+
() => (dispatch, getState) => {
|
|
35
|
+
const definition = selectFeatureDefinition(getState());
|
|
36
|
+
const title = definition?.title || values.featureName;
|
|
37
|
+
// Capitalize first letter of title
|
|
38
|
+
const capitalizedTitle = title
|
|
39
|
+
? title.charAt(0).toUpperCase() + title.slice(1)
|
|
40
|
+
: values.featureName;
|
|
41
|
+
dispatch(updateFeatureBuilderString(capitalizedTitle));
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Updates the feature builder icon in the global strings store
|
|
46
|
+
* This ensures UI components use the dynamic icon from the feature definition
|
|
47
|
+
*/
|
|
48
|
+
export const updateFeatureBuilderIcon = (icon) => (dispatch, getState) => {
|
|
49
|
+
const currentStrings = getState().strings?.config || {};
|
|
50
|
+
const updatedStrings = {
|
|
51
|
+
...currentStrings,
|
|
52
|
+
featureIcons: {
|
|
53
|
+
...currentStrings.featureIcons,
|
|
54
|
+
[values.featureKey]: icon,
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
dispatch({
|
|
59
|
+
type: UPDATE_STRINGS,
|
|
60
|
+
payload: updatedStrings,
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Updates the feature builder icon using the current icon from feature definition
|
|
66
|
+
* This is useful when the feature definition has been updated
|
|
67
|
+
*/
|
|
68
|
+
export const updateFeatureBuilderIconFromDefinition =
|
|
69
|
+
() => (dispatch, getState) => {
|
|
70
|
+
const definition = selectFeatureDefinition(getState());
|
|
71
|
+
const icon = definition?.icon || values.navigation.gridMenu.icon;
|
|
72
|
+
dispatch(updateFeatureBuilderIcon(icon));
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Updates the feature builder grid icon in the global strings store
|
|
77
|
+
* This ensures UI components use the dynamic grid icon from the feature definition
|
|
78
|
+
*/
|
|
79
|
+
export const updateFeatureBuilderGridIcon =
|
|
80
|
+
(gridIcon) => (dispatch, getState) => {
|
|
81
|
+
const currentStrings = getState().strings?.config || {};
|
|
82
|
+
const updatedStrings = {
|
|
83
|
+
...currentStrings,
|
|
84
|
+
featureIcons: {
|
|
85
|
+
...currentStrings.featureIcons,
|
|
86
|
+
[values.featureKey]: gridIcon,
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
dispatch({
|
|
91
|
+
type: UPDATE_STRINGS,
|
|
92
|
+
payload: updatedStrings,
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Updates both the title and icon from the current feature definition
|
|
98
|
+
* This is useful when both have been updated in the definition
|
|
99
|
+
*/
|
|
100
|
+
export const updateFeatureBuilderStringAndIconFromDefinition =
|
|
101
|
+
() => (dispatch, getState) => {
|
|
102
|
+
const definition = selectFeatureDefinition(getState());
|
|
103
|
+
const title = definition?.title || values.featureName;
|
|
104
|
+
const icon = definition?.icon || values.navigation.gridMenu.icon;
|
|
105
|
+
|
|
106
|
+
// Update title
|
|
107
|
+
const capitalizedTitle = title
|
|
108
|
+
? title.charAt(0).toUpperCase() + title.slice(1)
|
|
109
|
+
: values.featureName;
|
|
110
|
+
dispatch(updateFeatureBuilderString(capitalizedTitle));
|
|
111
|
+
|
|
112
|
+
// Update icon
|
|
113
|
+
dispatch(updateFeatureBuilderIcon(icon));
|
|
114
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Actions } from "../core.config";
|
|
2
|
+
|
|
3
|
+
export const getFollowers = Actions.getFollowers;
|
|
4
|
+
export const addFollower = Actions.addFollower;
|
|
5
|
+
export const selectEventTime = Actions.selectEventTime;
|
|
6
|
+
export const residentsLoaded = Actions.residentsLoaded;
|
|
7
|
+
export const linkedUsersLoaded = Actions.linkedToUsersLoaded;
|
|
8
|
+
export const linkedToUsersLoaded = Actions.linkedToUsersLoaded;
|
|
9
|
+
export const updateNavRead = Actions.updateNavRead;
|
|
10
|
+
|
|
11
|
+
// TODO: Add custom actions below for example,
|
|
12
|
+
// export * from './AlertActions';
|