Merge pull request #7543 from tchak/fix-js-in-preview
fix(preview): gon should not crash on preview pages
This commit is contained in:
commit
08611753d5
10 changed files with 113 additions and 40 deletions
|
@ -307,9 +307,9 @@ class ApplicationController < ActionController::Base
|
||||||
DS_SIGN_IN_COUNT: current_user&.sign_in_count,
|
DS_SIGN_IN_COUNT: current_user&.sign_in_count,
|
||||||
DS_CREATED_AT: current_administrateur&.created_at,
|
DS_CREATED_AT: current_administrateur&.created_at,
|
||||||
DS_ID: current_administrateur&.id,
|
DS_ID: current_administrateur&.id,
|
||||||
DS_NB_DEMARCHES_BROUILLONS: nb_demarches_by_state['brouillon'],
|
DS_NB_DEMARCHES_BROUILLONS: nb_demarches_by_state['brouillon'] || 0,
|
||||||
DS_NB_DEMARCHES_ACTIVES: nb_demarches_by_state['publiee'],
|
DS_NB_DEMARCHES_ACTIVES: nb_demarches_by_state['publiee'] || 0,
|
||||||
DS_NB_DEMARCHES_ARCHIVES: nb_demarches_by_state['close']
|
DS_NB_DEMARCHES_ARCHIVES: nb_demarches_by_state['close'] || 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
import { QueryClient, QueryFunction } from 'react-query';
|
import { QueryClient, QueryFunction } from 'react-query';
|
||||||
import { httpRequest, isNumeric } from '@utils';
|
import { httpRequest, isNumeric, getConfig } from '@utils';
|
||||||
import { matchSorter } from 'match-sorter';
|
import { matchSorter } from 'match-sorter';
|
||||||
|
|
||||||
type Gon = {
|
|
||||||
gon: {
|
|
||||||
autocomplete?: {
|
|
||||||
api_geo_url?: string;
|
|
||||||
api_adresse_url?: string;
|
|
||||||
api_education_url?: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
declare const window: Window & typeof globalThis & Gon;
|
|
||||||
|
|
||||||
const API_EDUCATION_QUERY_LIMIT = 5;
|
const API_EDUCATION_QUERY_LIMIT = 5;
|
||||||
const API_GEO_QUERY_LIMIT = 5;
|
const API_GEO_QUERY_LIMIT = 5;
|
||||||
const API_ADRESSE_QUERY_LIMIT = 5;
|
const API_ADRESSE_QUERY_LIMIT = 5;
|
||||||
|
@ -26,8 +15,9 @@ const API_ADRESSE_QUERY_LIMIT = 5;
|
||||||
// NB: 60 is arbitrary, we may add more if needed.
|
// NB: 60 is arbitrary, we may add more if needed.
|
||||||
const API_GEO_COMMUNES_QUERY_LIMIT = 60;
|
const API_GEO_COMMUNES_QUERY_LIMIT = 60;
|
||||||
|
|
||||||
const { api_geo_url, api_adresse_url, api_education_url } =
|
const {
|
||||||
window.gon.autocomplete || {};
|
autocomplete: { api_geo_url, api_adresse_url, api_education_url }
|
||||||
|
} = getConfig();
|
||||||
|
|
||||||
type QueryKey = readonly [
|
type QueryKey = readonly [
|
||||||
scope: string,
|
scope: string,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { httpRequest, ResponseError } from '@utils';
|
import { httpRequest, ResponseError, getConfig } from '@utils';
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import { ApplicationController } from './application_controller';
|
import { ApplicationController } from './application_controller';
|
||||||
import { AutoUpload } from '../shared/activestorage/auto-upload';
|
import { AutoUpload } from '../shared/activestorage/auto-upload';
|
||||||
|
@ -9,10 +8,9 @@ import {
|
||||||
ERROR_CODE_READ
|
ERROR_CODE_READ
|
||||||
} from '../shared/activestorage/file-upload-error';
|
} from '../shared/activestorage/file-upload-error';
|
||||||
|
|
||||||
const Gon = z.object({ autosave: z.object({ debounce_delay: z.number() }) });
|
const {
|
||||||
|
autosave: { debounce_delay }
|
||||||
declare const window: Window & typeof globalThis & { gon: unknown };
|
} = getConfig();
|
||||||
const { debounce_delay } = Gon.parse(window.gon).autosave;
|
|
||||||
|
|
||||||
const AUTOSAVE_DEBOUNCE_DELAY = debounce_delay;
|
const AUTOSAVE_DEBOUNCE_DELAY = debounce_delay;
|
||||||
const AUTOSAVE_TIMEOUT_DELAY = 60000;
|
const AUTOSAVE_TIMEOUT_DELAY = 60000;
|
||||||
|
|
|
@ -4,19 +4,15 @@ import {
|
||||||
hasClass,
|
hasClass,
|
||||||
addClass,
|
addClass,
|
||||||
removeClass,
|
removeClass,
|
||||||
ResponseError
|
ResponseError,
|
||||||
|
getConfig
|
||||||
} from '@utils';
|
} from '@utils';
|
||||||
import { z } from 'zod';
|
|
||||||
|
|
||||||
import { ApplicationController } from './application_controller';
|
import { ApplicationController } from './application_controller';
|
||||||
|
|
||||||
const Gon = z.object({
|
const {
|
||||||
autosave: z.object({ status_visible_duration: z.number() })
|
autosave: { status_visible_duration }
|
||||||
});
|
} = getConfig();
|
||||||
|
|
||||||
declare const window: Window & typeof globalThis & { gon: unknown };
|
|
||||||
const { status_visible_duration } = Gon.parse(window.gon).autosave;
|
|
||||||
|
|
||||||
const AUTOSAVE_STATUS_VISIBLE_DURATION = status_visible_duration;
|
const AUTOSAVE_STATUS_VISIBLE_DURATION = status_visible_duration;
|
||||||
|
|
||||||
// This is a controller we attach to the status area in the main form. It
|
// This is a controller we attach to the status area in the main form. It
|
||||||
|
|
|
@ -1,4 +1,16 @@
|
||||||
const { key, enabled, administrateur } = gon.crisp || {};
|
import { getConfig } from '@utils';
|
||||||
|
const {
|
||||||
|
crisp: { key, enabled, administrateur }
|
||||||
|
} = getConfig();
|
||||||
|
|
||||||
|
declare const window: Window &
|
||||||
|
typeof globalThis & {
|
||||||
|
CRISP_WEBSITE_ID?: string | null;
|
||||||
|
$crisp: (
|
||||||
|
| [cmd: string, key: string, value: unknown]
|
||||||
|
| [key: string, value: unknown]
|
||||||
|
)[];
|
||||||
|
};
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
window.$crisp = [];
|
window.$crisp = [];
|
||||||
|
@ -10,7 +22,7 @@ if (enabled) {
|
||||||
script.id = 'crisp-js';
|
script.id = 'crisp-js';
|
||||||
script.async = true;
|
script.async = true;
|
||||||
script.src = 'https://client.crisp.chat/l.js';
|
script.src = 'https://client.crisp.chat/l.js';
|
||||||
firstScript.parentNode.insertBefore(script, firstScript);
|
firstScript.parentNode?.insertBefore(script, firstScript);
|
||||||
|
|
||||||
window.$crisp.push(['set', 'user:email', [administrateur.email]]);
|
window.$crisp.push(['set', 'user:email', [administrateur.email]]);
|
||||||
window.$crisp.push(['set', 'session:segments', [['administrateur']]]);
|
window.$crisp.push(['set', 'session:segments', [['administrateur']]]);
|
|
@ -1,4 +1,11 @@
|
||||||
const { cookieDomain, domain, enabled, host, key } = gon.matomo || {};
|
import { getConfig } from '@utils';
|
||||||
|
|
||||||
|
const {
|
||||||
|
matomo: { cookieDomain, domain, enabled, host, key }
|
||||||
|
} = getConfig();
|
||||||
|
|
||||||
|
declare const window: Window &
|
||||||
|
typeof globalThis & { _paq: [key: string, value: unknown] };
|
||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
window._paq = window._paq || [];
|
window._paq = window._paq || [];
|
||||||
|
@ -30,5 +37,5 @@ if (enabled) {
|
||||||
script.id = 'matomo-js';
|
script.id = 'matomo-js';
|
||||||
script.async = true;
|
script.async = true;
|
||||||
script.src = jsUrl;
|
script.src = jsUrl;
|
||||||
firstScript.parentNode.insertBefore(script, firstScript);
|
firstScript.parentNode?.insertBefore(script, firstScript);
|
||||||
}
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
import * as Sentry from '@sentry/browser';
|
import * as Sentry from '@sentry/browser';
|
||||||
|
import { getConfig } from '@utils';
|
||||||
|
|
||||||
const { key, enabled, user, environment, browser } = gon.sentry || {};
|
const {
|
||||||
|
sentry: { key, enabled, user, environment, browser }
|
||||||
|
} = getConfig();
|
||||||
|
|
||||||
// We need to check for key presence here as we do not have a dsn for browser yet
|
// We need to check for key presence here as we do not have a dsn for browser yet
|
||||||
if (enabled && key) {
|
if (enabled && key) {
|
||||||
|
@ -22,7 +25,7 @@ if (enabled && key) {
|
||||||
|
|
||||||
// Register a way to explicitely capture messages from a different bundle.
|
// Register a way to explicitely capture messages from a different bundle.
|
||||||
addEventListener('sentry:capture-exception', (event) => {
|
addEventListener('sentry:capture-exception', (event) => {
|
||||||
const error = event.detail;
|
const error = (event as CustomEvent).detail;
|
||||||
Sentry.captureException(error);
|
Sentry.captureException(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
|
@ -1,10 +1,75 @@
|
||||||
import Rails from '@rails/ujs';
|
import Rails from '@rails/ujs';
|
||||||
import debounce from 'debounce';
|
import debounce from 'debounce';
|
||||||
import { session } from '@hotwired/turbo';
|
import { session } from '@hotwired/turbo';
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
export { debounce };
|
export { debounce };
|
||||||
export const { fire, csrfToken, cspNonce } = Rails;
|
export const { fire, csrfToken, cspNonce } = Rails;
|
||||||
|
|
||||||
|
const Gon = z
|
||||||
|
.object({
|
||||||
|
autosave: z
|
||||||
|
.object({
|
||||||
|
debounce_delay: z.number().default(0),
|
||||||
|
status_visible_duration: z.number().default(0)
|
||||||
|
})
|
||||||
|
.default({}),
|
||||||
|
autocomplete: z
|
||||||
|
.object({
|
||||||
|
api_geo_url: z.string().optional(),
|
||||||
|
api_adresse_url: z.string().optional(),
|
||||||
|
api_education_url: z.string().optional()
|
||||||
|
})
|
||||||
|
.default({}),
|
||||||
|
matomo: z
|
||||||
|
.object({
|
||||||
|
cookieDomain: z.string().optional(),
|
||||||
|
domain: z.string().optional(),
|
||||||
|
enabled: z.boolean().default(false),
|
||||||
|
host: z.string().optional(),
|
||||||
|
key: z.string().nullish()
|
||||||
|
})
|
||||||
|
.default({}),
|
||||||
|
sentry: z
|
||||||
|
.object({
|
||||||
|
key: z.string().nullish(),
|
||||||
|
enabled: z.boolean().default(false),
|
||||||
|
environment: z.string().optional(),
|
||||||
|
user: z.object({ id: z.string() }).default({ id: '' }),
|
||||||
|
browser: z.object({ modern: z.boolean() }).default({ modern: false })
|
||||||
|
})
|
||||||
|
.default({}),
|
||||||
|
crisp: z
|
||||||
|
.object({
|
||||||
|
key: z.string().nullish(),
|
||||||
|
enabled: z.boolean().default(false),
|
||||||
|
administrateur: z
|
||||||
|
.object({
|
||||||
|
email: z.string(),
|
||||||
|
DS_SIGN_IN_COUNT: z.number(),
|
||||||
|
DS_NB_DEMARCHES_BROUILLONS: z.number(),
|
||||||
|
DS_NB_DEMARCHES_ACTIVES: z.number(),
|
||||||
|
DS_NB_DEMARCHES_ARCHIVES: z.number(),
|
||||||
|
DS_ID: z.number()
|
||||||
|
})
|
||||||
|
.default({
|
||||||
|
email: '',
|
||||||
|
DS_SIGN_IN_COUNT: 0,
|
||||||
|
DS_NB_DEMARCHES_BROUILLONS: 0,
|
||||||
|
DS_NB_DEMARCHES_ACTIVES: 0,
|
||||||
|
DS_NB_DEMARCHES_ARCHIVES: 0,
|
||||||
|
DS_ID: 0
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.default({})
|
||||||
|
})
|
||||||
|
.default({});
|
||||||
|
declare const window: Window & typeof globalThis & { gon: unknown };
|
||||||
|
|
||||||
|
export function getConfig() {
|
||||||
|
return Gon.parse(window.gon);
|
||||||
|
}
|
||||||
|
|
||||||
export function show(el: HTMLElement | null) {
|
export function show(el: HTMLElement | null) {
|
||||||
el?.classList.remove('hidden');
|
el?.classList.remove('hidden');
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
= favicon_link_tag(image_url("#{FAVICON_32PX_SRC}"), type: "image/png", sizes: "32x32")
|
= favicon_link_tag(image_url("#{FAVICON_32PX_SRC}"), type: "image/png", sizes: "32x32")
|
||||||
= favicon_link_tag(image_url("#{FAVICON_96PX_SRC}"), type: "image/png", sizes: "96x96")
|
= favicon_link_tag(image_url("#{FAVICON_96PX_SRC}"), type: "image/png", sizes: "96x96")
|
||||||
|
|
||||||
|
= Gon::Base.render_data(camel_case: true, init: true, nonce: request.content_security_policy_nonce)
|
||||||
|
|
||||||
= vite_client_tag
|
= vite_client_tag
|
||||||
= vite_react_refresh_tag
|
= vite_react_refresh_tag
|
||||||
= vite_javascript_tag 'application'
|
= vite_javascript_tag 'application'
|
||||||
|
@ -31,8 +33,6 @@
|
||||||
|
|
||||||
= stylesheet_link_tag 'application', media: 'all'
|
= stylesheet_link_tag 'application', media: 'all'
|
||||||
|
|
||||||
= Gon::Base.render_data(camel_case: true, init: true, nonce: request.content_security_policy_nonce)
|
|
||||||
|
|
||||||
%body{ id: content_for(:page_id), class: browser.platform.ios? ? 'ios' : nil }
|
%body{ id: content_for(:page_id), class: browser.platform.ios? ? 'ios' : nil }
|
||||||
.page-wrapper
|
.page-wrapper
|
||||||
= render partial: "layouts/outdated_browser_banner"
|
= render partial: "layouts/outdated_browser_banner"
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
= favicon_link_tag(image_url("#{FAVICON_32PX_SRC}"), type: "image/png", sizes: "32x32")
|
= favicon_link_tag(image_url("#{FAVICON_32PX_SRC}"), type: "image/png", sizes: "32x32")
|
||||||
= favicon_link_tag(image_url("#{FAVICON_96PX_SRC}"), type: "image/png", sizes: "96x96")
|
= favicon_link_tag(image_url("#{FAVICON_96PX_SRC}"), type: "image/png", sizes: "96x96")
|
||||||
|
|
||||||
|
= vite_client_tag
|
||||||
|
= vite_react_refresh_tag
|
||||||
= vite_javascript_tag 'application'
|
= vite_javascript_tag 'application'
|
||||||
|
|
||||||
= preload_link_tag(asset_url("Muli-Regular.woff2"))
|
= preload_link_tag(asset_url("Muli-Regular.woff2"))
|
||||||
|
|
Loading…
Add table
Reference in a new issue