feat(planning): grille hebdomadaire complète avec API et filtres

- Connexion API via proxy Angular (résolution CORS, base path /api)
- Import CSS ng-zorro global pour les modales et composants
- Filtres Camion/Show câblés sur l'affichage de la grille
- Camions affichés via TrucksService (linkés au show du même créneau)
- Panneau de détails : spectacles + camions du jour sélectionné
- Modale de création de spectacle stylisée avec fond et centrage
- Positionnement précis des events à la minute dans leur créneau
- Auto-scroll vers l'heure courante au chargement
- Ligne "maintenant" sur la colonne du jour actuel
- Régénération des services OpenAPI (nouveaux noms de types)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 20:36:03 +02:00
parent 150b97cd2e
commit 654b297e2e
3131 changed files with 149304 additions and 104334 deletions
+1
View File
@@ -49,6 +49,7 @@ declare namespace AtRule {
raws?: AtRuleRaws
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { AtRule_ as default }
}
+1
View File
@@ -26,6 +26,7 @@ declare namespace Comment {
text: string
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Comment_ as default }
}
+6 -1
View File
@@ -8,7 +8,11 @@ import Rule from './rule.js'
declare namespace Container {
export type ContainerWithChildren<Child extends Node = ChildNode> = {
nodes: Child[]
} & (AtRule | Root | Rule)
} & (
| AtRule
| Root
| Rule
)
export interface ValueOptions {
/**
@@ -39,6 +43,7 @@ declare namespace Container {
| string
| undefined
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Container_ as default }
}
+1
View File
@@ -16,6 +16,7 @@ declare namespace CssSyntaxError {
line: number
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { CssSyntaxError_ as default }
}
+1
View File
@@ -39,6 +39,7 @@ declare namespace Declaration {
value: string
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Declaration_ as default }
}
+1
View File
@@ -16,6 +16,7 @@ declare namespace Document {
raws?: Record<string, any>
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Document_ as default }
}
+1 -1
View File
@@ -4,6 +4,6 @@ interface FromJSON extends JSONHydrator {
default: FromJSON
}
declare let fromJSON: FromJSON
declare const fromJSON: FromJSON
export = fromJSON
+1
View File
@@ -49,6 +49,7 @@ declare namespace Input {
url: string
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Input_ as default }
}
+1 -9
View File
@@ -142,15 +142,7 @@ class Input {
)
}
result.input = {
column,
endColumn,
endLine,
endOffset,
line,
offset,
source: this.css
}
result.input = { column, endColumn, endLine, endOffset, line, offset, source: this.css }
if (this.file) {
if (pathToFileURL) {
result.input.url = pathToFileURL(this.file).toString()
+4 -3
View File
@@ -6,6 +6,7 @@ import Root from './root.js'
import Warning from './warning.js'
declare namespace LazyResult {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { LazyResult_ as default }
}
@@ -18,9 +19,9 @@ declare namespace LazyResult {
* const lazy = postcss([autoprefixer]).process(css)
* ```
*/
declare class LazyResult_<RootNode = Document | Root> implements PromiseLike<
Result<RootNode>
> {
declare class LazyResult_<RootNode = Document | Root>
implements PromiseLike<Result<RootNode>>
{
/**
* Processes input CSS through synchronous and asynchronous plugins
* and calls onRejected for each error thrown in any plugin.
-13
View File
@@ -378,19 +378,6 @@ class LazyResult {
if (opts.stringifier) str = opts.stringifier
if (str.stringify) str = str.stringify
let rootSource = this.result.root.source
if (
opts.map === undefined &&
!(rootSource && rootSource.input && rootSource.input.map)
) {
let result = ''
str(this.result.root, i => {
result += i
})
this.result.css = result
return this.result
}
let map = new MapGenerator(str, this.result.root, this.result.opts)
let data = map.generate()
this.result.css = data[0]
+1 -1
View File
@@ -55,6 +55,6 @@ declare namespace list {
}
}
declare let list: list.List
declare const list: list.List
export = list
+1 -9
View File
@@ -75,15 +75,7 @@ class MapGenerator {
}
}
} else if (this.css) {
let startIndex
while ((startIndex = this.css.lastIndexOf('/*#')) !== -1) {
let endIndex = this.css.indexOf('*/', startIndex + 3)
if (endIndex === -1) break
while (startIndex > 0 && this.css[startIndex - 1] === '\n') {
startIndex--
}
this.css = this.css.slice(0, startIndex) + this.css.slice(endIndex + 2)
}
this.css = this.css.replace(/\n*\/\*#[\S\s]*?\*\/$/gm, '')
}
}
+1
View File
@@ -6,6 +6,7 @@ import Root from './root.js'
import Warning from './warning.js'
declare namespace NoWorkResult {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { NoWorkResult_ as default }
}
+4 -3
View File
@@ -2,7 +2,7 @@
let MapGenerator = require('./map-generator')
let parse = require('./parse')
let Result = require('./result')
const Result = require('./result')
let stringify = require('./stringify')
let warnOnce = require('./warn-once')
@@ -65,9 +65,10 @@ class NoWorkResult {
this._css = css
this._opts = opts
this._map = undefined
let root
let str = stringify
this.result = new Result(this._processor, undefined, this._opts)
this.result = new Result(this._processor, root, this._opts)
this.result.css = css
let self = this
@@ -77,7 +78,7 @@ class NoWorkResult {
}
})
let map = new MapGenerator(str, undefined, this._opts, css)
let map = new MapGenerator(str, root, this._opts, css)
if (map.isMap()) {
let [generatedCSS, generatedMap] = map.generate()
if (generatedCSS) {
+1
View File
@@ -126,6 +126,7 @@ declare namespace Node {
word?: string
}
// eslint-disable-next-line @typescript-eslint/no-shadow
class Node extends Node_ {}
export { Node as default }
}
+1 -1
View File
@@ -4,6 +4,6 @@ interface Parse extends Parser {
default: Parse
}
declare let parse: Parse
declare const parse: Parse
export = parse
+30 -37
View File
@@ -20,12 +20,6 @@ function findLastWithPosition(tokens) {
}
}
function tokensToString(tokens, from, to) {
let result = ''
for (let i = from; i < to; i++) result += tokens[i][1]
return result
}
class Parser {
constructor(input) {
this.input = input
@@ -138,10 +132,9 @@ class Parser {
if (founded === 2) break
}
}
// If the token is a word, e.g. `!important`, `red` or any other valid
// property's value. Then we need to return the colon after that word
// token. [3] is the "end" colon of that word. And because we need it
// after that one we do +1 to get the next one.
// If the token is a word, e.g. `!important`, `red` or any other valid property's value.
// Then we need to return the colon after that word token. [3] is the "end" colon of that word.
// And because we need it after that one we do +1 to get the next one.
throw this.input.error(
'Missed semicolon',
token[0] === 'word' ? token[3] + 1 : token[2]
@@ -183,7 +176,7 @@ class Parser {
node.source.end.offset++
let text = token[1].slice(2, -2)
if (!text.trim()) {
if (/^\s*$/.test(text)) {
node.text = ''
node.raws.left = text
node.raws.right = ''
@@ -214,50 +207,50 @@ class Parser {
)
node.source.end.offset++
let start = 0
while (tokens[start][0] !== 'word') {
if (start === tokens.length - 1) this.unknownWord([tokens[start]])
start++
while (tokens[0][0] !== 'word') {
if (tokens.length === 1) this.unknownWord(tokens)
node.raws.before += tokens.shift()[1]
}
node.raws.before += tokensToString(tokens, 0, start)
node.source.start = this.getPosition(tokens[start][2])
node.source.start = this.getPosition(tokens[0][2])
let propStart = start
while (start < tokens.length) {
let type = tokens[start][0]
node.prop = ''
while (tokens.length) {
let type = tokens[0][0]
if (type === ':' || type === 'space' || type === 'comment') {
break
}
start++
node.prop += tokens.shift()[1]
}
node.prop = tokensToString(tokens, propStart, start)
let betweenStart = start
node.raws.between = ''
let token
while (start < tokens.length) {
token = tokens[start]
start++
if (token[0] === ':') break
if (token[0] === 'word' && /\w/.test(token[1])) {
this.unknownWord([token])
while (tokens.length) {
token = tokens.shift()
if (token[0] === ':') {
node.raws.between += token[1]
break
} else {
if (token[0] === 'word' && /\w/.test(token[1])) {
this.unknownWord([token])
}
node.raws.between += token[1]
}
}
node.raws.between = tokensToString(tokens, betweenStart, start)
if (node.prop[0] === '_' || node.prop[0] === '*') {
node.raws.before += node.prop[0]
node.prop = node.prop.slice(1)
}
let firstSpacesStart = start
while (start < tokens.length) {
let next = tokens[start][0]
let firstSpaces = []
let next
while (tokens.length) {
next = tokens[0][0]
if (next !== 'space' && next !== 'comment') break
start++
firstSpaces.push(tokens.shift())
}
let firstSpaces = tokens.slice(firstSpacesStart, start)
tokens = tokens.slice(start)
this.precheckMissedSemicolon(tokens)
+3
View File
@@ -1,6 +1,7 @@
export {
// Type-only exports
AcceptedPlugin,
AnyNode,
atRule,
AtRule,
@@ -26,6 +27,7 @@ export {
fromJSON,
Helpers,
Input,
JSONHydrator,
// This is a class, but its not re-exported. Thats why its exported as type-only here.
type LazyResult,
@@ -62,5 +64,6 @@ export {
TransformCallback,
Transformer,
Warning,
WarningOptions
} from './postcss.js'
+3 -6
View File
@@ -351,11 +351,6 @@ declare namespace postcss {
* to generate correct source maps.
*/
to?: string
/**
* Disable source map file protections.
*/
unsafeMap?: boolean
}
export type Postcss = typeof postcss
@@ -455,7 +450,9 @@ declare namespace postcss {
* @param plugins PostCSS plugins.
* @return Processor to process multiple CSS.
*/
declare function postcss(plugins?: readonly postcss.AcceptedPlugin[]): Processor
declare function postcss(
plugins?: readonly postcss.AcceptedPlugin[]
): Processor
declare function postcss(...plugins: postcss.AcceptedPlugin[]): Processor
export = postcss
+1
View File
@@ -3,6 +3,7 @@ import { SourceMapConsumer } from 'source-map-js'
import { ProcessOptions } from './postcss.js'
declare namespace PreviousMap {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { PreviousMap_ as default }
}
+5 -22
View File
@@ -16,7 +16,6 @@ function fromBase64(str) {
class PreviousMap {
constructor(css, opts) {
if (opts.map === false) return
if (opts.unsafeMap) this.unsafeMap = true
this.loadAnnotation(css)
this.inline = this.startWith(this.annotation, 'data:')
@@ -31,7 +30,7 @@ class PreviousMap {
consumer() {
if (!this.consumerCache) {
this.consumerCache = new SourceMapConsumer(this.json || this.text)
this.consumerCache = new SourceMapConsumer(this.text)
}
return this.consumerCache
}
@@ -52,8 +51,7 @@ class PreviousMap {
return fromBase64(text.substr(baseUriMatch[0].length))
}
let encoding = text.slice('data:application/json;'.length)
encoding = encoding.slice(0, encoding.indexOf(','))
let encoding = text.match(/data:application\/json;([^,]+),/)[1]
throw new Error('Unsupported source map encoding ' + encoding)
}
@@ -84,13 +82,7 @@ class PreviousMap {
}
}
loadFile(path, cssFile, trusted) {
/* c8 ignore next 5 */
if (!trusted && !this.unsafeMap) {
if (!/\.map$/i.test(path)) {
return undefined
}
}
loadFile(path) {
this.root = dirname(path)
if (existsSync(path)) {
this.mapFile = path
@@ -107,7 +99,7 @@ class PreviousMap {
} else if (typeof prev === 'function') {
let prevPath = prev(file)
if (prevPath) {
let map = this.loadFile(prevPath, file, true)
let map = this.loadFile(prevPath)
if (!map) {
throw new Error(
'Unable to load previous source map: ' + prevPath.toString()
@@ -131,16 +123,7 @@ class PreviousMap {
} else if (this.annotation) {
let map = this.annotation
if (file) map = join(dirname(file), map)
let unknown = this.loadFile(map, file, false)
if (unknown) {
try {
/* c8 ignore next 4 */
this.json = JSON.parse(unknown.replace(/^\)]}'[^\n]*\n/, ''))
} catch {
return undefined
}
}
return unknown
return this.loadFile(map)
}
}
+1
View File
@@ -12,6 +12,7 @@ import Result from './result.js'
import Root from './root.js'
declare namespace Processor {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Processor_ as default }
}
+1 -1
View File
@@ -7,7 +7,7 @@ let Root = require('./root')
class Processor {
constructor(plugins = []) {
this.version = '8.5.15'
this.version = '8.5.6'
this.plugins = this.normalize(plugins)
}
+1
View File
@@ -39,6 +39,7 @@ declare namespace Result {
plugin?: string
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Result_ as default }
}
+1
View File
@@ -40,6 +40,7 @@ declare namespace Root {
raws?: RootRaws
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Root_ as default }
}
+12 -12
View File
@@ -44,19 +44,19 @@ declare namespace Rule {
/** Information used to generate byte-to-byte equal node string as it was in the origin input. */
raws?: RuleRaws
} & (
| {
/** Selector or selectors of the rule. */
selector: string
selectors?: never
}
| {
selector?: never
/** Selectors of the rule represented as an array of strings. */
selectors: readonly string[]
}
) &
ContainerProps
| {
/** Selector or selectors of the rule. */
selector: string
selectors?: never
}
| {
selector?: never
/** Selectors of the rule represented as an array of strings. */
selectors: readonly string[]
}
) & ContainerProps
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Rule_ as default }
}
+1
View File
@@ -11,6 +11,7 @@ import {
} from './postcss.js'
declare namespace Stringifier {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Stringifier_ as default }
}
+20 -41
View File
@@ -1,17 +1,5 @@
'use strict'
// Escapes sequences that could break out of an HTML <style> context.
// Uses CSS unicode escaping (\3c = '<') which is valid CSS and parsed
// correctly by all compliant CSS consumers.
const STYLE_TAG = /(<)(\/?style\b)/gi
const COMMENT_OPEN = /(<)(!--)/g
function escapeHTMLInCSS(str) {
if (typeof str !== 'string') return str
if (!str.includes('<')) return str
return str.replace(STYLE_TAG, '\\3c $2').replace(COMMENT_OPEN, '\\3c $2')
}
const DEFAULT_RAW = {
after: '\n',
beforeClose: '\n',
@@ -37,12 +25,11 @@ class Stringifier {
}
atrule(node, semicolon) {
let raws = node.raws
let name = '@' + node.name
let params = node.params ? this.rawValue(node, 'params') : ''
if (typeof raws.afterName !== 'undefined') {
name += raws.afterName
if (typeof node.raws.afterName !== 'undefined') {
name += node.raws.afterName
} else if (params) {
name += ' '
}
@@ -50,8 +37,8 @@ class Stringifier {
if (node.nodes) {
this.block(node, name + params)
} else {
let end = (raws.between || '') + (semicolon ? ';' : '')
this.builder(escapeHTMLInCSS(name + params + end), node)
let end = (node.raws.between || '') + (semicolon ? ';' : '')
this.builder(name + params + end, node)
}
}
@@ -86,7 +73,7 @@ class Stringifier {
block(node, start) {
let between = this.raw(node, 'between', 'beforeOpen')
this.builder(escapeHTMLInCSS(start + between) + '{', node, 'start')
this.builder(start + between + '{', node, 'start')
let after
if (node.nodes && node.nodes.length) {
@@ -96,24 +83,22 @@ class Stringifier {
after = this.raw(node, 'after', 'emptyBody')
}
if (after) this.builder(escapeHTMLInCSS(after))
if (after) this.builder(after)
this.builder('}', node, 'end')
}
body(node) {
let nodes = node.nodes
let last = nodes.length - 1
let last = node.nodes.length - 1
while (last > 0) {
if (nodes[last].type !== 'comment') break
if (node.nodes[last].type !== 'comment') break
last -= 1
}
let semicolon = this.raw(node, 'semicolon')
let isDocument = node.type === 'document'
for (let i = 0; i < nodes.length; i++) {
let child = nodes[i]
for (let i = 0; i < node.nodes.length; i++) {
let child = node.nodes[i]
let before = this.raw(child, 'before')
if (before) this.builder(isDocument ? before : escapeHTMLInCSS(before))
if (before) this.builder(before)
this.stringify(child, last !== i || semicolon)
}
}
@@ -121,21 +106,19 @@ class Stringifier {
comment(node) {
let left = this.raw(node, 'left', 'commentLeft')
let right = this.raw(node, 'right', 'commentRight')
this.builder(escapeHTMLInCSS('/*' + left + node.text + right + '*/'), node)
this.builder('/*' + left + node.text + right + '*/', node)
}
decl(node, semicolon) {
let raws = node.raws
let between = this.raw(node, 'between', 'colon')
let string = node.prop + between + this.rawValue(node, 'value')
if (node.important) {
string += raws.important || ' !important'
string += node.raws.important || ' !important'
}
if (semicolon) string += ';'
this.builder(escapeHTMLInCSS(string), node)
this.builder(string, node)
}
document(node) {
@@ -171,9 +154,9 @@ class Stringifier {
// Detect style by other nodes
let root = node.root()
let cache = root.rawCache || (root.rawCache = {})
if (typeof cache[detect] !== 'undefined') {
return cache[detect]
if (!root.rawCache) root.rawCache = {}
if (typeof root.rawCache[detect] !== 'undefined') {
return root.rawCache[detect]
}
if (detect === 'before' || detect === 'after') {
@@ -192,7 +175,7 @@ class Stringifier {
if (typeof value === 'undefined') value = DEFAULT_RAW[detect]
cache[detect] = value
root.rawCache[detect] = value
return value
}
@@ -341,17 +324,13 @@ class Stringifier {
root(node) {
this.body(node)
if (node.raws.after) {
let after = node.raws.after
let isDocument = node.parent && node.parent.type === 'document'
this.builder(isDocument ? after : escapeHTMLInCSS(after))
}
if (node.raws.after) this.builder(node.raws.after)
}
rule(node) {
this.block(node, this.rawValue(node, 'selector'))
if (node.raws.ownSemicolon) {
this.builder(escapeHTMLInCSS(node.raws.ownSemicolon), node, 'end')
this.builder(node.raws.ownSemicolon, node, 'end')
}
}
+1 -1
View File
@@ -4,6 +4,6 @@ interface Stringify extends Stringifier {
default: Stringify
}
declare let stringify: Stringify
declare const stringify: Stringify
export = stringify
-4
View File
@@ -36,7 +36,6 @@ module.exports = function tokenizer(input, options = {}) {
let pos = 0
let buffer = []
let returned = []
let lastBadParen = -1
function position() {
return pos
@@ -128,14 +127,11 @@ module.exports = function tokenizer(input, options = {}) {
currentToken = ['brackets', css.slice(pos, next + 1), pos, next]
pos = next
} else if (pos <= lastBadParen) {
currentToken = ['(', '(', pos]
} else {
next = css.indexOf(')', pos + 1)
content = css.slice(pos, next + 1)
if (next === -1 || RE_BAD_BRACKET.test(content)) {
lastBadParen = next === -1 ? length : next
currentToken = ['(', '(', pos]
} else {
currentToken = ['brackets', content, pos, next]
+1
View File
@@ -40,6 +40,7 @@ declare namespace Warning {
word?: string
}
// eslint-disable-next-line @typescript-eslint/no-use-before-define
export { Warning_ as default }
}