Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffac16cb05 | ||
|
|
98177d0cd3 | ||
|
|
2c5be718e6 | ||
|
|
019d92dd7b | ||
|
|
5b72afbb93 | ||
|
|
56348cdddf | ||
|
|
973d79ee99 | ||
|
|
5bfb912531 | ||
|
|
27e3dfee07 | ||
|
|
20b2bf6f89 | ||
|
|
4b870986c8 | ||
|
|
8fcf079359 | ||
|
|
54f8b07956 | ||
|
|
9bc251e694 | ||
|
|
e2a9d027dc | ||
|
|
22dfd8e603 | ||
|
|
53d1947311 | ||
|
|
d4e7c47772 | ||
|
|
e191dffdf8 | ||
|
|
7e0ee60d47 | ||
|
|
4ecaeb9d04 | ||
|
|
8e5c554431 | ||
|
|
727be0a98b | ||
|
|
4c2e44ced1 | ||
|
|
2fd1dd443f | ||
|
|
a6c3391237 | ||
|
|
5ede88a188 | ||
|
|
2785593d20 | ||
|
|
a37c743547 | ||
|
|
6f0e18c3cf | ||
|
|
bdfaa54e81 | ||
|
|
595796af6c | ||
|
|
c85b34e86f | ||
|
|
fc46b5a97b | ||
|
|
c7fcf57fdf | ||
|
|
560d8bd1e8 | ||
|
|
7a53de186e | ||
|
|
4feb798b25 | ||
|
|
c713b469f0 | ||
|
|
676392a5c4 | ||
|
|
c049e08555 | ||
|
|
d8c898db8c | ||
|
|
8a1ef5e7e2 | ||
|
|
293594235a | ||
|
|
a54d97591e | ||
|
|
dc2e7fb766 | ||
|
|
53df42df22 | ||
|
|
5b9840524c | ||
|
|
0d6ddfd95e | ||
|
|
0394e819ba | ||
|
|
67fc9ad560 | ||
|
|
8fe5c88eba | ||
|
|
1fbcf78745 | ||
|
|
83dc3236e8 | ||
|
|
7503c7fa7f | ||
|
|
e668181690 | ||
|
|
353dff3da5 | ||
|
|
a11993a155 | ||
|
|
7b53b7670f | ||
|
|
0aaa0c4e10 | ||
|
|
ea5e1f768c | ||
|
|
e6b16e9b31 | ||
|
|
1029d42163 | ||
|
|
fba5140d8b | ||
|
|
fe72f32dbb | ||
|
|
6a0890b42b | ||
|
|
320f45a775 | ||
|
|
3feb2283a4 | ||
|
|
c3b416a3cb | ||
|
|
36fba1a33b |
No files matched your search
@@ -22,9 +22,6 @@ jobs:
|
||||
- name: add tokens to .env
|
||||
run: |
|
||||
echo "SANITY_WRITE_KEY=${{ secrets.SANITY_FEEDBACK_WRITE_KEY }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ADMIN=${{ secrets.ALGOLIA_ADMIN }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ID=${{ secrets.ALGOLIA_ID}}" >> aksel.nav.no/website/.env
|
||||
echo "TRELLO_TOKEN=${{ secrets.TRELLO_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PREVIEW_TOKEN=${{ secrets.SANITY_PREVIEW_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PRIVATE_NO_DRAFTS=${{ secrets.SANITY_PRIVATE_NO_DRAFTS }}" >> aksel.nav.no/website/.env
|
||||
|
||||
@@ -21,9 +21,6 @@ jobs:
|
||||
- name: add tokens to .env
|
||||
run: |
|
||||
echo "SANITY_WRITE_KEY=${{ secrets.SANITY_FEEDBACK_WRITE_KEY }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ADMIN=${{ secrets.ALGOLIA_ADMIN }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ID=${{ secrets.ALGOLIA_ID}}" >> aksel.nav.no/website/.env
|
||||
echo "TRELLO_TOKEN=${{ secrets.TRELLO_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PREVIEW_TOKEN=${{ secrets.SANITY_PREVIEW_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PRIVATE_NO_DRAFTS=${{ secrets.SANITY_PRIVATE_NO_DRAFTS }}" >> aksel.nav.no/website/.env
|
||||
|
||||
@@ -22,18 +22,17 @@ jobs:
|
||||
key: ${{ runner.os }}-build-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-build-
|
||||
|
||||
- name: Install dependencies
|
||||
run: cd aksel.nav.no/sanity && yarn
|
||||
run: cd aksel.nav.no/website && yarn
|
||||
|
||||
- name: Export dataset
|
||||
run: cd aksel.nav.no/sanity && SANITY_TOKEN=${{secrets.SANITY_DATASET_EDITOR_TOKEN}} yarn backup
|
||||
run: cd aksel.nav.no/website && SANITY_TOKEN=${{secrets.SANITY_DATASET_EDITOR_TOKEN}} yarn backup
|
||||
- name: Upload GCP bucket
|
||||
uses: "google-github-actions/auth@v0"
|
||||
with:
|
||||
credentials_json: "${{ secrets.gcp_credentials_prod }}"
|
||||
- uses: "google-github-actions/upload-cloud-storage@v0"
|
||||
with:
|
||||
path: ./aksel.nav.no/sanity
|
||||
path: ./aksel.nav.no/website
|
||||
destination: "aksel-website-prod/backups"
|
||||
glob: "backup-*.tar.gz"
|
||||
@@ -21,9 +21,6 @@ jobs:
|
||||
- name: add tokens to .env
|
||||
run: |
|
||||
echo "SANITY_WRITE_KEY=${{ secrets.SANITY_FEEDBACK_WRITE_KEY }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ADMIN=${{ secrets.ALGOLIA_ADMIN }}" >> aksel.nav.no/website/.env
|
||||
echo "ALGOLIA_ID=${{ secrets.ALGOLIA_ID}}" >> aksel.nav.no/website/.env
|
||||
echo "TRELLO_TOKEN=${{ secrets.TRELLO_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PREVIEW_TOKEN=${{ secrets.SANITY_PREVIEW_TOKEN }}" >> aksel.nav.no/website/.env
|
||||
echo "SANITY_PRIVATE_NO_DRAFTS=${{ secrets.SANITY_PRIVATE_NO_DRAFTS }}" >> aksel.nav.no/website/.env
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
name: Indexing search
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# 01.00 & 12.00 every day
|
||||
- cron: "00 01,12 * * *"
|
||||
|
||||
jobs:
|
||||
searchcrawl:
|
||||
name: Search-indexing aksel.nav.no
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
APPLICATION_ID: ${{ secrets.ALGOLIA_ID}}
|
||||
API_KEY: ${{ secrets.ALGOLIA_ADMIN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Read crawler.json
|
||||
id: algolia_config
|
||||
run: echo "::set-output name=config::$(cat ./aksel.nav.no/crawler.json | jq -r tostring)"
|
||||
- name: Push indices to Algolia
|
||||
uses: signcl/docsearch-scraper-action@master
|
||||
env:
|
||||
APPLICATION_ID: ${{ secrets.ALGOLIA_ID}}
|
||||
API_KEY: ${{ secrets.ALGOLIA_ADMIN }}
|
||||
CONFIG: ${{ steps.algolia_config.outputs.config }}
|
||||
@@ -149,4 +149,5 @@ tmp.json
|
||||
playwright-report/
|
||||
/test-results/
|
||||
backup-*.tar.gz
|
||||
sitemap-urls.json
|
||||
sitemap-urls.json
|
||||
*.tar.gz
|
||||
@@ -1,5 +1,19 @@
|
||||
# @navikt/ds-codemod
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-codemod",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.18",
|
||||
"description": "Aksel codemods for NAVs designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
"build-pict": "svgr --silent --index-template index-template.js --out-dir src/pictograms pictograms"
|
||||
},
|
||||
"dependencies": {
|
||||
"@navikt/ds-icons": "^2.0.11",
|
||||
"@navikt/ds-react": "^2.0.11",
|
||||
"@navikt/ds-icons": "^2.0.18",
|
||||
"@navikt/ds-react": "^2.0.18",
|
||||
"clsx": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1748](https://github.com/navikt/Designsystemet/pull/1748) [`22dfd8e60`](https://github.com/navikt/Designsystemet/commit/22dfd8e60315c421749394d35e41f412a00a7593) Thanks [@KenAJoh](https://github.com/KenAJoh)! - toptextPosition prop i Chat for horisontal plassering av navn og dato.
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1737](https://github.com/navikt/Designsystemet/pull/1737) [`8a1ef5e7e`](https://github.com/navikt/Designsystemet/commit/8a1ef5e7e2c066cb80c13e14329e1585e2c427f8) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :bug: Fikset default visuell error-state for radio
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
@@ -77,6 +77,22 @@
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.navds-chat--top-text-left .navds-chat__top-text {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.navds-chat--top-text-right .navds-chat__top-text {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.navds-chat--left .navds-chat__top-text--right {
|
||||
align-self: flex-end;
|
||||
}
|
||||
|
||||
.navds-chat--right .navds-chat__top-text--left {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.navds-chat__name {
|
||||
font-weight: var(--a-font-weight-bold);
|
||||
}
|
||||
@@ -143,27 +143,21 @@
|
||||
.navds-checkbox--error
|
||||
> .navds-checkbox__input:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-radio--error
|
||||
> .navds-radio__input:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-radio__label::before {
|
||||
.navds-radio--error > .navds-radio__input:not(:hover):not(:disabled):not(:checked) + .navds-radio__label::before {
|
||||
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger));
|
||||
}
|
||||
|
||||
.navds-checkbox--error
|
||||
> .navds-checkbox__input:focus:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-radio--error
|
||||
> .navds-radio__input:focus:not(:hover):not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-radio__label::before {
|
||||
.navds-radio--error > .navds-radio__input:focus:not(:hover):not(:disabled):not(:checked) + .navds-radio__label::before {
|
||||
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger)), var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
.navds-checkbox--error
|
||||
> .navds-checkbox__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-radio--error
|
||||
> .navds-radio__input:hover:not(:disabled):not(:checked):not(:indeterminate):not(:focus)
|
||||
+ .navds-radio__label::before {
|
||||
.navds-radio--error > .navds-radio__input:hover:not(:disabled):not(:checked):not(:focus) + .navds-radio__label::before {
|
||||
background-color: var(--ac-radio-checkbox-error-hover-bg, var(--a-surface-danger-subtle));
|
||||
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger));
|
||||
}
|
||||
@@ -171,9 +165,7 @@
|
||||
.navds-checkbox--error
|
||||
> .navds-checkbox__input:focus:hover:not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-checkbox__label::before,
|
||||
.navds-radio--error
|
||||
> .navds-radio__input:focus:hover:not(:disabled):not(:checked):not(:indeterminate)
|
||||
+ .navds-radio__label::before {
|
||||
.navds-radio--error > .navds-radio__input:focus:hover:not(:disabled):not(:checked) + .navds-radio__label::before {
|
||||
background-color: var(--ac-radio-checkbox-error-hover-bg, var(--a-surface-danger-subtle));
|
||||
box-shadow: inset 0 0 0 2px var(--ac-radio-checkbox-error-border, var(--a-border-danger)), var(--a-shadow-focus);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.18",
|
||||
"description": "CSS for NAV Designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
@@ -20,7 +20,7 @@
|
||||
"watch": "postcss --watch --use postcss-import -o dist/index.css index.css"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^2.0.11",
|
||||
"@navikt/ds-tokens": "^2.0.18",
|
||||
"normalize.css": "^8.0.1",
|
||||
"postcss": "^8.4.0",
|
||||
"postcss-cli": "^9.0.0",
|
||||
|
||||
@@ -1,5 +1,60 @@
|
||||
# @navikt/ds-react
|
||||
|
||||
## 2.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`98177d0cd`](https://github.com/navikt/Designsystemet/commit/98177d0cd3802029dcf398ce93c1767d3b0860c5) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Bedre typer for ref i datepicker
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`27e3dfee0`](https://github.com/navikt/Designsystemet/commit/27e3dfee07e135893e9f62cd32f80ed83a3510de)]:
|
||||
- @navikt/ds-icons@2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`54f8b0795`](https://github.com/navikt/Designsystemet/commit/54f8b07956bbfb7de51f6682a5fc64903bfd1bdf)]:
|
||||
- @navikt/ds-icons@2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1748](https://github.com/navikt/Designsystemet/pull/1748) [`22dfd8e60`](https://github.com/navikt/Designsystemet/commit/22dfd8e60315c421749394d35e41f412a00a7593) Thanks [@KenAJoh](https://github.com/KenAJoh)! - toptextPosition prop i Chat for horisontal plassering av navn og dato.
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`8e5c55443`](https://github.com/navikt/Designsystemet/commit/8e5c554431c98b1b658c5054c0b3cf08b8a65e52) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Bumpet @floating-ui/react
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a6c339123`](https://github.com/navikt/Designsystemet/commit/a6c3391237f13394063e4c004ac9efb1875fc944)]:
|
||||
- @navikt/ds-icons@2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.18",
|
||||
"description": "Aksel react-components for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -36,8 +36,8 @@
|
||||
"test": "TZ=UTC jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react-dom-interactions": "0.9.2",
|
||||
"@navikt/ds-icons": "^2.0.11",
|
||||
"@floating-ui/react": "0.17.0",
|
||||
"@navikt/ds-icons": "^2.0.18",
|
||||
"@radix-ui/react-tabs": "1.0.0",
|
||||
"@radix-ui/react-toggle-group": "1.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
|
||||
@@ -19,6 +19,10 @@ export interface BubbleProps extends HTMLAttributes<HTMLDivElement> {
|
||||
* Background color on bubble
|
||||
*/
|
||||
backgroundColor?: string;
|
||||
/**
|
||||
* Overrides hoizontal position of toptext
|
||||
*/
|
||||
toptextPosition?: "left" | "right";
|
||||
}
|
||||
|
||||
export type BubbleType = React.ForwardRefExoticComponent<
|
||||
@@ -26,7 +30,18 @@ export type BubbleType = React.ForwardRefExoticComponent<
|
||||
>;
|
||||
|
||||
const Bubble: BubbleType = forwardRef(
|
||||
({ children, className, name, timestamp, backgroundColor, ...rest }, ref) => {
|
||||
(
|
||||
{
|
||||
children,
|
||||
className,
|
||||
name,
|
||||
timestamp,
|
||||
backgroundColor,
|
||||
toptextPosition,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
@@ -35,7 +50,12 @@ const Bubble: BubbleType = forwardRef(
|
||||
{...rest}
|
||||
>
|
||||
{(timestamp || name) && (
|
||||
<div className="navds-chat__top-text">
|
||||
<div
|
||||
className={cl(
|
||||
`navds-chat__top-text`,
|
||||
toptextPosition && `navds-chat__top-text--${toptextPosition}`
|
||||
)}
|
||||
>
|
||||
{name && <Detail className="navds-chat__name">{name}</Detail>}
|
||||
{timestamp && (
|
||||
<Detail className="navds-chat__timestamp">{timestamp}</Detail>
|
||||
|
||||
@@ -33,6 +33,11 @@ export interface ChatProps extends HTMLAttributes<HTMLDivElement> {
|
||||
* @default "left"
|
||||
*/
|
||||
position?: "left" | "right";
|
||||
/**
|
||||
* Hoizontal position of toptext
|
||||
* @default Same as chat
|
||||
*/
|
||||
toptextPosition?: "left" | "right";
|
||||
}
|
||||
|
||||
interface ChatComponent
|
||||
@@ -53,6 +58,7 @@ export const Chat = forwardRef<HTMLDivElement, ChatProps>(
|
||||
position = "left",
|
||||
avatarBgColor,
|
||||
backgroundColor,
|
||||
toptextPosition,
|
||||
...rest
|
||||
},
|
||||
ref
|
||||
@@ -60,7 +66,13 @@ export const Chat = forwardRef<HTMLDivElement, ChatProps>(
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cl("navds-chat", className, `navds-chat--${position}`)}
|
||||
className={cl(
|
||||
"navds-chat",
|
||||
className,
|
||||
`navds-chat--${position} navds-chat--top-text-${
|
||||
toptextPosition ?? position
|
||||
}`
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<BodyShort
|
||||
|
||||
@@ -116,6 +116,57 @@ export const Position = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const ToptextPosition = () => {
|
||||
return (
|
||||
<div className="colgap">
|
||||
<Chat
|
||||
avatar="ON"
|
||||
name="Ola Normann"
|
||||
timestamp="01.01.21 14:00"
|
||||
backgroundColor="rgba(255, 249, 240, 1)"
|
||||
avatarBgColor="rgba(255, 236, 204, 1)"
|
||||
toptextPosition="right"
|
||||
>
|
||||
<Chat.Bubble>
|
||||
Adipisicing laborum est eu laborum est sit in commodo enim sint
|
||||
laboris labore nisi ut.
|
||||
</Chat.Bubble>
|
||||
</Chat>
|
||||
<Chat
|
||||
avatar="KH"
|
||||
name="Kari Høyli"
|
||||
timestamp="01.01.21 14:32"
|
||||
position="right"
|
||||
backgroundColor="rgba(230, 240, 255, 1)"
|
||||
avatarBgColor="rgba(204, 225, 255, 1)"
|
||||
toptextPosition="left"
|
||||
>
|
||||
<Chat.Bubble>
|
||||
Reprehenderit pariatur officia exercitation laboris.
|
||||
</Chat.Bubble>
|
||||
<Chat.Bubble>
|
||||
Enim velit deserunt do quis. Eu fugiat magna esse dolore ad sunt sit
|
||||
est dolore incididunt. Occaecat cupidatat magna.
|
||||
</Chat.Bubble>
|
||||
</Chat>
|
||||
<Chat
|
||||
avatar="ON"
|
||||
name="Ola Normann"
|
||||
timestamp="01.01.21 15:00"
|
||||
backgroundColor="rgba(255, 249, 240, 1)"
|
||||
avatarBgColor="rgba(255, 236, 204, 1)"
|
||||
>
|
||||
<Chat.Bubble toptextPosition="right">
|
||||
Exercitation irure Lorem cupidatat culpa anim cillum esse ullamco qui
|
||||
dolore laborum et Lorem. Labore sunt duis id Lorem voluptate commodo
|
||||
ea esse. Dolore esse aliqua proident ea ad commodo ut dolore voluptate
|
||||
labore sunt aute.
|
||||
</Chat.Bubble>
|
||||
</Chat>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const Avatar = () => {
|
||||
return (
|
||||
<Chat avatar={<Illustration />} timestamp="01.01.21 14:00">
|
||||
|
||||
@@ -59,7 +59,10 @@ interface UseDatepickerValue {
|
||||
/**
|
||||
* Use: <DatePicker.Input {...inputProps}/>
|
||||
*/
|
||||
inputProps: Pick<DateInputProps, "onChange" | "onFocus" | "onBlur" | "value">;
|
||||
inputProps: Pick<
|
||||
DateInputProps,
|
||||
"onChange" | "onFocus" | "onBlur" | "value"
|
||||
> & { ref: React.RefObject<HTMLInputElement> };
|
||||
/**
|
||||
* Resets all states (callback)
|
||||
*/
|
||||
|
||||
@@ -45,7 +45,9 @@ interface UseMonthPickerValue {
|
||||
/**
|
||||
* Use: <MonthPicker.Input {...inputProps} />
|
||||
*/
|
||||
inputProps: Pick<DateInputProps, "onChange" | "onFocus" | "value">;
|
||||
inputProps: Pick<DateInputProps, "onChange" | "onFocus" | "value"> & {
|
||||
ref: React.RefObject<HTMLInputElement>;
|
||||
};
|
||||
/**
|
||||
* Currently selected Date
|
||||
* Up to user to validate value and extract month
|
||||
@@ -101,7 +103,7 @@ export const useMonthpicker = (
|
||||
const today = new Date();
|
||||
const locale = getLocaleFromString(_locale);
|
||||
|
||||
const inputRef = useRef<HTMLDivElement>(null);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const monthpickerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// Initialize states
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import differenceInCalendarDays from "date-fns/differenceInCalendarDays";
|
||||
import isWeekend from "date-fns/isWeekend";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { DateRange, isMatch } from "react-day-picker";
|
||||
import { DateInputProps } from "../DateInput";
|
||||
import { DatePickerProps } from "../datepicker/DatePicker";
|
||||
@@ -71,14 +71,14 @@ interface UseRangeDatepickerValue {
|
||||
fromInputProps: Pick<
|
||||
DateInputProps,
|
||||
"onChange" | "onFocus" | "onBlur" | "value"
|
||||
>;
|
||||
> & { ref: React.RefObject<HTMLInputElement> };
|
||||
/**
|
||||
* Use: <DatePicker.Input label="to" {...toInputProps}/>
|
||||
*/
|
||||
toInputProps: Pick<
|
||||
DateInputProps,
|
||||
"onChange" | "onFocus" | "onBlur" | "value"
|
||||
>;
|
||||
> & { ref: React.RefObject<HTMLInputElement> };
|
||||
/**
|
||||
* Resets all states (callback)
|
||||
*/
|
||||
@@ -206,8 +206,8 @@ export const useRangeDatepicker = (
|
||||
|
||||
const locale = getLocaleFromString(_locale);
|
||||
|
||||
const inputRefTo = useRef<HTMLDivElement>(null);
|
||||
const inputRefFrom = useRef<HTMLDivElement>(null);
|
||||
const inputRefTo = useRef<HTMLInputElement>(null);
|
||||
const inputRefFrom = useRef<HTMLInputElement>(null);
|
||||
const datePickerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const [defaultSelected, setDefaultSelected] = useState(_defaultSelected);
|
||||
|
||||
@@ -36,7 +36,7 @@ describe("Returns if year is at start or end of range", () => {
|
||||
expect(hasNextYear(new Date(), years, 1)).toBeTruthy();
|
||||
});
|
||||
test("Should have previous year (true)", () => {
|
||||
expect(hasNextYear(new Date("Aug 3 2023"), years, -1)).toBeTruthy();
|
||||
expect(hasNextYear(new Date("Aug 3 2024"), years, -1)).toBeTruthy();
|
||||
});
|
||||
test("Should not have next year (false)", () => {
|
||||
expect(hasNextYear(new Date("Aug 3 2029"), years, 1)).toBeFalsy();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import cl from "clsx";
|
||||
import React, { forwardRef, InputHTMLAttributes } from "react";
|
||||
import { BodyShort, Detail, omit } from "../..";
|
||||
import { FormFieldProps } from "../useFormField";
|
||||
import { useRadio } from "./useRadio";
|
||||
|
||||
@@ -23,7 +23,7 @@ export const Default = (props) => {
|
||||
value={props.controlled ? state : undefined}
|
||||
onChange={props.controlled ? setState : undefined}
|
||||
hideLegend={props.hideLegend}
|
||||
error={props.errorGroup ? "Errormelding" : undefined}
|
||||
error={props.error ? "Errormelding" : undefined}
|
||||
size={props?.size}
|
||||
>
|
||||
<Radio value="radio1">{props.children || "Apple"}</Radio>
|
||||
@@ -41,6 +41,7 @@ export const Default = (props) => {
|
||||
|
||||
Default.args = {
|
||||
controlled: false,
|
||||
error: false,
|
||||
size: "medium",
|
||||
legend: "Legend-tekst",
|
||||
radioDescription: false,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
useDismiss,
|
||||
useFloating,
|
||||
useInteractions,
|
||||
} from "@floating-ui/react-dom-interactions";
|
||||
} from "@floating-ui/react";
|
||||
import cl from "clsx";
|
||||
import React, {
|
||||
forwardRef,
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
useFocus,
|
||||
useHover,
|
||||
useInteractions,
|
||||
} from "@floating-ui/react-dom-interactions";
|
||||
} from "@floating-ui/react";
|
||||
import cl from "clsx";
|
||||
import React, {
|
||||
cloneElement,
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @navikt/ds-tailwind
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tailwind",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.18",
|
||||
"description": "Tailwind config based on @navikt/ds-tokens",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
@@ -22,7 +22,7 @@
|
||||
"directory": "@navikt/core/tailwind"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@navikt/ds-tokens": "^2.0.11",
|
||||
"@navikt/ds-tokens": "^2.0.18",
|
||||
"@types/jest": "^29.0.0",
|
||||
"color": "4.2.3",
|
||||
"jest": "^29.0.0",
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @navikt/ds-tokens
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tokens",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.18",
|
||||
"description": "Design-tokens for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# @navikt/ds-icons
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`27e3dfee0`](https://github.com/navikt/Designsystemet/commit/27e3dfee07e135893e9f62cd32f80ed83a3510de) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Translate og Paragraph ikon
|
||||
|
||||
## 2.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`54f8b0795`](https://github.com/navikt/Designsystemet/commit/54f8b07956bbfb7de51f6682a5fc64903bfd1bdf) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Oppdatert ikoner med feile farger
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`a6c339123`](https://github.com/navikt/Designsystemet/commit/a6c3391237f13394063e4c004ac9efb1875fc944) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Ikonjusteringer sirkleikoner
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -867,13 +867,13 @@
|
||||
"name": "Eu",
|
||||
"description": "",
|
||||
"created_at": "2022-02-08T11:45:47.104Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "EuFilled",
|
||||
"description": "",
|
||||
"created_at": "2022-02-08T11:45:47.109Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Expand",
|
||||
@@ -1479,13 +1479,13 @@
|
||||
"name": "Law",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:42.819Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "LawFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.330Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Left",
|
||||
@@ -1551,37 +1551,37 @@
|
||||
"name": "Locked",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:43.027Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "LockedFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.325Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Login",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:43.087Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "LoginFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.531Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Logout",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:42.931Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "LogoutFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.609Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Male",
|
||||
@@ -1811,6 +1811,12 @@
|
||||
"created_at": "2021-12-15T15:16:55.869Z",
|
||||
"pageName": "People"
|
||||
},
|
||||
{
|
||||
"name": "Paragraph",
|
||||
"description": "",
|
||||
"created_at": "2023-01-17T13:24:22.989Z",
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Parking",
|
||||
"description": "",
|
||||
@@ -1827,13 +1833,13 @@
|
||||
"name": "Passport",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:43.078Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "PassportFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.757Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "PensionBag",
|
||||
@@ -2615,6 +2621,12 @@
|
||||
"created_at": "2021-01-28T14:00:38.585Z",
|
||||
"pageName": "Buildings"
|
||||
},
|
||||
{
|
||||
"name": "Translate",
|
||||
"description": "",
|
||||
"created_at": "2023-01-18T10:52:22.311Z",
|
||||
"pageName": "Interface"
|
||||
},
|
||||
{
|
||||
"name": "Truck",
|
||||
"description": "",
|
||||
@@ -2643,13 +2655,13 @@
|
||||
"name": "Unlocked",
|
||||
"description": "",
|
||||
"created_at": "2020-07-01T10:37:42.823Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "UnlockedFilled",
|
||||
"description": "",
|
||||
"created_at": "2021-01-11T13:37:55.317Z",
|
||||
"pageName": "Privacy and secutity"
|
||||
"pageName": "Privacy and security"
|
||||
},
|
||||
{
|
||||
"name": "Up",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-icons",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.18",
|
||||
"description": "Aksel icons for NAV",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"repository": {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 0C18.6274 0 24 5.37258 24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0ZM12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM13 6V11H18V13H13V18H11V13H6V11H11V6H13Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.75 2.5C6.64137 2.5 2.5 6.64137 2.5 11.75C2.5 16.8586 6.64137 21 11.75 21C16.8586 21 21 16.8586 21 11.75C21 6.64137 16.8586 2.5 11.75 2.5ZM1 11.75C1 5.81294 5.81294 1 11.75 1C17.6871 1 22.5 5.81294 22.5 11.75C22.5 17.6871 17.6871 22.5 11.75 22.5C5.81294 22.5 1 17.6871 1 11.75Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17 12.75H7V11.25H17V12.75Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.25 17L11.25 7L12.75 7L12.75 17H11.25Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 435 B After Width: | Height: | Size: 655 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 0C18.6274 0 24 5.37258 24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0ZM13 6V11H18V13H13V18H11V13H6V11H11V6H13Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.75 1C5.81294 1 1 5.81294 1 11.75C1 17.6871 5.81294 22.5 11.75 22.5C17.6871 22.5 22.5 17.6871 22.5 11.75C22.5 5.81294 17.6871 1 11.75 1ZM11.25 12.75V17H12.75V12.75H17V11.25H12.75V7H11.25V11.25H7V12.75H11.25Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 381 B |
@@ -1,3 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 12C2 6.81465 5.94668 2.5511 11 2.04938V12.4142L18.3288 19.743C16.6044 21.1544 14.4017 22 12 22C6.47715 22 2 17.5228 2 12ZM19.7488 21.163C17.6587 22.9321 14.9533 24 12 24C5.37258 24 0 18.6274 0 12C0 5.70934 4.84047 0.549225 11 0.0410738V0H12H13V0.0410738C19.1595 0.549225 24 5.70934 24 12C24 14.9533 22.9321 17.6587 21.163 19.7488L21.1924 19.7782L20.4853 20.4853L19.7782 21.1924L19.7488 21.163ZM19.743 18.3288C21.1543 16.6044 22 14.4017 22 12C22 6.81465 18.0533 2.5511 13 2.04938V11.5858L19.743 18.3288Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.75C6.89137 2.75 2.75 6.89137 2.75 12C2.75 17.1086 6.89137 21.25 12 21.25C17.1086 21.25 21.25 17.1086 21.25 12C21.25 6.89137 17.1086 2.75 12 2.75ZM1.25 12C1.25 6.06294 6.06294 1.25 12 1.25C17.9371 1.25 22.75 6.06294 22.75 12C22.75 17.9371 17.9371 22.75 12 22.75C6.06294 22.75 1.25 17.9371 1.25 12Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.25 2.5H12.75V12.1729L19.5103 18.4504L18.4897 19.5496L11.25 12.8271V2.5Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 676 B After Width: | Height: | Size: 616 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 12V0.0410767C4.84047 0.549228 0 5.70934 0 12C0 18.6274 5.37258 24 12 24C14.9922 24 17.7286 22.9048 19.8303 21.0935L11 12ZM24 12C24 12.9017 23.9005 13.7803 23.712 14.6252C23.297 16.4847 22.4505 18.1814 21.2831 19.6048L13 11V0.0410767C18.2766 0.476386 22.5852 4.32557 23.712 9.37485C23.9005 10.2198 24 11.0983 24 12Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.25 1.27576C5.66285 1.6608 1.25 6.31506 1.25 12C1.25 17.9371 6.06294 22.75 12 22.75C14.5711 22.75 16.9313 21.8474 18.7812 20.3418L11.25 12.8107V1.27576ZM19.8766 19.3159C21.6596 17.3972 22.75 14.8259 22.75 12C22.75 6.31506 18.3372 1.6608 12.75 1.27576V12.1893L19.8766 19.3159Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 489 B After Width: | Height: | Size: 449 B |
@@ -1,3 +1,4 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 0C18.6274 0 24 5.37258 24 12C24 18.6274 18.6274 24 12 24C5.37258 24 0 18.6274 0 12C0 5.37258 5.37258 0 12 0ZM12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2ZM18 11H6V13H18V11Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.75 2.5C6.64137 2.5 2.5 6.64137 2.5 11.75C2.5 16.8586 6.64137 21 11.75 21C16.8586 21 21 16.8586 21 11.75C21 6.64137 16.8586 2.5 11.75 2.5ZM1 11.75C1 5.81294 5.81294 1 11.75 1C17.6871 1 22.5 5.81294 22.5 11.75C22.5 17.6871 17.6871 22.5 11.75 22.5C5.81294 22.5 1 17.6871 1 11.75Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17 12.75H7V11.25H17V12.75Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 413 B After Width: | Height: | Size: 546 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M24 12C24 5.37258 18.6274 0 12 0C5.37258 0 0 5.37258 0 12C0 18.6274 5.37258 24 12 24C18.6274 24 24 18.6274 24 12ZM18 11H6V13H18V11Z" fill="#262626"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.75 1C5.81294 1 1 5.81294 1 11.75C1 17.6871 5.81294 22.5 11.75 22.5C17.6871 22.5 22.5 17.6871 22.5 11.75C22.5 5.81294 17.6871 1 11.75 1ZM7 12.75H17V11.25H7V12.75Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 302 B After Width: | Height: | Size: 336 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C9.79085 2 7.99999 3.79086 7.99999 6C7.99999 6.66187 8.16311 7.29714 8.45828 7.85918C6.00646 9.12956 5.6173 13.1739 8.76271 14.4845L12.7692 16.1538C13.5145 16.4644 14 17.1926 14 18C14 19.1046 13.1046 20 12 20C10.8954 20 9.99999 19.1046 9.99999 18H7.99999C7.99999 20.2091 9.79085 22 12 22C14.2091 22 16 20.2091 16 18C16 17.3381 15.8369 16.7029 15.5417 16.1408C17.9935 14.8704 18.3827 10.8261 15.2373 9.51554L11.2308 7.84615C10.4855 7.53561 9.99999 6.8074 9.99999 6C9.99999 4.89543 10.8954 4 12 4C13.1046 4 14 4.89543 14 6H16C16 3.79086 14.2091 2 12 2ZM13.9738 14.5208C15.6075 14.4232 16.1245 12.0519 14.4681 11.3617L10.4615 9.69231C10.311 9.62957 10.1657 9.55832 10.0262 9.47924C8.39252 9.57681 7.87544 11.9481 9.53194 12.6383L13.5385 14.3077C13.689 14.3704 13.8343 14.4417 13.9738 14.5208Z" fill="#262626"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 965 B |
@@ -0,0 +1,13 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M11.5 19.5L15.5 10.5L19.5 19.5" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13 17H18" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<mask id="mask0_6814_1365" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="2" y="4" width="15" height="17">
|
||||
<path d="M9.90083 18.7893L13.9008 9.78926C14.1817 9.15728 14.8084 8.75 15.5 8.75C16.1193 8.75 16.6865 9.07657 17.0001 9.59861V4H2.00005V21H10.5983C9.85068 20.5519 9.53784 19.606 9.90083 18.7893Z" fill="black"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_6814_1365)">
|
||||
<path d="M4 7.5H16" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10 7.5V5.5" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13.5 7.5L13.4116 7.78744C12.2005 11.7232 9.30115 14.9162 5.5 16.5" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M6.5 7.5L6.58844 7.78744C7.79946 11.7232 10.6989 14.9162 14.5 16.5" stroke="#262626" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -1,5 +1,19 @@
|
||||
# @navikt/ds-css-internal
|
||||
|
||||
## 2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
## 2.0.10
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css-internal",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.18",
|
||||
"description": "CSS for NAV internal Designsystem-components",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,61 @@
|
||||
# @navikt/ds-react-internal
|
||||
|
||||
## 2.0.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`98177d0cd`](https://github.com/navikt/Designsystemet/commit/98177d0cd3802029dcf398ce93c1767d3b0860c5)]:
|
||||
- @navikt/ds-react@2.0.18
|
||||
- @navikt/ds-icons@2.0.18
|
||||
|
||||
## 2.0.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`27e3dfee0`](https://github.com/navikt/Designsystemet/commit/27e3dfee07e135893e9f62cd32f80ed83a3510de)]:
|
||||
- @navikt/ds-icons@2.0.17
|
||||
- @navikt/ds-react@2.0.17
|
||||
|
||||
## 2.0.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`54f8b0795`](https://github.com/navikt/Designsystemet/commit/54f8b07956bbfb7de51f6682a5fc64903bfd1bdf)]:
|
||||
- @navikt/ds-icons@2.0.16
|
||||
- @navikt/ds-react@2.0.16
|
||||
|
||||
## 2.0.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`22dfd8e60`](https://github.com/navikt/Designsystemet/commit/22dfd8e60315c421749394d35e41f412a00a7593)]:
|
||||
- @navikt/ds-react@2.0.15
|
||||
- @navikt/ds-icons@2.0.15
|
||||
|
||||
## 2.0.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`8e5c55443`](https://github.com/navikt/Designsystemet/commit/8e5c554431c98b1b658c5054c0b3cf08b8a65e52)]:
|
||||
- @navikt/ds-react@2.0.14
|
||||
- @navikt/ds-icons@2.0.14
|
||||
|
||||
## 2.0.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a6c339123`](https://github.com/navikt/Designsystemet/commit/a6c3391237f13394063e4c004ac9efb1875fc944)]:
|
||||
- @navikt/ds-icons@2.0.13
|
||||
- @navikt/ds-react@2.0.13
|
||||
|
||||
## 2.0.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.0.12
|
||||
- @navikt/ds-icons@2.0.12
|
||||
|
||||
## 2.0.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react-internal",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.18",
|
||||
"description": "Aksel react components for internal UIs in NAV",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -35,8 +35,8 @@
|
||||
"watch": "tsc --watch -p tsconfig.esm.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@navikt/ds-icons": "^2.0.11",
|
||||
"@navikt/ds-react": "^2.0.11",
|
||||
"@navikt/ds-icons": "^2.0.18",
|
||||
"@navikt/ds-react": "^2.0.18",
|
||||
"clsx": "^1.1.1",
|
||||
"copy-to-clipboard": "^3.3.1"
|
||||
},
|
||||
|
||||
@@ -65,11 +65,6 @@ Blir brukt flere keys i .env under `./website`, men kun `SANITY_PRIVATE_NO_DRAFT
|
||||
|
||||
- SANITY_WRITE_KEY:
|
||||
For å sende dokumenter til sanity, brukt til å oppdatere sandboxes/examples/farger. Trengs bare hvis kode skal synkes fra lokal branch
|
||||
- ALGOLIA_ADMIN:
|
||||
For å oppdatere records i søkemotoren. Trengs bare hvis man oppdaterer søkeindexen lokalt.
|
||||
- ALGOLIA_ID:
|
||||
Søkemotor index-id for å redigere riktig Index. Trengs bare for at søk skal fungere lokalt
|
||||
- TRELLO_TOKEN: Sender feedback til et egent trello-board. Ikke nødvendig lokalt hvis man ikke vil teste feedback-modulen.
|
||||
- SANITY_PREVIEW_TOKEN: Gir appen tilgang til å lese draft innhold fra sanity i "preview"-mode. Trengs for å teste preview-sider
|
||||
- SANITY_PRIVATE_NO_DRAFTS: Gir appen tilgang til å lese innhold fra Sanity da datasettet er privat
|
||||
|
||||
@@ -89,4 +84,4 @@ Kjøres backups hver 3 dag til GCP-bucket under `designsystem-prod`
|
||||
|
||||
Spørsmål og kontakt kan rettes til team Aksel
|
||||
|
||||
Aksel har også en egen slack-kanal #aksel
|
||||
Aksel har også en egen Slack-kanal #Aksel-designsystemet
|
||||
@@ -1,54 +0,0 @@
|
||||
{
|
||||
"index_name": "aksel_docsearch",
|
||||
"start_urls": [
|
||||
"https://aksel.nav.no/",
|
||||
{
|
||||
"url": "https://aksel.nav.no/designsystem",
|
||||
"tags": ["designsystem", "docs"]
|
||||
},
|
||||
{
|
||||
"url": "https://aksel.nav.no/god-praksis/",
|
||||
"tags": ["aksel"],
|
||||
"selectors_key": "aksel"
|
||||
},
|
||||
{
|
||||
"url": "https://aksel.nav.no/produktbloggen/",
|
||||
"tags": ["aksel"],
|
||||
"selectors_key": "aksel"
|
||||
},
|
||||
{
|
||||
"url": "https://aksel.nav.no/prinsipper/",
|
||||
"tags": ["aksel"],
|
||||
"selectors_key": "aksel"
|
||||
}
|
||||
],
|
||||
"selectors": {
|
||||
"default": {
|
||||
"lvl0": {
|
||||
"selector": "h1.algolia-index-lvl1",
|
||||
"global": true
|
||||
},
|
||||
"lvl1": ".algolia-index-tabs--active",
|
||||
"lvl2": "h2.algolia-index-lvl2",
|
||||
"lvl3": "h3.algolia-index-lvl3",
|
||||
"text": "p.algolia-index-body, p.algolia-index-ingress"
|
||||
},
|
||||
"aksel": {
|
||||
"lvl0": {
|
||||
"selector": "h1.algolia-index-lvl1",
|
||||
"global": true
|
||||
},
|
||||
"lvl1": "h2.algolia-index-lvl2",
|
||||
"lvl2": "h3.algolia-index-lvl3",
|
||||
"text": "p.algolia-index-body, p.algolia-index-ingress"
|
||||
}
|
||||
},
|
||||
"selectors_exclude": [".algolia-ignore-index"],
|
||||
"stop_urls": [
|
||||
"https://aksel.nav.no/preview",
|
||||
"https://old-design-nav.vercel.app",
|
||||
"https://aksel.nav.no/eksempler"
|
||||
],
|
||||
"sitemap_urls": ["https://aksel.nav.no/api/sitemap"],
|
||||
"js_render": true
|
||||
}
|
||||
@@ -15,14 +15,14 @@
|
||||
"website"
|
||||
],
|
||||
"dependencies": {
|
||||
"@navikt/ds-codemod": "^2.0.11",
|
||||
"@navikt/ds-css": "^2.0.11",
|
||||
"@navikt/ds-css-internal": "^2.0.11",
|
||||
"@navikt/ds-icons": "^2.0.11",
|
||||
"@navikt/ds-react": "^2.0.11",
|
||||
"@navikt/ds-react-internal": "^2.0.11",
|
||||
"@navikt/ds-tailwind": "^2.0.11",
|
||||
"@navikt/ds-tokens": "^2.0.11"
|
||||
"@navikt/ds-codemod": "^2.0.18",
|
||||
"@navikt/ds-css": "^2.0.18",
|
||||
"@navikt/ds-css-internal": "^2.0.18",
|
||||
"@navikt/ds-icons": "^2.0.18",
|
||||
"@navikt/ds-react": "^2.0.18",
|
||||
"@navikt/ds-react-internal": "^2.0.18",
|
||||
"@navikt/ds-tailwind": "^2.0.18",
|
||||
"@navikt/ds-tokens": "^2.0.18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier-plugin-tailwindcss": "^0.1.13"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
.yarn/cache
|
||||
production.tar.gz
|
||||
*.tar.gz
|
||||
@@ -62,8 +62,8 @@ export default function SetPrivateAction(props) {
|
||||
dele offentlig kan medføre eks omdømmetap og uønsket oppmerksomhet
|
||||
utenfra. Dobbelsjekk med temaansvarlig og andre som har skrevet
|
||||
artikkelen før du velger å åpne innholdet for alle. Er du usikker
|
||||
er det bare å sende en melding på #aksel eller #aksel-redaktører
|
||||
på slack.
|
||||
er det bare å sende en melding på #Aksel-designsystemet eller
|
||||
#aksel-redaktører på Slack.
|
||||
</BodyLong>
|
||||
) : (
|
||||
<>
|
||||
|
||||
@@ -75,8 +75,8 @@ const IntroPage = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
|
||||
>
|
||||
<ReadMore header="Har du ikke de rollene du trenger?">
|
||||
Send en melding til oss på{" "}
|
||||
<Link href="https://nav-it.slack.com/archives/C0370ADS0HX">
|
||||
#Aksel
|
||||
<Link href="https://nav-it.slack.com/archives/C7NE7A8UF">
|
||||
#Aksel-designsystemet
|
||||
</Link>{" "}
|
||||
slack så fikser vi det.
|
||||
</ReadMore>
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
const AkselLogo = (props): JSX.Element => (
|
||||
<svg
|
||||
focusable="false"
|
||||
aria-hidden="true"
|
||||
viewBox="0 0 28 28"
|
||||
width="28"
|
||||
height="28"
|
||||
fill="none"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="m3 9 5.268-5.268A2.5 2.5 0 0 1 10.036 3H22.5A2.5 2.5 0 0 1 25 5.5v12.465a2.5 2.5 0 0 1-.732 1.767L19 25"
|
||||
></path>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="m3 9 5.232-5.232a2.5 2.5 0 0 1 3.536 0l12.464 12.464a2.5 2.5 0 0 1 0 3.536L19 25m-7-9-9 9"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export default AkselLogo;
|
||||
@@ -1,116 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export const FigmaIcon = ({ ...props }): JSX.Element => (
|
||||
<svg
|
||||
{...props}
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 18 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable="false"
|
||||
aria-label="Figma"
|
||||
aria-hidden
|
||||
>
|
||||
<path
|
||||
d="M15.5 4.99999C15.5 6.93299 13.9531 8.49999 12.0449 8.49999H8.5V1.5H12.0449C13.9531 1.5 15.5 3.067 15.5 4.99999Z"
|
||||
fill="#FF7262"
|
||||
stroke="#262626"
|
||||
/>
|
||||
<path
|
||||
d="M1.5 4.99999C1.5 6.93299 3.04691 8.49999 4.95513 8.49999H8.5V1.5H4.95513C3.04691 1.5 1.5 3.067 1.5 4.99999Z"
|
||||
fill="#F24E1E"
|
||||
stroke="#262626"
|
||||
/>
|
||||
<path
|
||||
d="M1.5 12C1.5 13.933 3.04691 15.5 4.95513 15.5H8.5V8.5H4.95513C3.04691 8.5 1.5 10.067 1.5 12Z"
|
||||
fill="#A259FF"
|
||||
stroke="#262626"
|
||||
/>
|
||||
<path
|
||||
d="M1.5 19C1.5 20.933 3.0692 22.5 4.97742 22.5C6.91042 22.5 8.5 20.9126 8.5 18.9545V15.5H4.95513C3.04691 15.5 1.5 17.067 1.5 19Z"
|
||||
fill="#0ACF83"
|
||||
stroke="#262626"
|
||||
/>
|
||||
<path
|
||||
d="M8.5 12C8.5 13.933 10.0469 15.5 11.9551 15.5H12.0449C13.9531 15.5 15.5 13.933 15.5 12C15.5 10.067 13.9531 8.5 12.0449 8.5H11.9551C10.0469 8.5 8.5 10.067 8.5 12Z"
|
||||
fill="#1ABCFE"
|
||||
stroke="#262626"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const FigmaIconNoSync = ({ ...props }): JSX.Element => (
|
||||
<svg
|
||||
{...props}
|
||||
width="1.5rem"
|
||||
height="1.5rem"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable="false"
|
||||
aria-label="Figma ikke i sync"
|
||||
>
|
||||
<path d="M1.5 22.5L22.5 1.5" stroke="#BA3A26" strokeWidth="2" />
|
||||
<path
|
||||
d="M18.5 4.99999C18.5 6.93299 16.9531 8.49999 15.0449 8.49999H11.5V1.5H15.0449C16.9531 1.5 18.5 3.067 18.5 4.99999Z"
|
||||
stroke="#262626"
|
||||
/>
|
||||
<path
|
||||
d="M4.5 4.99999C4.5 6.93299 6.04691 8.49999 7.95513 8.49999H11.5V1.5H7.95513C6.04691 1.5 4.5 3.067 4.5 4.99999Z"
|
||||
stroke="#262626"
|
||||
/>
|
||||
<path
|
||||
d="M4.5 12C4.5 13.933 6.04691 15.5 7.95513 15.5H11.5V8.5H7.95513C6.04691 8.5 4.5 10.067 4.5 12Z"
|
||||
stroke="#262626"
|
||||
/>
|
||||
<path
|
||||
d="M4.5 19C4.5 20.933 6.0692 22.5 7.97742 22.5C9.91042 22.5 11.5 20.9126 11.5 18.9545V15.5H7.95513C6.04691 15.5 4.5 17.067 4.5 19Z"
|
||||
stroke="#262626"
|
||||
/>
|
||||
<path
|
||||
d="M11.5 12C11.5 13.933 13.0469 15.5 14.9551 15.5H15.0449C16.9531 15.5 18.5 13.933 18.5 12C18.5 10.067 16.9531 8.5 15.0449 8.5H14.9551C13.0469 8.5 11.5 10.067 11.5 12Z"
|
||||
stroke="#262626"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M15 17.335H16.6664C15.8573 17.9444 15.3333 18.9147 15.3333 20.0081C15.3333 21.319 16.0865 22.453 17.1812 23.0001L17.4786 22.402C16.6014 21.9636 16 21.056 16 20.0081C16 19.0192 16.5357 18.1551 17.3333 17.6925V19.674H18V16.6667H15V17.335ZM22.6667 19.9921C22.6667 21.0855 22.1427 22.0558 21.3336 22.6651H23V23.3334L20 23.3334V20.3262H20.6667V22.3076C21.4643 21.8451 22 20.981 22 19.9921C22 18.9442 21.3986 18.0366 20.5214 17.5982L20.8188 17.0001C21.9135 17.5472 22.6667 18.6811 22.6667 19.9921Z"
|
||||
fill="#262626"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
export const FigmaIconGrayScale = ({ ...props }): JSX.Element => (
|
||||
<svg
|
||||
width="18"
|
||||
height="26"
|
||||
viewBox="0 0 18 26"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
aria-label="Figma ikon"
|
||||
focusable="false"
|
||||
>
|
||||
<g clipPath="url(#clip0)">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M0.459473 5.44999C0.459473 2.97008 2.46984 0.959717 4.94975 0.959717H8.06672H9.53756H12.6545C15.1344 0.959717 17.1448 2.97008 17.1448 5.44999C17.1448 7.02029 16.3387 8.40232 15.1178 9.2049C16.3387 10.0075 17.1448 11.3895 17.1448 12.9598C17.1448 15.4397 15.1344 17.4501 12.6545 17.4501H12.557C11.3944 17.4501 10.335 17.0082 9.53756 16.2833V17.4501V20.4207C9.53756 22.9336 7.47466 24.9597 4.97398 24.9597C2.50023 24.9597 0.459473 22.9555 0.459473 20.4694C0.459473 18.8992 1.26547 17.5172 2.48632 16.7146C1.26547 15.912 0.459473 14.53 0.459473 12.9598C0.459473 11.3895 1.26553 10.0075 2.48647 9.2049C1.26553 8.40232 0.459473 7.02029 0.459473 5.44999ZM8.06672 12.9598V9.94037H4.94975C3.28215 9.94037 1.93031 11.2922 1.93031 12.9598C1.93031 14.6214 3.2725 15.9696 4.93186 15.9792L4.94975 15.9792H8.06672V12.9598ZM9.53756 12.9598C9.53756 14.6274 10.8894 15.9792 12.557 15.9792H12.6545C14.3221 15.9792 15.674 14.6274 15.674 12.9598C15.674 11.2922 14.3221 9.94037 12.6545 9.94037H12.557C10.8894 9.94037 9.53756 11.2922 9.53756 12.9598ZM4.94975 17.4501L4.93195 17.45C3.27255 17.4596 1.93031 18.8078 1.93031 20.4694C1.93031 22.1309 3.30021 23.4889 4.97398 23.4889C6.67467 23.4889 8.06672 22.1091 8.06672 20.4207V17.4501H4.94975ZM4.94975 2.43055H8.06672V8.46943H4.94975C3.28215 8.46943 1.93031 7.11758 1.93031 5.44999C1.93031 3.7824 3.28215 2.43055 4.94975 2.43055ZM9.53756 8.46943V2.43055H12.6545C14.3221 2.43055 15.674 3.7824 15.674 5.44999C15.674 7.11758 14.3221 8.46943 12.6545 8.46943H9.53756Z"
|
||||
fill="var(--a-text-subtle)"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0">
|
||||
<rect
|
||||
width="18"
|
||||
height="25"
|
||||
fill="white"
|
||||
transform="translate(0 0.5)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
@@ -0,0 +1,73 @@
|
||||
export const ChangelogIcon = () => (
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable={false}
|
||||
aria-hidden
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M10.4688 2.26716C10.3077 1.83185 9.69206 1.83185 9.53098 2.26716L9.26942 2.97401C9.21878 3.11087 9.11087 3.21877 8.97401 3.26942L8.26716 3.53098C7.83185 3.69206 7.83185 4.30775 8.26716 4.46883L8.97401 4.73039C9.11087 4.78103 9.21878 4.88894 9.26942 5.0258L9.53098 5.73265C9.69206 6.16796 10.3077 6.16796 10.4688 5.73265L10.7304 5.0258C10.781 4.88894 10.8889 4.78103 11.0258 4.73039L11.7327 4.46883C12.168 4.30775 12.168 3.69206 11.7327 3.53098L11.0258 3.26942C10.8889 3.21877 10.781 3.11087 10.7304 2.97401L10.4688 2.26716ZM4.53098 5.26715C4.69206 4.83185 5.30775 4.83185 5.46883 5.26716L6.00048 6.70392C6.05112 6.84078 6.15903 6.94868 6.29589 6.99933L7.73265 7.53098C8.16796 7.69206 8.16796 8.30775 7.73265 8.46883L6.29589 9.00048C6.15903 9.05112 6.05112 9.15903 6.00048 9.29589L5.46883 10.7327C5.30775 11.168 4.69206 11.168 4.53098 10.7326L3.99933 9.29589C3.94868 9.15903 3.84078 9.05112 3.70392 9.00048L2.26716 8.46883C1.83185 8.30775 1.83185 7.69206 2.26716 7.53098L3.70392 6.99933C3.84078 6.94868 3.94868 6.84078 3.99933 6.70392L4.53098 5.26715ZM12.531 8.26716C12.6921 7.83185 13.3077 7.83185 13.4688 8.26716L14.5407 11.1637C14.5913 11.3006 14.6992 11.4085 14.8361 11.4591L17.7326 12.531C18.168 12.6921 18.168 13.3077 17.7326 13.4688L14.8361 14.5407C14.6992 14.5913 14.5913 14.6992 14.5407 14.8361L13.4688 17.7326C13.3078 18.168 12.6921 18.168 12.531 17.7326L11.4591 14.8361C11.4085 14.6992 11.3006 14.5913 11.1637 14.5407L8.26716 13.4688C7.83185 13.3077 7.83185 12.6921 8.26716 12.531L11.1637 11.4591C11.3006 11.4085 11.4085 11.3006 11.4591 11.1637L12.531 8.26716Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const FigmaIcon = () => (
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable={false}
|
||||
aria-hidden
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M3 4C3 1.80306 4.76151 0 6.96154 0H9H10H11H13.0385C15.2385 0 17 1.80306 17 4C17 5.19041 16.4828 6.26518 15.6589 7.00012C16.4828 7.73506 17 8.80982 17 10.0002C17 12.1972 15.2385 14.0002 13.0385 14.0002H12.9615C12.2462 14.0002 11.5772 13.8096 11 13.4768V14.0002V15.9608C11 18.1876 9.19358 19.9998 6.98065 19.9998C4.78895 19.9998 3 18.2051 3 15.9998C3 14.8095 3.51701 13.7349 4.34067 13C3.51701 12.2651 3 11.1905 3 10.0002C3 8.80983 3.51718 7.73506 4.34108 7.00012C3.51718 6.26518 3 5.19041 3 4ZM9 10.0002V8.00024H6.96154C5.89033 8.00024 5 8.88346 5 10.0002C5 11.1046 5.87059 11.9805 6.92578 11.9999L6.96154 11.9998H9V10.0002ZM11 10.0002C11 11.117 11.8903 12.0002 12.9615 12.0002H13.0385C14.1097 12.0002 15 11.117 15 10.0002C15 8.88346 14.1097 8.00024 13.0385 8.00024H12.9615C11.8903 8.00024 11 8.88346 11 10.0002ZM6.96154 14.0002L6.92578 14.0001C5.87059 14.0195 5 14.8954 5 15.9998C5 17.1081 5.90111 17.9998 6.98065 17.9998C8.08142 17.9998 9 17.0907 9 15.9608V14.0002H6.96154ZM6.96154 2H9V6H6.96154C5.89033 6 5 5.11678 5 4C5 2.88323 5.89033 2 6.96154 2ZM11 6V2H13.0385C14.1097 2 15 2.88323 15 4C15 5.11678 14.1097 6 13.0385 6H11Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const GithubIcon = () => (
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable={false}
|
||||
aria-hidden
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M9.9702 0C4.45694 0 0 4.4898 0 10.0443C0 14.4843 2.85571 18.2427 6.81735 19.5729C7.31265 19.6729 7.49408 19.3567 7.49408 19.0908C7.49408 18.858 7.47775 18.0598 7.47775 17.2282C4.70429 17.8269 4.12673 16.0308 4.12673 16.0308C3.68102 14.8667 3.02061 14.5675 3.02061 14.5675C2.11286 13.9522 3.08673 13.9522 3.08673 13.9522C4.09367 14.0188 4.62204 14.9833 4.62204 14.9833C5.51327 16.5131 6.94939 16.0808 7.52714 15.8147C7.60959 15.1661 7.87388 14.7171 8.15449 14.4678C5.94245 14.2349 3.6151 13.3702 3.6151 9.51204C3.6151 8.41449 4.01102 7.51653 4.63837 6.81816C4.53939 6.56878 4.19265 5.53755 4.73755 4.15735C4.73755 4.15735 5.57939 3.89122 7.47755 5.18837C8.29022 4.9685 9.12832 4.85666 9.9702 4.85571C10.812 4.85571 11.6702 4.97224 12.4627 5.18837C14.361 3.89122 15.2029 4.15735 15.2029 4.15735C15.7478 5.53755 15.4008 6.56878 15.3018 6.81816C15.9457 7.51653 16.3253 8.41449 16.3253 9.51204C16.3253 13.3702 13.998 14.2182 11.7694 14.4678C12.1327 14.7837 12.4461 15.3822 12.4461 16.3302C12.4461 17.6771 12.4298 18.7582 12.4298 19.0906C12.4298 19.3567 12.6114 19.6729 13.1065 19.5731C17.0682 18.2424 19.9239 14.4843 19.9239 10.0443C19.9402 4.4898 15.4669 0 9.9702 0Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const YarnIcon = () => (
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable={false}
|
||||
aria-hidden
|
||||
>
|
||||
<path
|
||||
d="M19.0336 16.0116C18.0026 16.2564 17.4807 16.482 16.2049 17.3131C14.2075 18.6018 12.0297 19.201 12.0297 19.201C12.0297 19.201 11.8493 19.4716 11.3274 19.5941C10.4253 19.8131 7.02969 20 6.72041 20.0064C5.88923 20.0129 5.38021 19.7938 5.23845 19.4523C4.80675 18.4214 5.85701 17.9704 5.85701 17.9704C5.85701 17.9704 5.62505 17.8286 5.48974 17.6997C5.36732 17.5773 5.23845 17.3325 5.19979 17.4227C5.03871 17.8157 4.95495 18.7758 4.52325 19.2075C3.93046 19.8067 2.80933 19.6069 2.14567 19.259C1.41758 18.8724 2.19722 17.9639 2.19722 17.9639C2.19722 17.9639 1.80418 18.1959 1.48845 17.7191C1.20495 17.2809 0.940773 16.5335 1.01165 15.6121C1.10186 14.549 2.27454 13.5309 2.27454 13.5309C2.27454 13.5309 2.06835 11.9781 2.7449 10.3866C3.35701 8.93685 5.00649 7.77061 5.00649 7.77061C5.00649 7.77061 3.62119 6.24355 4.13665 4.85824C4.4717 3.95618 4.60701 3.96262 4.71655 3.92396C5.10314 3.77577 5.47686 3.61468 5.75392 3.31185C7.13923 1.817 8.90469 2.10051 8.90469 2.10051C8.90469 2.10051 9.72943 -0.431708 10.5026 0.0644255C10.741 0.219065 11.598 2.12628 11.598 2.12628C11.598 2.12628 12.5129 1.59149 12.616 1.79123C13.1702 2.86726 13.2346 4.92267 12.9897 6.17267C12.5774 8.23453 11.5464 9.34278 11.1341 10.0387C11.0374 10.1997 12.2423 10.7088 13.0026 12.8157C13.7049 14.7423 13.0799 16.3595 13.1895 16.5399C13.2088 16.5722 13.2153 16.585 13.2153 16.585C13.2153 16.585 14.0207 16.6495 15.6379 15.6508C16.5013 15.116 17.5258 14.5167 18.6921 14.5039C19.8196 14.4845 19.8776 15.8118 19.0336 16.0116Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
@@ -1,5 +1,5 @@
|
||||
export * from "./FigmaIcon";
|
||||
export { default as NavLogoWhite } from "./NavLogoWhite";
|
||||
export { default as NAVLogoDark } from "./NavLogoDark";
|
||||
|
||||
export * from "./Logo";
|
||||
export * from "./Icons";
|
||||
@@ -36,9 +36,9 @@ const Footer = () => {
|
||||
<li>
|
||||
<Link
|
||||
className="text-text-on-inverted focus:shadow-focus focus:text-text-default focus:bg-blue-200 focus:shadow-blue-200"
|
||||
href="https://nav-it.slack.com/archives/C0370ADS0HX"
|
||||
href="https://nav-it.slack.com/archives/C7NE7A8UF"
|
||||
>
|
||||
#Aksel på Slack
|
||||
#Aksel-designsystemet på Slack
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { FeedbackT } from "@/lib";
|
||||
import { IdContext } from "@/utils";
|
||||
import { Button, Heading, Label, Textarea } from "@navikt/ds-react";
|
||||
import { useRouter } from "next/router";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
|
||||
const FooterForm = () => {
|
||||
const idCtx = useContext(IdContext);
|
||||
|
||||
const [contactForm, setContactForm] = useState({
|
||||
content: "",
|
||||
hasWritten: false,
|
||||
@@ -27,12 +31,16 @@ const FooterForm = () => {
|
||||
if (fail) return;
|
||||
setContentError({ content: "" });
|
||||
|
||||
fetch("/api/generalFeedback", {
|
||||
const body: FeedbackT = {
|
||||
message: contactForm.content,
|
||||
url: `${basePath}${asPath}`,
|
||||
type: "footer",
|
||||
docId: idCtx?.id,
|
||||
};
|
||||
|
||||
fetch("/api/feedback", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
message: contactForm.content,
|
||||
url: `${basePath}${asPath}`,
|
||||
}),
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
|
||||
setSent({ status: true });
|
||||
|
||||
@@ -54,15 +54,18 @@ const AkselArtikkelTemplate = ({
|
||||
: `Relevante artikler`}
|
||||
</Heading>
|
||||
<div className="card-grid-3-1 mt-6 px-4">
|
||||
{data.relevante_artikler.map((x: any) => (
|
||||
<ArtikkelCard {...x} key={x._id} />
|
||||
))}
|
||||
{data.relevante_artikler.map((x: any) =>
|
||||
x && x?._id ? <ArtikkelCard {...x} key={x._id} /> : null
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
|
||||
const filteredTema =
|
||||
hasTema && data?.tema?.filter((x: any) => x?.title && x?.slug);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -136,7 +139,7 @@ const AkselArtikkelTemplate = ({
|
||||
</div>
|
||||
{hasTema && (
|
||||
<div className="mt-8 flex flex-wrap gap-2">
|
||||
{data.tema.map(({ title, slug }: any) => (
|
||||
{filteredTema.map(({ title, slug }: any) => (
|
||||
<span key={title}>
|
||||
<NextLink
|
||||
key={title}
|
||||
|
||||
@@ -125,7 +125,14 @@ export const WithSidebar = ({
|
||||
</div>
|
||||
</div>
|
||||
{variant === "page" && pageProps.status?.bilde && (
|
||||
<div className="relative hidden aspect-square h-[12.5rem] lg:block xl:mr-40">
|
||||
<div
|
||||
className={cl(
|
||||
"relative hidden aspect-square h-[12.5rem] lg:block xl:mr-40",
|
||||
{
|
||||
"hue-rotate-[65deg]": pageProps?.status?.tag === "beta",
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Image
|
||||
src={urlFor(pageProps.status?.bilde).auto("format").url()}
|
||||
decoding="async"
|
||||
|
||||
@@ -63,7 +63,11 @@ const NavItem = ({
|
||||
: "info"
|
||||
}
|
||||
>
|
||||
{link.tag}
|
||||
{link.tag === "new"
|
||||
? "ny"
|
||||
: link.tag === "deprecated"
|
||||
? "Avviklet"
|
||||
: link.tag}
|
||||
</Tag>
|
||||
)}
|
||||
</span>
|
||||
@@ -130,7 +134,17 @@ export const Sidebar = ({
|
||||
...x,
|
||||
pages: links
|
||||
.filter((y) => y?.kategori === x.value)
|
||||
.sort((a, b) => a?.heading.localeCompare(b?.heading)),
|
||||
.sort((a, b) => {
|
||||
if (a?.tag === "deprecated" && b?.tag === "deprecated") {
|
||||
return 0;
|
||||
} else if (a?.tag === "deprecated") {
|
||||
return 1;
|
||||
} else if (b.tag === "deprecated") {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return a?.heading.localeCompare(b?.heading);
|
||||
}),
|
||||
}))
|
||||
.filter((x) => !(!x.pages || x.pages.length === 0)),
|
||||
[links, kategori]
|
||||
|
||||
@@ -11,7 +11,12 @@ interface AkselTemaT extends SanityT.Schema.aksel_tema {
|
||||
}
|
||||
|
||||
const GodPraksisCard = ({ node }: { node: AkselTemaT }) => {
|
||||
if (!node?.pictogram || !node?.slug?.current || !node?.title) {
|
||||
if (
|
||||
!node?.pictogram ||
|
||||
!node?.slug?.current ||
|
||||
!node?.title ||
|
||||
!node?.refCount
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -43,7 +48,7 @@ const GodPraksisCard = ({ node }: { node: AkselTemaT }) => {
|
||||
</NextLink>
|
||||
<BodyShort className={cl("mb-2 lg:mb-6")}>{node.oppsummering}</BodyShort>
|
||||
<BodyShort size="small" className="text-text-subtle">
|
||||
{node.refCount} ARTIKLER
|
||||
{node.refCount === 1 ? "1 ARTIKKEL" : `${node.refCount} ARTIKLER`}
|
||||
</BodyShort>
|
||||
</li>
|
||||
);
|
||||
|
||||
@@ -3,10 +3,11 @@ import { withErrorBoundary } from "@/error-boundary";
|
||||
import { SanityT } from "@/lib";
|
||||
import { BodyLong, Link, Chips } from "@navikt/ds-react";
|
||||
import cl from "classnames";
|
||||
import { useEffect, useId, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { CodeSandbox } from "./CodeSandbox";
|
||||
|
||||
const iframePadding = 192;
|
||||
const iframeId = "example-iframe";
|
||||
|
||||
const ComponentExamples = ({
|
||||
node,
|
||||
@@ -16,22 +17,21 @@ const ComponentExamples = ({
|
||||
filnavn?: SanityT.Schema.kode_eksempler_fil;
|
||||
};
|
||||
}): JSX.Element => {
|
||||
const [iframeHeight, setIframeHeight] = useState(300);
|
||||
const [activeExample, setActiveExample] = useState(null);
|
||||
const iframeId = useId();
|
||||
const [frameState, setFrameState] = useState(300);
|
||||
|
||||
const handleExampleLoad = (id: string) => {
|
||||
const handleExampleLoad = () => {
|
||||
let attempts = 0;
|
||||
|
||||
const waitForExampleContentToRender = setInterval(() => {
|
||||
const exampleIframe = document.getElementById(id) as HTMLIFrameElement;
|
||||
const exampleIframe = document.getElementById(
|
||||
iframeId
|
||||
) as HTMLIFrameElement;
|
||||
const exampleIframeDOM = exampleIframe?.contentDocument;
|
||||
const exampleWrapper = exampleIframeDOM?.getElementById("ds-example");
|
||||
|
||||
if (exampleWrapper) {
|
||||
const newHeight = iframePadding + exampleWrapper.offsetHeight;
|
||||
setIframeHeight(newHeight);
|
||||
clearInterval(waitForExampleContentToRender);
|
||||
setFrameState(newHeight < 300 ? 300 : newHeight);
|
||||
}
|
||||
|
||||
attempts++;
|
||||
@@ -56,35 +56,6 @@ const ComponentExamples = ({
|
||||
.trim()
|
||||
) ?? str;
|
||||
|
||||
const element = (exampleUrl: string, code: string, id: string) => (
|
||||
<>
|
||||
<div className="overflow-hidden rounded-t border border-b-0 border-gray-300 bg-gray-50">
|
||||
<iframe
|
||||
src={exampleUrl}
|
||||
height={iframeHeight}
|
||||
onLoad={() => handleExampleLoad(id)}
|
||||
id={id}
|
||||
aria-label="Komponent eksempler"
|
||||
className="min-w-80 block w-full max-w-full resize-x overflow-auto bg-white shadow-[20px_0_20px_-20px_rgba(0,0,0,0.22)]"
|
||||
title="Kode-eksempler"
|
||||
/>
|
||||
</div>
|
||||
<div className="xs:justify-end mb-2 flex justify-center gap-2 rounded-b border border-gray-300 px-2 py-1 text-base ">
|
||||
<CodeSandbox code={code.trim()} />
|
||||
<Link href={exampleUrl} className="text-gray-900" target="_blank">
|
||||
Åpne i nytt vindu
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<Snippet
|
||||
node={{
|
||||
_type: "kode" as const,
|
||||
code: { code: code.trim(), language: "jsx" },
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
if (
|
||||
!node.dir?.filer ||
|
||||
node.dir.filer.length === 0 ||
|
||||
@@ -94,14 +65,6 @@ const ComponentExamples = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
if (node.standalone) {
|
||||
return element(
|
||||
`/eksempler/${node.filnavn.title.replace(".tsx", "")}`,
|
||||
node.filnavn?.filer?.[0]?.innhold ?? "",
|
||||
iframeId
|
||||
);
|
||||
}
|
||||
|
||||
const active = activeExample ?? node?.dir?.filer?.[0]?.navn;
|
||||
|
||||
return (
|
||||
@@ -122,7 +85,7 @@ const ComponentExamples = ({
|
||||
})}
|
||||
</Chips>
|
||||
</div>
|
||||
{node.dir.filer.map((fil, xi) => {
|
||||
{node.dir.filer.map((fil) => {
|
||||
return (
|
||||
<div
|
||||
key={fil._key}
|
||||
@@ -134,10 +97,46 @@ const ComponentExamples = ({
|
||||
{fil?.description && (
|
||||
<BodyLong className="mb-2">{fil.description}</BodyLong>
|
||||
)}
|
||||
{element(
|
||||
`/eksempler/${node.dir.title}/${fil.navn.replace(".tsx", "")}`,
|
||||
fil.innhold,
|
||||
iframeId + xi
|
||||
|
||||
{active === fil.navn && (
|
||||
<>
|
||||
<div className="overflow-hidden rounded-t border border-b-0 border-gray-300 bg-gray-50">
|
||||
<iframe
|
||||
src={`/eksempler/${node.dir.title}/${fil.navn.replace(
|
||||
".tsx",
|
||||
""
|
||||
)}`}
|
||||
height={frameState}
|
||||
onLoad={() => handleExampleLoad()}
|
||||
id={iframeId}
|
||||
aria-label="Komponent eksempler"
|
||||
className={cl(
|
||||
"min-w-80 block w-full max-w-full resize-x overflow-auto bg-white shadow-[20px_0_20px_-20px_rgba(0,0,0,0.22)]"
|
||||
)}
|
||||
title="Kode-eksempler"
|
||||
/>
|
||||
</div>
|
||||
<div className="xs:justify-end mb-2 flex justify-center gap-2 rounded-b border border-gray-300 px-2 py-1 text-base ">
|
||||
<CodeSandbox code={fil.innhold.trim()} />
|
||||
<Link
|
||||
href={`/eksempler/${node.dir.title}/${fil.navn.replace(
|
||||
".tsx",
|
||||
""
|
||||
)}`}
|
||||
className="text-gray-900"
|
||||
target="_blank"
|
||||
>
|
||||
Åpne i nytt vindu
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<Snippet
|
||||
node={{
|
||||
_type: "kode" as const,
|
||||
code: { code: fil.innhold.trim(), language: "jsx" },
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -27,7 +27,16 @@ const ComponentOverview = ({
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.sort((a, b) => a?.heading?.localeCompare(b?.heading));
|
||||
.sort((a, b) => {
|
||||
if (a?.status?.tag === "deprecated" && b?.status?.tag === "deprecated") {
|
||||
return 0;
|
||||
} else if (a?.status?.tag === "deprecated") {
|
||||
return 1;
|
||||
} else if (b?.status?.tag === "deprecated") {
|
||||
return -1;
|
||||
}
|
||||
return a?.heading?.localeCompare(b?.heading);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="mb-8">
|
||||
@@ -37,7 +46,12 @@ const ComponentOverview = ({
|
||||
<div className="bg-surface-subtle focus-within:ring-border-focus ring-border-subtle hover:shadow-medium min-h-56 group relative rounded-2xl focus-within:ring-[3px] hover:ring-1">
|
||||
<div
|
||||
className={cl(
|
||||
"flex max-h-44 items-center justify-center overflow-hidden rounded-t-2xl"
|
||||
"flex max-h-44 items-center justify-center overflow-hidden rounded-t-2xl",
|
||||
"filter",
|
||||
{
|
||||
"hue-rotate-[65deg]": x?.status?.tag === "beta",
|
||||
grayscale: x?.status?.tag === "deprecated",
|
||||
}
|
||||
)}
|
||||
>
|
||||
{x.status?.bilde ? (
|
||||
|
||||
@@ -162,7 +162,7 @@ const IconSearch = () => {
|
||||
href="https://nav-it.slack.com/archives/C7NE7A8UF"
|
||||
target="_blank"
|
||||
>
|
||||
#designsystem slack.
|
||||
#Aksel-designsystemet på Slack.
|
||||
</Link>
|
||||
</BodyLong>
|
||||
<Modal open={open} onClose={() => handleClose()}>
|
||||
|
||||
@@ -69,11 +69,10 @@ export const BloggAd = () => {
|
||||
</BodyLong>
|
||||
<BodyLong>
|
||||
Ta kontakt med{" "}
|
||||
<NextLink
|
||||
href="https://nav-it.slack.com/archives/C0370ADS0HX"
|
||||
passHref
|
||||
>
|
||||
<Link className="font-semibold text-[#831843]">#Aksel</Link>
|
||||
<NextLink href="https://nav-it.slack.com/archives/C7NE7A8UF" passHref>
|
||||
<Link className="font-semibold text-[#831843]">
|
||||
#Aksel-designsystemet
|
||||
</Link>
|
||||
</NextLink>{" "}
|
||||
på Slack
|
||||
</BodyLong>
|
||||
|
||||
@@ -17,19 +17,19 @@ export const StatusTag = ({
|
||||
case "new":
|
||||
return (
|
||||
<Tag variant="info" size="small">
|
||||
New
|
||||
Ny
|
||||
</Tag>
|
||||
);
|
||||
case "ready":
|
||||
return showStable ? (
|
||||
<Tag variant="success" size="small">
|
||||
Stable
|
||||
Stabil
|
||||
</Tag>
|
||||
) : null;
|
||||
case "deprecated":
|
||||
return (
|
||||
<Tag variant="neutral" size="small">
|
||||
Deprecated
|
||||
Avviklet
|
||||
</Tag>
|
||||
);
|
||||
default:
|
||||
|
||||
@@ -174,9 +174,6 @@ export function TableOfContentsv2({
|
||||
"text-text-subtle": link.id !== activeId || activeSubId,
|
||||
}
|
||||
)}
|
||||
aria-expanded={
|
||||
link?.lvl3?.length > 0 && link?.id === activeId
|
||||
}
|
||||
>
|
||||
{link.heading}
|
||||
</Link>
|
||||
|
||||
@@ -7,6 +7,8 @@ export const ScrollTop = () => {
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
className="text-xlarge text-text-on-inverted focus-visible:shadow-focus-inverted group -mt-[10px] flex h-[48px] w-fit items-center justify-center gap-2 rounded p-2 font-semibold hover:underline focus:outline-none"
|
||||
aria-hidden
|
||||
id="scroll-top-button"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
|
||||
@@ -76,7 +76,7 @@ export const ToolCard = () => {
|
||||
</div>
|
||||
<div>
|
||||
<NextLink href={t.href} passHref>
|
||||
<Link className="text-text-default mb-1 font-semibold no-underline hover:underline">
|
||||
<Link className="text-text-default mb-1 font-semibold">
|
||||
{t.title}
|
||||
</Link>
|
||||
</NextLink>
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
import { BodyShort, Button, Heading, Label, Textarea } from "@navikt/ds-react";
|
||||
import cl from "classnames";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { HelpfulArticleEnum, HelpfulArticleT } from "@/lib";
|
||||
import { AmplitudeEvents, logAmplitudeEvent } from "../utils";
|
||||
import React, {
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { FeedbackT, HelpfulArticleEnum } from "@/lib";
|
||||
import { AmplitudeEvents, IdContext, logAmplitudeEvent } from "../utils";
|
||||
|
||||
const Feedback = ({
|
||||
docId,
|
||||
@@ -18,6 +24,7 @@ const Feedback = ({
|
||||
akselFeedback?: boolean;
|
||||
text?: string;
|
||||
}): JSX.Element => {
|
||||
const idCtx = useContext(IdContext);
|
||||
const { asPath, basePath } = useRouter();
|
||||
const [textValue, setTextValue] = useState("");
|
||||
const [activeState, setActiveState] = useState<HelpfulArticleEnum | null>(
|
||||
@@ -30,17 +37,22 @@ const Feedback = ({
|
||||
const [hasLoggedFeedback, setHasLoggedFeedback] = useState(false);
|
||||
|
||||
const fetchFeedback = () => {
|
||||
const msg: HelpfulArticleT = {
|
||||
answer: activeState,
|
||||
message: textValue,
|
||||
url: `${basePath}${asPath}`,
|
||||
docId: docId,
|
||||
docType: docType,
|
||||
const state = {
|
||||
ja: "ja",
|
||||
nei: "nei",
|
||||
misc: "forslag",
|
||||
};
|
||||
|
||||
fetch("/api/helpfulArticleFeedback", {
|
||||
const body: FeedbackT = {
|
||||
message: textValue,
|
||||
url: `${basePath}${asPath}`,
|
||||
type: state[activeState],
|
||||
docId: idCtx?.id,
|
||||
};
|
||||
|
||||
fetch("/api/feedback", {
|
||||
method: "POST",
|
||||
body: JSON.stringify(msg),
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
};
|
||||
|
||||
@@ -208,6 +220,7 @@ const Feedback = ({
|
||||
x === HelpfulArticleEnum.MISC ? null : HelpfulArticleEnum.MISC
|
||||
)
|
||||
}
|
||||
id="feedback-forbedringer-button"
|
||||
>
|
||||
<Label as="span">Foreslå forbedring</Label>
|
||||
</Button>
|
||||
|
||||
@@ -63,7 +63,10 @@ export const usePageView = (router: Router, pageProps: any) => {
|
||||
const data = {};
|
||||
try {
|
||||
if (pageProps?.page && pageProps.page?._type === "aksel_artikkel") {
|
||||
data["tema"] = pageProps.page.tema.map((x) => x?.slug?.current);
|
||||
const tema = pageProps.page.tema.map((x) => x?.slug?.current) ?? null;
|
||||
if (tema && tema.length > 0) {
|
||||
data["tema"] = tema;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
isDevelopment && console.error(error);
|
||||
|
||||
@@ -7,7 +7,7 @@ export * from "./hooks";
|
||||
export * from "./contexts";
|
||||
|
||||
export const dateStr = (date: string) =>
|
||||
format(new Date(date), "d. MMM YYY", { locale: nbLocale });
|
||||
format(new Date(date), "d. MMMM YYY", { locale: nbLocale });
|
||||
|
||||
export const dateTimeStr = (date: string) =>
|
||||
format(new Date(date), "d-MM-YYY", { locale: nbLocale });
|
||||
|
||||
@@ -10,6 +10,7 @@ test.describe("Axe a11y", () => {
|
||||
const accessibilityScanResults = await new AxeBuilder({ page })
|
||||
.disableRules(["definition-list", "scrollable-region-focusable"])
|
||||
.exclude("iframe")
|
||||
.exclude("#scroll-top-button")
|
||||
.analyze();
|
||||
expect(accessibilityScanResults.violations).toEqual([]);
|
||||
});
|
||||
@@ -20,4 +21,5 @@ test.describe("Axe a11y", () => {
|
||||
Disabled rules:
|
||||
- definition-list: 'div' as a direct child of 'dl' should be valid. Ignoring failed test.
|
||||
- scrollable-region-focusable: Up for discussion. Should code-block be focusable fot easier access and allowing scroll with keyboard?
|
||||
- Excluded "Til toppen" button to avoid error around focusable items with aria-hidden
|
||||
*/
|
||||
@@ -167,7 +167,7 @@ export const akselTema = `*[_type == "godpraksis_landingsside"][0]{
|
||||
${deRefs}
|
||||
}
|
||||
},
|
||||
"temaer": *[_type == "aksel_tema"]{
|
||||
"temaer": *[_type == "aksel_tema" && defined(seksjoner[].sider[])]{
|
||||
...,
|
||||
"refCount": count(*[_type == "aksel_artikkel" && !(_id in path("drafts.**")) && references(^._id)])
|
||||
},
|
||||
@@ -233,8 +233,6 @@ export const akselForsideQuery = `*[_type == "aksel_forside"][0]{
|
||||
}
|
||||
}`;
|
||||
|
||||
export const akselDocumentsByType = `*[_type in $types]{ _type, _id, 'slug': slug.current }`;
|
||||
|
||||
export const akselPrinsippBySlug = `{
|
||||
"prinsipp": *[slug.current == $slug] | order(_updatedAt desc)[0]
|
||||
{
|
||||
@@ -282,8 +280,6 @@ export const akselEditorById = `*[_id == $id][0]
|
||||
${contributorsAll}
|
||||
}`;
|
||||
|
||||
export const dsDocuments = `*[_type in ["komponent_artikkel", "ds_artikkel"]]{ ..., 'slug': slug.current }`;
|
||||
|
||||
const sidebarQuery = `"sidebar": *[_type == $type && defined(kategori)] {
|
||||
heading,
|
||||
"slug": slug.current,
|
||||
@@ -291,6 +287,11 @@ const sidebarQuery = `"sidebar": *[_type == $type && defined(kategori)] {
|
||||
"tag": status.tag,
|
||||
}`;
|
||||
|
||||
/**
|
||||
* "refs" må disables i preview da next-sanity sin
|
||||
* preview-funksjonalitet fører til en infinite loop som låser applikasjonen.
|
||||
* Dette er på grunn av av hele datasettet blir lastet inn i preview flere ganger som til slutt låser vinduet.
|
||||
*/
|
||||
export const komponentQuery = `{
|
||||
"page": *[_type == "komponent_artikkel" && slug.current == $slug] | order(_updatedAt desc)[0]
|
||||
{
|
||||
@@ -313,12 +314,15 @@ export const komponentQuery = `{
|
||||
${deRefs}
|
||||
},
|
||||
},
|
||||
"refs": *[_type == "komponent_artikkel" && count(*[references(^._id)][slug.current == $slug]) > 0][0...3]{
|
||||
_id,
|
||||
heading,
|
||||
"slug": slug,
|
||||
status
|
||||
},
|
||||
"refs": select(
|
||||
$preview == "true" => [],
|
||||
$preview != "true" => *[_type == "komponent_artikkel" && count(*[references(^._id)][slug.current == $slug]) > 0][0...3]{
|
||||
_id,
|
||||
heading,
|
||||
"slug": slug,
|
||||
status
|
||||
}
|
||||
),
|
||||
"seo": *[_type == "komponenter_landingsside"][0].seo.image,
|
||||
${sidebarQuery}
|
||||
}`;
|
||||
@@ -337,8 +341,6 @@ export const grunnleggendeQuery = `{
|
||||
${sidebarQuery}
|
||||
}`;
|
||||
|
||||
export const akselTemaNames = `*[_type == "aksel_tema" && count(*[references(^._id)]) > 0].slug`;
|
||||
|
||||
export const akselTemaDocs = `{
|
||||
"tema": *[_type == "aksel_tema" && slug.current == $slug] | order(_updatedAt desc)[0]{
|
||||
...,
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import imageUrlBuilder from "@sanity/image-url";
|
||||
import { SanityT } from "..";
|
||||
import { akselDocumentsByType, akselTemaNames, dsDocuments } from "./queries";
|
||||
import { getClient, noCdnClient, sanityClient } from "./sanity.server";
|
||||
|
||||
const imageBuilder = imageUrlBuilder(sanityClient);
|
||||
@@ -10,23 +8,40 @@ export function urlFor(source: any) {
|
||||
}
|
||||
|
||||
export const getAllPages = async (token?: string) => {
|
||||
const komponenter = await getDocumentsTmp("komponent_artikkel", token);
|
||||
const grunnleggende = await getDocumentsTmp("ds_artikkel", token);
|
||||
|
||||
const artikler = await getAkselDocuments("all", token);
|
||||
const temaer = await getAkselTema(token);
|
||||
|
||||
return [
|
||||
"",
|
||||
"god-praksis",
|
||||
"produktbloggen",
|
||||
...komponenter,
|
||||
...grunnleggende,
|
||||
...artikler,
|
||||
...temaer.map((x) => `god-praksis/${x}`),
|
||||
];
|
||||
const pages = await sitemapPages(token);
|
||||
return pages.map((x) => x.path);
|
||||
};
|
||||
|
||||
export async function sitemapPages(
|
||||
token?: string
|
||||
): Promise<{ path: string; lastmod: string }[]> {
|
||||
const client = token ? noCdnClient(token) : getClient();
|
||||
const artikler = await getDocuments("all");
|
||||
const temaer = await getAkselTema();
|
||||
|
||||
const pages = await client.fetch(
|
||||
`{
|
||||
"frontpage": *[_type == "aksel_forside"][0]._updatedAt,
|
||||
"godpraksis": *[_type == "godpraksis_landingsside"][0]._updatedAt,
|
||||
"grunnleggende": *[_type == "grunnleggende_landingsside"][0]._updatedAt,
|
||||
"komponenter": *[_type == "komponenter_landingsside"][0]._updatedAt,
|
||||
"blogg": *[_type == "blogg_landingsside"][0]._updatedAt,
|
||||
}`
|
||||
);
|
||||
return [
|
||||
{ path: "", lastmod: pages.frontpage._updatedAt },
|
||||
{ path: "god-praksis", lastmod: pages.godpraksis._updatedAt },
|
||||
{ path: "grunnleggende", lastmod: pages.grunnleggende._updatedAt },
|
||||
{ path: "komponenter", lastmod: pages.komponenter._updatedAt },
|
||||
{ path: "produktbloggen", lastmod: pages.blogg._updatedAt },
|
||||
...temaer.map((x) => ({
|
||||
path: `god-praksis/${x.path}`,
|
||||
lastmod: x.lastmod,
|
||||
})),
|
||||
...artikler.map((x) => ({ ...x, path: x.slug })),
|
||||
];
|
||||
}
|
||||
|
||||
export const getAkselDocuments = async (
|
||||
source:
|
||||
| "aksel_artikkel"
|
||||
@@ -38,38 +53,60 @@ export const getAkselDocuments = async (
|
||||
token?: string
|
||||
): Promise<string[]> => {
|
||||
if (!source) return [];
|
||||
const client = token ? noCdnClient(token) : getClient();
|
||||
const documents: any[] | null = await client.fetch(akselDocumentsByType, {
|
||||
types:
|
||||
source === "all"
|
||||
? [
|
||||
"aksel_artikkel",
|
||||
"aksel_blogg",
|
||||
"aksel_prinsipp",
|
||||
"aksel_standalone",
|
||||
]
|
||||
: [source],
|
||||
});
|
||||
const paths = [];
|
||||
const docs = await getDocuments(source, token);
|
||||
|
||||
const nonDrafts = documents.filter((x) => !x._id.startsWith("drafts."));
|
||||
|
||||
nonDrafts?.forEach((page) => {
|
||||
page.slug && paths.push(page.slug);
|
||||
});
|
||||
|
||||
return paths;
|
||||
return docs.map((x) => x.slug);
|
||||
};
|
||||
|
||||
export const getDocumentsTmp = async (
|
||||
source: "komponent_artikkel" | "ds_artikkel",
|
||||
token?: string
|
||||
): Promise<string[]> => {
|
||||
const docs = await getDocuments(source, token);
|
||||
|
||||
return docs.map((x) => x.slug);
|
||||
};
|
||||
|
||||
export async function getAkselTema(
|
||||
token?: string
|
||||
): Promise<{ path: string; lastmod: string }[]> {
|
||||
const client = token ? noCdnClient(token) : getClient();
|
||||
const tags: { slug: { current: string }; _updatedAt: string }[] =
|
||||
await client.fetch(
|
||||
`*[_type == "aksel_tema" && count(*[references(^._id)]) > 0]{slug,_updatedAt}`
|
||||
);
|
||||
return tags.map((x) => ({
|
||||
path: x?.slug.current,
|
||||
lastmod: x?._updatedAt,
|
||||
}));
|
||||
}
|
||||
|
||||
async function getDocuments(
|
||||
source:
|
||||
| "komponent_artikkel"
|
||||
| "ds_artikkel"
|
||||
| "aksel_artikkel"
|
||||
| "aksel_blogg"
|
||||
| "aksel_prinsipp"
|
||||
| "aksel_standalone"
|
||||
| "all",
|
||||
token?: string
|
||||
): Promise<{ slug: string; lastmod: string }[]> {
|
||||
const client = token ? noCdnClient(token) : getClient();
|
||||
const documents: any[] | null = await client.fetch(
|
||||
`*[_type in $types]{ _type, _id, 'slug': slug.current }`,
|
||||
`*[_type in $types]{ _type, _id, 'slug': slug.current, _updatedAt }`,
|
||||
{
|
||||
types: [source],
|
||||
types:
|
||||
source === "all"
|
||||
? [
|
||||
"komponent_artikkel",
|
||||
"ds_artikkel",
|
||||
"aksel_artikkel",
|
||||
"aksel_blogg",
|
||||
"aksel_prinsipp",
|
||||
"aksel_standalone",
|
||||
]
|
||||
: [source],
|
||||
}
|
||||
);
|
||||
const paths = [];
|
||||
@@ -77,14 +114,8 @@ export const getDocumentsTmp = async (
|
||||
documents
|
||||
.filter((x) => !x._id.startsWith("drafts."))
|
||||
?.forEach((page) => {
|
||||
page.slug && paths.push(page.slug);
|
||||
page.slug && paths.push({ slug: page.slug, lastmod: page._updatedAt });
|
||||
});
|
||||
|
||||
return paths;
|
||||
};
|
||||
|
||||
export const getAkselTema = async (token?: string): Promise<string[]> => {
|
||||
const client = token ? noCdnClient(token) : getClient();
|
||||
const tags: { current: string }[] = await client.fetch(akselTemaNames);
|
||||
return tags.map((x) => x?.current);
|
||||
};
|
||||
}
|
||||
@@ -17,16 +17,9 @@ export enum HelpfulArticleEnum {
|
||||
"MISC" = "misc",
|
||||
}
|
||||
|
||||
export type HelpfulArticleT = {
|
||||
answer: HelpfulArticleEnum;
|
||||
message?: string;
|
||||
export type FeedbackT = {
|
||||
message: string;
|
||||
url: string;
|
||||
docId: string;
|
||||
docType: string;
|
||||
};
|
||||
|
||||
export type DsFeddbackMsgT = {
|
||||
message: string;
|
||||
user?: string;
|
||||
url: string;
|
||||
type?: "ja" | "nei" | "forslag" | "footer";
|
||||
};
|
||||
@@ -10,15 +10,16 @@
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"e2e": "yarn build && yarn start-server-and-test start http://localhost:3000 playwright",
|
||||
"e2e:full": "yarn build && npx ts-node ./e2e/genUrls.ts && FULL_TEST=true yarn start-server-and-test start http://localhost:3000 playwright",
|
||||
"update:props": "npx ts-node --project tsconfig.tsnode.json ./lib/update-documents/update-props",
|
||||
"update:tokens": "npx ts-node --project tsconfig.tsnode.json ./lib/update-documents/update-tokens",
|
||||
"update:eksempler": "npx ts-node --project tsconfig.tsnode.json ./lib/examples/update-sanity",
|
||||
"e2e:full": "yarn build && ts-node ./e2e/genUrls.ts && FULL_TEST=true yarn start-server-and-test start http://localhost:3000 playwright",
|
||||
"update:props": "ts-node --project tsconfig.tsnode.json ./scripts/update-props",
|
||||
"update:tokens": "ts-node --project tsconfig.tsnode.json ./scripts/update-tokens",
|
||||
"update:eksempler": "ts-node --project tsconfig.tsnode.json ./scripts/examples/update-sanity",
|
||||
"update:sanity": "yarn update:tokens && yarn update:props && yarn update:eksempler",
|
||||
"analyze": "cross-env ANALYZE=true next build",
|
||||
"test": "jest",
|
||||
"playwright": "playwright test",
|
||||
"test:watch": "jest --watch"
|
||||
"test:watch": "jest --watch",
|
||||
"backup": "ts-node scripts/backup.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@sanity/block-content-to-react": "^3.0.0",
|
||||
@@ -51,7 +52,6 @@
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"react-modal": "3.15.1",
|
||||
"react-snowfall": "1.2.1",
|
||||
"sanity": "3.0.6",
|
||||
"sanity-plugin-asset-source-unsplash": "^1.0.0",
|
||||
"sanity-plugin-iframe-pane": "^2.1.1",
|
||||
@@ -86,6 +86,7 @@
|
||||
"postcss-loader": "7.0.0",
|
||||
"start-server-and-test": "^1.14.0",
|
||||
"ts-jest": "^29.0.0",
|
||||
"ts-node": "10.9.0",
|
||||
"typescript": "^4.8.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import dotenv from "dotenv";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { FeedbackT } from "@/lib";
|
||||
import { noCdnClient } from "../../lib/sanity/sanity.server";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const isDevelopment = process.env.NODE_ENV === "development";
|
||||
|
||||
const randKey = () => {
|
||||
let result = "";
|
||||
const characters =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
const charactersLength = 12;
|
||||
for (let i = 0; i < charactersLength; i++) {
|
||||
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
): Promise<void> {
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const token = process.env.SANITY_WRITE_KEY;
|
||||
|
||||
if (!token && isDevelopment) {
|
||||
console.log("No token! api/feedback");
|
||||
return;
|
||||
}
|
||||
|
||||
// this is our transactional client, it won't push anything until we say .commit() later
|
||||
const transactionClient = noCdnClient(token).transaction();
|
||||
const data: FeedbackT = JSON.parse(req.body);
|
||||
|
||||
if (!data?.docId) {
|
||||
console.log("No docId! api/feedback");
|
||||
return;
|
||||
}
|
||||
const doc = {
|
||||
_id: `feedback.${randKey()}`,
|
||||
_type: "aksel_feedback",
|
||||
feedback_type:
|
||||
data.type === "footer" ? "footer" : "artikkel_feedback",
|
||||
...(data.type === "footer" ? {} : { artikkel_feedback: data.type }),
|
||||
melding: data.message,
|
||||
behandlet: false,
|
||||
url: data.url,
|
||||
doc_ref: {
|
||||
_ref: data.docId,
|
||||
_type: "reference",
|
||||
_weak: true,
|
||||
},
|
||||
};
|
||||
|
||||
transactionClient.create(doc);
|
||||
|
||||
await transactionClient
|
||||
.commit()
|
||||
.then(() => console.log("Feedback-logged"))
|
||||
.catch((e) => console.error(e.message));
|
||||
|
||||
return res.json({ status: "ok" });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ msg: "Error, check console" });
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { DsFeddbackMsgT } from "@/lib";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
): Promise<void> {
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const trelloKey = "c319bd921b9b1a9d8fb2d3c872c0134e";
|
||||
const trelloToken = process.env.TRELLO_TOKEN;
|
||||
const labels = "619e2f030ae5bb5e10c9572f";
|
||||
|
||||
const data: DsFeddbackMsgT = JSON.parse(req.body);
|
||||
|
||||
if (!trelloKey || !trelloToken) {
|
||||
res.status(500).json({ msg: "Could not find needed tokens in .env" });
|
||||
return;
|
||||
}
|
||||
|
||||
const card = `&name=${data.message}&desc=**Bruker:** %0A **Side:** %0A ${data.url}`;
|
||||
const url = `https://api.trello.com/1/cards?idList=619cc5721924df5816bcc45f&idLabels=${labels}&key=${trelloKey}&token=${trelloToken}${card}`;
|
||||
|
||||
const postRes = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
if (!postRes.ok) {
|
||||
throw new Error(
|
||||
`request failed with status ${res.status}: ${await postRes.text()}`
|
||||
);
|
||||
}
|
||||
return res.json({ status: "ok" });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ msg: "Error, check console" });
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { HelpfulArticleT, HelpfulArticleEnum } from "@/lib";
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse
|
||||
): Promise<void> {
|
||||
switch (req.method) {
|
||||
case "POST":
|
||||
try {
|
||||
const trelloKey = "c319bd921b9b1a9d8fb2d3c872c0134e";
|
||||
const trelloToken = process.env.TRELLO_TOKEN;
|
||||
|
||||
if (!trelloKey || !trelloToken) {
|
||||
res.status(500).json({ msg: "Could not find needed tokens in .env" });
|
||||
return;
|
||||
}
|
||||
|
||||
const data: HelpfulArticleT = JSON.parse(req.body);
|
||||
const sideUrl = "https://aksel.nav.no";
|
||||
|
||||
/* Var denne artikkelen til hjelp? */
|
||||
const trelloList = "61d44fc3995604743a83f5cb";
|
||||
|
||||
let label = "";
|
||||
switch (data.answer) {
|
||||
case HelpfulArticleEnum.JA:
|
||||
label = "61d44fd76c19645dd4d423ab";
|
||||
break;
|
||||
case HelpfulArticleEnum.DELVIS:
|
||||
label = "61d44fe8180b832f7c89c3d4";
|
||||
break;
|
||||
case HelpfulArticleEnum.NEI:
|
||||
label = "61d44fdeb5bfff71c69d619b";
|
||||
break;
|
||||
case HelpfulArticleEnum.MISC:
|
||||
label = "61d44ff4f92e56297e937af8";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const editUrl = `https://verktoykasse.sanity.studio/desk/__edit__${data.docId}%2Ctype%3D${data.docType}`;
|
||||
|
||||
const card = `&name=${data.message}&desc=**Side:** %0A
|
||||
${sideUrl + data.url} %0A
|
||||
**[Rediger side](${editUrl})**`;
|
||||
|
||||
const url = `https://api.trello.com/1/cards?idList=${trelloList}&idLabels=${label}&key=${trelloKey}&token=${trelloToken}${card}`;
|
||||
|
||||
const postRes = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
if (!postRes.ok) {
|
||||
throw new Error(
|
||||
`request failed with status ${res.status}: ${await postRes.text()}`
|
||||
);
|
||||
}
|
||||
return res.json({ status: "ok" });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ msg: "Error, check console" });
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import { SitemapStream, streamToPromise } from "sitemap";
|
||||
import { getAllPages } from "@/lib";
|
||||
import { sitemapPages } from "@/lib";
|
||||
|
||||
/* https://linguinecode.com/post/add-robots-txt-file-sitemaps-nextjs */
|
||||
export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
@@ -9,14 +9,14 @@ export default async (req: NextApiRequest, res: NextApiResponse) => {
|
||||
hostname: `https://${req.headers.host}`,
|
||||
});
|
||||
|
||||
const pages = await getAllPages();
|
||||
const pages = await sitemapPages();
|
||||
|
||||
// Create each URL row
|
||||
pages.forEach((post) => {
|
||||
smStream.write({
|
||||
url: `/${post}`,
|
||||
changefreq: "weekly",
|
||||
priority: 0.5,
|
||||
url: `/${post.path}`,
|
||||
changefreq: "monthly",
|
||||
lastmod: post.lastmod,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Chat } from "@navikt/ds-react";
|
||||
import { withDsExample } from "components/website-modules/examples/withDsExample";
|
||||
|
||||
const Example = () => {
|
||||
return (
|
||||
<div className="grid gap-10">
|
||||
<Chat avatar="EVA" name="EVA" timestamp="01.01.21 14:00">
|
||||
<Chat.Bubble>Hei! Mitt navn er Eva.</Chat.Bubble>
|
||||
<Chat.Bubble>Hva kan jeg hjelpe deg med?</Chat.Bubble>
|
||||
</Chat>
|
||||
<Chat
|
||||
avatar="NO"
|
||||
name="Ola Normann"
|
||||
timestamp="01.01.21 14:00"
|
||||
position="right"
|
||||
toptextPosition="left"
|
||||
>
|
||||
<Chat.Bubble>Hei Eva.</Chat.Bubble>
|
||||
<Chat.Bubble>
|
||||
Hvor sjekker jeg statusen på foreldrepengersøknaden min?
|
||||
</Chat.Bubble>
|
||||
</Chat>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default withDsExample(Example);
|
||||
|
||||
export const args = {
|
||||
index: 3,
|
||||
desc: "Noen ganger ønsker man mer fleksibilitet for plassering av navn + tid i chatboblen.",
|
||||
};
|
||||
@@ -43,6 +43,8 @@ const Page = ({ tema: page }: PageProps): JSX.Element => {
|
||||
|
||||
const hasAnsvarlig = !!page?.ansvarlig?.title;
|
||||
|
||||
const hasPages = !!page.seksjoner.find((x) => !!x.sider);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -74,10 +76,10 @@ const Page = ({ tema: page }: PageProps): JSX.Element => {
|
||||
<main
|
||||
tabIndex={-1}
|
||||
id="hovedinnhold"
|
||||
className="min-h-[80vh] focus:outline-none"
|
||||
className="relative min-h-[80vh] overflow-hidden focus:outline-none"
|
||||
>
|
||||
<div className="relative overflow-hidden pt-20 text-center">
|
||||
<AkselCubeStatic className="text-deepblue-300 opacity-5 " />
|
||||
<AkselCubeStatic className="text-deepblue-300 opacity-5 " />
|
||||
<div className=" pt-20 text-center">
|
||||
<div className="dynamic-wrapper px-4 pb-6 text-center">
|
||||
<Image
|
||||
src={urlFor(page.pictogram.url).auto("format").url()}
|
||||
@@ -143,35 +145,45 @@ const Page = ({ tema: page }: PageProps): JSX.Element => {
|
||||
</div>
|
||||
|
||||
<div className="relative px-4 pt-8 pb-24 md:pt-16 xl:pt-8 ">
|
||||
<div className="dynamic-wrapper grid gap-20">
|
||||
{page.seksjoner.map((seksjon) => (
|
||||
<div key={seksjon._key}>
|
||||
<Heading level="2" size="medium">
|
||||
{seksjon.title}
|
||||
</Heading>
|
||||
{seksjon.beskrivelse && (
|
||||
<div className="max-w-prose">
|
||||
<SanityBlockContent
|
||||
blocks={seksjon.beskrivelse}
|
||||
noLastMargin
|
||||
/>
|
||||
{hasPages ? (
|
||||
<div className="dynamic-wrapper grid gap-20">
|
||||
{page.seksjoner.map((seksjon) =>
|
||||
seksjon?.sider ? (
|
||||
<div key={seksjon._key}>
|
||||
<Heading level="2" size="medium">
|
||||
{seksjon.title}
|
||||
</Heading>
|
||||
{seksjon.beskrivelse && (
|
||||
<div className="max-w-prose">
|
||||
<SanityBlockContent
|
||||
blocks={seksjon.beskrivelse}
|
||||
noLastMargin
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div className="card-grid-3-1 mt-6">
|
||||
{(seksjon?.sider as unknown as ArtiklerT[])?.map(
|
||||
(x: ArtiklerT) => (
|
||||
<ArtikkelCard
|
||||
{...x}
|
||||
source={page?.slug?.current}
|
||||
key={x._id}
|
||||
variant="god-praksis"
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="card-grid-3-1 mt-6">
|
||||
{(seksjon.sider as unknown as ArtiklerT[]).map(
|
||||
(x: ArtiklerT) => (
|
||||
<ArtikkelCard
|
||||
{...x}
|
||||
source={page?.slug?.current}
|
||||
key={x._id}
|
||||
variant="god-praksis"
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : null
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
<div className="dynamic-wrapper mb-20">
|
||||
<Heading level="2" size="medium">
|
||||
Fant ingen artikler her enda...
|
||||
</Heading>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</main>
|
||||
<Footer />
|
||||
@@ -206,9 +218,9 @@ export default Wrapper;
|
||||
export const getStaticPaths = async () => {
|
||||
return {
|
||||
paths: await getAkselTema().then((paths) =>
|
||||
paths.map((slug) => ({
|
||||
paths.map(({ path }) => ({
|
||||
params: {
|
||||
slug,
|
||||
slug: path,
|
||||
},
|
||||
}))
|
||||
),
|
||||
|
||||
@@ -109,6 +109,7 @@ export const getStaticProps = async () => {
|
||||
return {
|
||||
props: {
|
||||
articles,
|
||||
id: "godpraksis_landingsside_id1",
|
||||
},
|
||||
revalidate: 60,
|
||||
};
|
||||
|
||||
@@ -3,7 +3,13 @@ import { Footer } from "@/layout";
|
||||
import { akselForsideQuery, SanityT, urlFor } from "@/lib";
|
||||
import { getClient } from "@/sanity-client";
|
||||
import { BodyLong, Heading } from "@navikt/ds-react";
|
||||
import { ComponentIcon, DownloadIcon, TokenIcon } from "@sanity/icons";
|
||||
import {
|
||||
ComponentIcon,
|
||||
DownloadIcon,
|
||||
PauseIcon,
|
||||
PlayIcon,
|
||||
TokenIcon,
|
||||
} from "@sanity/icons";
|
||||
import { Header } from "components/layout/header/Header";
|
||||
import ArtikkelCard from "components/sanity-modules/cards/ArtikkelCard";
|
||||
import GodPraksisCard from "components/sanity-modules/cards/GodPraksisCard";
|
||||
@@ -14,8 +20,15 @@ import { ToolCard } from "components/website-modules/ToolsCard";
|
||||
import { PreviewSuspense } from "next-sanity/preview";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import Snowfall from "react-snowfall";
|
||||
import { lazy } from "react";
|
||||
import { lazy, useEffect, useState } from "react";
|
||||
import cl from "classnames";
|
||||
|
||||
function getPrefersReducedMotion() {
|
||||
const QUERY = "(prefers-reduced-motion: no-preference)";
|
||||
const mediaQueryList = window.matchMedia(QUERY);
|
||||
const prefersReducedMotion = !mediaQueryList.matches;
|
||||
return prefersReducedMotion;
|
||||
}
|
||||
|
||||
const introcards = [
|
||||
{
|
||||
@@ -62,9 +75,21 @@ const IntroCards = () => {
|
||||
|
||||
const GetStarted = ({
|
||||
links,
|
||||
togglePause,
|
||||
}: {
|
||||
links: { title: string; slug: string }[];
|
||||
togglePause: (x: boolean) => void;
|
||||
}) => {
|
||||
const [reducedMotion, setReducedMotion] = useState(false);
|
||||
const [pause, setPause] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setReducedMotion(getPrefersReducedMotion());
|
||||
const data = localStorage.getItem("pause-animations");
|
||||
setPause(JSON.parse(data) ?? false);
|
||||
togglePause(JSON.parse(data) ?? false);
|
||||
}, [togglePause]);
|
||||
|
||||
return (
|
||||
<div className="bg-deepblue-700 text-text-on-action relative mx-auto w-full max-w-screen-lg -translate-y-1/2 rounded-2xl py-12 px-2">
|
||||
<Heading size="xlarge" level="2" className="text-center">
|
||||
@@ -84,13 +109,28 @@ const GetStarted = ({
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div aria-hidden>
|
||||
<Snowfall
|
||||
color="rgba(230, 241, 248, 0.3)"
|
||||
speed={[0.2, 1.0]}
|
||||
snowflakeCount={70}
|
||||
/>
|
||||
</div>
|
||||
{!reducedMotion && (
|
||||
<button
|
||||
className="focus-visible:ring-border-focus-on-inverted absolute top-2 right-2 grid h-11 w-11 place-items-center rounded text-2xl focus:outline-none focus-visible:ring-2"
|
||||
onClick={() => {
|
||||
setPause(!pause);
|
||||
togglePause(!pause);
|
||||
localStorage.setItem("pause-animations", JSON.stringify(!pause));
|
||||
}}
|
||||
>
|
||||
{pause ? (
|
||||
<>
|
||||
<PlayIcon aria-hidden />
|
||||
<span className="sr-only">Start animasjon</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<PauseIcon aria-hidden />
|
||||
<span className="sr-only">Stopp animasjon</span>
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -104,6 +144,8 @@ const Forside = ({
|
||||
resent,
|
||||
komigang,
|
||||
}: PageProps): JSX.Element => {
|
||||
const [pause, setPause] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
@@ -141,10 +183,15 @@ const Forside = ({
|
||||
/>
|
||||
</Head>
|
||||
|
||||
<div className="header-animated-bg relative max-w-[100vw] overflow-hidden bg-[#DCCAF3]">
|
||||
<div
|
||||
className={cl(
|
||||
"header-animated-bg relative max-w-[100vw] overflow-hidden bg-[#DCCAF3]",
|
||||
{ "animation-stop": pause }
|
||||
)}
|
||||
>
|
||||
<Header variant="transparent" />
|
||||
|
||||
<main tabIndex={-1} id="hovedinnhold" className=" focus:outline-none">
|
||||
<main tabIndex={-1} id="hovedinnhold" className="focus:outline-none">
|
||||
<div className="z-20 pb-8">
|
||||
<div className="centered-layout xs:mt-36 xs:mb-18 xs:max-w-screen-xs relative mb-16 mt-20 grid max-w-xs place-items-center text-center">
|
||||
<Heading
|
||||
@@ -161,7 +208,7 @@ const Forside = ({
|
||||
</div>
|
||||
<div className="bg-surface-subtle min-h-96 relative pb-72 md:pb-40">
|
||||
<div className="centered-layout grid max-w-screen-2xl">
|
||||
<GetStarted links={komigang} />
|
||||
<GetStarted links={komigang} togglePause={setPause} />
|
||||
{/* God praksis */}
|
||||
<div className="mx-auto">
|
||||
<Heading
|
||||
@@ -296,11 +343,10 @@ export const getStaticProps = async ({
|
||||
komigang,
|
||||
slug: "/",
|
||||
preview,
|
||||
id: page?._id ?? "",
|
||||
},
|
||||
revalidate: 60,
|
||||
};
|
||||
};
|
||||
|
||||
export default Page;
|
||||
|
||||
<div>lorem</div>;
|
||||
@@ -1,8 +1,15 @@
|
||||
import { dateStr } from "@/components";
|
||||
import {
|
||||
ChangelogIcon,
|
||||
dateStr,
|
||||
FigmaIcon,
|
||||
GithubIcon,
|
||||
logAmplitudeEvent,
|
||||
YarnIcon,
|
||||
} from "@/components";
|
||||
import { getDocumentsTmp, komponentQuery, urlFor } from "@/lib";
|
||||
import { SanityBlockContent } from "@/sanity-block";
|
||||
import { getClient } from "@/sanity-client";
|
||||
import { Detail, Heading } from "@navikt/ds-react";
|
||||
import { BodyShort, Detail, Heading } from "@navikt/ds-react";
|
||||
import { WithSidebar } from "components/layout/page-templates/WithSidebar";
|
||||
import ComponentOverview from "components/sanity-modules/component-overview";
|
||||
import IntroSeksjon from "components/sanity-modules/IntroSeksjon";
|
||||
@@ -13,6 +20,51 @@ import Head from "next/head";
|
||||
import { lazy } from "react";
|
||||
import NotFotfund from "../404";
|
||||
|
||||
const kodepakker = {
|
||||
"ds-react": {
|
||||
title: "@navikt/ds-react",
|
||||
git: "https://github.com/navikt/Designsystemet/tree/master/%40navikt/core/react",
|
||||
changelog:
|
||||
"https://github.com/navikt/Designsystemet/blob/master/%40navikt/core/react/CHANGELOG.md",
|
||||
},
|
||||
"ds-css": {
|
||||
title: "@navikt/ds-css",
|
||||
git: "https://github.com/navikt/Designsystemet/tree/master/%40navikt/core/css",
|
||||
changelog:
|
||||
"https://github.com/navikt/Designsystemet/blob/master/%40navikt/core/css/CHANGELOG.md",
|
||||
},
|
||||
"ds-react-internal": {
|
||||
title: "@navikt/ds-react-internal",
|
||||
git: "https://github.com/navikt/Designsystemet/tree/master/%40navikt/internal/react",
|
||||
changelog:
|
||||
"https://github.com/navikt/Designsystemet/blob/master/%40navikt/internal/react/CHANGELOG.md",
|
||||
},
|
||||
"ds-css-internal": {
|
||||
title: "@navikt/ds-css-internal",
|
||||
git: "https://github.com/navikt/Designsystemet/tree/master/%40navikt/internal/css",
|
||||
changelog:
|
||||
"https://github.com/navikt/Designsystemet/blob/master/%40navikt/internal/css/CHANGELOG.md",
|
||||
},
|
||||
"ds-icons": {
|
||||
title: "@navikt/ds-reaciconst",
|
||||
git: "https://github.com/navikt/Designsystemet/tree/master/%40navikt/icons",
|
||||
changelog:
|
||||
"https://github.com/navikt/Designsystemet/blob/master/%40navikt/icons/CHANGELOG.md",
|
||||
},
|
||||
"ds-tokens": {
|
||||
title: "@navikt/ds-tokens",
|
||||
git: "https://github.com/navikt/Designsystemet/tree/master/%40navikt/core/tokens",
|
||||
changelog:
|
||||
"https://github.com/navikt/Designsystemet/blob/master/%40navikt/core/tokens/CHANGELOG.md",
|
||||
},
|
||||
"ds-tailwind": {
|
||||
title: "@navikt/ds-tailwind",
|
||||
git: "https://github.com/navikt/Designsystemet/tree/master/%40navikt/core/tailwind",
|
||||
changelog:
|
||||
"https://github.com/navikt/Designsystemet/blob/master/%40navikt/core/tailwind/CHANGELOG.md",
|
||||
},
|
||||
};
|
||||
|
||||
const Page = ({
|
||||
page,
|
||||
sidebar,
|
||||
@@ -30,6 +82,8 @@ const Page = ({
|
||||
return <NotFotfund />;
|
||||
}
|
||||
|
||||
const pack = page?.kodepakker?.length > 0 && kodepakker[page?.kodepakker[0]];
|
||||
|
||||
const date = page?.updateInfo?.lastVerified
|
||||
? page?.updateInfo?.lastVerified
|
||||
: page?.publishedAt
|
||||
@@ -98,6 +152,81 @@ const Page = ({
|
||||
)
|
||||
}
|
||||
>
|
||||
<BodyShort
|
||||
as="span"
|
||||
size="small"
|
||||
className="text-text-subtle mb-6 flex flex-wrap gap-4"
|
||||
>
|
||||
{pack && (
|
||||
<>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
href={pack.git}
|
||||
className="hover:text-text-default focus:text-text-on-inverted focus:shadow-focus flex items-center gap-1 underline hover:no-underline focus:bg-blue-800 focus:no-underline focus:outline-none"
|
||||
onClick={() =>
|
||||
logAmplitudeEvent("link", {
|
||||
kilde: "intro-lenker komponenter",
|
||||
til: "github",
|
||||
})
|
||||
}
|
||||
>
|
||||
<GithubIcon /> Github
|
||||
</a>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
href={`https://yarnpkg.com/package/${pack.title}`}
|
||||
className="hover:text-text-default focus:text-text-on-inverted focus:shadow-focus flex items-center gap-1 underline hover:no-underline focus:bg-blue-800 focus:no-underline focus:outline-none"
|
||||
onClick={() =>
|
||||
logAmplitudeEvent("link", {
|
||||
kilde: "intro-lenker komponenter",
|
||||
til: "yarn",
|
||||
})
|
||||
}
|
||||
>
|
||||
<YarnIcon />
|
||||
Yarn
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
|
||||
{page.figma_link && (
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
href={page.figma_link}
|
||||
className="hover:text-text-default focus:text-text-on-inverted focus:shadow-focus flex items-center gap-1 underline hover:no-underline focus:bg-blue-800 focus:no-underline focus:outline-none"
|
||||
onClick={() =>
|
||||
logAmplitudeEvent("link", {
|
||||
kilde: "intro-lenker komponenter",
|
||||
til: "figma",
|
||||
})
|
||||
}
|
||||
>
|
||||
<FigmaIcon /> Figma
|
||||
</a>
|
||||
)}
|
||||
{pack && (
|
||||
<>
|
||||
<a
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
href={pack.changelog}
|
||||
className="hover:text-text-default focus:text-text-on-inverted focus:shadow-focus flex items-center gap-1 underline hover:no-underline focus:bg-blue-800 focus:no-underline focus:outline-none"
|
||||
onClick={() =>
|
||||
logAmplitudeEvent("link", {
|
||||
kilde: "intro-lenker komponenter",
|
||||
til: "endringslogg",
|
||||
})
|
||||
}
|
||||
>
|
||||
<ChangelogIcon />
|
||||
Endringslogg
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
</BodyShort>
|
||||
{page?.status?.tag === "beta" && <BetaWarning />}
|
||||
<IntroSeksjon node={page?.intro} />
|
||||
<SanityBlockContent blocks={page["content"]} />
|
||||
@@ -118,6 +247,7 @@ const Wrapper = (props: any): JSX.Element => {
|
||||
params={{
|
||||
slug: `komponenter/${props.slug.slice(0, 2).join("/")}`,
|
||||
type: "komponent_artikkel",
|
||||
preview: "true",
|
||||
}}
|
||||
props={props}
|
||||
/>
|
||||
@@ -156,6 +286,7 @@ export const getStaticProps = async ({
|
||||
const { page, sidebar, refs, seo } = await getClient().fetch(komponentQuery, {
|
||||
slug: `komponenter/${slug.slice(0, 2).join("/")}`,
|
||||
type: "komponent_artikkel",
|
||||
preview: "false",
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -131,7 +131,7 @@ const Page = ({
|
||||
aria-hidden
|
||||
priority
|
||||
className="rounded-2xl"
|
||||
alt="Illustrasjon"
|
||||
alt=""
|
||||
quality={100}
|
||||
/>
|
||||
) : (
|
||||
@@ -143,7 +143,7 @@ const Page = ({
|
||||
aria-hidden
|
||||
priority
|
||||
className="rounded-2xl"
|
||||
alt="Illustrasjon"
|
||||
alt=""
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -270,7 +270,7 @@ export const getServerSideProps: GetServerSideProps = async (
|
||||
morePosts,
|
||||
slug: context.params.slug as string,
|
||||
preview: context.preview ?? false,
|
||||
id: blogg?._id,
|
||||
id: blogg?._id ?? "",
|
||||
},
|
||||
notFound: !blogg && !context.preview,
|
||||
};
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
User-agent: *
|
||||
Allow: /*
|
||||
|
||||
Sitemap: https://aksel.nav.no/api/sitemap
|
||||
|
||||
# Next.JS Crawl Budget Performance Updates
|
||||
# Block files ending in .json, _buildManifest.js, _middlewareManifest.js, _ssgManifest.js, and any other JS files
|
||||
# The asterisks allows any file name
|
||||
@@ -18,4 +16,7 @@ Disallow: /*_ssgManifest.js$
|
||||
|
||||
Disallow: /*.js$
|
||||
|
||||
Disallow: /eksempler/
|
||||
Disallow: /eksempler
|
||||
Disallow: /admin
|
||||
|
||||
Sitemap: https://aksel.nav.no/api/sitemap
|
||||
@@ -6,6 +6,23 @@ export const allArticleDocuments = [
|
||||
"aksel_prinsipp",
|
||||
];
|
||||
|
||||
export const previews = [
|
||||
"aksel_artikkel",
|
||||
"komponent_artikkel",
|
||||
"ds_artikkel",
|
||||
"aksel_blogg",
|
||||
"aksel_prinsipp",
|
||||
"aksel_standalone",
|
||||
];
|
||||
|
||||
export const landingsider = [
|
||||
{ name: "godpraksis_landingsside", url: "god-praksis" },
|
||||
{ name: "blogg_landingsside", url: "produktbloggen" },
|
||||
{ name: "grunnleggende_landingsside", url: "grunnleggende" },
|
||||
{ name: "komponenter_landingsside", url: "komponenter" },
|
||||
{ name: "prinsipper_landingsside", url: "prinsipper" },
|
||||
];
|
||||
|
||||
export const allArticleDocsRef = allArticleDocuments.map((x) => ({ type: x }));
|
||||
|
||||
export const komponentKategorier = [
|
||||
@@ -17,6 +34,9 @@ export const grunnleggendeKategorier = [
|
||||
{ title: "Styling", value: "styling" },
|
||||
{ title: "Guider", value: "guider" },
|
||||
{ title: "Stæsj", value: "staesj" },
|
||||
{ title: "Design", value: "design" },
|
||||
{ title: "Kode", value: "kode" },
|
||||
{ title: "Nedlastbart", value: "nedlastbart" },
|
||||
];
|
||||
|
||||
export const monsterKategorier = [];
|
||||
|
||||
@@ -29,10 +29,11 @@ export const createWrappedDefaultPublish = (
|
||||
tone: "positive",
|
||||
onHandle: () => {
|
||||
setIsPublishing(true);
|
||||
patch.execute(
|
||||
[{ set: { publishedAt: new Date().toISOString() } }],
|
||||
props.published
|
||||
);
|
||||
!props.published &&
|
||||
patch.execute(
|
||||
[{ set: { publishedAt: new Date().toISOString() } }],
|
||||
props.published
|
||||
);
|
||||
publish.execute();
|
||||
|
||||
props.onComplete();
|
||||
|
||||
@@ -67,11 +67,15 @@ export const publicationFlow = definePlugin<PublicationFlowOptions>(
|
||||
({ hasQualityControl, hasPublishedAt }) => ({
|
||||
name: "publication-flow",
|
||||
document: {
|
||||
actions: (prev, { schemaType }) => {
|
||||
actions: (prev, { schemaType, currentUser }) => {
|
||||
if (hasQualityControl.some((e) => e === schemaType)) {
|
||||
return getCustomActions(prev);
|
||||
} else if (hasPublishedAt.some((e) => e === schemaType)) {
|
||||
return withCustomPublishAction(prev);
|
||||
} else if (schemaType === "aksel_feedback") {
|
||||
return currentUser.roles.find((x) => x.name === "developer")
|
||||
? prev
|
||||
: [prev[0]];
|
||||
}
|
||||
return prev;
|
||||
},
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
import { Accordion, Loader } from "@navikt/ds-react";
|
||||
import { Card } from "@sanity/ui";
|
||||
import {
|
||||
getPublishedId,
|
||||
IntentButton,
|
||||
Preview,
|
||||
useClient,
|
||||
useSchema,
|
||||
} from "sanity";
|
||||
import useSWR from "swr";
|
||||
|
||||
export function FeedbackView(props) {
|
||||
const { documentId } = props;
|
||||
|
||||
const schema = useSchema();
|
||||
|
||||
const schemaType = schema.get("aksel_feedback");
|
||||
|
||||
const client = useClient({ apiVersion: "2021-06-07" });
|
||||
const { data, error, isValidating } = useSWR(
|
||||
`*[_type == "aksel_feedback" && references($id)]`,
|
||||
(query) =>
|
||||
client.fetch(query, {
|
||||
id: documentId,
|
||||
})
|
||||
);
|
||||
|
||||
if (isValidating) {
|
||||
return (
|
||||
<div className="grid place-items-center px-6">
|
||||
<div className="mx-auto mt-24">
|
||||
<Loader size="xlarge" variant="neutral" />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div className="grid place-items-center">
|
||||
<div className="mx-auto mt-24 px-6">
|
||||
En feil oppstod, prøv å laste side på nytt eller kontakt utvikler.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (data.length === 0) {
|
||||
return (
|
||||
<div className="grid place-items-center">
|
||||
<div className="mx-auto mt-24 px-6">
|
||||
Siden har ingen tilbakemeldinger enda.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const done = data.filter((x) => x?.behandlet === true);
|
||||
const notDone = data.filter((x) => x?.behandlet === false);
|
||||
|
||||
return (
|
||||
<div className="grid place-items-center">
|
||||
<div className="mx-auto mt-8 w-full px-6">
|
||||
<div className="mt-7">
|
||||
<ul>
|
||||
{notDone.map((x) => (
|
||||
<li key={x._id}>
|
||||
<Card flex={1}>
|
||||
<IntentButton
|
||||
key={x._id}
|
||||
intent="edit"
|
||||
mode="ghost"
|
||||
padding={1}
|
||||
radius={0}
|
||||
params={{
|
||||
type: "aksel_feedback",
|
||||
id: getPublishedId(x._id),
|
||||
}}
|
||||
style={{ width: "100%" }}
|
||||
>
|
||||
<Preview
|
||||
schemaType={schemaType}
|
||||
value={x}
|
||||
key={x._id}
|
||||
layout="default"
|
||||
/>
|
||||
</IntentButton>
|
||||
</Card>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
{done.length > 0 && (
|
||||
<div className="mt-7">
|
||||
<Accordion>
|
||||
<Accordion.Item>
|
||||
<Accordion.Header>{`Ferdig behandlet ${done.length}`}</Accordion.Header>
|
||||
<Accordion.Content>
|
||||
<ul>
|
||||
{done.map((x) => (
|
||||
<li key={x._id}>
|
||||
<Card flex={1}>
|
||||
<IntentButton
|
||||
intent="edit"
|
||||
mode="bleed"
|
||||
padding={1}
|
||||
radius={2}
|
||||
params={{
|
||||
type: "aksel_feedback",
|
||||
id: getPublishedId(x._id),
|
||||
}}
|
||||
style={{ width: "100%" }}
|
||||
>
|
||||
<Preview
|
||||
schemaType={schemaType}
|
||||
value={x}
|
||||
key={x._id}
|
||||
/>
|
||||
</IntentButton>
|
||||
</Card>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Accordion.Content>
|
||||
</Accordion.Item>
|
||||
</Accordion>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { EyeClosedIcon, EyeOpenIcon } from "@sanity/icons";
|
||||
import { StructureBuilder } from "sanity/desk";
|
||||
|
||||
export const FeedbackPanes = async (getClient, S: StructureBuilder) => {
|
||||
const fb = await getClient({ apiVersion: "2021-06-07" }).fetch(
|
||||
`{
|
||||
"behandlet": count(*[_type == "aksel_feedback" && behandlet == true]),
|
||||
"ubehandlet": count(*[_type == "aksel_feedback" && behandlet == false]),
|
||||
}`
|
||||
);
|
||||
|
||||
return [
|
||||
S.listItem().title(`Ubehandlet (${fb.ubehandlet})`).icon(EyeOpenIcon).child(
|
||||
S.documentList()
|
||||
.title(`Ubehandlet`)
|
||||
.filter(`_type == "aksel_feedback" && behandlet == false`)
|
||||
/* .menuItems([...S.documentTypeList("aksel_artikkel").getMenuItems()]) */
|
||||
),
|
||||
S.listItem().title(`Behandlet (${fb.behandlet})`).icon(EyeClosedIcon).child(
|
||||
S.documentList()
|
||||
.title(`Behandlet`)
|
||||
.filter(`_type == "aksel_feedback" && behandlet == true`)
|
||||
/* .menuItems([...S.documentTypeList("aksel_artikkel").getMenuItems()]) */
|
||||
),
|
||||
];
|
||||
};
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
AccessDeniedIcon,
|
||||
BookIcon,
|
||||
BulbOutlineIcon,
|
||||
CommentIcon,
|
||||
JoystickIcon,
|
||||
OkHandIcon,
|
||||
TokenIcon,
|
||||
@@ -13,11 +14,15 @@ import {
|
||||
bloggKategorier,
|
||||
grunnleggendeKategorier,
|
||||
komponentKategorier,
|
||||
landingsider,
|
||||
previews,
|
||||
prinsippKategorier,
|
||||
} from "../../config";
|
||||
|
||||
import { FeedbackPanes } from "./feedback";
|
||||
import { GodPraksisPanes } from "./god-praksis";
|
||||
import { PanesWithCount } from "./with-count";
|
||||
import { FeedbackView } from "./FeedbackPreview";
|
||||
|
||||
/* import { WebPreview, JsonView } from './previews' */
|
||||
const filtered = [
|
||||
@@ -42,6 +47,7 @@ const filtered = [
|
||||
"aksel_artikkel",
|
||||
"skrivehjelp",
|
||||
"publication_flow",
|
||||
"aksel_feedback",
|
||||
];
|
||||
|
||||
export const structure = async (
|
||||
@@ -58,6 +64,9 @@ export const structure = async (
|
||||
const adminOrDev = currentUser.roles.find((x) =>
|
||||
["developer", "administrator", "editor"].includes(x.name)
|
||||
);
|
||||
const developer = currentUser.roles.find((x) =>
|
||||
["developer"].includes(x.name)
|
||||
);
|
||||
/* const hasBloggerRole = currentUser.roles.find((x) => x.name === "blogger");
|
||||
const hasGrunnleggendeRole = currentUser.roles.find(
|
||||
(x: Role) => x.name === "grunnleggende"
|
||||
@@ -201,6 +210,15 @@ export const structure = async (
|
||||
.schemaType(`aksel_forside`)
|
||||
.icon(Picture)
|
||||
.id(`aksel_forside_dokument`),
|
||||
S.listItem()
|
||||
.title("Feedback")
|
||||
.icon(CommentIcon)
|
||||
.child(
|
||||
S.list()
|
||||
.title("Feedback")
|
||||
.items([...(await FeedbackPanes(getClient, S))])
|
||||
),
|
||||
|
||||
S.listItem().title("Standalone-sider").child(
|
||||
S.documentList()
|
||||
.title("Sider")
|
||||
@@ -264,29 +282,14 @@ export const structure = async (
|
||||
: []),
|
||||
|
||||
S.divider(),
|
||||
...S.documentTypeListItems().filter(
|
||||
(listItem) => !filtered.includes(listItem.getId())
|
||||
),
|
||||
...(developer
|
||||
? S.documentTypeListItems().filter(
|
||||
(listItem) => !filtered.includes(listItem.getId())
|
||||
)
|
||||
: []),
|
||||
]);
|
||||
};
|
||||
|
||||
const previews = [
|
||||
"aksel_artikkel",
|
||||
"komponent_artikkel",
|
||||
"ds_artikkel",
|
||||
"aksel_blogg",
|
||||
"aksel_prinsipp",
|
||||
"aksel_standalone",
|
||||
];
|
||||
|
||||
const landingsider = [
|
||||
{ name: "godpraksis_landingsside", url: "god-praksis" },
|
||||
{ name: "blogg_landingsside", url: "produktbloggen" },
|
||||
{ name: "grunnleggende_landingsside", url: "grunnleggende" },
|
||||
{ name: "komponenter_landingsside", url: "komponenter" },
|
||||
{ name: "prinsipper_landingsside", url: "prinsipper" },
|
||||
];
|
||||
|
||||
export const resolveProductionUrl = (doc) => {
|
||||
const basePath = "https://aksel.nav.no";
|
||||
const devPath = "http://localhost:3000";
|
||||
@@ -324,7 +327,7 @@ export const resolveProductionUrl = (doc) => {
|
||||
}
|
||||
};
|
||||
|
||||
export const defaultDocumentNode = (S, { schemaType }) => {
|
||||
export const defaultDocumentNode = (S, { schemaType, getClient }) => {
|
||||
if (
|
||||
[...previews, "aksel_tema", ...landingsider.map((x) => x.name)].includes(
|
||||
schemaType
|
||||
@@ -343,6 +346,10 @@ export const defaultDocumentNode = (S, { schemaType }) => {
|
||||
},
|
||||
})
|
||||
.title("Preview"),
|
||||
S.view
|
||||
.component(FeedbackView)
|
||||
.icon(CommentIcon)
|
||||
.title("Tilbakemeldinger"),
|
||||
]);
|
||||
}
|
||||
return S.document().views([S.view.form()]);
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
import { InputWithCounter } from "./schema/custom-components";
|
||||
|
||||
export const form = {
|
||||
form: {
|
||||
components: {
|
||||
field: (props) => {
|
||||
const name = props.schemaType?.name;
|
||||
|
||||
if (name === "string" && props.schemaType?.options?.maxLength) {
|
||||
return <InputWithCounter {...props.inputProps} />;
|
||||
}
|
||||
|
||||
if (name === "text" && props.schemaType?.options?.maxLength) {
|
||||
return <InputWithCounter {...props.inputProps} size="large" />;
|
||||
}
|
||||
return props.renderDefault(props);
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,156 +0,0 @@
|
||||
import { codeInput } from "@sanity/code-input";
|
||||
import { colorInput } from "@sanity/color-input";
|
||||
import { table } from "@sanity/table";
|
||||
import { visionTool } from "@sanity/vision";
|
||||
import { createAuthStore, defineConfig } from "sanity";
|
||||
import { unsplashImageAsset } from "sanity-plugin-asset-source-unsplash";
|
||||
import { media } from "sanity-plugin-media";
|
||||
import { deskTool } from "sanity/desk";
|
||||
import {
|
||||
defaultDocumentNode,
|
||||
publicationFlow,
|
||||
structure,
|
||||
} from "./custom-plugins";
|
||||
import { form } from "./form";
|
||||
import { getTemplates } from "./util";
|
||||
|
||||
import { DatabaseIcon, RemoveCircleIcon } from "@sanity/icons";
|
||||
import { allArticleDocuments } from "./config";
|
||||
import { schema } from "./schema";
|
||||
|
||||
const projectId = "hnbe3yhs";
|
||||
|
||||
const sharedConfig = {
|
||||
projectId,
|
||||
apiVersion: "2021-10-21",
|
||||
schema: schema,
|
||||
...form,
|
||||
document: {
|
||||
newDocumentOptions: (prev, { currentUser }) => {
|
||||
const adminOrDev = currentUser.roles.find((x) =>
|
||||
["developer", "administrator", "editor"].includes(x.name)
|
||||
);
|
||||
if (adminOrDev) {
|
||||
return [...getTemplates(currentUser.roles), ...prev];
|
||||
}
|
||||
return getTemplates(currentUser.roles);
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
deskTool({
|
||||
title: "Desk",
|
||||
structure,
|
||||
defaultDocumentNode,
|
||||
}),
|
||||
table(),
|
||||
codeInput(),
|
||||
media({
|
||||
projectId,
|
||||
dataset: "production",
|
||||
}),
|
||||
visionTool(),
|
||||
unsplashImageAsset(),
|
||||
publicationFlow({
|
||||
hasQualityControl: [
|
||||
"komponent_artikkel",
|
||||
"ds_artikkel",
|
||||
"aksel_artikkel",
|
||||
],
|
||||
hasPublishedAt: allArticleDocuments,
|
||||
}),
|
||||
colorInput(),
|
||||
],
|
||||
};
|
||||
|
||||
export const workspaceConfig = defineConfig([
|
||||
{
|
||||
name: "default",
|
||||
title: "Prod",
|
||||
icon: DatabaseIcon,
|
||||
dataset: "production",
|
||||
basePath: "/admin/prod",
|
||||
...sharedConfig,
|
||||
auth: createAuthStore({
|
||||
redirectOnSingle: false,
|
||||
mode: "replace",
|
||||
projectId,
|
||||
dataset: "production",
|
||||
providers: [
|
||||
{
|
||||
name: "saml",
|
||||
title: "NAV SSO",
|
||||
url: "https://api.sanity.io/v2021-10-01/auth/saml/login/f3270b37",
|
||||
logo: "/images/navlogo.svg",
|
||||
},
|
||||
{
|
||||
name: "github",
|
||||
title: "GitHub",
|
||||
url: "https://api.sanity.io/v1/auth/login/github",
|
||||
},
|
||||
{
|
||||
name: "google",
|
||||
title: "Google",
|
||||
url: "https://api.sanity.io/v1/auth/login/google",
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "dev",
|
||||
title: "Dev (testing only)",
|
||||
icon: RemoveCircleIcon,
|
||||
dataset: "development",
|
||||
basePath: "/admin/dev",
|
||||
...sharedConfig,
|
||||
auth: createAuthStore({
|
||||
redirectOnSingle: false,
|
||||
mode: "replace",
|
||||
projectId,
|
||||
dataset: "development",
|
||||
providers: [
|
||||
{
|
||||
name: "saml",
|
||||
title: "NAV SSO",
|
||||
url: "https://api.sanity.io/v2021-10-01/auth/saml/login/f3270b37",
|
||||
logo: "/images/navlogo.svg",
|
||||
},
|
||||
{
|
||||
name: "github",
|
||||
title: "GitHub",
|
||||
url: "https://api.sanity.io/v1/auth/login/github",
|
||||
},
|
||||
{
|
||||
name: "google",
|
||||
title: "Google",
|
||||
url: "https://api.sanity.io/v1/auth/login/google",
|
||||
},
|
||||
],
|
||||
}),
|
||||
},
|
||||
]);
|
||||
|
||||
/* interface WorkspaceOptions {
|
||||
name: string
|
||||
title: string
|
||||
projectId: string
|
||||
dataset: string
|
||||
plugins?: PluginOptions[]
|
||||
schema?: SchemaPluginOptions
|
||||
document?: DocumentPluginOptions
|
||||
tools?: Tool[] | ComposableOption<Tool[], ConfigContext>
|
||||
form?: SanityFormConfig
|
||||
basePath?: string
|
||||
subtitle?: string
|
||||
logo?: React.ComponentType
|
||||
icon?: React.ComponentType
|
||||
navbar?: {
|
||||
components?: {
|
||||
ToolMenu: React.ComponentType<ToolMenuProps>
|
||||
}
|
||||
}
|
||||
theme?: StudioTheme
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,125 @@
|
||||
import { InputWithCounter } from "./schema/custom-components";
|
||||
import { codeInput } from "@sanity/code-input";
|
||||
import { colorInput } from "@sanity/color-input";
|
||||
import { table } from "@sanity/table";
|
||||
import { visionTool } from "@sanity/vision";
|
||||
import { createAuthStore, defineConfig } from "sanity";
|
||||
import { unsplashImageAsset } from "sanity-plugin-asset-source-unsplash";
|
||||
import { media } from "sanity-plugin-media";
|
||||
import { deskTool } from "sanity/desk";
|
||||
import {
|
||||
defaultDocumentNode,
|
||||
publicationFlow,
|
||||
structure,
|
||||
} from "./custom-plugins";
|
||||
|
||||
import { getTemplates } from "./util";
|
||||
|
||||
import { DatabaseIcon, RemoveCircleIcon } from "@sanity/icons";
|
||||
import { allArticleDocuments } from "./config";
|
||||
import { schema } from "./schema";
|
||||
|
||||
const projectId = "hnbe3yhs";
|
||||
|
||||
export const workspaceConfig = defineConfig([
|
||||
{
|
||||
...defaultConfig(),
|
||||
title: "Aksel",
|
||||
name: "default",
|
||||
dataset: "production",
|
||||
basePath: "/admin/prod",
|
||||
icon: DatabaseIcon,
|
||||
auth: authStore(),
|
||||
},
|
||||
{
|
||||
...defaultConfig(),
|
||||
title: "Aksel Dev-miljø",
|
||||
name: "dev",
|
||||
dataset: "development",
|
||||
basePath: "/admin/dev",
|
||||
icon: RemoveCircleIcon,
|
||||
auth: authStore(),
|
||||
},
|
||||
]);
|
||||
|
||||
function defaultConfig() {
|
||||
return {
|
||||
projectId,
|
||||
apiVersion: "2021-10-21",
|
||||
schema,
|
||||
form: {
|
||||
components: {
|
||||
field: (props) => {
|
||||
const name = props.schemaType?.name;
|
||||
|
||||
if (name === "string" && props.schemaType?.options?.maxLength) {
|
||||
return <InputWithCounter {...props.inputProps} />;
|
||||
}
|
||||
|
||||
if (name === "text" && props.schemaType?.options?.maxLength) {
|
||||
return <InputWithCounter {...props.inputProps} size="large" />;
|
||||
}
|
||||
return props.renderDefault(props);
|
||||
},
|
||||
},
|
||||
},
|
||||
document: {
|
||||
newDocumentOptions: (prev, { currentUser }) =>
|
||||
currentUser.roles.find((x) =>
|
||||
["developer", "administrator", "editor"].includes(x.name)
|
||||
)
|
||||
? [...getTemplates(currentUser.roles), ...prev]
|
||||
: getTemplates(currentUser.roles),
|
||||
},
|
||||
plugins: [
|
||||
deskTool({
|
||||
title: "Editor",
|
||||
structure,
|
||||
defaultDocumentNode,
|
||||
}),
|
||||
publicationFlow({
|
||||
hasQualityControl: [
|
||||
"komponent_artikkel",
|
||||
"ds_artikkel",
|
||||
"aksel_artikkel",
|
||||
],
|
||||
hasPublishedAt: allArticleDocuments,
|
||||
}),
|
||||
|
||||
/* 3rd-party */
|
||||
table(),
|
||||
codeInput(),
|
||||
media(),
|
||||
visionTool(),
|
||||
unsplashImageAsset(),
|
||||
colorInput(),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
function authStore() {
|
||||
return createAuthStore({
|
||||
redirectOnSingle: false,
|
||||
mode: "replace",
|
||||
projectId,
|
||||
dataset: "production",
|
||||
providers: [
|
||||
{
|
||||
name: "saml",
|
||||
title: "NAV SSO",
|
||||
url: "https://api.sanity.io/v2021-10-01/auth/saml/login/f3270b37",
|
||||
logo: "/images/navlogo.svg",
|
||||
},
|
||||
{
|
||||
name: "github",
|
||||
title: "GitHub",
|
||||
url: "https://api.sanity.io/v1/auth/login/github",
|
||||
},
|
||||
{
|
||||
name: "google",
|
||||
title: "Google",
|
||||
url: "https://api.sanity.io/v1/auth/login/google",
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
@@ -70,7 +70,7 @@ const OutDatedList = ({ data }: { data: any[] }) => {
|
||||
() =>
|
||||
data.filter(
|
||||
(x) =>
|
||||
!isAfter(x?.updateInfo?.lastVerified) &&
|
||||
isAfter(x?.updateInfo?.lastVerified) &&
|
||||
["ds_artikkel", "aksel_artikkel", "komponent_artikkel"].includes(
|
||||
x._type
|
||||
)
|
||||
@@ -81,7 +81,7 @@ const OutDatedList = ({ data }: { data: any[] }) => {
|
||||
return (
|
||||
<Accordion.Item>
|
||||
<Accordion.Header>
|
||||
Artikler til godkjenning ({list.length})
|
||||
Artikler som må godkjennes ({list.length})
|
||||
</Accordion.Header>
|
||||
<Accordion.Content>
|
||||
<ul>
|
||||
@@ -158,6 +158,56 @@ const DraftList = ({ data }: { data: any[] }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const FeedbackList = ({ data, title }: { data: any[]; title: string }) => {
|
||||
const schema = useSchema();
|
||||
|
||||
const list = useMemo(
|
||||
() =>
|
||||
data.filter((x) =>
|
||||
title.startsWith("Ferdig") ? x.behandlet : !x.behandlet
|
||||
),
|
||||
[data, title]
|
||||
);
|
||||
|
||||
if (list.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Accordion.Item>
|
||||
<Accordion.Header>{`${title} (${list.length ?? 0})`}</Accordion.Header>
|
||||
<Accordion.Content>
|
||||
<ul>
|
||||
{list.map((x) => (
|
||||
<li key={x._id}>
|
||||
<Card flex={1}>
|
||||
<IntentButton
|
||||
intent="edit"
|
||||
mode="ghost"
|
||||
padding={1}
|
||||
radius={0}
|
||||
params={{
|
||||
type: "aksel_feedback",
|
||||
id: getPublishedId(x._id),
|
||||
}}
|
||||
style={{ width: "100%" }}
|
||||
>
|
||||
<Preview
|
||||
layout="default"
|
||||
schemaType={schema.get("aksel_feedback")}
|
||||
value={x}
|
||||
key={x._id}
|
||||
/>
|
||||
</IntentButton>
|
||||
</Card>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Accordion.Content>
|
||||
</Accordion.Item>
|
||||
);
|
||||
};
|
||||
|
||||
export const EditorPage = () => {
|
||||
const user = useCurrentUser();
|
||||
const userId = useFormValue([`user_id`]) as { current?: string };
|
||||
@@ -168,6 +218,17 @@ export const EditorPage = () => {
|
||||
(query) => client.fetch(query)
|
||||
);
|
||||
|
||||
console.log(data);
|
||||
|
||||
const {
|
||||
data: fbData,
|
||||
error: fbError,
|
||||
isValidating: fbValidating,
|
||||
} = useSWR(
|
||||
`*[_type == "aksel_feedback" && $id in doc_ref->contributors[]->user_id.current]{_id, behandlet}`,
|
||||
(query) => client.fetch(query, { id: userId.current })
|
||||
);
|
||||
|
||||
if (error || !user) {
|
||||
return <div>Feilet lasting av bruker...</div>;
|
||||
}
|
||||
@@ -197,18 +258,29 @@ export const EditorPage = () => {
|
||||
</dl>
|
||||
<p>
|
||||
Om det er noe du mangler tilgang til kan du sende melding på{" "}
|
||||
<Link href="https://nav-it.slack.com/archives/C0370ADS0HX">
|
||||
#Aksel
|
||||
<Link href="https://nav-it.slack.com/archives/C7NE7A8UF">
|
||||
#Aksel-designsystemet
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
{!fbError && !fbValidating && (
|
||||
<div className="mt-7">
|
||||
<Heading level="2" size="small" spacing>
|
||||
Tilbakemeldinger på artikler du er satt som forfatter (
|
||||
{fbData?.length ?? 0})
|
||||
</Heading>
|
||||
{fbData?.length > 0 && (
|
||||
<Accordion>
|
||||
<FeedbackList data={fbData} title="Ubehandlet" />
|
||||
<FeedbackList data={fbData} title="Ferdig behandlet" />
|
||||
</Accordion>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="mt-7">
|
||||
<Heading level="2" size="small" spacing>
|
||||
Innhold du jobber med
|
||||
Under arbeid / må re-valideres
|
||||
</Heading>
|
||||
<BodyShort spacing>
|
||||
Dette er alle artikler du jobber med eller må godkjenne asap.
|
||||
</BodyShort>
|
||||
<Accordion>
|
||||
<DraftList data={data} />
|
||||
<OutDatedList data={data} />
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import { Stack, Heading, Card, Text } from "@sanity/ui";
|
||||
import { Card, Heading, Stack } from "@sanity/ui";
|
||||
import { useEffect, useState } from "react";
|
||||
import { IntentButton, Preview } from "sanity";
|
||||
import { getPublishedId, useClient, useSchema, useFormValue } from "sanity";
|
||||
import {
|
||||
getPublishedId,
|
||||
IntentButton,
|
||||
Preview,
|
||||
useClient,
|
||||
useFormValue,
|
||||
useSchema,
|
||||
} from "sanity";
|
||||
|
||||
export function TemaView(props) {
|
||||
const client = useClient({ apiVersion: "2021-06-07" });
|
||||
@@ -13,14 +19,14 @@ export function TemaView(props) {
|
||||
const type = schema.get("aksel_artikkel");
|
||||
|
||||
useEffect(() => {
|
||||
const query = `*[_type == "aksel_tema" && defined(seksjoner) && !(_id in path("drafts.**"))]{_id,title,seksjoner, "artikler":*[_type == "aksel_artikkel" && !(_id in path("drafts.**")) && ^._id in tema[]._ref]{_id}}`;
|
||||
const query = `*[_type == "aksel_tema" && !(_id in path("drafts.**"))]{_id,title,seksjoner, "artikler":*[_type == "aksel_artikkel" && !(_id in path("drafts.**")) && ^._id in tema[]._ref]{_id}}`;
|
||||
client.fetch(query).then(setTema);
|
||||
}, [client]);
|
||||
|
||||
const sider = tema
|
||||
.find((x) => x.title === title)
|
||||
?.["seksjoner"]?.reduce(
|
||||
(b, n) => [...b, ...(n?.sider.map((x) => x._ref) ?? [])],
|
||||
(b, n) => [...b, ...(n?.sider?.map((x) => x._ref) ?? [])],
|
||||
[]
|
||||
);
|
||||
const artikler = tema.find((x) => x.title === title)?.["artikler"];
|
||||
@@ -36,12 +42,6 @@ export function TemaView(props) {
|
||||
<Heading size={1}>
|
||||
{`Artikler ikke i seksjoner (${notFound.length})`}
|
||||
</Heading>
|
||||
{notFound.length ? (
|
||||
<Text>
|
||||
Disse artiklene vil man ikke kunne finne i navigasjonen før dette er
|
||||
fikset.
|
||||
</Text>
|
||||
) : null}
|
||||
{notFound.map((x) => (
|
||||
<Card flex={1}>
|
||||
<IntentButton
|
||||
|
||||