mirror of
https://github.com/navikt/aksel.git
synced 2026-10-13 01:02:02 +00:00
Compare commits
148
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51bbeb00b0 | ||
|
|
79773ff44b | ||
|
|
1e7633e692 | ||
|
|
ba22ba7b70 | ||
|
|
ccedba0132 | ||
|
|
2dbc5125d6 | ||
|
|
bdf83d447f | ||
|
|
da9445389e | ||
|
|
c0601bb510 | ||
|
|
e20df992ec | ||
|
|
d42200b61f | ||
|
|
4e5f422693 | ||
|
|
2c77e103f9 | ||
|
|
45e9e5f564 | ||
|
|
6b1f9f1560 | ||
|
|
eb50604788 | ||
|
|
5ca140d4f7 | ||
|
|
7943489380 | ||
|
|
82cdd68d00 | ||
|
|
76af311b63 | ||
|
|
b624bff400 | ||
|
|
d5ab822973 | ||
|
|
c8b230fc1c | ||
|
|
d35f7326d7 | ||
|
|
eb07f63d12 | ||
|
|
df42875d41 | ||
|
|
404274003c | ||
|
|
fc9c5170b9 | ||
|
|
dc2f1958ff | ||
|
|
fc9196ad6f | ||
|
|
9cfc03fe6b | ||
|
|
9b8ed2d985 | ||
|
|
728dd2ead3 | ||
|
|
71fbe7d7f2 | ||
|
|
2a4447b6e7 | ||
|
|
aaad005455 | ||
|
|
3bb4a2e36f | ||
|
|
f346a4694c | ||
|
|
51c0883255 | ||
|
|
45e67d5b50 | ||
|
|
6739d29074 | ||
|
|
189858a9d7 | ||
|
|
f1731730fa | ||
|
|
1b37aad4dc | ||
|
|
323018a935 | ||
|
|
7b6e5f2e60 | ||
|
|
5557fc2ef0 | ||
|
|
6c07afe963 | ||
|
|
ac217adaa6 | ||
|
|
5c50658036 | ||
|
|
8ab100dfb3 | ||
|
|
3ac20c695c | ||
|
|
218707905e | ||
|
|
72f1ab0c85 | ||
|
|
2c57117098 | ||
|
|
f6ba5e1219 | ||
|
|
1c53160a2a | ||
|
|
22527c073f | ||
|
|
5b41ecac4c | ||
|
|
14e07e4ca6 | ||
|
|
cd1c93f9d4 | ||
|
|
545864553f | ||
|
|
3b2f10fb91 | ||
|
|
bec7d5945f | ||
|
|
f32bd408a2 | ||
|
|
7ba8c466f4 | ||
|
|
bede18133c | ||
|
|
81e65cc0ab | ||
|
|
5acdbe33c1 | ||
|
|
727999ba72 | ||
|
|
7ad82450b4 | ||
|
|
a72e965785 | ||
|
|
e3fd48728b | ||
|
|
89c3603765 | ||
|
|
03f7034fca | ||
|
|
527ba00287 | ||
|
|
b3831f0b1c | ||
|
|
0549ad19b6 | ||
|
|
7d1095fd96 | ||
|
|
acb1d0b955 | ||
|
|
4fc51e00b5 | ||
|
|
796bb5225f | ||
|
|
9ff2830297 | ||
|
|
d40939458a | ||
|
|
310974b3c3 | ||
|
|
73b30a8ea7 | ||
|
|
790e70a90d | ||
|
|
4114cecd93 | ||
|
|
797f48a9fb | ||
|
|
13d3007293 | ||
|
|
bcfd6747d9 | ||
|
|
122bbf0090 | ||
|
|
c0cb5a02b3 | ||
|
|
b60d047b95 | ||
|
|
98dbc155fe | ||
|
|
87f194c1dc | ||
|
|
7f73315264 | ||
|
|
66badd5df5 | ||
|
|
7360426aef | ||
|
|
b71d407396 | ||
|
|
ca7c4964a2 | ||
|
|
5e078db3fd | ||
|
|
eb32b0a80b | ||
|
|
b56f83bf50 | ||
|
|
1399f6f084 | ||
|
|
1cf90c1753 | ||
|
|
c027c2e464 | ||
|
|
92dd582d68 | ||
|
|
b55bfac1c3 | ||
|
|
bb302bbbd6 | ||
|
|
55005c80f3 | ||
|
|
27e6423b54 | ||
|
|
de2dcdcc15 | ||
|
|
12e95d063a | ||
|
|
643ae3bc15 | ||
|
|
21a842d419 | ||
|
|
73f5f9fbfd | ||
|
|
527fe4f0c1 | ||
|
|
1a9214e328 | ||
|
|
8c0b2363e0 | ||
|
|
6d38b7bbdd | ||
|
|
936e794e2f | ||
|
|
500eecc43d | ||
|
|
2ac73a7812 | ||
|
|
451dacb14a | ||
|
|
e6228c103d | ||
|
|
572d913718 | ||
|
|
c0cd0dd66f | ||
|
|
613e20eb12 | ||
|
|
4bf0506362 | ||
|
|
5997db2b38 | ||
|
|
9f18063fe5 | ||
|
|
b037114863 | ||
|
|
e47521d6e5 | ||
|
|
61357fb40a | ||
|
|
5678d4cf10 | ||
|
|
d403c09b1a | ||
|
|
deff5b25b2 | ||
|
|
31e60deea8 | ||
|
|
847142dc72 | ||
|
|
a5b3ad81a7 | ||
|
|
fe1ac779bf | ||
|
|
064b2fc612 | ||
|
|
5d57586dc1 | ||
|
|
e8d012b82d | ||
|
|
4e90102efd | ||
|
|
02c55aaa0f | ||
|
|
8d4ee29d78 |
No files matched your search
@@ -9,6 +9,34 @@ env:
|
||||
IMAGE: ghcr.io/navikt/designsystemet
|
||||
|
||||
jobs:
|
||||
snyk-monitor:
|
||||
name: monitor dependencies
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
continue-on-error: true
|
||||
uses: snyk/actions/node@master
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
command: monitor
|
||||
args: --org=designsystemet --severity-threshold=high
|
||||
snyk-test:
|
||||
name: analyze dependencies
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
uses: snyk/actions/node@master
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
command: test
|
||||
args: --org=designsystemet --severity-threshold=high
|
||||
build_and_deploy:
|
||||
name: Build and deploy to dev-gcp
|
||||
runs-on: ubuntu-20.04
|
||||
@@ -17,8 +45,6 @@ jobs:
|
||||
with:
|
||||
node-version: "14"
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
ref: "next"
|
||||
- name: add tokens to .env
|
||||
run: |
|
||||
echo "SANITY_WRITE_KEY=${{ secrets.SANITY_FEEDBACK_WRITE_KEY }}" >> aksel.nav.no/website/.env
|
||||
@@ -40,11 +66,10 @@ jobs:
|
||||
- name: Build application
|
||||
run: |
|
||||
yarn boot
|
||||
yarn docgen
|
||||
yarn workspace aksel.nav.no build:next
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@ab80d026d4753220c4243394c07c7d80f9638d06 # Use commit-sha1 instead of tag for security concerns
|
||||
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # Use commit-sha1 instead of tag for security concerns
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
|
||||
@@ -10,9 +10,68 @@ env:
|
||||
IMAGE: ghcr.io/navikt/designsystemet
|
||||
|
||||
jobs:
|
||||
snyk-monitor:
|
||||
name: monitor dependencies
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
continue-on-error: true
|
||||
uses: snyk/actions/node@master
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
command: monitor
|
||||
args: --org=designsystemet --severity-threshold=high
|
||||
snyk-test:
|
||||
name: analyze dependencies
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
- name: Run Snyk to check for vulnerabilities
|
||||
uses: snyk/actions/node@master
|
||||
continue-on-error: true
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
command: test
|
||||
args: --org=designsystemet --severity-threshold=high
|
||||
sync_data_with_sanity:
|
||||
name: Update component data
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: "14"
|
||||
- uses: actions/checkout@v2
|
||||
- name: add tokens to .env
|
||||
run: |
|
||||
echo "SANITY_WRITE_KEY=${{ secrets.SANITY_FEEDBACK_WRITE_KEY }}" >> aksel.nav.no/website/.env
|
||||
|
||||
- name: Restore cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
key: ${{ runner.os }}-prod-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-prod-
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
- name: Run docgen
|
||||
run: |
|
||||
yarn boot
|
||||
yarn docgen
|
||||
|
||||
- name: Update sanity sync
|
||||
run: yarn workspace aksel.nav.no sanity:update
|
||||
|
||||
build_and_deploy:
|
||||
name: Build and deploy to prod-gcp
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
@@ -36,25 +95,17 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
- name: build packages
|
||||
run: |
|
||||
yarn boot
|
||||
yarn docgen
|
||||
- name: Build packages
|
||||
run: yarn boot
|
||||
|
||||
- name: Tests
|
||||
run: yarn workspace aksel.nav.no test
|
||||
|
||||
- name: E2E
|
||||
run: NEXT_PUBLIC_TEST=true yarn workspace website e2e
|
||||
|
||||
- name: Update sanity sync
|
||||
run: yarn workspace aksel.nav.no sanity:update
|
||||
|
||||
- name: Build application
|
||||
run: yarn workspace aksel.nav.no build:next
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@ab80d026d4753220c4243394c07c7d80f9638d06 # Use commit-sha1 instead of tag for security concerns
|
||||
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # Use commit-sha1 instead of tag for security concerns
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
@@ -65,6 +116,13 @@ jobs:
|
||||
run: echo "DOCKER_TAG=${{ env.IMAGE }}:${{ env.TAG }}" >> $GITHUB_ENV
|
||||
- name: Build docker image
|
||||
run: docker build -t ${{ env.DOCKER_TAG }} . -f aksel.nav.no/Dockerfile
|
||||
- name: Wait for e2e-tests to succeed
|
||||
uses: lewagon/wait-on-check-action@v1.2.0
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
check-name: "Smoketest Aksel"
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
- name: Push docker image
|
||||
run: |
|
||||
docker push ${{ env.DOCKER_TAG }}
|
||||
|
||||
@@ -24,7 +24,7 @@ jobs:
|
||||
node-version: "14"
|
||||
- uses: actions/checkout@v2
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@ab80d026d4753220c4243394c07c7d80f9638d06 # Use commit-sha1 instead of tag for security concerns
|
||||
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # Use commit-sha1 instead of tag for security concerns
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
|
||||
@@ -12,6 +12,8 @@ on:
|
||||
jobs:
|
||||
playwright:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: mcr.microsoft.com/playwright:v1.30.0-focal
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-node@v3
|
||||
@@ -36,15 +38,15 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
- name: build packages
|
||||
- name: Build packages
|
||||
run: |
|
||||
yarn boot
|
||||
yarn docgen
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: npx playwright install --with-deps
|
||||
- name: Build application
|
||||
run: yarn workspace aksel.nav.no build:next
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: yarn workspace website e2e:full
|
||||
run: yarn workspace website e2e:ci-full
|
||||
- uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
name: Smoketest aksel.nav.no
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- "aksel.nav.no/**"
|
||||
|
||||
env:
|
||||
IMAGE: ghcr.io/navikt/designsystemet
|
||||
|
||||
jobs:
|
||||
smoketest:
|
||||
name: Smoketest Aksel
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: mcr.microsoft.com/playwright:v1.30.0-focal
|
||||
steps:
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: "14"
|
||||
- uses: actions/checkout@v2
|
||||
- name: add tokens to .env
|
||||
run: |
|
||||
echo "SANITY_WRITE_KEY=${{ secrets.SANITY_FEEDBACK_WRITE_KEY }}" >> 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
|
||||
|
||||
- name: Restore cache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: "**/node_modules"
|
||||
key: ${{ runner.os }}-prod-${{ github.sha }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-prod-
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
|
||||
- name: build packages
|
||||
run: |
|
||||
yarn boot
|
||||
|
||||
- name: Build application
|
||||
run: yarn workspace aksel.nav.no build:next
|
||||
|
||||
- name: E2E smoketest
|
||||
run: yarn workspace website e2e:ci
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-codemod
|
||||
|
||||
## 2.1.6
|
||||
|
||||
## 2.1.5
|
||||
|
||||
## 2.1.4
|
||||
|
||||
## 2.1.3
|
||||
|
||||
## 2.1.2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-codemod",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.6",
|
||||
"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.1.3",
|
||||
"@navikt/ds-react": "^2.1.3",
|
||||
"@navikt/ds-icons": "^2.1.6",
|
||||
"@navikt/ds-react": "^2.1.6",
|
||||
"clsx": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-css
|
||||
|
||||
## 2.1.6
|
||||
|
||||
## 2.1.5
|
||||
|
||||
## 2.1.4
|
||||
|
||||
## 2.1.3
|
||||
|
||||
## 2.1.2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.6",
|
||||
"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.1.3",
|
||||
"@navikt/ds-tokens": "^2.1.6",
|
||||
"normalize.css": "^8.0.1",
|
||||
"postcss": "^8.4.0",
|
||||
"postcss-cli": "^9.0.0",
|
||||
|
||||
@@ -1,5 +1,32 @@
|
||||
# @navikt/ds-react
|
||||
|
||||
## 2.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#1777](https://github.com/navikt/Designsystemet/pull/1777) [`cd1c93f9d`](https://github.com/navikt/Designsystemet/commit/cd1c93f9d471fbbc38215d788a73f21b5b216c5b) Thanks [@KenAJoh](https://github.com/KenAJoh)! - :sparkles: Datepicker og monthpicker kan nå bestemme om popover skal dukke opp ved fokus
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.1.6
|
||||
|
||||
## 2.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Hotfix: ESM import fra date-fns feilet
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.1.5
|
||||
|
||||
## 2.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [`87f194c1d`](https://github.com/navikt/Designsystemet/commit/87f194c1dc29b10a604de676b358d117e2dbf52f) Thanks [@KenAJoh](https://github.com/KenAJoh)! - Fikset edgecase i useRangepicker der valg av startdato etter sluttdato ga feil output
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-icons@2.1.4
|
||||
|
||||
## 2.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.6",
|
||||
"description": "Aksel react-components for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
@@ -37,7 +37,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@floating-ui/react": "0.17.0",
|
||||
"@navikt/ds-icons": "^2.1.3",
|
||||
"@navikt/ds-icons": "^2.1.6",
|
||||
"@radix-ui/react-tabs": "1.0.0",
|
||||
"@radix-ui/react-toggle-group": "1.0.0",
|
||||
"clsx": "^1.2.1",
|
||||
|
||||
@@ -148,6 +148,7 @@ export const UseDatepicker = () => {
|
||||
fromDate: new Date("Aug 23 2019"),
|
||||
onDateChange: console.log,
|
||||
locale: "en",
|
||||
openOnFocus: false,
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -164,6 +165,7 @@ export const UseRangedDatepicker = () => {
|
||||
UNSAFE_useRangeDatepicker({
|
||||
fromDate: new Date("Aug 23 2019"),
|
||||
onRangeChange: console.log,
|
||||
onValidate: console.log,
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -178,6 +180,21 @@ export const UseRangedDatepicker = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export const OpenOnFocus = () => {
|
||||
const { datepickerProps, inputProps } = UNSAFE_useDatepicker({
|
||||
onDateChange: console.log,
|
||||
openOnFocus: false,
|
||||
});
|
||||
|
||||
return (
|
||||
<div style={{ display: "flex", gap: "1rem" }}>
|
||||
<DatePicker {...datepickerProps}>
|
||||
<DatePicker.Input {...inputProps} label="Velg dato" />
|
||||
</DatePicker>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export const NB = () => (
|
||||
<DatePicker.Standalone locale="nb" today={new Date("2006-07-01")} />
|
||||
);
|
||||
|
||||
@@ -56,6 +56,11 @@ export interface UseDatepickerOptions
|
||||
* In 2023 this equals to 1943 - 2042
|
||||
*/
|
||||
allowTwoDigitYear?: boolean;
|
||||
/**
|
||||
* Opens datepicker on input-focus
|
||||
* @default true
|
||||
*/
|
||||
openOnFocus?: boolean;
|
||||
}
|
||||
|
||||
interface UseDatepickerValue {
|
||||
@@ -123,6 +128,7 @@ export const useDatepicker = (
|
||||
onValidate,
|
||||
defaultMonth,
|
||||
allowTwoDigitYear = true,
|
||||
openOnFocus = true,
|
||||
} = opt;
|
||||
|
||||
const locale = getLocaleFromString(_locale);
|
||||
@@ -198,7 +204,7 @@ export const useDatepicker = (
|
||||
};
|
||||
|
||||
const handleFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
||||
!open && setOpen(true);
|
||||
!open && openOnFocus && setOpen(true);
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
|
||||
@@ -42,6 +42,11 @@ export interface UseMonthPickerOptions
|
||||
* In 2023 this equals to 1943 - 2042
|
||||
*/
|
||||
allowTwoDigitYear?: boolean;
|
||||
/**
|
||||
* Opens datepicker on input-focus
|
||||
* @default true
|
||||
*/
|
||||
openOnFocus?: boolean;
|
||||
}
|
||||
|
||||
interface UseMonthPickerValue {
|
||||
@@ -104,6 +109,7 @@ export const useMonthpicker = (
|
||||
onValidate,
|
||||
defaultYear,
|
||||
allowTwoDigitYear = true,
|
||||
openOnFocus = true,
|
||||
} = opt;
|
||||
|
||||
const [defaultSelected, setDefaultSelected] = useState(_defaultSelected);
|
||||
@@ -180,7 +186,7 @@ export const useMonthpicker = (
|
||||
};
|
||||
|
||||
const handleFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
|
||||
!open && setOpen(true);
|
||||
!open && openOnFocus && setOpen(true);
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import differenceInCalendarDays from "date-fns/differenceInCalendarDays";
|
||||
import isBefore from "date-fns/isBefore";
|
||||
import isWeekend from "date-fns/isWeekend";
|
||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { DateRange, isMatch } from "react-day-picker";
|
||||
@@ -203,6 +204,7 @@ export const useRangeDatepicker = (
|
||||
onValidate,
|
||||
defaultMonth,
|
||||
allowTwoDigitYear = true,
|
||||
openOnFocus = true,
|
||||
} = opt;
|
||||
|
||||
const locale = getLocaleFromString(_locale);
|
||||
@@ -322,7 +324,7 @@ export const useRangeDatepicker = (
|
||||
};
|
||||
|
||||
const handleFocus = (e, src: RangeT) => {
|
||||
!open && setOpen(true);
|
||||
!open && openOnFocus && setOpen(true);
|
||||
let day = parseDate(
|
||||
e.target.value,
|
||||
today,
|
||||
@@ -371,24 +373,26 @@ export const useRangeDatepicker = (
|
||||
if (range?.from && range?.to) {
|
||||
setOpen(false);
|
||||
}
|
||||
const prevToRange =
|
||||
let prevToRange =
|
||||
!selectedRange?.from && selectedRange?.to ? selectedRange?.to : range?.to;
|
||||
|
||||
const resetTo = isBefore(prevToRange, range?.from);
|
||||
|
||||
range?.from
|
||||
? setFromInputValue(
|
||||
formatDateForInput(range?.from, locale, "date", inputFormat)
|
||||
)
|
||||
: setFromInputValue("");
|
||||
prevToRange
|
||||
prevToRange && !resetTo
|
||||
? setToInputValue(
|
||||
formatDateForInput(prevToRange, locale, "date", inputFormat)
|
||||
)
|
||||
: setToInputValue("");
|
||||
updateValidation(
|
||||
{ isValidDate: !!range?.from, isEmpty: !range?.from },
|
||||
{ isValidDate: !!range?.to, isEmpty: !prevToRange }
|
||||
{ isValidDate: !!range?.to, isEmpty: !prevToRange || resetTo }
|
||||
);
|
||||
updateRange({ from: range?.from, to: prevToRange });
|
||||
updateRange({ from: range?.from, to: resetTo ? undefined : prevToRange });
|
||||
};
|
||||
|
||||
const fromChange = (
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-tailwind
|
||||
|
||||
## 2.1.6
|
||||
|
||||
## 2.1.5
|
||||
|
||||
## 2.1.4
|
||||
|
||||
## 2.1.3
|
||||
|
||||
## 2.1.2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tailwind",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.6",
|
||||
"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.1.3",
|
||||
"@navikt/ds-tokens": "^2.1.6",
|
||||
"@types/jest": "^29.0.0",
|
||||
"color": "4.2.3",
|
||||
"jest": "^29.0.0",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-tokens
|
||||
|
||||
## 2.1.6
|
||||
|
||||
## 2.1.5
|
||||
|
||||
## 2.1.4
|
||||
|
||||
## 2.1.3
|
||||
|
||||
## 2.1.2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-tokens",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.6",
|
||||
"description": "Design-tokens for NAV designsystem",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-icons
|
||||
|
||||
## 2.1.6
|
||||
|
||||
## 2.1.5
|
||||
|
||||
## 2.1.4
|
||||
|
||||
## 2.1.3
|
||||
|
||||
## 2.1.2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-icons",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.6",
|
||||
"description": "Aksel icons for NAV",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"repository": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @navikt/ds-css-internal
|
||||
|
||||
## 2.1.6
|
||||
|
||||
## 2.1.5
|
||||
|
||||
## 2.1.4
|
||||
|
||||
## 2.1.3
|
||||
|
||||
## 2.1.2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-css-internal",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.6",
|
||||
"description": "CSS for NAV internal Designsystem-components",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @navikt/ds-react-internal
|
||||
|
||||
## 2.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cd1c93f9d`](https://github.com/navikt/Designsystemet/commit/cd1c93f9d471fbbc38215d788a73f21b5b216c5b)]:
|
||||
- @navikt/ds-react@2.1.6
|
||||
- @navikt/ds-icons@2.1.6
|
||||
|
||||
## 2.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @navikt/ds-react@2.1.5
|
||||
- @navikt/ds-icons@2.1.5
|
||||
|
||||
## 2.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`87f194c1d`](https://github.com/navikt/Designsystemet/commit/87f194c1dc29b10a604de676b358d117e2dbf52f)]:
|
||||
- @navikt/ds-react@2.1.4
|
||||
- @navikt/ds-icons@2.1.4
|
||||
|
||||
## 2.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@navikt/ds-react-internal",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.6",
|
||||
"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.1.3",
|
||||
"@navikt/ds-react": "^2.1.3",
|
||||
"@navikt/ds-icons": "^2.1.6",
|
||||
"@navikt/ds-react": "^2.1.6",
|
||||
"clsx": "^1.1.1",
|
||||
"copy-to-clipboard": "^3.3.1"
|
||||
},
|
||||
|
||||
@@ -39,8 +39,7 @@
|
||||
|
||||
aksel.nav.no/
|
||||
├── website # NEXT.JS app (v12)
|
||||
├── website/sanity # Sanity CMS-app (v3)
|
||||
└── sanity # Sanity CMS-app (deprecated v2)
|
||||
└── website/sanity # Sanity CMS-app (v3)
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM node:16.4-alpine3.14
|
||||
FROM node:16.13.1-alpine3.14
|
||||
RUN apk add --no-cache libc6-compat
|
||||
|
||||
ENV NODE_ENV production
|
||||
@@ -8,7 +8,6 @@ COPY aksel.nav.no/website/package.json .
|
||||
COPY aksel.nav.no/website/.next/ .next/
|
||||
COPY aksel.nav.no/website/public/ public
|
||||
COPY aksel.nav.no/website/.env .
|
||||
COPY aksel.nav.no/website/redirects.json .
|
||||
COPY aksel.nav.no/website/next.config.js .
|
||||
COPY node_modules/ node_modules/
|
||||
COPY @navikt/ @navikt/
|
||||
|
||||
@@ -19,7 +19,7 @@ Det publiserte studioet finner man på [aksel.nav.no/admin](https://aksel.nav.no
|
||||
|
||||
### Bidrag
|
||||
|
||||
Branch `master` blir pusher rett til prod -> aksel.nav.no. For å utvikle nye features brukes branch `next` som ved push publiseres til devmiljø aksel.dev.nav.no (krever naisdevice).
|
||||
Branch `master` blir pusher rett til prod -> aksel.nav.no. For å utvikle nye features brukes branch `next` som ved push publiseres til devmiljø aksel.dev.nav.no (krever naisdevice). Kan også publisere andre branches til dev ved bruk av workflow-dispatch.
|
||||
|
||||
### Nettside (localhost:3000)
|
||||
|
||||
|
||||
@@ -12,24 +12,11 @@ spec:
|
||||
- "https://aksel.dev.nav.no"
|
||||
liveness:
|
||||
path: /api/isAlive
|
||||
initialDelay: 20
|
||||
timeout: 1
|
||||
periodSeconds: 5
|
||||
failureThreshold: 10
|
||||
readiness:
|
||||
path: /api/isAlive
|
||||
initialDelay: 20
|
||||
timeout: 1
|
||||
replicas:
|
||||
min: 1
|
||||
max: 1
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 256Mi
|
||||
accessPolicy:
|
||||
outbound:
|
||||
external:
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
"website"
|
||||
],
|
||||
"dependencies": {
|
||||
"@navikt/ds-codemod": "^2.1.3",
|
||||
"@navikt/ds-css": "^2.1.3",
|
||||
"@navikt/ds-css-internal": "^2.1.3",
|
||||
"@navikt/ds-icons": "^2.1.3",
|
||||
"@navikt/ds-react": "^2.1.3",
|
||||
"@navikt/ds-react-internal": "^2.1.3",
|
||||
"@navikt/ds-tailwind": "^2.1.3",
|
||||
"@navikt/ds-tokens": "^2.1.3"
|
||||
"@navikt/ds-codemod": "^2.1.6",
|
||||
"@navikt/ds-css": "^2.1.6",
|
||||
"@navikt/ds-css-internal": "^2.1.6",
|
||||
"@navikt/ds-icons": "^2.1.6",
|
||||
"@navikt/ds-react": "^2.1.6",
|
||||
"@navikt/ds-react-internal": "^2.1.6",
|
||||
"@navikt/ds-tailwind": "^2.1.6",
|
||||
"@navikt/ds-tokens": "^2.1.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier-plugin-tailwindcss": "^0.1.13"
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
.yarn/cache
|
||||
*.tar.gz
|
||||
@@ -1,46 +0,0 @@
|
||||
// https://www.sanity.io/schemas/make-a-field-read-only-after-publishing-once-d87bf5f6
|
||||
import { useState, useEffect } from "react";
|
||||
import { useDocumentOperation, useValidationStatus } from "@sanity/react-hooks";
|
||||
import PublishIcon from "part:@sanity/base/publish-icon";
|
||||
|
||||
export default function SetAndPublishAction(props) {
|
||||
const { patch, publish }: any = useDocumentOperation(props.id, props.type);
|
||||
const { isValidating, markers }: any = useValidationStatus(
|
||||
props.id,
|
||||
props.type
|
||||
);
|
||||
const [isPublishing, setIsPublishing] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// if the isPublishing state was set to true and the draft has changed
|
||||
// to become `null` the document has been published
|
||||
if (isPublishing && !props.draft) {
|
||||
setIsPublishing(false);
|
||||
}
|
||||
}, [props.draft]);
|
||||
|
||||
return {
|
||||
disabled:
|
||||
publish.disabled ||
|
||||
isValidating ||
|
||||
markers.some((x) => x?.level === "error"),
|
||||
label: isPublishing ? "Publishing…" : "Publish",
|
||||
color: "success",
|
||||
icon: PublishIcon,
|
||||
|
||||
onHandle: () => {
|
||||
// This will update the button text
|
||||
setIsPublishing(true);
|
||||
|
||||
// Set publishedAt to current date and time
|
||||
!props.published &&
|
||||
patch.execute([{ set: { publishedAt: new Date().toISOString() } }]);
|
||||
|
||||
// Perform the publish
|
||||
publish.execute();
|
||||
|
||||
// Signal that the action is completed
|
||||
props.onComplete();
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
import { EyeScreened } from "@navikt/ds-icons";
|
||||
import { BodyLong, Button } from "@navikt/ds-react";
|
||||
import React from "react";
|
||||
const sanityClient = require("@sanity/client");
|
||||
const SanityConfig = require("../../sanity.json");
|
||||
|
||||
const client = sanityClient({
|
||||
projectId: SanityConfig.api.projectId,
|
||||
dataset: SanityConfig.api.dataset,
|
||||
apiVersion: "2021-08-21",
|
||||
withCredentials: true,
|
||||
});
|
||||
|
||||
export default function SetPrivateAction(props) {
|
||||
const [isDialogOpen, setDialogOpen] = React.useState(false);
|
||||
|
||||
const isPrivate =
|
||||
props?.published?.tilgang?.privat ?? props?.draft?.tilgang?.privat;
|
||||
|
||||
const handlePatch = async (dir: boolean) => {
|
||||
props?.published &&
|
||||
(await client
|
||||
.patch(props.id)
|
||||
.set({ tilgang: { privat: dir } })
|
||||
.commit()
|
||||
.catch((err) => {
|
||||
console.error(err.message);
|
||||
}));
|
||||
props?.draft &&
|
||||
(await client
|
||||
.patch(props.draft._id)
|
||||
.set({ tilgang: { privat: dir } })
|
||||
.commit()
|
||||
.catch((err) => {
|
||||
console.error(err.message);
|
||||
}));
|
||||
props.onComplete();
|
||||
};
|
||||
|
||||
return {
|
||||
label: isPrivate ? "Åpne side for alle" : "Skjul side bak innlogging",
|
||||
/* color: "success",
|
||||
icon: PublishIcon, */
|
||||
icon: EyeScreened,
|
||||
|
||||
onHandle: async () => {
|
||||
setDialogOpen(true);
|
||||
},
|
||||
dialog: isDialogOpen && {
|
||||
type: "modal",
|
||||
onClose: props.onComplete,
|
||||
header: isPrivate
|
||||
? "Åpne innhold for alle"
|
||||
: "Gjemme innhold bak innlogging",
|
||||
content: (
|
||||
<div>
|
||||
{isPrivate ? (
|
||||
<BodyLong spacing>
|
||||
Innholdet gjøres nå tilgjengelig for alle utenfor NAV! Dette kan
|
||||
medføre konsekvenser siden innholdet i artikkelen blir
|
||||
tilgjengelig for alle. Innhold som NAV potensielt ikke ønsker å
|
||||
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-designsystemet eller
|
||||
#aksel-redaktører på Slack.
|
||||
</BodyLong>
|
||||
) : (
|
||||
<>
|
||||
<BodyLong spacing>
|
||||
Innholdet gjøres nå bare tilgjengelig for NAV-ansatte. Alt
|
||||
utenom "innhold" vil fortsatt være tilgjengelig for alle. Dette
|
||||
inkluderer alle bilder som er lastet opp til sanity også! Husk
|
||||
at ingen "sikker" data skal skrives i Aksel, og at
|
||||
innloggings-barrieren er ment for å kunne dele innhold som vi
|
||||
ikke er helt trygg på å dele med alle.
|
||||
</BodyLong>
|
||||
Dette vil fortsatt være åpent for alle
|
||||
<ul>
|
||||
<li>Sidetittel</li>
|
||||
<li>Ingress</li>
|
||||
<li>Redaktører</li>
|
||||
<li>Bilder/filer</li>
|
||||
<li>SEO</li>
|
||||
</ul>
|
||||
Dette vil bare være tilgjengelig for NAV-ansatte
|
||||
<ul>
|
||||
<li>"Innhold"-blokken</li>
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
<div style={{ display: "flex", gap: "6px", marginTop: 8 }}>
|
||||
{isPrivate ? (
|
||||
<>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setDialogOpen(false);
|
||||
handlePatch(false);
|
||||
}}
|
||||
>
|
||||
Åpne innholdet for alle
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
setDialogOpen(false);
|
||||
props.onComplete();
|
||||
}}
|
||||
>
|
||||
Avbryt
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Button
|
||||
onClick={() => {
|
||||
setDialogOpen(false);
|
||||
handlePatch(true);
|
||||
}}
|
||||
>
|
||||
Skjul innholdet bak innlogging
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={() => {
|
||||
setDialogOpen(false);
|
||||
props.onComplete();
|
||||
}}
|
||||
>
|
||||
Avbryt
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
import MediaAssetSource from "part:sanity-plugin-media/asset-source";
|
||||
import Unsplash from "part:sanity-plugin-asset-source-unsplash/image-asset-source";
|
||||
export default [MediaAssetSource, Unsplash];
|
||||
@@ -1,53 +0,0 @@
|
||||
import { Send } from "@navikt/ds-icons";
|
||||
import { BodyLong, Button, Heading, Modal } from "@navikt/ds-react";
|
||||
import React, { useRef, useState } from "react";
|
||||
|
||||
const BundleChecker = () => {
|
||||
const [inc, setInc] = useState(0);
|
||||
const interval = useRef(null);
|
||||
|
||||
const start = () => {
|
||||
interval.current = setInterval(() => {
|
||||
setInc((x) => x + 0.4);
|
||||
}, 10);
|
||||
};
|
||||
if (inc > 99) {
|
||||
clearInterval(interval.current);
|
||||
window.location.replace("https://aksel.nav.no/admin");
|
||||
}
|
||||
|
||||
document.body.style.opacity = `${100 - inc}%`;
|
||||
document.body.style.scale = `${1 - inc / 150}`;
|
||||
document.body.style.rotate = `${inc ** 1.3}deg`;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
aria-labelledby="modal-heading"
|
||||
closeButton={false}
|
||||
open
|
||||
onClose={() => null}
|
||||
>
|
||||
<Modal.Content style={{ minWidth: "20rem", maxWidth: "40rem" }}>
|
||||
<Heading spacing id="modal-heading" size="medium" level="1">
|
||||
Studioet er flyttet!
|
||||
</Heading>
|
||||
|
||||
<BodyLong spacing>
|
||||
Vi har oppdatert studioet og flyttet det til ny url:
|
||||
aksel.nav.no/admin. Hvis noe ikke fungerer, ta kontakt på slack
|
||||
#aksel-redaksjonen! Husk å logge inn med samme login-provider. For de
|
||||
fleste vil dette være NAV SSO.
|
||||
</BodyLong>
|
||||
<Button
|
||||
onClick={() => start()}
|
||||
icon={<Send aria-hidden />}
|
||||
iconPosition="right"
|
||||
>
|
||||
Gå til nytt studio
|
||||
</Button>
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default BundleChecker;
|
||||
@@ -1,44 +0,0 @@
|
||||
import { allDocumentTypes } from "../config";
|
||||
|
||||
export default {
|
||||
widgets: [
|
||||
{
|
||||
name: "document-list",
|
||||
options: {
|
||||
title: "Drafts for God Praksis",
|
||||
query: '*[_type in $types && (_id in path("drafts.**"))]',
|
||||
queryParams: {
|
||||
types: allDocumentTypes.filter((x) => x.startsWith("gp")),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "document-list",
|
||||
options: {
|
||||
title: "Drafts for Designsystemet",
|
||||
query: '*[_type in $types && (_id in path("drafts.**"))]',
|
||||
queryParams: {
|
||||
types: allDocumentTypes.filter((x) => x.startsWith("ds")),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "outdated-documents-widget",
|
||||
options: {
|
||||
type: "warning",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "outdated-documents-widget",
|
||||
options: {
|
||||
type: "error",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "project-info",
|
||||
},
|
||||
{
|
||||
name: "project-users",
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
import { Picture } from "@navikt/ds-icons";
|
||||
import S from "@sanity/desk-tool/structure-builder";
|
||||
|
||||
import React from "react";
|
||||
|
||||
export const adminPanel = async (roles) =>
|
||||
roles.find((x) => x.name === "administrator") &&
|
||||
S.listItem()
|
||||
.title("Admin")
|
||||
.child(
|
||||
S.list()
|
||||
.title("Admin")
|
||||
.items([
|
||||
S.listItem()
|
||||
.title("Standalone-sider")
|
||||
.child(S.documentTypeList("aksel_standalone")),
|
||||
S.listItem().title("Redirects").child(S.documentTypeList("redirect")),
|
||||
])
|
||||
);
|
||||
@@ -1,104 +0,0 @@
|
||||
import { prinsipper } from "@/lib";
|
||||
import { Facilitet } from "@navikt/ds-icons";
|
||||
import S from "@sanity/desk-tool/structure-builder";
|
||||
import documentStore from "part:@sanity/base/datastore/document";
|
||||
import React from "react";
|
||||
import { map } from "rxjs/operators";
|
||||
|
||||
const temaQuery = `*[_type == "aksel_tema" && count(*[references(^._id)]) > 0]`;
|
||||
|
||||
const AkselLogo = () => (
|
||||
<svg
|
||||
width="192px"
|
||||
height="192px"
|
||||
viewBox="0 0 192 192"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
focusable="false"
|
||||
aria-hidden="true"
|
||||
strokeLinecap="round"
|
||||
strokeWidth="10"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path d="m41.63 150.3 47.39-47.38" />
|
||||
<path d="M40.92 80.3 77.7 43.53c4.25-4.24 9.9-4.24 14.15 0l56.56 56.57c4.25 4.25 4.25 9.9 0 14.14l-36.77 36.77" />
|
||||
<path d="m40.92 80.3 38.19-38.18c3.53-3.54 6.72-3.18 13.79-3.18h48.79s0 0 0 0c6.36 0 11.31 4.95 11.31 11.31 0 0 0 0 0 0v48.8c0 7.06.35 10.24-3.18 13.78l-38.19 38.18" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const akselInnhold = async () => {
|
||||
return S.listItem()
|
||||
.title("Aksel")
|
||||
.icon(() => <AkselLogo />)
|
||||
.child(
|
||||
S.list()
|
||||
.title("Innhold")
|
||||
.items([
|
||||
S.listItem()
|
||||
.title("Artikler")
|
||||
.child(() =>
|
||||
documentStore.listenQuery(temaQuery).pipe(
|
||||
map((tema: any) => {
|
||||
return S.list()
|
||||
.title("Artikler")
|
||||
.items([
|
||||
S.listItem()
|
||||
.title("Alle artikler")
|
||||
.child(S.documentTypeList("aksel_artikkel")),
|
||||
S.listItem()
|
||||
.title("Uten tema")
|
||||
.child(
|
||||
S.documentTypeList("aksel_artikkel").filter(
|
||||
`_type == "aksel_artikkel" && !defined(tema)`
|
||||
)
|
||||
),
|
||||
...tema.map((tag) => {
|
||||
return S.listItem()
|
||||
.title(tag.title)
|
||||
.child(
|
||||
S.documentList()
|
||||
.title(tag.title)
|
||||
.filter(
|
||||
`_type == 'aksel_artikkel' && $tag in tema[]->title`
|
||||
)
|
||||
.params({ tag: tag.title })
|
||||
);
|
||||
}),
|
||||
]);
|
||||
})
|
||||
)
|
||||
),
|
||||
S.listItem()
|
||||
.title("Produktbloggen")
|
||||
.child(S.documentTypeList("aksel_blogg")),
|
||||
S.listItem()
|
||||
.title("Prinsipper")
|
||||
.child(
|
||||
S.list()
|
||||
.title("Prinsipper")
|
||||
.items([
|
||||
S.listItem()
|
||||
.title("Alle artikler")
|
||||
.child(S.documentTypeList("aksel_prinsipp")),
|
||||
...prinsipper.map(({ value, title }) =>
|
||||
S.listItem()
|
||||
.title(title)
|
||||
.child(
|
||||
S.documentList()
|
||||
.title(title)
|
||||
.filter(
|
||||
`_type == 'aksel_prinsipp' && $value == prinsipp.prinsippvalg`
|
||||
)
|
||||
.params({ value })
|
||||
)
|
||||
),
|
||||
])
|
||||
),
|
||||
S.divider(),
|
||||
S.listItem()
|
||||
.title("Temasider")
|
||||
.icon(() => <Facilitet />)
|
||||
.child(S.documentTypeList("aksel_tema")),
|
||||
])
|
||||
);
|
||||
};
|
||||
@@ -1,92 +0,0 @@
|
||||
import { CoApplicant, Facilitet, Information, People } from "@navikt/ds-icons";
|
||||
import S from "@sanity/desk-tool/structure-builder";
|
||||
import userStore from "part:@sanity/base/user";
|
||||
import React from "react";
|
||||
import { createSuperPane } from "sanity-super-pane";
|
||||
import { ComponentPageWebPreview } from "../../web-previews/ComponentWebPreview";
|
||||
import { KomponentPreview } from "../../web-previews/KomponentPreview";
|
||||
import { PageWebPreview } from "../../web-previews/PageWebPreview";
|
||||
import { adminPanel } from "./admin";
|
||||
import { akselInnhold } from "./aksel";
|
||||
import { dsPanel } from "./ds";
|
||||
import { profilePanel } from "./profile";
|
||||
|
||||
export const getDefaultDocumentNode = ({ schemaType }) => {
|
||||
switch (schemaType) {
|
||||
case "komponent_artikkel":
|
||||
return S.document().views([
|
||||
S.view.form(),
|
||||
S.view.component(ComponentPageWebPreview).title("Preview"),
|
||||
S.view.component(KomponentPreview).title("Preview-dev"),
|
||||
]);
|
||||
case "ds_artikkel":
|
||||
return S.document().views([
|
||||
S.view.form(),
|
||||
S.view.component(PageWebPreview).title("Preview"),
|
||||
S.view.component(KomponentPreview).title("Preview-dev"),
|
||||
]);
|
||||
case "aksel_artikkel":
|
||||
return S.document().views([
|
||||
S.view.form(),
|
||||
S.view.component(PageWebPreview).title("Preview"),
|
||||
S.view.component(KomponentPreview).title("Preview-dev"),
|
||||
]);
|
||||
case "aksel_blogg":
|
||||
return S.document().views([
|
||||
S.view.form(),
|
||||
S.view.component(PageWebPreview).title("Preview"),
|
||||
S.view.component(KomponentPreview).title("Preview-dev"),
|
||||
]);
|
||||
case "aksel_prinsipp":
|
||||
return S.document().views([
|
||||
S.view.form(),
|
||||
S.view.component(PageWebPreview).title("Preview"),
|
||||
S.view.component(KomponentPreview).title("Preview-dev"),
|
||||
]);
|
||||
case "aksel_standalone":
|
||||
return S.document().views([
|
||||
S.view.form(),
|
||||
S.view.component(PageWebPreview).title("Preview"),
|
||||
S.view.component(KomponentPreview).title("Preview-dev"),
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
const items = [
|
||||
S.divider(),
|
||||
S.listItem()
|
||||
.title("Redaktører")
|
||||
.icon(() => <People />)
|
||||
.child(createSuperPane("editor")),
|
||||
|
||||
S.divider(),
|
||||
];
|
||||
|
||||
export default () => {
|
||||
return userStore.getCurrentUser().then(async ({ roles, id }) => {
|
||||
const panels = [];
|
||||
const admin = await adminPanel(roles);
|
||||
|
||||
const profile = await profilePanel(id);
|
||||
const ds = await dsPanel(roles);
|
||||
const aksel = await akselInnhold();
|
||||
const intro = [];
|
||||
|
||||
profile && intro.push(profile);
|
||||
profile && intro.push(S.divider());
|
||||
|
||||
let struct = items;
|
||||
|
||||
if (ds) {
|
||||
struct = [ds, ...struct];
|
||||
}
|
||||
struct = [aksel, ...struct];
|
||||
if (admin) {
|
||||
struct = [...struct, admin];
|
||||
}
|
||||
|
||||
return S.list()
|
||||
.title("Aksel")
|
||||
.items([...intro, ...struct, ...panels]);
|
||||
});
|
||||
};
|
||||
@@ -1,115 +0,0 @@
|
||||
import {
|
||||
Facilitet,
|
||||
FileContent,
|
||||
Findout,
|
||||
Folder,
|
||||
Picture,
|
||||
Place,
|
||||
Ruler,
|
||||
Task,
|
||||
} from "@navikt/ds-icons";
|
||||
import S from "@sanity/desk-tool/structure-builder";
|
||||
import client from "part:@sanity/base/client";
|
||||
import React from "react";
|
||||
import { createSuperPane } from "sanity-super-pane";
|
||||
|
||||
export const dsPanel = async (roles) => {
|
||||
const role = roles.some(({ name }) => "aksel-editor" === name);
|
||||
|
||||
if (role) {
|
||||
return null;
|
||||
} else {
|
||||
return S.listItem()
|
||||
.title("Designsystemet")
|
||||
.icon(() => <Facilitet />)
|
||||
.child(
|
||||
S.list()
|
||||
.title("Designsystem")
|
||||
.items([
|
||||
S.listItem()
|
||||
.title("Komponentsider")
|
||||
.icon(() => <Facilitet />)
|
||||
.child(createSuperPane("komponent_artikkel")),
|
||||
S.listItem()
|
||||
.title("Artikler")
|
||||
.icon(() => <FileContent />)
|
||||
.child(createSuperPane("ds_artikkel")),
|
||||
S.divider(),
|
||||
S.documentListItem()
|
||||
.title(`Navigasjon`)
|
||||
.schemaType(`ds_navigation`)
|
||||
.icon(() => <Place />)
|
||||
.id(`ds_navigationid`),
|
||||
|
||||
S.listItem()
|
||||
.title("Publiserte sider ikke i navigasjon")
|
||||
.child(async (): Promise<any> => {
|
||||
const doc = await client.fetch(
|
||||
`*[_id == 'ds_navigationid'][0]{
|
||||
headings[]{
|
||||
title,
|
||||
menu
|
||||
}
|
||||
}`
|
||||
);
|
||||
if (!doc.headings) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let allIds = "";
|
||||
try {
|
||||
allIds = doc.headings
|
||||
.map((heading) =>
|
||||
heading.menu
|
||||
.filter((item) => item._type === "item")
|
||||
.map((item) => item.link._ref)
|
||||
.map((x) => `"${x}"`)
|
||||
.join(",")
|
||||
)
|
||||
.join(",");
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
return S.documentList()
|
||||
.title("Sider ikke i navigasjon")
|
||||
.filter(
|
||||
`!(_id in [${allIds}]) && !(_id in path('drafts.**')) && _type in ["komponent_artikkel", "ds_artikkel"]`
|
||||
);
|
||||
}),
|
||||
S.documentListItem()
|
||||
.title(`Forside`)
|
||||
.schemaType(`ds_frontpage`)
|
||||
.icon(() => <Picture />)
|
||||
.id(`frontpage_designsystem`),
|
||||
S.divider(),
|
||||
S.listItem()
|
||||
.title("Autogenerert data")
|
||||
.child(
|
||||
S.list()
|
||||
.title("Autogenerert data")
|
||||
.items([
|
||||
S.listItem()
|
||||
.title("Eksempler")
|
||||
.icon(() => <span>{`EX`}</span>)
|
||||
.child(S.documentTypeList("kode_eksempler_fil")),
|
||||
S.listItem()
|
||||
.title("Props")
|
||||
.icon(() => <Folder />)
|
||||
.child(S.documentTypeList("ds_props")),
|
||||
S.listItem()
|
||||
.title("Token-kategorier")
|
||||
.icon(() => <Folder />)
|
||||
.child(S.documentTypeList("token_kategori")),
|
||||
])
|
||||
),
|
||||
S.divider(),
|
||||
S.documentListItem()
|
||||
.title(`Komponent-template`)
|
||||
.schemaType(`ds_component_template`)
|
||||
.icon(() => <Task />)
|
||||
.id(`ds_component_templateid`),
|
||||
])
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
import { Picture } from "@navikt/ds-icons";
|
||||
import S from "@sanity/desk-tool/structure-builder";
|
||||
import userStore from "part:@sanity/base/user";
|
||||
import client from "part:@sanity/base/client";
|
||||
|
||||
import React from "react";
|
||||
|
||||
export const profilePanel = async (id) => {
|
||||
const ids = await client.withConfig({ apiVersion: "2021-05-31" })
|
||||
.fetch(`*[_type == "editor"]{
|
||||
_id,
|
||||
user_id
|
||||
}`);
|
||||
|
||||
const editor = ids.find(({ user_id }) => user_id?.current === id);
|
||||
|
||||
if (editor) {
|
||||
return S.documentListItem()
|
||||
.title(`Profil`)
|
||||
.schemaType(`editor`)
|
||||
.icon(() => <Picture />)
|
||||
.id(editor._id);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -1,53 +0,0 @@
|
||||
import React from "react";
|
||||
import { People } from "@navikt/ds-icons";
|
||||
import T from "@sanity/base/initial-value-template-builder";
|
||||
import userStore from "part:@sanity/base/user";
|
||||
|
||||
const sanityClient = require("@sanity/client");
|
||||
const sanityToken = process.env.SANITY_TOKEN;
|
||||
const SanityConfig = require("../sanity.json");
|
||||
|
||||
const client = sanityClient({
|
||||
projectId: SanityConfig.api.projectId,
|
||||
dataset: SanityConfig.api.dataset,
|
||||
apiVersion: "2020-06-19",
|
||||
/* Token er safe og har bare tillatelse til å lese template doc */
|
||||
token:
|
||||
"skt6kqEcXmRxUTGDzdEcw11g7HJi9DaHX2fyn8Z0Dearr1k67ykW2N64KTP9GxAPNN6P8TlzPjUdkfGsvbJkfmwfq0UNudKfMYOfyz9OeA666y15pPLRr6D7xnrJGEEBYwSvG6baLLiJI478YowWpjqp1Mz2U1PbAPnIMW4W5btTpdQbwPSD",
|
||||
useCdn: false,
|
||||
});
|
||||
|
||||
export default [
|
||||
...T.defaults().filter((x) => !["komponent_artikkel"].includes(x.spec.id)),
|
||||
|
||||
T.template({
|
||||
id: "komponent_artikkel_template",
|
||||
title: "Mal for Komponentsider",
|
||||
schemaType: "komponent_artikkel",
|
||||
value: async () => {
|
||||
const doc = await client.fetch(`*[_type == "ds_component_template"][0]`);
|
||||
return doc
|
||||
? Object.entries(doc).reduce((old, [key, val]) => {
|
||||
return key.startsWith("_") ? { ...old } : { ...old, [key]: val };
|
||||
}, {})
|
||||
: {};
|
||||
},
|
||||
}),
|
||||
T.template({
|
||||
id: "newEditor",
|
||||
title: "Editor",
|
||||
schemaType: "editor",
|
||||
icon: () => <People />,
|
||||
value: async () => {
|
||||
const { id, displayName } = await userStore.getUser("me");
|
||||
|
||||
return {
|
||||
title: displayName,
|
||||
user_id: {
|
||||
current: id,
|
||||
},
|
||||
_type: "editor",
|
||||
};
|
||||
},
|
||||
}),
|
||||
];
|
||||
@@ -1,38 +0,0 @@
|
||||
import S from "@sanity/base/structure-builder";
|
||||
|
||||
const docTypes = [
|
||||
{
|
||||
name: "aksel_artikkel",
|
||||
title: "Aksel Artikkel",
|
||||
},
|
||||
{
|
||||
name: "newEditor",
|
||||
title: "Bruker/redaktør",
|
||||
desc: "Lager en psuedo-bruker for deg som kan koble artikler til brukeren",
|
||||
},
|
||||
{
|
||||
name: "aksel_blogg",
|
||||
title: "Bloggpost",
|
||||
},
|
||||
{
|
||||
name: "ds_artikkel",
|
||||
title: "Designsystem Artikkel",
|
||||
desc: "Atikkel som legges under designsystemet",
|
||||
},
|
||||
{
|
||||
name: "komponent_artikkel_template",
|
||||
title: "Designsystem Komponentside",
|
||||
desc: "Atikkel som legges under designsystemet",
|
||||
},
|
||||
];
|
||||
|
||||
export default [
|
||||
...docTypes.map((doct) =>
|
||||
S.initialValueTemplateItem(doct.name)
|
||||
.id(`doc-${doct.name}`)
|
||||
.title(doct.title)
|
||||
.templateId(doct.name)
|
||||
.description(doct?.desc ?? "")
|
||||
),
|
||||
/* ...S.defaultInitialValueTemplateItems() */
|
||||
];
|
||||
@@ -1,15 +0,0 @@
|
||||
import defaultResolve, {
|
||||
PublishAction,
|
||||
} from "part:@sanity/base/document-actions";
|
||||
import SetAndPublishAction from "./actions/publishedAt";
|
||||
/* import SetPrivateAction from "./actions/set-private"; */
|
||||
import { allDocumentTypes } from "../config";
|
||||
|
||||
export default function resolveDocumentActions(props) {
|
||||
const [publish, ...rest] = defaultResolve(props).map((Action) => {
|
||||
return allDocumentTypes.includes(props.type) && Action === PublishAction
|
||||
? SetAndPublishAction
|
||||
: Action;
|
||||
});
|
||||
return [publish /* SetPrivateAction */, ...rest];
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
import { Button, Card, Inline, Stack, Text } from "@sanity/ui";
|
||||
import moment from "moment";
|
||||
import PatchEvent, { set } from "part:@sanity/form-builder/patch-event";
|
||||
import React from "react";
|
||||
|
||||
const CustomDisplay = React.forwardRef((props, ref) => {
|
||||
const click = () => {
|
||||
props.onChange &&
|
||||
props.onChange(
|
||||
PatchEvent.from(set(new Date().toISOString().split("T")[0]))
|
||||
);
|
||||
};
|
||||
|
||||
const lastUpdate = moment(props.value);
|
||||
const daysSince = moment().diff(lastUpdate, "days");
|
||||
|
||||
return (
|
||||
<Stack tabIndex={0} space={4} ref={ref}>
|
||||
{daysSince > 90 && (
|
||||
<Card
|
||||
padding={[3, 3, 4]}
|
||||
radius={2}
|
||||
shadow={1}
|
||||
tone={daysSince > 180 ? "critical" : "caution"}
|
||||
>
|
||||
<Text align="center" size={[2, 2, 3]}>
|
||||
{daysSince > 180
|
||||
? "Innholdet er utdatert!"
|
||||
: "Innholdet er stagnert!"}
|
||||
</Text>
|
||||
</Card>
|
||||
)}
|
||||
<Stack space={4}>
|
||||
<Text size={1} weight="semibold">
|
||||
Sist oppdatert
|
||||
</Text>
|
||||
<Text size={2}>{props.value?.split("-").reverse().join("/")}</Text>
|
||||
</Stack>
|
||||
|
||||
<Inline space={[3, 3, 4]}>
|
||||
<Button
|
||||
onClick={() => click()}
|
||||
fontSize={[2]}
|
||||
mode="ghost"
|
||||
padding={[2, 2]}
|
||||
text="Oppdater"
|
||||
/>
|
||||
</Inline>
|
||||
</Stack>
|
||||
);
|
||||
});
|
||||
|
||||
export default CustomDisplay;
|
||||
@@ -1,30 +0,0 @@
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import { withDocument } from "part:@sanity/form-builder";
|
||||
import {
|
||||
TextInput,
|
||||
Stack,
|
||||
Label,
|
||||
Checkbox,
|
||||
Radio,
|
||||
Flex,
|
||||
Text,
|
||||
Box,
|
||||
Card,
|
||||
} from "@sanity/ui";
|
||||
import styled from "styled-components";
|
||||
/* TODO: Implement this. Issue now is that document returns null in props */
|
||||
const CustomDisplay = React.forwardRef((props, ref) => {
|
||||
const [doc, setDoc] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
doc && setDoc(props.document);
|
||||
}, [props]);
|
||||
|
||||
return (
|
||||
<Stack space={0} ref={ref}>
|
||||
<Card padding={0}>T</Card>
|
||||
</Stack>
|
||||
);
|
||||
});
|
||||
|
||||
export default withDocument(CustomDisplay);
|
||||
@@ -1,49 +0,0 @@
|
||||
import React from "react";
|
||||
import Preview from "part:@sanity/base/preview";
|
||||
import { IntentLink } from "part:@sanity/base/router";
|
||||
import schema from "part:@sanity/base/schema";
|
||||
import {
|
||||
Item as DefaultItem,
|
||||
List as DefaultList,
|
||||
} from "part:@sanity/components/lists/default";
|
||||
import styles from "./profile.css";
|
||||
|
||||
const ReferringDocumentsList = (props) => {
|
||||
const { documents } = props;
|
||||
return (
|
||||
<DefaultList className={styles.root}>
|
||||
{documents
|
||||
.sort(
|
||||
(a, b) =>
|
||||
new Date(b._updatedAt).getTime() - new Date(a._updatedAt).getTime()
|
||||
)
|
||||
.map((document) => {
|
||||
const schemaType = schema.get(document._type);
|
||||
return (
|
||||
<DefaultItem key={document._id} className={styles.item}>
|
||||
{schemaType ? (
|
||||
<IntentLink
|
||||
className={styles.link}
|
||||
intent="edit"
|
||||
params={{ id: document._id, type: document._type }}
|
||||
>
|
||||
<Preview value={document} type={schemaType} />
|
||||
{document._updatedAt
|
||||
.split("T")[0]
|
||||
.split("-")
|
||||
.reverse()
|
||||
.join("-")}
|
||||
</IntentLink>
|
||||
) : (
|
||||
<div>
|
||||
A document of the unknown type <em>{document._type}</em>
|
||||
</div>
|
||||
)}
|
||||
</DefaultItem>
|
||||
);
|
||||
})}
|
||||
</DefaultList>
|
||||
);
|
||||
};
|
||||
|
||||
export default ReferringDocumentsList;
|
||||
@@ -1,18 +0,0 @@
|
||||
export const getUnpublished = (docs: Record<string, any>[]) =>
|
||||
docs.filter(
|
||||
(doc, i, arr) =>
|
||||
doc._id.startsWith("drafts.") &&
|
||||
!arr.find((x, y) => i !== y && doc._id.includes(x._id))
|
||||
);
|
||||
|
||||
export const getDrafts = (docs: Record<string, any>[]) =>
|
||||
docs.filter((doc, i, arr) =>
|
||||
arr.find((x, y) => i !== y && x._id.includes(doc._id))
|
||||
);
|
||||
|
||||
export const getPublished = (docs: Record<string, any>[]) =>
|
||||
docs
|
||||
.filter(
|
||||
(doc, i, arr) => !arr.find((x, y) => i !== y && x._id.includes(doc._id))
|
||||
)
|
||||
.filter((doc) => !doc._id.includes("drafts"));
|
||||
@@ -1,147 +0,0 @@
|
||||
import { Caseworker, Sandglass, Upload, Wrench } from "@navikt/ds-icons";
|
||||
import {
|
||||
BodyShort,
|
||||
Detail,
|
||||
Heading,
|
||||
HelpText,
|
||||
Label,
|
||||
Link,
|
||||
ReadMore,
|
||||
} from "@navikt/ds-react";
|
||||
import { SanityDocument } from "@sanity/client";
|
||||
import { Stack } from "@sanity/ui";
|
||||
import userStore from "part:@sanity/base/user";
|
||||
import { WithReferringDocuments } from "part:@sanity/base/with-referring-documents";
|
||||
import Spinner from "part:@sanity/components/loading/spinner";
|
||||
import { withDocument } from "part:@sanity/form-builder";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import ReferringDocumentsList from "./document-list";
|
||||
import styles from "../styles.css";
|
||||
import { getDrafts, getPublished, getUnpublished } from "./filter-docs";
|
||||
|
||||
type Props = {
|
||||
referringDocuments: Record<string, any>[];
|
||||
isLoading: boolean;
|
||||
published?: SanityDocument | null;
|
||||
type: any;
|
||||
document: any;
|
||||
};
|
||||
|
||||
const IntroPage = React.forwardRef<HTMLDivElement, Props>((props, ref) => {
|
||||
const { document } = props;
|
||||
const [user, setUser] = useState<any>({});
|
||||
|
||||
useEffect(() => {
|
||||
userStore.getCurrentUser().then((user) => setUser(user));
|
||||
}, []);
|
||||
|
||||
const EmptyState = () => (
|
||||
<Detail className={styles.detailsContent} size="small">
|
||||
Ingen sider her...
|
||||
</Detail>
|
||||
);
|
||||
if (
|
||||
!document._id ||
|
||||
(document?.user_id?.current !== user.id &&
|
||||
!user?.roles?.find((x) => x.name === "administrator"))
|
||||
)
|
||||
return null;
|
||||
|
||||
return (
|
||||
<Stack ref={ref} space={[3, 1, 2, 4]}>
|
||||
<Heading level="2" size="medium" spacing style={{ display: "flex" }}>
|
||||
Profil <Caseworker style={{ marginLeft: "0.5rem", fontSize: "2rem" }} />
|
||||
</Heading>
|
||||
{user?.roles && (
|
||||
<div>
|
||||
<Heading level="3" size="small" spacing>
|
||||
Roller/tilganger:
|
||||
</Heading>
|
||||
{user?.roles.map((x, i) => (
|
||||
<div key={i}>
|
||||
<Label size="small" spacing as="p">
|
||||
{x?.title}
|
||||
</Label>
|
||||
<BodyShort size="small">{x?.description}</BodyShort>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<BodyShort
|
||||
size="small"
|
||||
spacing
|
||||
as="span"
|
||||
style={{ display: "flex", gap: "0.5rem" }}
|
||||
>
|
||||
<ReadMore header="Har du ikke de rollene du trenger?">
|
||||
Send en melding til oss på{" "}
|
||||
<Link href="https://nav-it.slack.com/archives/C7NE7A8UF">
|
||||
#Aksel-designsystemet
|
||||
</Link>{" "}
|
||||
slack så fikser vi det.
|
||||
</ReadMore>
|
||||
</BodyShort>
|
||||
<div style={{ borderTop: "1px solid #bbb" }} />
|
||||
|
||||
<WithReferringDocuments id={document._id?.replace("drafts.", "")}>
|
||||
{({ referringDocuments, isLoading }) => {
|
||||
if (isLoading) {
|
||||
return <Spinner message="Looking for referring documents…" />;
|
||||
}
|
||||
if (!referringDocuments.length) return null;
|
||||
|
||||
const drafts = getDrafts(referringDocuments);
|
||||
const published = getPublished(referringDocuments);
|
||||
const unpublished = getUnpublished(referringDocuments);
|
||||
|
||||
return (
|
||||
<Stack space={2}>
|
||||
<Heading level="3" size="xsmall" style={{ display: "flex" }}>
|
||||
<Upload />
|
||||
Publiserte sider
|
||||
</Heading>
|
||||
|
||||
<ReadMore header={`Oppdaterte: ${published.length}`}>
|
||||
{published ? (
|
||||
<ReferringDocumentsList documents={published} />
|
||||
) : (
|
||||
<EmptyState />
|
||||
)}
|
||||
</ReadMore>
|
||||
<ReadMore header={`Med upubliserte endringer: ${drafts.length}`}>
|
||||
{drafts ? (
|
||||
<ReferringDocumentsList documents={drafts} />
|
||||
) : (
|
||||
<EmptyState />
|
||||
)}
|
||||
</ReadMore>
|
||||
<Heading level="3" size="xsmall" className={styles.headings}>
|
||||
<Wrench />
|
||||
Under arbeid
|
||||
</Heading>
|
||||
<ReadMore header={`Sider: ${unpublished.length}`}>
|
||||
{unpublished ? (
|
||||
<ReferringDocumentsList documents={unpublished} />
|
||||
) : (
|
||||
<EmptyState />
|
||||
)}
|
||||
</ReadMore>
|
||||
<Heading level="3" size="xsmall" className={styles.headings}>
|
||||
<Sandglass />
|
||||
Utdaterte sider
|
||||
</Heading>
|
||||
<ReadMore header={`Ikke oppdatert på over 90 dager: 0`}>
|
||||
<EmptyState />
|
||||
</ReadMore>
|
||||
<ReadMore header={`Ikke oppdatert på over 180 dager: 0`}>
|
||||
<EmptyState />
|
||||
</ReadMore>
|
||||
</Stack>
|
||||
);
|
||||
}}
|
||||
</WithReferringDocuments>
|
||||
</Stack>
|
||||
);
|
||||
});
|
||||
|
||||
export default withDocument(IntroPage);
|
||||
@@ -1,35 +0,0 @@
|
||||
/* ./cms/styles/ReferringDocumentsList.css */
|
||||
|
||||
@import "part:@sanity/base/theme/variables-style";
|
||||
|
||||
.root {
|
||||
composes: root from "part:@sanity/components/lists/default-style";
|
||||
}
|
||||
|
||||
.item {
|
||||
composes: lineBetween from "part:@sanity/components/lists/default-item-style";
|
||||
background: var(--white);
|
||||
border-radius: var(--border-radius-base);
|
||||
color: inherit;
|
||||
margin-bottom: var(--small-padding);
|
||||
border: 1px solid var(--list-border-color);
|
||||
}
|
||||
|
||||
.item:hover {
|
||||
background-color: var(--a-surface-action-subtle-hover, rgba(230, 240, 255, 1));
|
||||
}
|
||||
|
||||
.link {
|
||||
padding: var(--small-padding);
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.link:focus {
|
||||
border-radius: 2px;
|
||||
outline: none;
|
||||
box-shadow: var(--a-shadow-focus, var(--a-shadow-focus, 0 0 0 3px rgba(0, 52, 125, 1)));
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
@import "part:@sanity/base/theme/variables-style";
|
||||
|
||||
.link {
|
||||
composes: item from "part:@sanity/base/theme/layout/selectable-style";
|
||||
display: block;
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
outline: none;
|
||||
padding: 0.5rem 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.headings {
|
||||
margin-top: 1rem !important;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
p.detailsContent {
|
||||
margin-left: 2rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
import { Heading, Stack, Text } from "@sanity/ui";
|
||||
import { withDocument } from "part:@sanity/form-builder";
|
||||
import { getPublishedId } from "part:@sanity/base/util/draft-utils";
|
||||
import schema from "part:@sanity/base/schema";
|
||||
import React, { useEffect, useCallback, useState } from "react";
|
||||
import moment from "moment";
|
||||
import { IntentLink } from "part:@sanity/base/router";
|
||||
import { Item, List } from "part:@sanity/components/lists/default";
|
||||
import SanityPreview from "part:@sanity/base/preview";
|
||||
import styles from "./styles.css";
|
||||
const sanityClient = require("@sanity/client");
|
||||
const SanityConfig = require("../sanity.json");
|
||||
|
||||
const client = sanityClient({
|
||||
projectId: SanityConfig.api.projectId,
|
||||
dataset: SanityConfig.api.dataset,
|
||||
apiVersion: "2020-06-19",
|
||||
useCdn: false,
|
||||
});
|
||||
|
||||
const RelatedArticles = React.forwardRef((props, ref) => {
|
||||
const [userDocuments, setUserDocuments] = useState([]);
|
||||
|
||||
const getUserDocs = useCallback(async () => {
|
||||
const userDocs = await client
|
||||
.fetch(`*["${props.document._id}" == contact._ref]`)
|
||||
.catch((e) => console.error(e.message));
|
||||
userDocs && setUserDocuments(userDocs);
|
||||
}, [props.document]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!props.document) {
|
||||
return;
|
||||
}
|
||||
getUserDocs();
|
||||
}, [getUserDocs]);
|
||||
|
||||
const outdated = userDocuments.filter((doc) => {
|
||||
if (!doc?.metadata?.last_update) return false;
|
||||
const lastUpdate = moment(doc._updatedAt);
|
||||
const daysSince = moment().diff(lastUpdate, "days");
|
||||
return daysSince > 180;
|
||||
});
|
||||
|
||||
const stagnated = userDocuments.filter((doc) => {
|
||||
if (!doc?.metadata?.last_update) return false;
|
||||
const lastUpdate = moment(doc._updatedAt);
|
||||
const daysSince = moment().diff(lastUpdate, "days");
|
||||
return daysSince > 90 && daysSince <= 180;
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack space={0} ref={ref} space={[3, 1, 2, 4]}>
|
||||
<details>
|
||||
<summary>Utdaterte sider: {outdated.length}</summary>
|
||||
<List>
|
||||
{outdated.map((doc) => (
|
||||
<Item key={doc._id}>
|
||||
<IntentLink
|
||||
intent="edit"
|
||||
params={{
|
||||
type: doc._type,
|
||||
id: getPublishedId(doc._id),
|
||||
}}
|
||||
className={styles.link}
|
||||
>
|
||||
<SanityPreview
|
||||
layout="default"
|
||||
type={schema.get(doc._type)}
|
||||
value={doc}
|
||||
key={doc._id}
|
||||
/>
|
||||
</IntentLink>
|
||||
</Item>
|
||||
))}
|
||||
</List>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Stagnerte sider: {stagnated.length}</summary>
|
||||
<List>
|
||||
{stagnated.map((doc) => (
|
||||
<Item key={doc._id}>
|
||||
<IntentLink
|
||||
intent="edit"
|
||||
params={{
|
||||
type: doc._type,
|
||||
id: getPublishedId(doc._id),
|
||||
}}
|
||||
className={styles.link}
|
||||
>
|
||||
<SanityPreview
|
||||
layout="default"
|
||||
type={schema.get(doc._type)}
|
||||
value={doc}
|
||||
key={doc._id}
|
||||
/>
|
||||
</IntentLink>
|
||||
</Item>
|
||||
))}
|
||||
</List>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Alle sider: {userDocuments.length}</summary>
|
||||
<List>
|
||||
{userDocuments.map((doc) => (
|
||||
<Item key={doc._id}>
|
||||
<IntentLink
|
||||
intent="edit"
|
||||
params={{
|
||||
type: doc._type,
|
||||
id: getPublishedId(doc._id),
|
||||
}}
|
||||
className={styles.link}
|
||||
>
|
||||
<SanityPreview
|
||||
layout="default"
|
||||
type={schema.get(doc._type)}
|
||||
value={doc}
|
||||
key={doc._id}
|
||||
/>
|
||||
</IntentLink>
|
||||
</Item>
|
||||
))}
|
||||
</List>
|
||||
</details>
|
||||
</Stack>
|
||||
);
|
||||
});
|
||||
|
||||
export default withDocument(RelatedArticles);
|
||||
@@ -1,41 +0,0 @@
|
||||
const teams = [
|
||||
{
|
||||
name: "designsystem",
|
||||
prefix: "ds",
|
||||
documents: ["komponent_artikkel", "ds_artikkel"],
|
||||
navigation: `navigation_designsystem`,
|
||||
},
|
||||
{
|
||||
name: "god_praksis",
|
||||
prefix: "gp",
|
||||
documents: ["aksel_artikkel", "aksel_blogg", "aksel_prinsipp"],
|
||||
},
|
||||
];
|
||||
|
||||
/* Collection of all document-pages to account for */
|
||||
const allDocumentTypes = teams.reduce(
|
||||
(docs, team) => [...docs, ...team.documents],
|
||||
[]
|
||||
);
|
||||
|
||||
/* Collection of all navigation-documents */
|
||||
const allNavDocumentIds = teams.map((x) => x?.navigation).filter((x) => x);
|
||||
|
||||
/**
|
||||
* Defines when a document of a spesific type is set to stagnant or expired
|
||||
* @returns [stagnant Date, expired Date]
|
||||
*/
|
||||
function getExpireDates() {
|
||||
const stagnantDate = new Date();
|
||||
const expiredDate = new Date();
|
||||
stagnantDate.setDate(stagnantDate.getDate() + 120);
|
||||
expiredDate.setDate(expiredDate.getDate() + 180);
|
||||
return [stagnantDate, expiredDate];
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
teams,
|
||||
allDocumentTypes,
|
||||
allNavDocumentIds,
|
||||
getExpireDates,
|
||||
};
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"#": "Used by Sanity to keep track of configuration file checksums, do not delete or modify!",
|
||||
"@sanity/default-layout": "bb034f391ba508a6ca8cd971967cbedeb131c4d19b17b28a0895f32db5d568ea",
|
||||
"@sanity/default-login": "6fb6d3800aa71346e1b84d95bbcaa287879456f2922372bb0294e30b968cd37f",
|
||||
"@sanity/form-builder": "b38478227ba5e22c91981da4b53436df22e48ff25238a55a973ed620be5068aa",
|
||||
"@sanity/data-aspects": "d199e2c199b3e26cd28b68dc84d7fc01c9186bf5089580f2e2446994d36b3cb6",
|
||||
"@sanity/vision": "da5b6ed712703ecd04bf4df560570c668aa95252c6bc1c41d6df1bda9b8b8f60",
|
||||
"power-table": "922902575995e62af8f628e6abe652ecc5f3b1e1d2dec5859392e79e47707088",
|
||||
"table": "e56785cc6cecbacf8ebe6bb99ffae32b973e233503c0714497ac7df3042863f1"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"listOptions": {}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
{
|
||||
"toolSwitcher": {
|
||||
"order": [],
|
||||
"hidden": []
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"providers": {
|
||||
"mode": "append",
|
||||
"redirectOnSingle": false,
|
||||
"entries": [
|
||||
{
|
||||
"name": "saml",
|
||||
"title": "NAV SSO",
|
||||
"url": "https://api.sanity.io/v2021-10-01/auth/saml/login/f3270b37",
|
||||
"logo": "/static/navlogo.svg"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"images": {
|
||||
"directUploads": true
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"defaultApiVersion": "2021-10-21"
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
import { allDocumentTypes } from "../config";
|
||||
|
||||
export const editorField = {
|
||||
title: "Redaktører",
|
||||
description: "Legg til alle som har bidratt med denne siden!",
|
||||
name: "contributors",
|
||||
type: "array",
|
||||
of: [{ type: "reference", to: [{ type: "editor" }] }],
|
||||
group: "settings",
|
||||
validation: (Rule) => Rule.required(),
|
||||
};
|
||||
|
||||
export const privateField = {
|
||||
title: "Sidetilganger",
|
||||
name: "tilgang",
|
||||
type: "object",
|
||||
description: "Styrer tilgang for side-innhold",
|
||||
hidden: true,
|
||||
fields: [
|
||||
{
|
||||
title: "Privat",
|
||||
name: "privat",
|
||||
type: "boolean",
|
||||
},
|
||||
],
|
||||
initialValue: {
|
||||
privat: true,
|
||||
},
|
||||
};
|
||||
|
||||
export const publishedAtField = {
|
||||
title: "Publiseringsdato",
|
||||
name: "publishedAt",
|
||||
type: "datetime",
|
||||
group: "settings",
|
||||
description: "Synlig bare for admins. Setter publiseringsdato for dokument",
|
||||
hidden: ({ currentUser }) =>
|
||||
!currentUser.roles.find((x) => x.name === "administrator"),
|
||||
};
|
||||
|
||||
export const titleField = {
|
||||
title: "Sidetittel",
|
||||
name: "heading",
|
||||
type: "string",
|
||||
group: "innhold",
|
||||
description:
|
||||
"Bruk en kort og konsis tittel om mulig. Blir satt som `<H1 />` på toppen av siden i URL.",
|
||||
validation: (Rule) =>
|
||||
Rule.required()
|
||||
.max(60)
|
||||
.error("Siden bør ha en kort og konsis heading (<h1>)"),
|
||||
};
|
||||
|
||||
export const ingressField = {
|
||||
title: "Ingress",
|
||||
name: "ingress",
|
||||
description: "Side, innganger og seo description-tag",
|
||||
type: "text",
|
||||
group: "innhold",
|
||||
rows: 3,
|
||||
validation: (Rule) =>
|
||||
Rule.required().max(210).error("Ingress kan ikke være på over 210 tegn"),
|
||||
};
|
||||
|
||||
export const innholdFieldNew = {
|
||||
title: "Innhold",
|
||||
name: "content",
|
||||
type: "riktekst_aksel",
|
||||
group: "innhold",
|
||||
};
|
||||
|
||||
export const innholdFieldPrinsipp = {
|
||||
title: "Innhold",
|
||||
name: "content",
|
||||
type: "riktekst_prinsipp",
|
||||
group: "innhold",
|
||||
};
|
||||
|
||||
export const relevanteArtiklerField = {
|
||||
title: "Relevante artikler",
|
||||
description:
|
||||
"Legg til relaterte artikler som du tenker er relevant å lese (maks 3)",
|
||||
name: "relevante_artikler",
|
||||
type: "array",
|
||||
group: "innhold",
|
||||
validation: (Rule) =>
|
||||
Rule.max(3).error("Kan ikke ha mer enn 3 relevante artikler lagt til"),
|
||||
of: [
|
||||
{
|
||||
type: "reference",
|
||||
weak: true,
|
||||
to: [...allDocumentTypes.map((x) => ({ type: x }))],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const innholdFieldNewNested = (name?: string, type?: string) => {
|
||||
const fields = {
|
||||
...innholdFieldNew,
|
||||
type: type ?? "riktekst_ds_artikkel",
|
||||
name: name ?? "content",
|
||||
};
|
||||
delete fields.group;
|
||||
return fields;
|
||||
};
|
||||
@@ -1,154 +0,0 @@
|
||||
export * from "./fields";
|
||||
export * from "./preview";
|
||||
export * from "./seo";
|
||||
import { Settings } from "@navikt/ds-icons";
|
||||
import sanityClient from "part:@sanity/base/client";
|
||||
|
||||
const client = sanityClient.withConfig({ apiVersion: "2020-06-19" });
|
||||
|
||||
export const prinsipper = [
|
||||
{ title: "Brukeropplevelse", value: "brukeropplevelse" },
|
||||
];
|
||||
|
||||
export function toPlainText(blocks = []) {
|
||||
return blocks
|
||||
.filter((block) => !(block._type !== "block" || !block.children))
|
||||
.map((block) => {
|
||||
return block.children.map((child) => child.text).join("");
|
||||
})
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
export const sanitySlug = (prefix: string, depth: number, source?: string) => ({
|
||||
title: "url",
|
||||
name: "slug",
|
||||
type: "slug",
|
||||
validation: (Rule) => validateSlug(Rule, prefix, depth ?? 3),
|
||||
group: "settings",
|
||||
options: {
|
||||
isUnique: isSlugUnique,
|
||||
source: source ?? "heading",
|
||||
slugify: (input) =>
|
||||
`${prefix}${input}`
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.slice(0, 80)
|
||||
.trim()
|
||||
.replace(/\s+/g, "-")
|
||||
.replace("--", "-")
|
||||
.replace("(", "")
|
||||
.replace(")", "")
|
||||
.replace("æ", "a")
|
||||
.replace("ø", "o")
|
||||
.replace("å", "a")
|
||||
.replace(".", "-"),
|
||||
},
|
||||
});
|
||||
|
||||
/* Checks that slug starts with prefix and is nested to x depth */
|
||||
export const validateSlug = (Rule, prefix, nesting) =>
|
||||
Rule.required().custom((slug) => {
|
||||
if (!slug.current.startsWith(prefix)) {
|
||||
return `Slug må starte med prefiks: ${prefix}`;
|
||||
}
|
||||
if ((slug.current.match(/\//g) || []).length > nesting - 1) {
|
||||
return `Siden kan bare være på ${nesting} nivå`;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
/* Checks every document for matching slug */
|
||||
export const isSlugUnique = (slug, options) => {
|
||||
const { document } = options;
|
||||
|
||||
const id = document._id.replace(/^drafts\./, "");
|
||||
const params = {
|
||||
draft: `drafts.${id}`,
|
||||
published: id,
|
||||
slug,
|
||||
};
|
||||
|
||||
const query = `!defined(*[!(_id in [$draft, $published]) && slug.current == $slug][0]._id)`;
|
||||
return client.fetch(query, params);
|
||||
};
|
||||
|
||||
export const isEditorUnique = (slug, options) => {
|
||||
const { document } = options;
|
||||
|
||||
const id = document._id.replace(/^drafts\./, "");
|
||||
const params = {
|
||||
draft: `drafts.${id}`,
|
||||
published: id,
|
||||
slug,
|
||||
};
|
||||
|
||||
const query = `!defined(*[!(_id in [$draft, $published]) && _type == "editor" && user_id.current == $slug][0]._id)`;
|
||||
return client.fetch(query, params);
|
||||
};
|
||||
|
||||
export const groups = [
|
||||
{
|
||||
name: "innhold",
|
||||
title: "Innhold",
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
name: "metadata",
|
||||
title: "Metadata",
|
||||
},
|
||||
{
|
||||
name: "settings",
|
||||
title: "Innstillinger",
|
||||
icon: Settings,
|
||||
},
|
||||
{
|
||||
name: "lenker",
|
||||
title: "Linking",
|
||||
},
|
||||
{
|
||||
name: "beta",
|
||||
title: "Beta",
|
||||
},
|
||||
{
|
||||
name: "seo",
|
||||
title: "SEO",
|
||||
},
|
||||
];
|
||||
|
||||
export const validateKategoriSlug = (Rule, prefix) =>
|
||||
Rule.required().custom((slug, { document }) => {
|
||||
if (!slug.current.startsWith(`${prefix}${document?.kategori}/`)) {
|
||||
return `Slug må starte med prefiks: ${prefix}${document?.kategori}`;
|
||||
}
|
||||
if ((slug.current.match(/\//g) || []).length > 3 - 1) {
|
||||
return `Siden kan bare være på ${3} nivå`;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
export const kategoriSlug = (prefix: string) => ({
|
||||
title: "url (v2)",
|
||||
name: "slug_v2",
|
||||
type: "slug",
|
||||
validation: (Rule) => validateKategoriSlug(Rule, prefix),
|
||||
group: "settings",
|
||||
options: {
|
||||
source: (s) => `${s?.kategori}/${s?.heading}`,
|
||||
slugify: (input) => {
|
||||
return (
|
||||
`${prefix}${input}`
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.slice(0, 200)
|
||||
.trim()
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/-+/gm, "-")
|
||||
.replace(/æ/g, "a")
|
||||
.replace(/å/g, "a")
|
||||
.replace(/ø/g, "o")
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
.replace(/[&\\#!,+()$~%.'"¨:*?<>{}]/g, "")
|
||||
);
|
||||
},
|
||||
},
|
||||
});
|
||||
@@ -1,38 +0,0 @@
|
||||
import { Edit, Task } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export const defaultDocPreview = {
|
||||
preview: {
|
||||
select: {
|
||||
heading: "heading",
|
||||
status: "status",
|
||||
metadata: "metadata",
|
||||
id: "_id",
|
||||
type: "_type",
|
||||
tema: "tema.0.title",
|
||||
prinsipp: "prinsipp",
|
||||
},
|
||||
prepare(selection) {
|
||||
const { id, heading, type, tema, prinsipp } = selection;
|
||||
return {
|
||||
title: heading,
|
||||
subtitle: !!prinsipp
|
||||
? !!prinsipp?.hovedside
|
||||
? "Hovedside"
|
||||
: "Artikkel"
|
||||
: !!tema
|
||||
? `${tema}`
|
||||
: type.includes("_component_")
|
||||
? "Komponentside"
|
||||
: type.includes("_tabbed_")
|
||||
? "Artikkel m/tabs"
|
||||
: "Artikkel",
|
||||
media: id.includes("drafts.") ? (
|
||||
<Edit aria-hidden />
|
||||
) : (
|
||||
<Task aria-hidden />
|
||||
),
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,48 +0,0 @@
|
||||
const pattern = /^image-([a-f\d]+)-(\d+x\d+)-(\w+)$/;
|
||||
|
||||
const decodeAssetId = (id) => {
|
||||
const [, assetId, dimensions, format] = pattern.exec(id);
|
||||
const [width, height] = dimensions.split("x").map((v) => parseInt(v, 10));
|
||||
|
||||
return {
|
||||
assetId,
|
||||
dimensions: { width, height },
|
||||
format,
|
||||
};
|
||||
};
|
||||
|
||||
export const SEOFields = {
|
||||
name: "seo",
|
||||
type: "object",
|
||||
title: "SEO",
|
||||
group: "seo",
|
||||
fields: [
|
||||
{
|
||||
name: "meta",
|
||||
type: "text",
|
||||
title: "Meta/:og description",
|
||||
description:
|
||||
"Anbefalt maks 150-160 bokstaver. Erstatter ingress som <meta /> description",
|
||||
rows: 3,
|
||||
},
|
||||
{
|
||||
title: "og:Image",
|
||||
name: "image",
|
||||
type: "image",
|
||||
description: "Anbefalt størrelse er 1200:630px",
|
||||
options: {
|
||||
accept: "image/*",
|
||||
},
|
||||
validation: (Rule) =>
|
||||
Rule.custom((image) => {
|
||||
if (!image) return true;
|
||||
const { dimensions } = decodeAssetId(image.asset._ref);
|
||||
const aspectR = dimensions.width / dimensions.height;
|
||||
if (aspectR < 1.5 || aspectR > 2.4) {
|
||||
return `Forventet aspect-ration rundt 1.91:1. Er nå: ${aspectR}:1.`;
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
{
|
||||
"name": "sanity",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"description": "Sanity setup (v2) for Aksel.nav.no",
|
||||
"author": "Aksel | NAV designsystem team",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"start": "sanity start",
|
||||
"build": "sanity build",
|
||||
"deploy": "yarn typegen && sanity deploy",
|
||||
"backup": "node scripts/backup.js",
|
||||
"typegen": "sanity exec typegen.ts",
|
||||
"sanity:dev": "sanity start",
|
||||
"sanity:deploy": "yarn typegen && sanity deploy",
|
||||
"sanity:backup": "node scripts/backup.js"
|
||||
},
|
||||
"main": "package.json",
|
||||
"keywords": [
|
||||
"sanity"
|
||||
],
|
||||
"dependencies": {
|
||||
"@sanity/base": "^2.35.0",
|
||||
"@sanity/cli": "^2.35.0",
|
||||
"@sanity/code-input": "^2.35.0",
|
||||
"@sanity/components": "^2.14.0",
|
||||
"@sanity/core": "^2.35.0",
|
||||
"@sanity/dashboard": "^2.35.0",
|
||||
"@sanity/default-layout": "^2.35.0",
|
||||
"@sanity/default-login": "^2.35.0",
|
||||
"@sanity/desk-tool": "^2.35.0",
|
||||
"@sanity/export": "^2.30.3",
|
||||
"@sanity/production-preview": "^2.29.3",
|
||||
"@sanity/react-hooks": "^2.35.0",
|
||||
"@sanity/ui": "^0.37.22",
|
||||
"@sanity/vision": "^2.35.0",
|
||||
"moment": "2.29.4",
|
||||
"sanity-codegen": "0.9.8",
|
||||
"sanity-plugin-asset-source-unsplash": "^0.1.5",
|
||||
"sanity-plugin-dashboard-widget-document-list": "^0.0.13",
|
||||
"sanity-plugin-media": "^1.4.4",
|
||||
"sanity-super-pane": "^1.0.0-alpha.11",
|
||||
"styled-components": "^5.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.19.0",
|
||||
"@babel/preset-env": "^7.0.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@babel/preset-typescript": "^7.0.0",
|
||||
"@sanity-codegen/schema-codegen": "1.0.0-alpha.13",
|
||||
"babel-plugin-mock-imports": "1.2.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/navikt/aksel-website.git"
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
User-specific packages can be placed here
|
||||
@@ -1,137 +0,0 @@
|
||||
/* https://github.com/sanity-io/dashboard-widget-document-list/blob/master/src/DocumentList.js */
|
||||
|
||||
import client from "@sanity/client";
|
||||
import { Button, Flex } from "@sanity/ui";
|
||||
import { DashboardWidget } from "@sanity/dashboard";
|
||||
|
||||
import React, { useEffect, useState, useRef, useCallback } from "react";
|
||||
import config from "../../config";
|
||||
import SanityConfig from "../../sanity.json";
|
||||
import moment from "moment";
|
||||
import styles from "./widget.css";
|
||||
import { Item, List } from "part:@sanity/components/lists/default";
|
||||
import { IntentLink } from "part:@sanity/base/router";
|
||||
import { getPublishedId } from "part:@sanity/base/util/draft-utils";
|
||||
import { Tag } from "@navikt/ds-react";
|
||||
|
||||
const sanityClient = client({
|
||||
projectId: SanityConfig.api.projectId,
|
||||
dataset: SanityConfig.api.dataset,
|
||||
apiVersion: "2020-06-19",
|
||||
useCdn: false,
|
||||
});
|
||||
|
||||
const OutDatedComponents = ({ type }) => {
|
||||
const query = `*[_type in [${config.allDocumentTypes.map((x) => `"${x}"`)}]]`;
|
||||
const [docs, setDocs] = useState([]);
|
||||
const [loading, setloading] = useState(true);
|
||||
const [timer, setTimer] = useState(new Date());
|
||||
const [fromTime, setFromTime] = useState(moment(new Date()).fromNow());
|
||||
|
||||
const success = (v) => {
|
||||
setDocs(
|
||||
v
|
||||
.filter((x) => {
|
||||
if (!x?._updatedAt) return false;
|
||||
const lastUpdate = moment(x._updatedAt);
|
||||
const daysSince = moment().diff(lastUpdate, "days");
|
||||
return type === "error"
|
||||
? daysSince > 180
|
||||
: daysSince >= 90 && daysSince < 180;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
const lastUpdateA = moment(a._updatedAt);
|
||||
const lastUpdateB = moment(b._updatedAt);
|
||||
return lastUpdateA.diff(lastUpdateB, "days");
|
||||
})
|
||||
);
|
||||
setloading(false);
|
||||
setTimer(new Date());
|
||||
};
|
||||
|
||||
const load = useCallback(() => {
|
||||
setloading(true);
|
||||
sanityClient.fetch(query).then(success, (e) => console.error(e));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
load();
|
||||
}, []);
|
||||
|
||||
/* Refreshes every 5 minutes */
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
load();
|
||||
}, 300000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setFromTime(moment(timer).fromNow());
|
||||
}, 10000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
const refresh = () => {
|
||||
load();
|
||||
};
|
||||
|
||||
const footer = (
|
||||
<Flex direction="column" align="stretch">
|
||||
<Button
|
||||
fontSize={[2]}
|
||||
tone="primary"
|
||||
paddingX={2}
|
||||
paddingY={4}
|
||||
text={`Updated ${fromTime}`}
|
||||
onClick={() => refresh()}
|
||||
mode="bleed"
|
||||
loading={loading}
|
||||
disabled={loading}
|
||||
/>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
return (
|
||||
<DashboardWidget
|
||||
header={type === "error" ? "Utdaterte sider" : "Stagnerte sider"}
|
||||
footer={footer}
|
||||
>
|
||||
<List>
|
||||
{docs &&
|
||||
docs.map((doc) => {
|
||||
const lastUpdate = moment(doc._updatedAt);
|
||||
const daysSince = moment().diff(lastUpdate, "days");
|
||||
|
||||
return (
|
||||
<Item key={doc._id}>
|
||||
<IntentLink
|
||||
intent="edit"
|
||||
params={{
|
||||
type: doc._type,
|
||||
id: getPublishedId(doc._id),
|
||||
}}
|
||||
className={styles.link}
|
||||
>
|
||||
<span className={styles.spacing}>
|
||||
<Tag size="small" variant={type}>
|
||||
{daysSince}d
|
||||
</Tag>
|
||||
{doc?.heading}
|
||||
</span>
|
||||
</IntentLink>
|
||||
</Item>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</DashboardWidget>
|
||||
);
|
||||
};
|
||||
|
||||
export default {
|
||||
name: "outdated-documents-widget",
|
||||
component: OutDatedComponents,
|
||||
};
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"parts": [
|
||||
{
|
||||
"name": "part:@sanity/dashboard/widget/outdated-documents-widget",
|
||||
"implements": "part:@sanity/dashboard/widget",
|
||||
"path": "index.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
@import "part:@sanity/base/theme/variables-style";
|
||||
|
||||
.container {
|
||||
composes: container from "part:@sanity/dashboard/widget-styles";
|
||||
}
|
||||
|
||||
.header {
|
||||
composes: header from "part:@sanity/dashboard/widget-styles";
|
||||
}
|
||||
|
||||
.title {
|
||||
composes: title from "part:@sanity/dashboard/widget-styles";
|
||||
}
|
||||
|
||||
.content {
|
||||
composes: content from "part:@sanity/dashboard/widget-styles";
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
padding: var(--small-padding) 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.link {
|
||||
composes: item from "part:@sanity/base/theme/layout/selectable-style";
|
||||
display: block;
|
||||
color: inherit;
|
||||
text-decoration: inherit;
|
||||
outline: none;
|
||||
padding: var(--small-padding) var(--medium-padding);
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.footer {
|
||||
composes: footer from "part:@sanity/dashboard/widget-styles";
|
||||
border-top: 1px solid var(--hairline-color);
|
||||
}
|
||||
|
||||
.img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.spacing {
|
||||
display: inline-flex;
|
||||
gap: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"project": {
|
||||
"name": "Aksel"
|
||||
},
|
||||
"api": {
|
||||
"projectId": "hnbe3yhs",
|
||||
"dataset": "production"
|
||||
},
|
||||
"env": {
|
||||
"development": {
|
||||
"api": {
|
||||
"dataset": "production"
|
||||
},
|
||||
"plugins": ["@sanity/vision"]
|
||||
}
|
||||
},
|
||||
"plugins": [
|
||||
"@sanity/base",
|
||||
"@sanity/components",
|
||||
"@sanity/default-layout",
|
||||
"@sanity/default-login",
|
||||
"@sanity/desk-tool",
|
||||
"@sanity/code-input",
|
||||
"@sanity/dashboard",
|
||||
"dashboard-widget-document-list",
|
||||
"outdated-documents-widget",
|
||||
"media",
|
||||
"asset-source-unsplash"
|
||||
],
|
||||
"parts": [
|
||||
{
|
||||
"name": "part:@sanity/base/schema",
|
||||
"path": "./schemas/schema"
|
||||
},
|
||||
{
|
||||
"name": "part:@sanity/desk-tool/structure",
|
||||
"path": "./client/desk-structure/deskStructure.tsx"
|
||||
},
|
||||
{
|
||||
"implements": "part:@sanity/dashboard/config",
|
||||
"path": "./client/dashboardConfig.tsx"
|
||||
},
|
||||
{
|
||||
"name": "part:@sanity/base/initial-value-templates",
|
||||
"path": "./client/initialValueTemplates.tsx"
|
||||
},
|
||||
{
|
||||
"name": "part:@sanity/base/new-document-structure",
|
||||
"path": "./client/newDocumentStructure.tsx"
|
||||
},
|
||||
{
|
||||
"implements": "part:@sanity/base/absolutes",
|
||||
"path": "./client/bundleCheck.tsx"
|
||||
},
|
||||
{
|
||||
"implements": "part:@sanity/form-builder/input/image/asset-sources",
|
||||
"path": "./client/assetSources.ts"
|
||||
},
|
||||
{
|
||||
"implements": "part:@sanity/form-builder/input/file/asset-sources",
|
||||
"path": "./client/assetSources.ts"
|
||||
},
|
||||
{
|
||||
"implements": "part:@sanity/base/document-actions/resolver",
|
||||
"path": "./client/resolveDocumentActions.tsx"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export default null;
|
||||
@@ -1,57 +0,0 @@
|
||||
import {
|
||||
defaultDocPreview,
|
||||
editorField,
|
||||
groups,
|
||||
ingressField,
|
||||
innholdFieldNew,
|
||||
publishedAtField,
|
||||
relevanteArtiklerField,
|
||||
sanitySlug,
|
||||
SEOFields,
|
||||
titleField,
|
||||
} from "@/lib";
|
||||
|
||||
const prefix = "god-praksis/artikler/";
|
||||
|
||||
export default {
|
||||
title: "Aksel Artikkel",
|
||||
name: "aksel_artikkel",
|
||||
type: "document",
|
||||
groups,
|
||||
...defaultDocPreview,
|
||||
fields: [
|
||||
publishedAtField,
|
||||
{
|
||||
title: "Sist godkjent",
|
||||
name: "updateInfo",
|
||||
type: "object",
|
||||
hidden: true,
|
||||
fields: [
|
||||
{
|
||||
type: "date",
|
||||
name: "lastVerified",
|
||||
title: "Sist oppdatert",
|
||||
description: "Kun synlig for utviklere",
|
||||
readOnly: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
editorField,
|
||||
titleField,
|
||||
sanitySlug(prefix, 3),
|
||||
{
|
||||
title: "Tema",
|
||||
description: "Legg til de viktigeste temaene",
|
||||
name: "tema",
|
||||
type: "array",
|
||||
of: [{ type: "reference", to: [{ type: "aksel_tema" }] }],
|
||||
group: "innhold",
|
||||
},
|
||||
|
||||
ingressField,
|
||||
innholdFieldNew,
|
||||
relevanteArtiklerField,
|
||||
|
||||
SEOFields,
|
||||
],
|
||||
};
|
||||
@@ -1,31 +0,0 @@
|
||||
import {
|
||||
defaultDocPreview,
|
||||
editorField,
|
||||
groups,
|
||||
ingressField,
|
||||
innholdFieldNew,
|
||||
publishedAtField,
|
||||
sanitySlug,
|
||||
SEOFields,
|
||||
titleField,
|
||||
} from "@/lib";
|
||||
|
||||
const prefix = "produktbloggen/";
|
||||
|
||||
export default {
|
||||
title: "Blogg",
|
||||
name: "aksel_blogg",
|
||||
type: "document",
|
||||
groups,
|
||||
...defaultDocPreview,
|
||||
fields: [
|
||||
publishedAtField,
|
||||
editorField,
|
||||
titleField,
|
||||
sanitySlug(prefix, 2),
|
||||
ingressField,
|
||||
innholdFieldNew,
|
||||
|
||||
SEOFields,
|
||||
],
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
import KomponentArtikkel from "./komponent";
|
||||
|
||||
export default {
|
||||
...KomponentArtikkel,
|
||||
title: "Komponentartikkel-template",
|
||||
name: "ds_component_template",
|
||||
};
|
||||
@@ -1,65 +0,0 @@
|
||||
import {
|
||||
defaultDocPreview,
|
||||
editorField,
|
||||
groups,
|
||||
innholdFieldNew,
|
||||
kategoriSlug,
|
||||
publishedAtField,
|
||||
titleField,
|
||||
} from "@/lib";
|
||||
|
||||
const prefix = "grunnleggende/";
|
||||
|
||||
export default {
|
||||
title: "Artikkel",
|
||||
name: "ds_artikkel",
|
||||
type: "document",
|
||||
groups,
|
||||
...defaultDocPreview,
|
||||
fields: [
|
||||
{
|
||||
title: "Sist godkjent",
|
||||
name: "updateInfo",
|
||||
type: "object",
|
||||
hidden: true,
|
||||
fields: [
|
||||
{
|
||||
type: "date",
|
||||
name: "lastVerified",
|
||||
title: "Sist oppdatert",
|
||||
description: "Kun synlig for utviklere",
|
||||
readOnly: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
publishedAtField,
|
||||
editorField,
|
||||
titleField,
|
||||
kategoriSlug(prefix),
|
||||
{ title: "url", name: "slug", type: "slug", hidden: true },
|
||||
{
|
||||
title: "Kategori",
|
||||
name: "kategori",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required(),
|
||||
options: {
|
||||
list: [
|
||||
{ title: "Styling", value: "styling" },
|
||||
{ title: "Tokens", value: "tokens" },
|
||||
{ title: "Stæsj", value: "staesj" },
|
||||
{ title: "Guider", value: "guider" },
|
||||
].map((x) => ({
|
||||
title: x.title,
|
||||
value: x.value,
|
||||
})),
|
||||
layout: "radio",
|
||||
},
|
||||
hidden: ({ currentUser }) =>
|
||||
!currentUser.roles.find((x) => x.name === "developer"),
|
||||
},
|
||||
{
|
||||
...innholdFieldNew,
|
||||
type: "riktekst_ds_artikkel",
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,77 +0,0 @@
|
||||
export default {
|
||||
title: "Forside",
|
||||
name: "ds_frontpage",
|
||||
type: "document",
|
||||
fields: [
|
||||
{
|
||||
name: "body",
|
||||
type: "riktekst_enkel",
|
||||
title: "Innhold",
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
{
|
||||
name: "cards",
|
||||
type: "array",
|
||||
title: "Cards",
|
||||
of: [
|
||||
{
|
||||
title: "Card",
|
||||
name: "card",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Lenke",
|
||||
name: "link_ref",
|
||||
type: "reference",
|
||||
to: [{ type: "komponent_artikkel" }, { type: "ds_artikkel" }],
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
{
|
||||
title: "Tittel",
|
||||
name: "title",
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
title: "Innhold",
|
||||
name: "content",
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
title: "Pictogram",
|
||||
name: "picture",
|
||||
type: "image",
|
||||
options: {
|
||||
hotspot: true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: "title",
|
||||
title: "Alt-tekst",
|
||||
type: "string",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Bilde må ha en alt-tekst"),
|
||||
description: "Beskriv bildet for skjermlesere",
|
||||
options: {
|
||||
isHighlighted: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Må legge til et pictogram"),
|
||||
},
|
||||
],
|
||||
options: {
|
||||
modal: {
|
||||
type: "dialog",
|
||||
width: "medium", // 'small' | 'medium' | 'large' | 'full'
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
prepare: () => ({ title: "Forside designsystemet" }),
|
||||
},
|
||||
};
|
||||
@@ -1,218 +0,0 @@
|
||||
// MIGRERT
|
||||
|
||||
import { People } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
import profilePage from "../../components/profile/profile-page";
|
||||
import { isEditorUnique } from "@/lib";
|
||||
import userStore from "part:@sanity/base/user";
|
||||
import sanityClient from "part:@sanity/base/client";
|
||||
|
||||
const navn = [
|
||||
"Alpesteinbukk",
|
||||
"Amurtiger",
|
||||
"Kamel",
|
||||
"Blissbukk",
|
||||
"Borneoorangutang",
|
||||
"Damfrosk",
|
||||
"Dvergsilkeape",
|
||||
"Dåhjort",
|
||||
"Edderkoppape",
|
||||
"Elandantilope",
|
||||
"Elg",
|
||||
"Esel",
|
||||
"Oter",
|
||||
"Fjellrev",
|
||||
"Flodsvin",
|
||||
"Fugler",
|
||||
"Gaupe",
|
||||
"Gepard",
|
||||
"Gulkinngibbon",
|
||||
"Javalangur",
|
||||
"Jerv",
|
||||
"Krokodille",
|
||||
"Labrador",
|
||||
"Puddel",
|
||||
"Skogskatt",
|
||||
"Maine Coon",
|
||||
"Lavlandstapir",
|
||||
"Beagle",
|
||||
"Hysky",
|
||||
"Løve",
|
||||
"Løvetamarin",
|
||||
"Nubisk geit",
|
||||
"Papegøye",
|
||||
"Ringhalelemur",
|
||||
"Rødpanda",
|
||||
"Sau",
|
||||
"Sjimpanse",
|
||||
"Sjiraff",
|
||||
"Stråleskilpadde",
|
||||
"Slanger",
|
||||
"Steppesebra",
|
||||
"Flamingo",
|
||||
"Struts",
|
||||
"Shetlandsponni",
|
||||
"Surikat",
|
||||
"Tiger",
|
||||
"Ulv",
|
||||
"Fjordfe",
|
||||
"Ekorn",
|
||||
"Bever",
|
||||
"Lemen",
|
||||
"Klatremus",
|
||||
"Fjellmarkmus",
|
||||
"Dvergmus",
|
||||
"Småskogmus",
|
||||
"Steinkobbe",
|
||||
"Røyskatt",
|
||||
"Moskusfe",
|
||||
];
|
||||
|
||||
const adjektiv = [
|
||||
"aktuell",
|
||||
"alvorlig",
|
||||
"ansvarlig",
|
||||
"berømt",
|
||||
"bevisst",
|
||||
"klein",
|
||||
"eksisterende",
|
||||
"fjern",
|
||||
"forsiktig",
|
||||
"heldig",
|
||||
"hjelpsom",
|
||||
"hyppig",
|
||||
"imponerende",
|
||||
"kul",
|
||||
"sjarmerende",
|
||||
"lykkelig",
|
||||
"lys",
|
||||
"merkelig",
|
||||
"mistenkelig",
|
||||
"modig",
|
||||
"morsom",
|
||||
"nysgjerrig",
|
||||
"rå",
|
||||
"rask",
|
||||
"blå",
|
||||
"fersk",
|
||||
"grønn",
|
||||
"rettferdig",
|
||||
"rimelig",
|
||||
"ryddig",
|
||||
"selvsikker",
|
||||
"skarp",
|
||||
"skikkelig",
|
||||
"skyldig",
|
||||
"smal",
|
||||
"sprudlende",
|
||||
"søt",
|
||||
"stolt",
|
||||
"streng",
|
||||
"sulten",
|
||||
"tilgjengelig",
|
||||
"vennlig",
|
||||
"voksen",
|
||||
"ærlig",
|
||||
"flittig",
|
||||
];
|
||||
|
||||
const client = sanityClient.withConfig({ apiVersion: "2020-06-19" });
|
||||
|
||||
const generateName = async () => {
|
||||
const names = await client.fetch(`*[_type == "editor"].anon_navn.current`);
|
||||
|
||||
let c = 0;
|
||||
let res = "";
|
||||
while ((res === "" || names.includes(res)) && c < 1000) {
|
||||
const adj = adjektiv[Math.floor(Math.random() * adjektiv.length)];
|
||||
const animal = navn[Math.floor(Math.random() * navn.length)];
|
||||
res = `${adj.charAt(0).toUpperCase() + adj.slice(1)} ${animal}`;
|
||||
c += 1;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
const generateInitialName = async () => ({
|
||||
current: await generateName(),
|
||||
});
|
||||
|
||||
export default {
|
||||
title: "Redaktører",
|
||||
name: "editor",
|
||||
type: "document",
|
||||
fields: [
|
||||
{
|
||||
title: "Navn",
|
||||
name: "title",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required().error("Må legge til navn"),
|
||||
},
|
||||
{
|
||||
title: "Sanity bruker-id",
|
||||
name: "user_id",
|
||||
type: "slug",
|
||||
validation: (Rule) => Rule.required().error("Må ha Id"),
|
||||
options: {
|
||||
isUnique: isEditorUnique,
|
||||
source: async () => {
|
||||
const { id } = await userStore.getUser("me");
|
||||
return id;
|
||||
},
|
||||
slugify: (input) => input,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Gjør meg anonym",
|
||||
description:
|
||||
"På artikler bytter vi ut navnet ditt med et tullenavn. Eks. Sprudlende Tiger",
|
||||
name: "anonym",
|
||||
type: "boolean",
|
||||
initialValue: true,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
hidden: true,
|
||||
title: "Anonymt navn",
|
||||
name: "anon_navn",
|
||||
type: "slug",
|
||||
initialValue: () => generateInitialName(),
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
title: "Roller",
|
||||
description: "eks: Utvikler, Webanalytiker, uu-spesialist",
|
||||
name: "roller",
|
||||
type: "array",
|
||||
of: [{ type: "string" }],
|
||||
options: {
|
||||
layout: "tags",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "profile_page",
|
||||
type: "string",
|
||||
title: "Profil",
|
||||
inputComponent: profilePage,
|
||||
hidden: ({ currentUser, parent }) => {
|
||||
const { id, roles } = currentUser;
|
||||
return (
|
||||
!roles.find(({ name }) => name === "administrator") &&
|
||||
parent?.user_id?.current !== id
|
||||
);
|
||||
},
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
title: "title",
|
||||
},
|
||||
prepare(selection) {
|
||||
const { title } = selection;
|
||||
return {
|
||||
title,
|
||||
media: () => <People />,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
import { groups, SEOFields } from "@/lib";
|
||||
|
||||
export default {
|
||||
title: "Forside",
|
||||
name: "vk_frontpage",
|
||||
type: "document",
|
||||
groups,
|
||||
fields: [
|
||||
{
|
||||
title: "Tittel",
|
||||
name: "title",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
{
|
||||
title: "Beskrivelse",
|
||||
name: "beskrivelse",
|
||||
type: "riktekst_enkel",
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
{
|
||||
title: "Brukeropplevelse",
|
||||
name: "prinsipp_1",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Vis på forside",
|
||||
name: "vis",
|
||||
type: "boolean",
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
{
|
||||
title: "Beskrivelse",
|
||||
name: "beskrivelse",
|
||||
type: "riktekst_enkel",
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
{
|
||||
title: "Hovedside",
|
||||
name: "hovedside",
|
||||
type: "reference",
|
||||
weak: true,
|
||||
to: [{ type: "aksel_prinsipp" }],
|
||||
},
|
||||
{
|
||||
title: "Undersider",
|
||||
description: "Rekkefølge bestemmer rekkefølgen på forsiden!",
|
||||
name: "undersider",
|
||||
type: "array",
|
||||
of: [
|
||||
{ type: "reference", weak: true, to: [{ type: "aksel_prinsipp" }] },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
SEOFields,
|
||||
],
|
||||
};
|
||||
@@ -1,57 +0,0 @@
|
||||
/* import { ExampleKeys } from "website/component-examples"; */
|
||||
|
||||
export default {
|
||||
title: "Dir/filnavn for kode eksempler",
|
||||
name: "kode_eksempler_fil",
|
||||
type: "document",
|
||||
fields: [
|
||||
{
|
||||
title: "Tittel",
|
||||
name: "title",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required(),
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
title: "Toggle om eksemplet er et dir eller filnavn",
|
||||
name: "dir",
|
||||
type: "boolean",
|
||||
validation: (Rule) => Rule.required(),
|
||||
initialValue: false,
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
title: "Filer",
|
||||
name: "filer",
|
||||
type: "array",
|
||||
readOnly: true,
|
||||
of: [
|
||||
{
|
||||
title: "Data i filer",
|
||||
name: "fil",
|
||||
type: "object",
|
||||
fields: [
|
||||
{ title: "Filnavn", name: "navn", type: "string" },
|
||||
{ title: "Innhold", name: "innhold", type: "string" },
|
||||
{ title: "Beskrivelse", name: "description", type: "text" },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
title: "title",
|
||||
dir: "dir",
|
||||
},
|
||||
prepare(selection) {
|
||||
const { title, dir } = selection;
|
||||
return {
|
||||
title: title,
|
||||
subtitle: dir ? "Alle kode-eksempler" : "Spesifikt kode-eksempel",
|
||||
media: () => "</>",
|
||||
};
|
||||
},
|
||||
},
|
||||
__experimental_omnisearch_visibility: false,
|
||||
};
|
||||
@@ -1,126 +0,0 @@
|
||||
import {
|
||||
defaultDocPreview,
|
||||
editorField,
|
||||
groups,
|
||||
innholdFieldNew,
|
||||
kategoriSlug,
|
||||
publishedAtField,
|
||||
titleField,
|
||||
} from "@/lib";
|
||||
|
||||
const prefix = "komponenter/";
|
||||
|
||||
export default {
|
||||
title: "Komponentartikkel",
|
||||
name: "komponent_artikkel",
|
||||
type: "document",
|
||||
groups,
|
||||
...defaultDocPreview,
|
||||
fields: [
|
||||
publishedAtField,
|
||||
editorField,
|
||||
titleField,
|
||||
kategoriSlug(prefix),
|
||||
{ title: "url", name: "slug", type: "slug", hidden: true },
|
||||
{
|
||||
title: "Sist godkjent",
|
||||
name: "updateInfo",
|
||||
type: "object",
|
||||
hidden: true,
|
||||
fields: [
|
||||
{
|
||||
type: "date",
|
||||
name: "lastVerified",
|
||||
title: "Sist oppdatert",
|
||||
description: "Kun synlig for utviklere",
|
||||
readOnly: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Kategori",
|
||||
name: "kategori",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required(),
|
||||
options: {
|
||||
list: [
|
||||
{ title: "Core", value: "core" },
|
||||
{ title: "Internal", value: "internal" },
|
||||
].map((x) => ({
|
||||
title: x.title,
|
||||
value: x.value,
|
||||
})),
|
||||
layout: "radio",
|
||||
},
|
||||
hidden: ({ currentUser }) =>
|
||||
!currentUser.roles.find((x) => x.name === "developer"),
|
||||
},
|
||||
{
|
||||
title: "Metadata",
|
||||
name: "status",
|
||||
group: "innhold",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Status",
|
||||
name: "tag",
|
||||
type: "string",
|
||||
initialValue: "new",
|
||||
options: {
|
||||
list: [
|
||||
{ title: "Beta", value: "beta" },
|
||||
{ title: "New", value: "new" },
|
||||
{ title: "Ready", value: "ready" },
|
||||
{ title: "Deprecated", value: "deprecated" },
|
||||
],
|
||||
layout: "radio",
|
||||
},
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
{
|
||||
name: "bilde",
|
||||
title: "Thumbnail",
|
||||
type: "image",
|
||||
},
|
||||
],
|
||||
options: {
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "intro",
|
||||
type: "intro_komponent",
|
||||
group: "innhold",
|
||||
},
|
||||
{
|
||||
...innholdFieldNew,
|
||||
type: "riktekst_komponent",
|
||||
name: "content",
|
||||
title: "Innhold",
|
||||
},
|
||||
{
|
||||
title: "Kodepakker",
|
||||
name: "kodepakker",
|
||||
type: "array",
|
||||
of: [{ type: "string" }],
|
||||
options: {
|
||||
list: [
|
||||
{ title: "ds-react", value: "ds-react" },
|
||||
{ title: "ds-css", value: "ds-css" },
|
||||
{ title: "ds-react-internal", value: "ds-react-internal" },
|
||||
{ title: "ds-css-internal", value: "ds-css-internal" },
|
||||
{ title: "ds-icons", value: "ds-icons" },
|
||||
{ title: "ds-tokens", value: "ds-tokens" },
|
||||
{ title: "ds-tailwind", value: "ds-tailwind" },
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Figma lenke (optional)",
|
||||
name: "figma_link",
|
||||
type: "url",
|
||||
group: "lenker",
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,129 +0,0 @@
|
||||
export default {
|
||||
name: "ds_navigation",
|
||||
title: "Navigation",
|
||||
type: "document",
|
||||
fields: [
|
||||
{
|
||||
title: "Designsystem navigajsons-struktur",
|
||||
name: "title",
|
||||
type: "string",
|
||||
readOnly: true,
|
||||
hidden: true,
|
||||
initialValue: "Designsystem navigajsons-struktur",
|
||||
},
|
||||
{
|
||||
name: "headings",
|
||||
title: "Header linker",
|
||||
type: "array",
|
||||
of: [
|
||||
{
|
||||
type: "ds_navigation_heading",
|
||||
name: "heading",
|
||||
title: "Header link",
|
||||
},
|
||||
],
|
||||
validation: (Rule) =>
|
||||
Rule.required()
|
||||
.min(1)
|
||||
.error("Headingmenyen må ha minst en koblet lenke i sidemenyen"),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const ds_header_heading = {
|
||||
name: "ds_navigation_heading",
|
||||
title: "Header link",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
name: "title",
|
||||
title: "Heading tittel",
|
||||
type: "string",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Header lenken må ha en tittel"),
|
||||
},
|
||||
{
|
||||
title: "Side selve headingen linker til",
|
||||
description:
|
||||
"Husk å legge denne til i menyen også, hvis ikke blir den bare tilgjengelig via headern",
|
||||
name: "link_ref",
|
||||
type: "reference",
|
||||
to: [{ type: "komponent_artikkel" }, { type: "ds_artikkel" }],
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Header lenken må linke til en startside"),
|
||||
},
|
||||
{
|
||||
title: "Meny for denne headingen",
|
||||
name: "menu",
|
||||
type: "array",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Sidemeny må ha misnt en lenke"),
|
||||
of: [
|
||||
{
|
||||
title: "Menypunkt",
|
||||
name: "item",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Menypunkt tittel",
|
||||
name: "title",
|
||||
type: "string",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Sidemeny-lenken må ha en tittel"),
|
||||
},
|
||||
{
|
||||
title: "Link til side",
|
||||
name: "link",
|
||||
type: "reference",
|
||||
to: [{ type: "komponent_artikkel" }, { type: "ds_artikkel" }],
|
||||
options: {
|
||||
modal: {
|
||||
type: "dialog",
|
||||
width: "medium", // 'small' | 'medium' | 'large' | 'full'
|
||||
},
|
||||
},
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Sidemeny-lenken må lenke til en side"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Subheading",
|
||||
name: "subheading",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Subheading",
|
||||
name: "title",
|
||||
type: "string",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Subheading må være fylt ut"),
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
title: "title",
|
||||
},
|
||||
prepare(selection) {
|
||||
const { title } = selection;
|
||||
return {
|
||||
title: title,
|
||||
subtitle: "Subheading",
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
title: "title",
|
||||
},
|
||||
prepare({ title }) {
|
||||
return {
|
||||
title: `${title}`,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,141 +0,0 @@
|
||||
import {
|
||||
defaultDocPreview,
|
||||
editorField,
|
||||
groups,
|
||||
ingressField,
|
||||
innholdFieldPrinsipp,
|
||||
isSlugUnique,
|
||||
prinsipper,
|
||||
publishedAtField,
|
||||
SEOFields,
|
||||
titleField,
|
||||
} from "@/lib";
|
||||
import sanityClient from "part:@sanity/base/client";
|
||||
|
||||
const client = sanityClient.withConfig({ apiVersion: "2020-06-19" });
|
||||
|
||||
const prefix = "prinsipper/";
|
||||
|
||||
export default {
|
||||
title: "Aksel Prinsipp",
|
||||
name: "aksel_prinsipp",
|
||||
type: "document",
|
||||
groups,
|
||||
...defaultDocPreview,
|
||||
fields: [
|
||||
publishedAtField,
|
||||
editorField,
|
||||
titleField,
|
||||
{
|
||||
title: "url",
|
||||
name: "slug",
|
||||
type: "slug",
|
||||
validation: (Rule) =>
|
||||
Rule.required().custom((slug, { document }) => {
|
||||
if (!slug || !slug.current)
|
||||
return `Må ha noe innhold. Har du husket å velget et prinsipp først?`;
|
||||
const maxLength = document?.prinsipp?.hovedside ? 2 : 3;
|
||||
const newPrefix = `${prefix}${document?.prinsipp?.prinsippvalg}`;
|
||||
|
||||
if (!document?.prinsipp?.prinsippvalg)
|
||||
return `Siden må ha valgt prinsipp for å sette opp url`;
|
||||
if (document?.prinsipp?.hovedside && slug.current !== newPrefix) {
|
||||
return `Siden er en hovedside for prinsippet og må derfor være på url ${newPrefix}`;
|
||||
}
|
||||
if (
|
||||
!document?.prinsipp?.hovedside &&
|
||||
!slug.current.startsWith(newPrefix)
|
||||
) {
|
||||
return `Slug må starte med: ${newPrefix}`;
|
||||
}
|
||||
|
||||
if (
|
||||
(slug.current.split("/") || []).filter((x) => !!x).length !==
|
||||
maxLength
|
||||
) {
|
||||
return `Siden må være på ${maxLength} nivå`;
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
group: "settings",
|
||||
options: {
|
||||
isUnique: isSlugUnique,
|
||||
source: ({ prinsipp = null, heading = null }) => ({
|
||||
prinsipp,
|
||||
heading,
|
||||
}),
|
||||
slugify: ({ prinsipp, heading }) => {
|
||||
if (!prinsipp || !heading) return "";
|
||||
const rest = prinsipp.hovedside ? "" : `/${heading}`;
|
||||
return `${prefix}${prinsipp.prinsippvalg}${rest}`
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.slice(0, 80)
|
||||
.trim()
|
||||
.replace(/\s+/g, "-")
|
||||
.replace("æ", "a")
|
||||
.replace("ø", "o")
|
||||
.replace("å", "a");
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Prinsipp",
|
||||
description: "Velg prinsippet siden omhandler",
|
||||
name: "prinsipp",
|
||||
group: "innhold",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Velg prinsipp",
|
||||
name: "prinsippvalg",
|
||||
type: "string",
|
||||
options: {
|
||||
list: prinsipper,
|
||||
layout: "radio",
|
||||
},
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Prinsippsider må ha valgt et prinsipp"),
|
||||
},
|
||||
{
|
||||
title: "Er denne siden hovedsiden til Prinsippet?",
|
||||
name: "hovedside",
|
||||
type: "boolean",
|
||||
initialValue: false,
|
||||
validation: (Rule) =>
|
||||
Rule.required().custom(async (_, { document, parent }) => {
|
||||
const id = document._id.replace(/^drafts\./, "");
|
||||
const params = {
|
||||
draft: `drafts.${id}`,
|
||||
published: id,
|
||||
hoved: parent?.hovedside,
|
||||
prinsipp: parent?.prinsippvalg,
|
||||
};
|
||||
|
||||
const query = `*[!(_id in [$draft, $published]) && _type == "aksel_prinsipp" && prinsipp.prinsippvalg == $prinsipp && prinsipp.hovedside == true][0]{heading,_id}`;
|
||||
const res = await client.fetch(query, params);
|
||||
|
||||
if (parent?.hovedside && !!res?._id) {
|
||||
return `Kan bare ha en hovedside for hvert prinsipp. Hovedsiden er nå: ${
|
||||
res?.heading ?? "Siden har ikke en heading"
|
||||
}`;
|
||||
} else if (!parent?.hovedside && !res?._id) {
|
||||
return `Hvert prinsipp må ha minst en hovedside. Velg en hovedside før du fortsetter`;
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Hero bilde",
|
||||
name: "hero_bilde",
|
||||
type: "herobilde",
|
||||
group: "innhold",
|
||||
hidden: ({ parent }) => !parent.prinsipp.hovedside,
|
||||
},
|
||||
ingressField,
|
||||
innholdFieldPrinsipp,
|
||||
SEOFields,
|
||||
],
|
||||
};
|
||||
@@ -1,88 +0,0 @@
|
||||
/* import { ExampleKeys } from "website/component-examples"; */
|
||||
|
||||
export default {
|
||||
title: "Autogenerert Propdata",
|
||||
name: "ds_props",
|
||||
type: "document",
|
||||
fields: [
|
||||
{
|
||||
title: "Tittel",
|
||||
name: "title",
|
||||
type: "string",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
title: "Displayname",
|
||||
name: "displayname",
|
||||
type: "string",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
title: "Filepath",
|
||||
name: "filepath",
|
||||
type: "string",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
title: "props",
|
||||
name: "proplist",
|
||||
type: "array",
|
||||
readOnly: true,
|
||||
of: [
|
||||
{
|
||||
title: "Prop",
|
||||
name: "prop",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Name",
|
||||
name: "name",
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
title: "DefaultValue",
|
||||
name: "defaultValue",
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
title: "Description",
|
||||
name: "description",
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
title: "Required",
|
||||
name: "required",
|
||||
type: "boolean",
|
||||
},
|
||||
{
|
||||
title: "Type",
|
||||
name: "type",
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
title: "isRef",
|
||||
name: "ref",
|
||||
type: "boolean",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
title: "title",
|
||||
filepath: "filepath",
|
||||
id: "_id",
|
||||
},
|
||||
prepare(selection) {
|
||||
const { title, filepath, id } = selection;
|
||||
const str = id.includes("core") ? "ds-react" : "ds-internal";
|
||||
return {
|
||||
title,
|
||||
subtitle: `${str}: ${filepath}`,
|
||||
};
|
||||
},
|
||||
},
|
||||
__experimental_omnisearch_visibility: false,
|
||||
};
|
||||
@@ -1,49 +0,0 @@
|
||||
const limits = [
|
||||
"/blogg/",
|
||||
"/artikkel/",
|
||||
"/prinsipper/",
|
||||
"/designsystem/side/",
|
||||
"/designsystem/komponenter/",
|
||||
];
|
||||
|
||||
export default {
|
||||
name: "redirect",
|
||||
title: "Redirect",
|
||||
type: "document",
|
||||
fields: [
|
||||
{
|
||||
name: "source",
|
||||
title: "Fra",
|
||||
type: "string",
|
||||
validation: (Rule) =>
|
||||
Rule.required().custom((_, { parent }) => {
|
||||
if (!parent?.source?.startsWith?.("/")) {
|
||||
return "Kan bare redirecte fra relativ-url, eks /min/gamle/sideurl";
|
||||
}
|
||||
const valid = limits.find(
|
||||
(x) => parent?.source?.startsWith?.(x) && parent.source > x
|
||||
);
|
||||
|
||||
if (!valid) {
|
||||
return `Kan bare redirecte fra sider som starter med en av disse url-ene ${limits.join(
|
||||
", "
|
||||
)}`;
|
||||
}
|
||||
return true;
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "destination",
|
||||
title: "Til",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
{
|
||||
name: "permanent",
|
||||
title: "Permanent",
|
||||
type: "boolean",
|
||||
initialValue: () => true,
|
||||
},
|
||||
],
|
||||
__experimental_omnisearch_visibility: false,
|
||||
};
|
||||
@@ -1,24 +0,0 @@
|
||||
import {
|
||||
defaultDocPreview,
|
||||
groups,
|
||||
innholdFieldNew,
|
||||
publishedAtField,
|
||||
sanitySlug,
|
||||
titleField,
|
||||
} from "@/lib";
|
||||
|
||||
const prefix = "side/";
|
||||
|
||||
export default {
|
||||
title: "Standalone-sider",
|
||||
name: "aksel_standalone",
|
||||
type: "document",
|
||||
groups,
|
||||
...defaultDocPreview,
|
||||
fields: [
|
||||
publishedAtField,
|
||||
titleField,
|
||||
sanitySlug(prefix, 2),
|
||||
innholdFieldNew,
|
||||
],
|
||||
};
|
||||
@@ -1,148 +0,0 @@
|
||||
import { groups } from "@/lib";
|
||||
|
||||
export default {
|
||||
title: "Aksel Tema",
|
||||
name: "aksel_tema",
|
||||
type: "document",
|
||||
groups,
|
||||
fields: [
|
||||
{
|
||||
title: "Navn",
|
||||
name: "title",
|
||||
type: "string",
|
||||
group: "innhold",
|
||||
validation: (Rule) =>
|
||||
Rule.required()
|
||||
.warning("Denne endringe påvirker URL")
|
||||
.error("Temaet må ha et navn"),
|
||||
},
|
||||
{
|
||||
title: "Kort Intro/Oppsummering",
|
||||
description: "Brukes i kort og innganger",
|
||||
name: "oppsummering",
|
||||
type: "string",
|
||||
group: "innhold",
|
||||
validation: (Rule) =>
|
||||
Rule.required()
|
||||
.max(65)
|
||||
.error("Temaet burde ha en kort oppsummering/intro på max 65tegn"),
|
||||
},
|
||||
{
|
||||
title: "Beskrivelse",
|
||||
name: "beskrivelse",
|
||||
type: "riktekst_enkel",
|
||||
group: "innhold",
|
||||
},
|
||||
{
|
||||
title: "Hidden",
|
||||
name: "bruk_seksjoner",
|
||||
type: "boolean",
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
title: "Shortname",
|
||||
description: "En mer sanitert visning av tema-navnet i url ene",
|
||||
name: "slug",
|
||||
type: "slug",
|
||||
group: "innhold",
|
||||
validation: (Rule) => Rule.required().error("Tema må ha en URL"),
|
||||
options: {
|
||||
source: "title",
|
||||
slugify: (s: string) =>
|
||||
s
|
||||
? s
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/-+/gm, "-")
|
||||
.replace(/æ/g, "a")
|
||||
.replace(/å/g, "a")
|
||||
.replace(/ø/g, "o")
|
||||
// eslint-disable-next-line no-useless-escape
|
||||
.replace(/[&\\#!,+()$~%.'"¨:*?<>{}]/g, "")
|
||||
: "",
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Ansvarlig for tema",
|
||||
description: "Legg til redaktør som har forvaltningsansvaret for temaet",
|
||||
name: "ansvarlig",
|
||||
type: "reference",
|
||||
to: [{ type: "editor" }],
|
||||
validation: (Rule) => Rule.required(),
|
||||
group: "innhold",
|
||||
},
|
||||
{
|
||||
title: "Seksjonering",
|
||||
description:
|
||||
"Del inn artiklene i flere seksjoner (vises ikke i preview før publisering desverre)",
|
||||
name: "seksjoner",
|
||||
type: "array",
|
||||
group: "innhold",
|
||||
of: [
|
||||
{
|
||||
type: "object",
|
||||
title: "Seksjon",
|
||||
name: "seksjon",
|
||||
fields: [
|
||||
{
|
||||
type: "string",
|
||||
name: "title",
|
||||
title: "Tittel",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Seksjonen må ha et navn"),
|
||||
},
|
||||
{
|
||||
title: "Beskrivelse",
|
||||
name: "beskrivelse",
|
||||
type: "riktekst_enkel",
|
||||
},
|
||||
{
|
||||
name: "sider",
|
||||
type: "array",
|
||||
title: "Sider",
|
||||
of: [
|
||||
{
|
||||
type: "reference",
|
||||
name: "ref",
|
||||
title: "Side",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Seksjonen må ha minst en referanse"),
|
||||
to: [{ type: "aksel_artikkel" }],
|
||||
options: {
|
||||
filter: ({ document, parent }) => {
|
||||
const selected = parent
|
||||
.filter((x) => !!x._ref)
|
||||
.map((x) => x._ref);
|
||||
return {
|
||||
filter: "references($refId) && !(_id in $docIds)",
|
||||
params: {
|
||||
refId: document._id.replace("drafts.", ""),
|
||||
docIds: selected,
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Pictogram",
|
||||
name: "pictogram",
|
||||
type: "image",
|
||||
fields: [
|
||||
{
|
||||
name: "alt",
|
||||
type: "string",
|
||||
title: "Attribution",
|
||||
hidden: true,
|
||||
},
|
||||
],
|
||||
validation: (Rule) => Rule.required().error("Tema må ha pictogram"),
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
export default {
|
||||
title: "Tokens",
|
||||
name: "token_kategori",
|
||||
type: "document",
|
||||
fields: [
|
||||
{
|
||||
title: "Navn",
|
||||
name: "title",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required(),
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
title: "Kategori",
|
||||
name: "kategori",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required(),
|
||||
readOnly: true,
|
||||
},
|
||||
],
|
||||
__experimental_omnisearch_visibility: false,
|
||||
};
|
||||
@@ -1,75 +0,0 @@
|
||||
import { Expand } from "@navikt/ds-icons";
|
||||
import { innholdFieldNewNested } from "@/lib";
|
||||
import React from "react";
|
||||
import { BodyLong, Label } from "@navikt/ds-react";
|
||||
|
||||
export default {
|
||||
name: "accordion",
|
||||
title: "Accordion",
|
||||
type: "object",
|
||||
fields: [
|
||||
{ title: "Tittel (optional)", type: "string", name: "title" },
|
||||
{
|
||||
title: "Liste",
|
||||
description: "Legg til en eller flere elementer",
|
||||
name: "list",
|
||||
type: "array",
|
||||
of: [
|
||||
{
|
||||
title: "Accordion",
|
||||
name: "element",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Tittel ",
|
||||
name: "title",
|
||||
type: "string",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Accordion må ha en tittel"),
|
||||
},
|
||||
innholdFieldNewNested("content", "riktekst_aksel"),
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
title: "title",
|
||||
},
|
||||
prepare(selection) {
|
||||
return {
|
||||
title: selection.title ?? "",
|
||||
media: () => <Expand />,
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
validation: (Rule) =>
|
||||
Rule.required().min(1).error("Accordion modul må ha minst 1 element"),
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
title: "title",
|
||||
list: "list",
|
||||
},
|
||||
prepare(s) {
|
||||
return {
|
||||
title: s?.title ? s.title : "Accordion",
|
||||
list: s?.list,
|
||||
};
|
||||
},
|
||||
component: ({ value }) => {
|
||||
return value?.list ? (
|
||||
<BodyLong as="div">
|
||||
<Label as="p">{`Accordion (${value.list.length})`}</Label>
|
||||
<ul>
|
||||
{value.list.map((x, y) => (
|
||||
<li key={x._key}>{x.title}</li>
|
||||
))}
|
||||
</ul>
|
||||
</BodyLong>
|
||||
) : (
|
||||
<Label as="p">Accordion</Label>
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,68 +0,0 @@
|
||||
import { toPlainText } from "@/lib";
|
||||
import { Warning } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
name: "alert",
|
||||
title: "Alert",
|
||||
type: "object",
|
||||
icon: Warning,
|
||||
fields: [
|
||||
{
|
||||
title: "Variant",
|
||||
name: "variant",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required().error("Alert må ha en variant"),
|
||||
options: {
|
||||
list: [
|
||||
{ value: "success", title: "Suksess" },
|
||||
{ value: "info", title: "Info" },
|
||||
{ value: "warning", title: "Fare" },
|
||||
{ value: "error", title: "Error" },
|
||||
],
|
||||
layout: "radio",
|
||||
},
|
||||
initialValue: "info",
|
||||
},
|
||||
{
|
||||
title: "Heading (optional)",
|
||||
name: "heading",
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
title: "Heading nivå",
|
||||
name: "heading_level",
|
||||
type: "string",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Alert må ha et heading-nivå"),
|
||||
options: {
|
||||
list: [
|
||||
{ value: "h3", title: "H3" },
|
||||
{ value: "h4", title: "H4" },
|
||||
],
|
||||
layout: "radio",
|
||||
},
|
||||
hidden: ({ parent }) => !parent.heading,
|
||||
initialValue: "h3",
|
||||
},
|
||||
{
|
||||
title: "Innhold",
|
||||
name: "body",
|
||||
type: "riktekst_enkel",
|
||||
validation: (Rule) => Rule.required().error("Alert må ha noe innhold"),
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
variant: "variant",
|
||||
body: "body",
|
||||
},
|
||||
prepare(selection) {
|
||||
return {
|
||||
title: toPlainText(selection?.body),
|
||||
subtitle: `Alert - ${selection.variant}`,
|
||||
media: () => <Warning />,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,105 +0,0 @@
|
||||
import { Picture } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
title: "Bilde",
|
||||
name: "bilde",
|
||||
type: "image",
|
||||
icon: Picture,
|
||||
options: {
|
||||
hotspot: true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: "alt",
|
||||
title: "Alt-tekst",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required().error("Bilde må ha en alt-tekst"),
|
||||
description: "Beskriv bildet for skjermlesere",
|
||||
options: {
|
||||
isHighlighted: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "caption",
|
||||
title: "Bilde-tekst (optional)",
|
||||
description: "Dette vil stå under bildet",
|
||||
type: "string",
|
||||
hidden: ({ parent }) => parent?.floating,
|
||||
options: {
|
||||
isHighlighted: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "small",
|
||||
title: "Bildet tar bare ~halve bredden",
|
||||
type: "boolean",
|
||||
initialValue: false,
|
||||
hidden: ({ parent }) => parent?.floating || parent?.hide_floating,
|
||||
options: {
|
||||
isHighlighted: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Kilde",
|
||||
type: "object",
|
||||
name: "kilde",
|
||||
options: {
|
||||
isHighlighted: true,
|
||||
collapsible: true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
title: "Legg til kilde",
|
||||
name: "har_kilde",
|
||||
type: "boolean",
|
||||
initialValue: false,
|
||||
},
|
||||
{
|
||||
title: "Kilde-prefix",
|
||||
name: "prefix",
|
||||
type: "string",
|
||||
options: {
|
||||
list: [
|
||||
{ title: "FOTO:", value: "FOTO" },
|
||||
{ title: "Kilde:", value: "Kilde" },
|
||||
],
|
||||
layout: "radio",
|
||||
direction: "horizontal",
|
||||
},
|
||||
hidden: ({ parent }) => !parent?.har_kilde,
|
||||
},
|
||||
{
|
||||
title: "Tekst",
|
||||
name: "tekst",
|
||||
type: "string",
|
||||
hidden: ({ parent }) => !parent?.har_kilde,
|
||||
},
|
||||
{
|
||||
title: "Lenke-kilde",
|
||||
description: "Kilde-teksten blir satt som lenke",
|
||||
name: "link",
|
||||
type: "url",
|
||||
hidden: ({ parent }) => !parent?.har_kilde,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
validation: (Rule) =>
|
||||
Rule.custom((v) => {
|
||||
return v?.asset ? true : "Må legge til et bilde";
|
||||
}).error(),
|
||||
preview: {
|
||||
select: {
|
||||
alt: "alt",
|
||||
floating: "floating",
|
||||
},
|
||||
prepare(selection) {
|
||||
return {
|
||||
title: selection?.alt,
|
||||
subtitle: `Bilde`,
|
||||
media: () => <Picture />,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,89 +0,0 @@
|
||||
import { Success } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
title: "Do / Dont",
|
||||
name: "do_dont",
|
||||
type: "object",
|
||||
icon: Success,
|
||||
fields: [
|
||||
{
|
||||
type: "array",
|
||||
name: "blokker",
|
||||
title: "Do / donts",
|
||||
of: [{ type: "do_dont_block" }],
|
||||
validation: (Rule) => Rule.required().max(4),
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
prepare() {
|
||||
return {
|
||||
title: "Do / Dont",
|
||||
media: () => <Success />,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const doDontBlock = {
|
||||
title: "DoDont",
|
||||
name: "do_dont_block",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Fullwidth",
|
||||
description: "Tar opp ~ 40% eller 100% av tilgjengelig bredde",
|
||||
name: "fullwidth",
|
||||
type: "boolean",
|
||||
validation: (Rule) => Rule.required(),
|
||||
initialValue: false,
|
||||
},
|
||||
{
|
||||
title: "Bilde",
|
||||
name: "picture",
|
||||
type: "image",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Do/dont må ha et bilde lagt til"),
|
||||
options: {
|
||||
hotspot: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "alt tekst for bilde",
|
||||
name: "alt",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required().error("Do/dont må ha en alt-tekst"),
|
||||
options: {
|
||||
isHighlighted: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "description",
|
||||
title: "Fritekst",
|
||||
description:
|
||||
"Korte konsise beskrivelser. Bruk fullbredde bilde i dodont med egen tekst for lengre forklaringer",
|
||||
type: "text",
|
||||
},
|
||||
{
|
||||
name: "variant",
|
||||
title: "Variant",
|
||||
type: "string",
|
||||
options: {
|
||||
list: [
|
||||
{ title: "Do", value: "do" },
|
||||
{ title: "Dont", value: "dont" },
|
||||
{ title: "Warning", value: "warning" },
|
||||
],
|
||||
layout: "radio",
|
||||
},
|
||||
initialValue: "do",
|
||||
validation: (Rule) => Rule.required(),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
|
||||
|
||||
*/
|
||||
@@ -1,36 +0,0 @@
|
||||
import { Picture } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
title: "Hero bilde",
|
||||
name: "herobilde",
|
||||
type: "image",
|
||||
icon: Picture,
|
||||
options: {
|
||||
hotspot: true,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
name: "alt",
|
||||
title: "Alt-tekst",
|
||||
type: "string",
|
||||
validation: (Rule) => Rule.required().error("Bilde må ha en alt-tekst"),
|
||||
description: "Beskriv bildet for skjermlesere",
|
||||
options: {
|
||||
isHighlighted: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
alt: "alt",
|
||||
},
|
||||
prepare(selection) {
|
||||
return {
|
||||
title: selection?.alt,
|
||||
subtitle: `Bilde`,
|
||||
media: () => <Picture />,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
import Accordion from "./accordion";
|
||||
import Alert from "./alert";
|
||||
import Innholdskort from "./innholdskort";
|
||||
import Bilde from "./bilde";
|
||||
import DoDont, { doDontBlock } from "./do-dont";
|
||||
import HeroBilde from "./hero-bilde";
|
||||
import introKomponent from "./intro-komponent";
|
||||
import Kode from "./kode";
|
||||
import KodeEksempler from "./kode-eksempler";
|
||||
import Props from "./props";
|
||||
import RelatertInnhold from "./relatert-innhold";
|
||||
import { tmpTabell, tmpTabellRow } from "./tabellv2";
|
||||
import {
|
||||
RiktekstAksel,
|
||||
RiktekstDsArtikkel,
|
||||
RiktekstEnkel,
|
||||
RiktekstKomponent,
|
||||
RiktekstPrinsipp,
|
||||
RiktekstTabell,
|
||||
} from "./riktekst";
|
||||
import SpesialSeksjon from "./spesial-seksjon";
|
||||
import Tastatur from "./tastatur";
|
||||
import Tips from "./tips";
|
||||
import TokenRef from "./token-tabell";
|
||||
import Video from "./video";
|
||||
|
||||
const v2Blocks = [
|
||||
tmpTabell,
|
||||
tmpTabellRow,
|
||||
/* Blocks */
|
||||
RiktekstEnkel,
|
||||
RiktekstAksel,
|
||||
RiktekstDsArtikkel,
|
||||
RiktekstKomponent,
|
||||
RiktekstTabell,
|
||||
RiktekstPrinsipp,
|
||||
|
||||
/* Moduler */
|
||||
/* Tabellv2, */
|
||||
DoDont,
|
||||
doDontBlock,
|
||||
Bilde,
|
||||
HeroBilde,
|
||||
Alert,
|
||||
Kode,
|
||||
RelatertInnhold,
|
||||
Innholdskort,
|
||||
introKomponent,
|
||||
Props,
|
||||
Accordion,
|
||||
SpesialSeksjon,
|
||||
Video,
|
||||
Tips,
|
||||
Tastatur,
|
||||
KodeEksempler,
|
||||
TokenRef,
|
||||
];
|
||||
|
||||
export default v2Blocks;
|
||||
@@ -1,55 +0,0 @@
|
||||
// Usikker på om skal være med videre
|
||||
|
||||
import { FileContent } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
title: "Innholdskort",
|
||||
name: "innholdskort",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Tittel",
|
||||
name: "title",
|
||||
type: "string",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Innholdskort må ha en beskrivende tittel"),
|
||||
},
|
||||
{
|
||||
title: "Lenke til prinsipp",
|
||||
name: "lenke",
|
||||
type: "reference",
|
||||
to: [{ type: "aksel_prinsipp" }],
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Innholdskort må ha en lenke"),
|
||||
},
|
||||
{
|
||||
title: "Innhold",
|
||||
description: "Ikke bruk lenker inne i selve kortet",
|
||||
name: "body",
|
||||
type: "riktekst_enkel",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Innholdskort må ha noe beskrivende innhold"),
|
||||
},
|
||||
],
|
||||
validation: (Rule) =>
|
||||
Rule.custom((_, { document }) => {
|
||||
if (!document?.prinsipp?.hovedside) {
|
||||
return "Innholdskort kan bare brukes på 'hovedsiden' til prinsippet";
|
||||
}
|
||||
|
||||
return true;
|
||||
}),
|
||||
preview: {
|
||||
select: {
|
||||
title: "title",
|
||||
},
|
||||
prepare(selection) {
|
||||
return {
|
||||
title: selection?.title,
|
||||
subtitle: `Innholdskort`,
|
||||
media: () => <FileContent />,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,45 +0,0 @@
|
||||
import { Home } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
title: "Intro",
|
||||
name: "intro_komponent",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Intro-tekst",
|
||||
name: "body",
|
||||
type: "riktekst_enkel",
|
||||
validation: (Rule) =>
|
||||
Rule.required().error("Komponentintro må ha en intro"),
|
||||
},
|
||||
{
|
||||
type: "array",
|
||||
name: "brukes_til",
|
||||
title: "Egnet til å:",
|
||||
of: [{ type: "string" }],
|
||||
validation: (Rule) => Rule.required().min(1),
|
||||
},
|
||||
{
|
||||
type: "array",
|
||||
name: "brukes_ikke_til",
|
||||
title: "Vurder noe annet: (optional)",
|
||||
of: [{ type: "string" }],
|
||||
},
|
||||
],
|
||||
options: {
|
||||
collapsible: true,
|
||||
collapsed: true,
|
||||
},
|
||||
preview: {
|
||||
select: {
|
||||
title: "title",
|
||||
},
|
||||
prepare() {
|
||||
return {
|
||||
title: "Komponent-intro",
|
||||
media: () => <Home />,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
import { Ruler } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
title: "Kode-eksempler",
|
||||
name: "kode_eksempler",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "tittel",
|
||||
name: "title",
|
||||
type: "string",
|
||||
initialValue: "Kode-eksempler",
|
||||
readOnly: true,
|
||||
hidden: true,
|
||||
},
|
||||
{
|
||||
title: "Standalone-eksempel",
|
||||
description: "Vis bare et spesfikt eksempel",
|
||||
name: "standalone",
|
||||
type: "boolean",
|
||||
initialValue: false,
|
||||
},
|
||||
{
|
||||
title: "Eksempel-navn",
|
||||
name: "dir",
|
||||
type: "reference",
|
||||
to: [{ type: "kode_eksempler_fil" }],
|
||||
options: {
|
||||
filter: "dir == true",
|
||||
},
|
||||
hidden: ({ parent }) => parent.standalone,
|
||||
},
|
||||
{
|
||||
title: "Installasjon-snippet",
|
||||
name: "filnavn",
|
||||
type: "reference",
|
||||
to: [{ type: "kode_eksempler_fil" }],
|
||||
options: {
|
||||
filter: "dir != true",
|
||||
},
|
||||
hidden: ({ parent }) => !parent.standalone,
|
||||
},
|
||||
],
|
||||
icon: () => <Ruler />,
|
||||
preview: {
|
||||
select: {
|
||||
standalone: "standalone",
|
||||
filnavn: "filnavn.title",
|
||||
dir: "dir.title",
|
||||
},
|
||||
prepare({ standalone, filnavn, dir }) {
|
||||
return {
|
||||
title: "Komponent-demo",
|
||||
subtitle: standalone ? filnavn?.replace(".tsx", "") ?? "" : dir ?? "",
|
||||
media: () => <Ruler />,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,41 +0,0 @@
|
||||
// MIGRERT
|
||||
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
title: "Kode",
|
||||
name: "kode",
|
||||
type: "object",
|
||||
icon: () => <div>{`<>`}</div>,
|
||||
fields: [
|
||||
{
|
||||
name: "code",
|
||||
title: "Kode",
|
||||
type: "code",
|
||||
hidden: ({ parent }) => parent?.variant,
|
||||
validation: (Rule) => Rule.required(),
|
||||
options: {
|
||||
languageAlternatives: [
|
||||
{ value: "js", title: "Javascript" },
|
||||
{ value: "jsx", title: "JSX" },
|
||||
{ value: "html", title: "HTML" },
|
||||
{ value: "css", title: "CSS" },
|
||||
{ value: "less", title: "Less" },
|
||||
{ value: "terminal", title: "Terminal/Bash" },
|
||||
{ value: "terminal", title: "Standard" },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
code: "code",
|
||||
ref: "ref.title",
|
||||
},
|
||||
prepare: ({ code, ref }) => ({
|
||||
title: code ? `${code?.code?.slice(0, 50)}...` : ref ? ref : "Kode",
|
||||
subtitle: "kode",
|
||||
media: () => <div>{`</>`}</div>,
|
||||
}),
|
||||
},
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
// MIGRERT
|
||||
|
||||
import { List } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
title: "Props",
|
||||
name: "props_seksjon",
|
||||
type: "object",
|
||||
icon: List,
|
||||
fields: [
|
||||
{
|
||||
title: "Tittel (h2)",
|
||||
name: "title",
|
||||
type: "string",
|
||||
initialValue: "Props",
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
title: "Props",
|
||||
type: "array",
|
||||
name: "komponenter",
|
||||
of: [
|
||||
{
|
||||
title: "Komponent",
|
||||
type: "object",
|
||||
name: "komponent",
|
||||
fields: [
|
||||
{
|
||||
title: "Komponent navn",
|
||||
description: "Slik man ville brukt den, eks Accordion.Item",
|
||||
type: "string",
|
||||
name: "title",
|
||||
},
|
||||
{
|
||||
title: "Bruker komponenten OverridableComponent API-et",
|
||||
type: "boolean",
|
||||
name: "overridable",
|
||||
initialValue: false,
|
||||
},
|
||||
{
|
||||
name: "propref",
|
||||
title: "Komponent referanse",
|
||||
type: "reference",
|
||||
to: [{ type: "ds_props" }],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
prepare() {
|
||||
return {
|
||||
title: "Props",
|
||||
media: () => <List />,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,79 +0,0 @@
|
||||
// MIGRERT
|
||||
|
||||
import { allDocumentTypes } from "../../config";
|
||||
import { Link } from "@navikt/ds-icons";
|
||||
import React from "react";
|
||||
|
||||
export default {
|
||||
name: "relatert_innhold",
|
||||
title: "Relatert Innhold",
|
||||
type: "object",
|
||||
icon: Link,
|
||||
fields: [
|
||||
{
|
||||
title: "Lenker til innhold",
|
||||
name: "lenker",
|
||||
type: "array",
|
||||
validation: (Rule) =>
|
||||
Rule.required().max(4).error("Kan ha maks 4 relaterte lenker"),
|
||||
of: [
|
||||
{
|
||||
title: "Lenke",
|
||||
name: "lenke",
|
||||
type: "object",
|
||||
fields: [
|
||||
{
|
||||
title: "Tittel",
|
||||
name: "title",
|
||||
type: "string",
|
||||
validation: (Rule) =>
|
||||
Rule.required()
|
||||
.max(40)
|
||||
.error("Tittelen kan være på maks 35 tegn"),
|
||||
},
|
||||
{
|
||||
title: "Intern side i Sanity",
|
||||
name: "intern",
|
||||
type: "boolean",
|
||||
option: {
|
||||
layout: "checkbox",
|
||||
},
|
||||
validation: (Rule) => Rule.required(),
|
||||
initialValue: false,
|
||||
},
|
||||
{
|
||||
title: "Lenke til Intern sanity-side",
|
||||
name: "intern_lenke",
|
||||
type: "reference",
|
||||
to: [...allDocumentTypes.map((x) => ({ type: x }))],
|
||||
hidden: ({ parent }) => !parent?.intern,
|
||||
},
|
||||
{
|
||||
title: "Lenke til ekstern side",
|
||||
name: "ekstern_link",
|
||||
type: "url",
|
||||
hidden: ({ parent }) => parent?.intern,
|
||||
},
|
||||
{
|
||||
title: "Linker til et eksternt domene",
|
||||
description:
|
||||
"Sett denne hvis lenken går til en side utenfor aksel.nav.no",
|
||||
name: "ekstern_domene",
|
||||
type: "boolean",
|
||||
initialValue: false,
|
||||
hidden: ({ parent }) => parent?.intern,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
preview: {
|
||||
select: {
|
||||
links: "links",
|
||||
},
|
||||
prepare(s) {
|
||||
return { title: "Relatert innhold kort", media: () => <Link /> };
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -1,269 +0,0 @@
|
||||
import "@navikt/ds-css?raw";
|
||||
import "@navikt/ds-css-internal?raw";
|
||||
import { ExternalLink, FileContent, Link } from "@navikt/ds-icons";
|
||||
import { BodyLong, Heading } from "@navikt/ds-react/cjs";
|
||||
import { KBD } from "@sanity/ui";
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import { allDocumentTypes } from "../../config";
|
||||
|
||||
export const TitleRenderer = (props, size, level) => (
|
||||
<Heading size={size} level={level}>
|
||||
{props.children}
|
||||
</Heading>
|
||||
);
|
||||
|
||||
export const ScCode = styled.code`
|
||||
color: var(--a-deepblue-500);
|
||||
background-color: var(--a-deepblue-50);
|
||||
border-radius: 6px;
|
||||
font-size: 1rem;
|
||||
padding: 2px 0.5rem;
|
||||
`;
|
||||
|
||||
export const styles = [
|
||||
{
|
||||
title: "Avsnitt",
|
||||
value: "normal",
|
||||
blockEditor: {
|
||||
render: (props) => <BodyLong>{props.children}</BodyLong>,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const block = {
|
||||
title: "Block",
|
||||
type: "block",
|
||||
styles: [...styles],
|
||||
lists: [
|
||||
{ title: "Bullet", value: "bullet" },
|
||||
{ title: "Numbered", value: "number" },
|
||||
],
|
||||
// Marks let you mark up inline text in the block editor.
|
||||
marks: {
|
||||
// Decorators usually describe a single property – e.g. a typographic
|
||||
// preference or highlighting by editors.
|
||||
decorators: [
|
||||
{ title: "Strong", value: "strong" },
|
||||
{ title: "Emphasis", value: "em" },
|
||||
{
|
||||
title: "Code",
|
||||
value: "code",
|
||||
blockEditor: {
|
||||
render: (props) => <ScCode>{props.children}</ScCode>,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "KBD",
|
||||
value: "kbd",
|
||||
blockEditor: {
|
||||
icon: () => <div>KBD</div>,
|
||||
render: (props) => (
|
||||
<KBD padding={[1, 1, 2]} style={{ verticalAlign: "super" }}>
|
||||
{props.children}
|
||||
</KBD>
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
// Annotations can be any object structure – e.g. a link or a footnote.
|
||||
annotations: [
|
||||
{
|
||||
title: "Link til side i sanity",
|
||||
name: "internalLink",
|
||||
type: "object",
|
||||
blockEditor: {
|
||||
icon: () => <Link />,
|
||||
},
|
||||
options: {
|
||||
modal: {
|
||||
type: "dialog",
|
||||
width: "medium", // 'small' | 'medium' | 'large' | 'full'
|
||||
},
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
title: "Reference",
|
||||
name: "reference",
|
||||
type: "reference",
|
||||
to: [
|
||||
...allDocumentTypes.map((doc) => ({
|
||||
type: doc,
|
||||
})),
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Lenke",
|
||||
name: "link",
|
||||
type: "object",
|
||||
blockEditor: {
|
||||
icon: () => <ExternalLink />,
|
||||
},
|
||||
fields: [
|
||||
{
|
||||
title: "URL",
|
||||
name: "href",
|
||||
type: "url",
|
||||
validation: (Rule) =>
|
||||
Rule.uri({
|
||||
scheme: ["https", "mailto", "tel"],
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: "Åpne siden i ny tab",
|
||||
description:
|
||||
"Vi anbefaler å ikke åpne lenker i ny fane slik at brukeren selv kan styre det om ønsket.",
|
||||
name: "blank",
|
||||
type: "boolean",
|
||||
initialValue: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const headingStyles = [
|
||||
...block.styles,
|
||||
{
|
||||
title: "H2",
|
||||
value: "h2",
|
||||
blockEditor: {
|
||||
render: (props) => (
|
||||
<Heading as="span" size="medium">
|
||||
{props.children}
|
||||
</Heading>
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "H3",
|
||||
value: "h3",
|
||||
blockEditor: {
|
||||
render: (props) => (
|
||||
<Heading as="span" size="small">
|
||||
{props.children}
|
||||
</Heading>
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "H4",
|
||||
value: "h4",
|
||||
blockEditor: {
|
||||
render: (props) => (
|
||||
<Heading as="span" size="xsmall">
|
||||
{props.children}
|
||||
</Heading>
|
||||
),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const Riktekst = (type: "aksel" | "ds" | "komponent" | "prinsipp") => {
|
||||
const fields: string[] = [];
|
||||
const standard = [
|
||||
"relatert_innhold",
|
||||
"bilde",
|
||||
"kode",
|
||||
"tips",
|
||||
"do_dont",
|
||||
"accordion",
|
||||
"alert",
|
||||
"tabell_v2",
|
||||
"video",
|
||||
];
|
||||
|
||||
const comp = [
|
||||
"props_seksjon",
|
||||
"tastatur_modul",
|
||||
"kode_eksempler",
|
||||
"token_ref",
|
||||
];
|
||||
|
||||
const ds_artikkel = ["spesial_seksjon"];
|
||||
|
||||
fields.push(...standard);
|
||||
|
||||
switch (type) {
|
||||
case "komponent":
|
||||
fields.push(...comp);
|
||||
break;
|
||||
case "ds":
|
||||
fields.push(...ds_artikkel);
|
||||
break;
|
||||
case "prinsipp":
|
||||
fields.push("innholdskort");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const uniq = fields.filter((item, pos, self) => self.indexOf(item) === pos);
|
||||
|
||||
return [
|
||||
{
|
||||
...block,
|
||||
styles: [...headingStyles],
|
||||
},
|
||||
...uniq.map((x) => ({ type: x })),
|
||||
];
|
||||
};
|
||||
|
||||
export const RiktekstAksel = {
|
||||
title: "Riktekst Aksel",
|
||||
name: "riktekst_aksel",
|
||||
type: "array",
|
||||
of: Riktekst("aksel"),
|
||||
icon: () => <FileContent />,
|
||||
};
|
||||
|
||||
export const RiktekstPrinsipp = {
|
||||
title: "Riktekst Aksel",
|
||||
name: "riktekst_prinsipp",
|
||||
type: "array",
|
||||
of: Riktekst("prinsipp"),
|
||||
icon: () => <FileContent />,
|
||||
};
|
||||
|
||||
export const RiktekstDsArtikkel = {
|
||||
title: "Riktekst Aksel",
|
||||
name: "riktekst_ds_artikkel",
|
||||
type: "array",
|
||||
of: Riktekst("ds"),
|
||||
icon: () => <FileContent />,
|
||||
};
|
||||
|
||||
export const RiktekstKomponent = {
|
||||
title: "Riktekst Aksel",
|
||||
name: "riktekst_komponent",
|
||||
type: "array",
|
||||
of: Riktekst("komponent"),
|
||||
icon: () => <FileContent />,
|
||||
};
|
||||
|
||||
export const RiktekstTabell = {
|
||||
title: "Riktekst",
|
||||
name: "riktekst_tabell",
|
||||
type: "array",
|
||||
of: [
|
||||
{
|
||||
...block,
|
||||
marks: {
|
||||
...block.marks,
|
||||
annotations: block.marks.annotations.filter(
|
||||
(x) => x.name !== "internalLink"
|
||||
),
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const RiktekstEnkel = {
|
||||
title: "Riktekst",
|
||||
name: "riktekst_enkel",
|
||||
type: "array",
|
||||
of: [block],
|
||||
};
|
||||
Loaded 100 of 199 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user