-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #946 from ae-utbm/product-csv
Rework the product admin page
- Loading branch information
Showing
24 changed files
with
665 additions
and
214 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import type { NestedKeyOf } from "#core:utils/types"; | ||
|
||
interface StringifyOptions<T extends object> { | ||
/** The columns to include in the resulting CSV. */ | ||
columns: readonly NestedKeyOf<T>[]; | ||
/** Content of the first row */ | ||
titleRow?: readonly string[]; | ||
} | ||
|
||
function getNested<T extends object>(obj: T, key: NestedKeyOf<T>) { | ||
const path: (keyof object)[] = key.split(".") as (keyof unknown)[]; | ||
let res = obj[path.shift() as keyof T]; | ||
for (const node of path) { | ||
if (res === null) { | ||
break; | ||
} | ||
res = res[node]; | ||
} | ||
return res; | ||
} | ||
|
||
/** | ||
* Convert the content the string to make sure it won't break | ||
* the resulting csv. | ||
* cf. https://en.wikipedia.org/wiki/Comma-separated_values#Basic_rules | ||
*/ | ||
function sanitizeCell(content: string): string { | ||
return `"${content.replace(/"/g, '""')}"`; | ||
} | ||
|
||
export const csv = { | ||
stringify: <T extends object>(objs: T[], options?: StringifyOptions<T>) => { | ||
const columns = options.columns; | ||
const content = objs | ||
.map((obj) => { | ||
return columns | ||
.map((col) => { | ||
return sanitizeCell((getNested(obj, col) ?? "").toString()); | ||
}) | ||
.join(","); | ||
}) | ||
.join("\n"); | ||
if (!options.titleRow) { | ||
return content; | ||
} | ||
const firstRow = options.titleRow.map(sanitizeCell).join(","); | ||
return `${firstRow}\n${content}`; | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/** | ||
* A key of an object, or of one of its descendants. | ||
* | ||
* Example : | ||
* ```typescript | ||
* interface Foo { | ||
* foo_inner: number; | ||
* } | ||
* | ||
* interface Bar { | ||
* foo: Foo; | ||
* } | ||
* | ||
* const foo = (key: NestedKeyOf<Bar>) { | ||
* console.log(key); | ||
* } | ||
* | ||
* foo("foo.foo_inner"); // OK | ||
* foo("foo.bar"); // FAIL | ||
* ``` | ||
*/ | ||
export type NestedKeyOf<T extends object> = { | ||
[Key in keyof T & (string | number)]: NestedKeyOfHandleValue<T[Key], `${Key}`>; | ||
}[keyof T & (string | number)]; | ||
|
||
type NestedKeyOfInner<T extends object> = { | ||
[Key in keyof T & (string | number)]: NestedKeyOfHandleValue< | ||
T[Key], | ||
`['${Key}']` | `.${Key}` | ||
>; | ||
}[keyof T & (string | number)]; | ||
|
||
type NestedKeyOfHandleValue<T, Text extends string> = T extends unknown[] | ||
? Text | ||
: T extends object | ||
? Text | `${Text}${NestedKeyOfInner<T>}` | ||
: Text; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
@import "core/static/core/colors"; | ||
|
||
@mixin row-layout { | ||
min-height: 100px; | ||
width: 100%; | ||
max-width: 100%; | ||
display: flex; | ||
flex-direction: row; | ||
gap: 10px; | ||
.card-image { | ||
max-width: 75px; | ||
} | ||
.card-content { | ||
flex: 1; | ||
text-align: left; | ||
} | ||
} | ||
|
||
.card { | ||
background-color: $primary-neutral-light-color; | ||
border-radius: 5px; | ||
position: relative; | ||
box-sizing: border-box; | ||
padding: 20px 10px; | ||
height: fit-content; | ||
width: 150px; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
gap: 20px; | ||
|
||
&:hover { | ||
background-color: darken($primary-neutral-light-color, 5%); | ||
} | ||
|
||
&.selected { | ||
animation: bg-in-out 1s ease; | ||
background-color: rgb(216, 236, 255); | ||
} | ||
|
||
.card-image { | ||
width: 100%; | ||
height: 100%; | ||
min-height: 70px; | ||
max-height: 70px; | ||
object-fit: contain; | ||
border-radius: 4px; | ||
line-height: 70px; | ||
} | ||
|
||
i.card-image { | ||
color: black; | ||
text-align: center; | ||
background-color: rgba(173, 173, 173, 0.2); | ||
width: 80%; | ||
} | ||
|
||
.card-content { | ||
color: black; | ||
display: flex; | ||
flex-direction: column; | ||
gap: 5px; | ||
width: 100%; | ||
|
||
p { | ||
font-size: 13px; | ||
margin: 0; | ||
} | ||
|
||
.card-title { | ||
margin: 0; | ||
font-size: 15px; | ||
word-break: break-word; | ||
} | ||
} | ||
|
||
@keyframes bg-in-out { | ||
0% { | ||
background-color: white; | ||
} | ||
100% { | ||
background-color: rgb(216, 236, 255); | ||
} | ||
} | ||
|
||
@media screen and (max-width: 765px) { | ||
@include row-layout | ||
} | ||
|
||
// When combined with card, card-row display the card in a row layout, | ||
// whatever the size of the screen. | ||
&.card-row { | ||
@include row-layout | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -107,7 +107,7 @@ form { | |
} | ||
} | ||
|
||
label { | ||
label, legend { | ||
display: block; | ||
margin-bottom: 8px; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.