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
+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)