5htp-core 0.3.9 → 0.4.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "5htp-core",
3
3
  "description": "Convenient TypeScript framework designed for Performance and Productivity.",
4
- "version": "0.3.9",
4
+ "version": "0.4.0",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/5htp-core.git",
7
7
  "license": "MIT",
@@ -99,6 +99,6 @@
99
99
  "babel-plugin-glob-import": "^0.0.7"
100
100
  },
101
101
  "peerDependencies": {
102
- "5htp": "0.3.8"
102
+ "5htp": "0.3.9"
103
103
  }
104
104
  }
@@ -254,18 +254,6 @@ export default () => {
254
254
  const lastToast = modals[ modals.length - 1 ];
255
255
  focusContent( lastToast );
256
256
 
257
- // Backdrop color
258
- const header = lastToast.querySelector('header');
259
- if (!header || !header.className)
260
- return;
261
-
262
- const headerColor = window.getComputedStyle(header, null).getPropertyValue('background-color');
263
- if (!headerColor || !headerColor.startsWith('rgb('))
264
- return;
265
-
266
- const rgbBg = headerColor.substring(4, headerColor.length - 1);
267
- lastToast.style.background = 'rgba(' + rgbBg + ', .5)';
268
-
269
257
  });
270
258
 
271
259
  return <>
@@ -24,9 +24,17 @@ export default ({ page }: { page: Page }) => {
24
24
  const [apiData, setApiData] = React.useState<{[k: string]: any} | null>(
25
25
  page.data || {}
26
26
  );
27
+
27
28
  page.setAllData = setApiData;
28
29
  context.data = apiData;
29
30
 
31
+ // Page component has not changed, but data were updated (ex: url parameters change)
32
+ React.useEffect(() => {
33
+
34
+ setApiData(page.data);
35
+
36
+ }, [page.data]);
37
+
30
38
  /*----------------------------------
31
39
  - RENDER
32
40
  ----------------------------------*/
@@ -117,13 +117,8 @@ export default ({ service: clientRouter }: { service?: ClientRouter }) => {
117
117
  // Add page container
118
118
  setPages( pages => {
119
119
 
120
- // Check if the page changed
121
- if (pages.current?.chunkId === newpage.chunkId) {
122
- console.warn(LogPrefix, "Canceling navigation to the same page:", {...request});
123
- pages.current.setAllData(newData);
124
- clientRouter.setLoading(false);
125
- return { ...pages }
126
- }
120
+ // WARN: Don't cancel navigation if same page as before, as we already instanciated the new page and bound the context with it
121
+ // Otherwise it would cause reference issues (ex: page.setAllData makes ref to the new context)
127
122
 
128
123
  // If if the layout changed
129
124
  const curLayout = pages.current?.layout;
@@ -126,7 +126,6 @@ type THookName = 'location.change' | 'page.changed'
126
126
  type Config<TAdditionnalContext extends {} = {}> = {
127
127
  preload: string[], // List of globs
128
128
  context: (context: ClientContext, router: ClientRouter) => TAdditionnalContext,
129
- domains: TDomainsList
130
129
  }
131
130
 
132
131
  /*----------------------------------
@@ -140,6 +139,7 @@ export default class ClientRouter<
140
139
  // Context data
141
140
  public ssrRoutes = window["routes"] as TSsrUnresolvedRoute[];
142
141
  public ssrContext = window["ssr"] as (TBasicSSrData | undefined);
142
+ public domains = window["ssr"].domains;
143
143
  public context!: ClientContext;
144
144
 
145
145
  public setLoading!: React.Dispatch< React.SetStateAction<boolean> >;
File without changes
@@ -37,6 +37,7 @@ export default class ClientPage<TRouter = ClientRouter> extends PageResponse<TRo
37
37
 
38
38
  this.bodyId = context.route.options.bodyId;
39
39
  this.scrollToId = context.request.hash;
40
+
40
41
  }
41
42
 
42
43
  public async preRender( data?: TObjetDonnees ) {
@@ -124,7 +124,8 @@ export default class SchemaValidators {
124
124
  const checkChoice = ( choice: any ) => {
125
125
 
126
126
  // Choice object = extract value
127
- if (typeof choice === 'object' && ('value' in choice) && typeof choice.value !== 'object')
127
+ // We check for choice objec via the label prop, as the value can be undefined (and so, not transmitted)
128
+ if (typeof choice === 'object' && ('label' in choice) && typeof choice.label === 'string' && typeof choice.value !== 'object')
128
129
  choice = choice.value;
129
130
 
130
131
  // If choices list rpovided, check if the choice is in the choices list
@@ -88,13 +88,8 @@ export default class ConfigParser {
88
88
  // We assume that when we run 5htp dev, we're in local
89
89
  // Otherwise, we're in production environment (docker)
90
90
  console.log("[app] Using environment:", process.env.NODE_ENV);
91
- return process.env.NODE_ENV === 'development' ? {
92
- name: 'local',
93
- profile: 'dev'
94
- } : {
95
- name: 'server',
96
- profile: 'prod',
97
- }
91
+ const envFileName = this.appDir + '/env.yaml';
92
+ return this.loadYaml( envFileName );
98
93
  }
99
94
 
100
95
  public identity() {
@@ -14,7 +14,7 @@ import express from 'express';
14
14
  import { Application } from '@server/app';
15
15
  import type ServerRouter from '@server/services/router';
16
16
  import ServerRequest from '@server/services/router/request';
17
- import { TRoute, TAnyRoute } from '@common/router';
17
+ import { TRoute, TAnyRoute, TDomainsList } from '@common/router';
18
18
  import { NotFound, Forbidden, Anomaly } from '@common/errors';
19
19
  import BaseResponse, { TResponseData } from '@common/router/response';
20
20
  import Page from './page';
@@ -31,7 +31,8 @@ const debug = true;
31
31
  export type TBasicSSrData = {
32
32
  request: { data: TObjetDonnees, id: string },
33
33
  page: { chunkId: string, data?: TObjetDonnees },
34
- user: User | null
34
+ user: User | null,
35
+ domains: TDomainsList
35
36
  }
36
37
 
37
38
  export type TRouterContext<TRouter extends ServerRouter = ServerRouter> = (
@@ -176,6 +177,7 @@ export default class ServerResponse<
176
177
  chunkId: page.chunkId,
177
178
  data: page.data
178
179
  },
180
+ domains: this.router.config.domains,
179
181
  ...customSsrData
180
182
  }
181
183
  }
@@ -83,7 +83,7 @@ export default class DocumentRenderer<TRouter extends Router> {
83
83
  <meta content={page.description} name="description" />
84
84
  <link rel="canonical" href={fullUrl} />
85
85
 
86
- {this.metas()}
86
+ {this.metas( page )}
87
87
 
88
88
  {this.styles( page )}
89
89
 
@@ -100,7 +100,7 @@ export default class DocumentRenderer<TRouter extends Router> {
100
100
  )
101
101
  }
102
102
 
103
- private metas() {
103
+ private metas( page: Page ) {
104
104
  return <>
105
105
  {/* Réseaux sociaux */}
106
106
  {/*page.metas.metasAdditionnelles && Object.entries(page.metas.metasAdditionnelles).map(
@@ -130,6 +130,10 @@ export default class DocumentRenderer<TRouter extends Router> {
130
130
  <link rel="icon" type="image/png" sizes="32x32" href="/public/app/favicon-32x32.png" />
131
131
  <link rel="apple-touch-icon" sizes="180x180" href="/public/app/apple-touch-icon-180x180.png" />
132
132
  <meta name="msapplication-config" content="/public/app/browserconfig.xml" />
133
+
134
+ {page.metas?.map(({ $, ...attrs }) => (
135
+ React.createElement($, attrs)
136
+ ))}
133
137
  </>
134
138
  }
135
139
 
@@ -27,12 +27,16 @@ const seoLimits = {
27
27
  description: 255
28
28
  }
29
29
 
30
+ type TMetasList = ({ $: string } & { [key: string]: string })[]
31
+
30
32
  /*----------------------------------
31
33
  - FONCTION
32
34
  ----------------------------------*/
33
35
 
34
36
  export default class Page<TRouter extends Router = Router> extends PageResponse<TRouter> {
35
37
 
38
+ public metas: TMetasList = [];
39
+
36
40
  public constructor(
37
41
  public route: TRoute | TErrorRoute,
38
42
  public renderer: TFrontRenderer,