mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-10-30 01:55:58 +01:00
Integrate tailwind css and create new button library (#2098)
Introduce tailwind as new frontend styling library to replace bulma in the longer run. Also create the first new ui library `ui-buttons` which will be the new standard for buttons ins SCM-Manager. In this library we reconsidered which types of buttons should be used to create a clean and consistent ui. Co-authored-by: Eduard Heimbuch <eduard.heimbuch@cloudogu.com>
This commit is contained in:
committed by
GitHub
parent
09beb8cd3b
commit
27dbcbf28d
1
.gitignore
vendored
1
.gitignore
vendored
@@ -40,3 +40,4 @@ rebel.xml
|
|||||||
.cache
|
.cache
|
||||||
|
|
||||||
.turbo
|
.turbo
|
||||||
|
storybook-static
|
||||||
|
|||||||
@@ -18,20 +18,21 @@
|
|||||||
"set-version": "ui-scripts version"
|
"set-version": "ui-scripts version"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@scm-manager/eslint-config": "^2.15.1"
|
"@scm-manager/eslint-config": "2.16.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/remark-preset-lint": "^1.0.0",
|
"@scm-manager/remark-preset-lint": "^1.0.0",
|
||||||
"babel-plugin-reflow": "^0.2.7",
|
"babel-plugin-reflow": "^0.2.7",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
"husky": "^4.2.5",
|
"husky": "^4.2.5",
|
||||||
"lint-staged": "^10.2.11",
|
"lint-staged": "^10.2.11",
|
||||||
"remark-cli": "^9.0.0",
|
"remark-cli": "^9.0.0",
|
||||||
"turbo": "^1.2.5",
|
"turbo": "^1.2.5"
|
||||||
"cross-env": "^7.0.3"
|
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"babel-core": "7.0.0-bridge.0",
|
"babel-core": "7.0.0-bridge.0",
|
||||||
"gitdiff-parser": "https://github.com/scm-manager/gitdiff-parser#420d6cfa17a6a8f9bf1a517a2c629dcb332dbe13"
|
"gitdiff-parser": "https://github.com/scm-manager/gitdiff-parser#420d6cfa17a6a8f9bf1a517a2c629dcb332dbe13",
|
||||||
|
"@types/react": "17.0.47"
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
"presets": [
|
"presets": [
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ com.cloudogu.legman.support:micrometer:2.0.0=testRuntimeClasspath,testRuntimeCla
|
|||||||
com.cloudogu.legman.support:shiro:2.0.0=testRuntimeClasspath,testRuntimeClasspathCopy
|
com.cloudogu.legman.support:shiro:2.0.0=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.cloudogu.legman:core:2.0.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.cloudogu.legman:core:2.0.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.cloudogu.spotter:spotter-core:4.0.0=testRuntimeClasspath,testRuntimeClasspathCopy
|
com.cloudogu.spotter:spotter-core:4.0.0=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.cronutils:cron-utils:9.1.6=testRuntimeClasspath,testRuntimeClasspathCopy
|
com.cronutils:cron-utils:9.1.8=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.damnhandy:handy-uri-templates:2.1.7=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.damnhandy:handy-uri-templates:2.1.7=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.fasterxml.jackson.core:jackson-annotations:2.11.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.fasterxml.jackson.core:jackson-annotations:2.11.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.fasterxml.jackson.core:jackson-core:2.11.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.fasterxml.jackson.core:jackson-core:2.11.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
@@ -34,8 +34,7 @@ com.github.sdorra:web-resources:1.1.1=testRuntimeClasspath,testRuntimeClasspathC
|
|||||||
com.github.spullara.mustache.java:compiler:0.9.7=testRuntimeClasspath,testRuntimeClasspathCopy
|
com.github.spullara.mustache.java:compiler:0.9.7=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.google.auto:auto-common:0.11=testRuntimeClasspath,testRuntimeClasspathCopy
|
com.google.auto:auto-common:0.11=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.google.code.findbugs:jsr305:3.0.2=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.google.code.findbugs:jsr305:3.0.2=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.google.code.gson:gson:2.8.6=testRuntimeClasspath
|
com.google.code.gson:gson:2.8.7=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.google.code.gson:gson:2.8.7=testRuntimeClasspathCopy
|
|
||||||
com.google.errorprone:error_prone_annotations:2.3.4=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.google.errorprone:error_prone_annotations:2.3.4=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.google.guava:failureaccess:1.0.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.google.guava:failureaccess:1.0.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.google.guava:guava:30.1-jre=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.google.guava:guava:30.1-jre=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
@@ -46,8 +45,7 @@ com.google.inject.extensions:guice-servlet:5.0.1=testCompileClasspath,testCompil
|
|||||||
com.google.inject.extensions:guice-throwingproviders:5.0.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.google.inject.extensions:guice-throwingproviders:5.0.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.google.inject:guice:5.0.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.google.inject:guice:5.0.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.google.j2objc:j2objc-annotations:1.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.google.j2objc:j2objc-annotations:1.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.googlecode.javaewah:JavaEWAH:1.1.12=testCompileClasspathCopy,testRuntimeClasspathCopy
|
com.googlecode.javaewah:JavaEWAH:1.1.12=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.googlecode.javaewah:JavaEWAH:1.1.7=testCompileClasspath,testRuntimeClasspath
|
|
||||||
com.ibm.async:asyncutil:0.1.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.ibm.async:asyncutil:0.1.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.jcraft:jsch.agentproxy.connector-factory:0.0.7=testRuntimeClasspath,testRuntimeClasspathCopy
|
com.jcraft:jsch.agentproxy.connector-factory:0.0.7=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.jcraft:jsch.agentproxy.core:0.0.7=testRuntimeClasspath,testRuntimeClasspathCopy
|
com.jcraft:jsch.agentproxy.core:0.0.7=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
@@ -147,13 +145,10 @@ org.apache.sling:org.apache.sling.javax.activation:0.1.0=testCompileClasspath,te
|
|||||||
org.apache.tika:tika-core:1.25=testRuntimeClasspath,testRuntimeClasspathCopy
|
org.apache.tika:tika-core:1.25=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.apiguardian:apiguardian-api:1.1.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.apiguardian:apiguardian-api:1.1.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.assertj:assertj-core:3.18.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.assertj:assertj-core:3.18.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.bouncycastle:bcpg-jdk15on:1.67=testRuntimeClasspath
|
org.bouncycastle:bcpg-jdk15on:1.69=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.bouncycastle:bcpg-jdk15on:1.69=testRuntimeClasspathCopy
|
org.bouncycastle:bcpkix-jdk15on:1.69=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.bouncycastle:bcpkix-jdk15on:1.67=testRuntimeClasspath
|
org.bouncycastle:bcprov-jdk15on:1.69=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.bouncycastle:bcpkix-jdk15on:1.69=testRuntimeClasspathCopy
|
org.bouncycastle:bcutil-jdk15on:1.69=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.bouncycastle:bcprov-jdk15on:1.67=testRuntimeClasspath
|
|
||||||
org.bouncycastle:bcprov-jdk15on:1.69=testRuntimeClasspathCopy
|
|
||||||
org.bouncycastle:bcutil-jdk15on:1.69=testRuntimeClasspathCopy
|
|
||||||
org.ccil.cowan.tagsoup:tagsoup:1.2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.ccil.cowan.tagsoup:tagsoup:1.2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.checkerframework:checker-qual:3.5.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.checkerframework:checker-qual:3.5.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.codehaus.groovy:groovy-json:3.0.2=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.codehaus.groovy:groovy-json:3.0.2=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
@@ -162,6 +157,7 @@ org.codehaus.groovy:groovy:3.0.2=testCompileClasspath,testCompileClasspathCopy,t
|
|||||||
org.eclipse.microprofile.config:microprofile-config-api:2.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.eclipse.microprofile.config:microprofile-config-api:2.0=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.glassfish.jaxb:jaxb-runtime:2.3.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.glassfish.jaxb:jaxb-runtime:2.3.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.glassfish.jaxb:txw2:2.3.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.glassfish.jaxb:txw2:2.3.3=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
|
org.glassfish:jakarta.el:3.0.4=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.glassfish:javax.el:3.0.1-b11=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.glassfish:javax.el:3.0.1-b11=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.glassfish:javax.json:1.1.4=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.glassfish:javax.json:1.1.4=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.hamcrest:hamcrest-core:2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.hamcrest:hamcrest-core:2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
@@ -174,7 +170,6 @@ org.jacoco:org.jacoco.ant:0.8.7=jacocoAntCopy
|
|||||||
org.jacoco:org.jacoco.core:0.8.7=jacocoAntCopy
|
org.jacoco:org.jacoco.core:0.8.7=jacocoAntCopy
|
||||||
org.jacoco:org.jacoco.report:0.8.7=jacocoAntCopy
|
org.jacoco:org.jacoco.report:0.8.7=jacocoAntCopy
|
||||||
org.javahg:javahg:1.0.0=testRuntimeClasspath,testRuntimeClasspathCopy
|
org.javahg:javahg:1.0.0=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.javassist:javassist:3.27.0-GA=testRuntimeClasspath,testRuntimeClasspathCopy
|
|
||||||
org.jboss.logging:jboss-logging:3.4.2.Final=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.jboss.logging:jboss-logging:3.4.2.Final=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.jboss.resteasy:resteasy-client-api:4.7.5.Final=testRuntimeClasspath,testRuntimeClasspathCopy
|
org.jboss.resteasy:resteasy-client-api:4.7.5.Final=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.jboss.resteasy:resteasy-client:4.7.5.Final=testRuntimeClasspath,testRuntimeClasspathCopy
|
org.jboss.resteasy:resteasy-client:4.7.5.Final=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
@@ -215,18 +210,12 @@ org.reactivestreams:reactive-streams:1.0.3=testCompileClasspath,testCompileClass
|
|||||||
org.slf4j:jcl-over-slf4j:1.7.30=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.slf4j:jcl-over-slf4j:1.7.30=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.slf4j:slf4j-api:1.7.30=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.slf4j:slf4j-api:1.7.30=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.tmatesoft.sqljet:sqljet:1.1.14=testRuntimeClasspath,testRuntimeClasspathCopy
|
org.tmatesoft.sqljet:sqljet:1.1.14=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
sonia.jgit:org.eclipse.jgit.gpg.bc:5.11.1.202105131744-r-scm2=testRuntimeClasspath
|
sonia.jgit:org.eclipse.jgit.gpg.bc:5.13.0.202109080827-r-scm1=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
sonia.jgit:org.eclipse.jgit.gpg.bc:5.13.0.202109080827-r-scm1=testRuntimeClasspathCopy
|
sonia.jgit:org.eclipse.jgit.http.apache:5.13.0.202109080827-r-scm1=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
sonia.jgit:org.eclipse.jgit.http.apache:5.11.1.202105131744-r-scm2=testRuntimeClasspath
|
sonia.jgit:org.eclipse.jgit.http.server:5.13.0.202109080827-r-scm1=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
sonia.jgit:org.eclipse.jgit.http.apache:5.13.0.202109080827-r-scm1=testRuntimeClasspathCopy
|
sonia.jgit:org.eclipse.jgit.lfs.server:5.13.0.202109080827-r-scm1=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
sonia.jgit:org.eclipse.jgit.http.server:5.11.1.202105131744-r-scm2=testRuntimeClasspath
|
sonia.jgit:org.eclipse.jgit.lfs:5.13.0.202109080827-r-scm1=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
sonia.jgit:org.eclipse.jgit.http.server:5.13.0.202109080827-r-scm1=testRuntimeClasspathCopy
|
sonia.jgit:org.eclipse.jgit:5.13.0.202109080827-r-scm1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
sonia.jgit:org.eclipse.jgit.lfs.server:5.11.1.202105131744-r-scm2=testRuntimeClasspath
|
|
||||||
sonia.jgit:org.eclipse.jgit.lfs.server:5.13.0.202109080827-r-scm1=testRuntimeClasspathCopy
|
|
||||||
sonia.jgit:org.eclipse.jgit.lfs:5.11.1.202105131744-r-scm2=testRuntimeClasspath
|
|
||||||
sonia.jgit:org.eclipse.jgit.lfs:5.13.0.202109080827-r-scm1=testRuntimeClasspathCopy
|
|
||||||
sonia.jgit:org.eclipse.jgit:5.11.1.202105131744-r-scm2=testCompileClasspath,testRuntimeClasspath
|
|
||||||
sonia.jgit:org.eclipse.jgit:5.13.0.202109080827-r-scm1=testCompileClasspathCopy,testRuntimeClasspathCopy
|
|
||||||
sonia.svnkit:svnkit-dav:1.10.3-scm2=testRuntimeClasspath,testRuntimeClasspathCopy
|
sonia.svnkit:svnkit-dav:1.10.3-scm2=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
sonia.svnkit:svnkit:1.10.3-scm2=testRuntimeClasspath,testRuntimeClasspathCopy
|
sonia.svnkit:svnkit:1.10.3-scm2=testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
empty=annotationProcessor,annotationProcessorCopy,archives,archivesCopy,compileClasspath,compileClasspathCopy,corePlugin,corePluginCopy,default,defaultCopy,itPlugin,itPluginCopy,itWebApp,itWebAppCopy,runtimeClasspath,runtimeClasspathCopy,testAnnotationProcessor,testAnnotationProcessorCopy
|
empty=annotationProcessor,annotationProcessorCopy,archives,archivesCopy,compileClasspath,compileClasspathCopy,corePlugin,corePluginCopy,default,defaultCopy,itPlugin,itPluginCopy,itWebApp,itWebAppCopy,runtimeClasspath,runtimeClasspathCopy,testAnnotationProcessor,testAnnotationProcessorCopy
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/plugin-scripts": "^1.2.2",
|
"@scm-manager/plugin-scripts": "^1.2.2",
|
||||||
"@scm-manager/prettier-config": "^2.11.1",
|
"@scm-manager/prettier-config": "^2.11.1",
|
||||||
@@ -33,4 +33,4 @@
|
|||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "@scm-manager/eslint-config"
|
"extends": "@scm-manager/eslint-config"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/plugin-scripts": "^1.2.2",
|
"@scm-manager/plugin-scripts": "^1.2.2",
|
||||||
"@scm-manager/prettier-config": "^2.11.1",
|
"@scm-manager/prettier-config": "^2.11.1",
|
||||||
@@ -32,4 +32,4 @@
|
|||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "@scm-manager/eslint-config"
|
"extends": "@scm-manager/eslint-config"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/plugin-scripts": "^1.2.2",
|
"@scm-manager/plugin-scripts": "^1.2.2",
|
||||||
"@scm-manager/prettier-config": "^2.11.1",
|
"@scm-manager/prettier-config": "^2.11.1",
|
||||||
@@ -32,4 +32,4 @@
|
|||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "@scm-manager/eslint-config"
|
"extends": "@scm-manager/eslint-config"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/plugin-scripts": "^1.2.2",
|
"@scm-manager/plugin-scripts": "^1.2.2",
|
||||||
"@scm-manager/prettier-config": "^2.11.1",
|
"@scm-manager/prettier-config": "^2.11.1",
|
||||||
@@ -32,4 +32,4 @@
|
|||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "@scm-manager/eslint-config"
|
"extends": "@scm-manager/eslint-config"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -279,6 +279,7 @@ license {
|
|||||||
exclude '**/*.snap'
|
exclude '**/*.snap'
|
||||||
exclude '**/*.iml'
|
exclude '**/*.iml'
|
||||||
exclude '**/.babelrc'
|
exclude '**/.babelrc'
|
||||||
|
exclude '**/storybook-static/**'
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
modules {
|
modules {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"fluent-ffmpeg": "^2.1.2"
|
"fluent-ffmpeg": "^2.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/eslint-config": "^2.15.1"
|
"@scm-manager/eslint-config": "^2.16.0"
|
||||||
},
|
},
|
||||||
"prettier": "@scm-manager/prettier-config",
|
"prettier": "@scm-manager/prettier-config",
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
@@ -26,4 +26,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/prettier-config": "^2.10.1",
|
"@scm-manager/prettier-config": "^2.10.1",
|
||||||
"@scm-manager/tsconfig": "^2.13.0",
|
"@scm-manager/tsconfig": "^2.13.0",
|
||||||
@@ -52,4 +52,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,12 +23,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { ApiResult, useIndexLink, useRequiredIndexLink } from "./base";
|
import { ApiResult, useIndexLink, useRequiredIndexLink } from "./base";
|
||||||
import { isPluginCollection, PendingPlugins, Plugin, PluginCollection } from "@scm-manager/ui-types";
|
import type { PendingPlugins, Plugin, PluginCollection, HalRepresentation } from "@scm-manager/ui-types";
|
||||||
import { useMutation, useQuery, useQueryClient } from "react-query";
|
import { useMutation, useQuery, useQueryClient } from "react-query";
|
||||||
import { apiClient } from "./apiclient";
|
import { apiClient } from "./apiclient";
|
||||||
import { requiredLink } from "./links";
|
import { requiredLink } from "./links";
|
||||||
import { BadGatewayError } from "./errors";
|
import { BadGatewayError } from "./errors";
|
||||||
|
|
||||||
|
const isPluginCollection = (input: HalRepresentation): input is PluginCollection =>
|
||||||
|
input._embedded ? "plugins" in input._embedded : false;
|
||||||
|
|
||||||
type WaitForRestartOptions = {
|
type WaitForRestartOptions = {
|
||||||
initialDelay?: number;
|
initialDelay?: number;
|
||||||
timeout?: number;
|
timeout?: number;
|
||||||
|
|||||||
4
scm-ui/ui-buttons/.storybook/.babelrc
Normal file
4
scm-ui/ui-buttons/.storybook/.babelrc
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"presets": ["@scm-manager/babel-preset"],
|
||||||
|
"plugins": ["@babel/plugin-syntax-dynamic-import"]
|
||||||
|
}
|
||||||
57
scm-ui/ui-buttons/.storybook/RemoveThemesPlugin.js
Normal file
57
scm-ui/ui-buttons/.storybook/RemoveThemesPlugin.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
|
|
||||||
|
class RemoveThemesPlugin {
|
||||||
|
apply (compiler) {
|
||||||
|
compiler.hooks.compilation.tap('RemoveThemesPlugin', (compilation) => {
|
||||||
|
|
||||||
|
HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync(
|
||||||
|
'RemoveThemesPlugin',
|
||||||
|
(data, cb) => {
|
||||||
|
|
||||||
|
// remove generated style-loader bundles from the page
|
||||||
|
// there should be a better way, which does not generate the bundles at all
|
||||||
|
// but for now it works
|
||||||
|
if (data.assets.js) {
|
||||||
|
data.assets.js = data.assets.js.filter(bundle => !bundle.startsWith("ui-theme-"))
|
||||||
|
.filter(bundle => !bundle.startsWith("runtime~ui-theme-"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove css links to avoid conflicts with the themes
|
||||||
|
// so we remove all and add our own via preview-head.html
|
||||||
|
if (data.assets.css) {
|
||||||
|
data.assets.css = data.assets.css.filter(css => !css.startsWith("ui-theme-"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tell webpack to move on
|
||||||
|
cb(null, data)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = RemoveThemesPlugin
|
||||||
27
scm-ui/ui-buttons/.storybook/index.css
Normal file
27
scm-ui/ui-buttons/.storybook/index.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
109
scm-ui/ui-buttons/.storybook/main.js
Normal file
109
scm-ui/ui-buttons/.storybook/main.js
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||||
|
const RemoveThemesPlugin = require("./RemoveThemesPlugin");
|
||||||
|
const ReactDOM = require("react-dom");
|
||||||
|
|
||||||
|
const root = path.resolve("..");
|
||||||
|
|
||||||
|
const themedir = path.join(root, "ui-styles", "src");
|
||||||
|
|
||||||
|
ReactDOM.createPortal = (node) => node;
|
||||||
|
|
||||||
|
const themes = fs
|
||||||
|
.readdirSync(themedir)
|
||||||
|
.map((filename) => path.parse(filename))
|
||||||
|
.filter((p) => p.ext === ".scss")
|
||||||
|
.reduce((entries, current) => ({ ...entries, [`ui-theme-${current.name}`]: path.join(themedir, current.base) }), {});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
typescript: { reactDocgen: false },
|
||||||
|
core: {
|
||||||
|
builder: "webpack5",
|
||||||
|
},
|
||||||
|
stories: ["../docs/**/*.stories.mdx", "../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
|
||||||
|
addons: [
|
||||||
|
"storybook-addon-i18next",
|
||||||
|
"storybook-addon-themes",
|
||||||
|
"@storybook/addon-links",
|
||||||
|
"@storybook/addon-essentials",
|
||||||
|
"@storybook/addon-interactions",
|
||||||
|
"@storybook/addon-a11y",
|
||||||
|
"storybook-addon-pseudo-states"
|
||||||
|
],
|
||||||
|
framework: "@storybook/react",
|
||||||
|
webpackFinal: async (config) => {
|
||||||
|
// add our themes to webpack entry points
|
||||||
|
config.entry = {
|
||||||
|
main: config.entry,
|
||||||
|
...themes,
|
||||||
|
};
|
||||||
|
|
||||||
|
// create separate css files for our themes
|
||||||
|
config.plugins.push(
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
|
filename: "[name].css",
|
||||||
|
ignoreOrder: false,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
config.module.rules.push({
|
||||||
|
test: /\.scss$/,
|
||||||
|
use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
|
||||||
|
});
|
||||||
|
|
||||||
|
config.module.rules.push({
|
||||||
|
test: /\.css$/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: "postcss-loader",
|
||||||
|
options: {
|
||||||
|
postcssOptions: {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: { config: require("./tailwind.config") },
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
include: path.resolve(__dirname, "../"),
|
||||||
|
});
|
||||||
|
|
||||||
|
// the html-webpack-plugin adds the generated css and js files to the iframe,
|
||||||
|
// which overrides our manually loaded css files.
|
||||||
|
// So we use a custom plugin which uses a hook of html-webpack-plugin
|
||||||
|
// to filter our themes from the output.
|
||||||
|
config.plugins.push(new RemoveThemesPlugin());
|
||||||
|
|
||||||
|
// force cjs instead of esm
|
||||||
|
// https://github.com/tannerlinsley/react-query/issues/3513
|
||||||
|
config.resolve.alias["react-query/devtools"] = require.resolve("react-query/devtools");
|
||||||
|
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
};
|
||||||
26
scm-ui/ui-buttons/.storybook/preview-head.html
Normal file
26
scm-ui/ui-buttons/.storybook/preview-head.html
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<!--
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<link id="ui-theme" data-theme="light" rel="stylesheet" type="text/css" href="/ui-theme-light.css">
|
||||||
|
|
||||||
97
scm-ui/ui-buttons/.storybook/preview.js
Normal file
97
scm-ui/ui-buttons/.storybook/preview.js
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import "./index.css";
|
||||||
|
|
||||||
|
import i18next from "i18next";
|
||||||
|
import { initReactI18next } from "react-i18next";
|
||||||
|
import { withI18next } from "storybook-addon-i18next";
|
||||||
|
import React, {useEffect} from "react";
|
||||||
|
import withApiProvider from "./withApiProvider";
|
||||||
|
import { withThemes } from 'storybook-addon-themes/react';
|
||||||
|
|
||||||
|
let i18n = i18next;
|
||||||
|
|
||||||
|
// only use fetch backend for storybook
|
||||||
|
// and not for storyshots
|
||||||
|
if (!process.env.JEST_WORKER_ID) {
|
||||||
|
const Backend = require("i18next-fetch-backend");
|
||||||
|
i18n = i18n.use(Backend.default);
|
||||||
|
}
|
||||||
|
|
||||||
|
i18n.use(initReactI18next).init({
|
||||||
|
whitelist: ["en", "de", "es"],
|
||||||
|
lng: "en",
|
||||||
|
fallbackLng: "en",
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false,
|
||||||
|
},
|
||||||
|
react: {
|
||||||
|
useSuspense: false,
|
||||||
|
},
|
||||||
|
backend: {
|
||||||
|
loadPath: "/locales/{{lng}}/{{ns}}.json",
|
||||||
|
init: {
|
||||||
|
credentials: "same-origin",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const decorators = [
|
||||||
|
withI18next({
|
||||||
|
i18n,
|
||||||
|
languages: {
|
||||||
|
en: "English",
|
||||||
|
de: "Deutsch",
|
||||||
|
es: "Spanisch",
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
withApiProvider,
|
||||||
|
withThemes
|
||||||
|
];
|
||||||
|
|
||||||
|
const Decorator = ({children, themeName}) => {
|
||||||
|
useEffect(() => {
|
||||||
|
const link = document.querySelector("#ui-theme");
|
||||||
|
if (link && link["data-theme"] !== themeName) {
|
||||||
|
link.href = `ui-theme-${themeName}.css`;
|
||||||
|
link["data-theme"] = themeName;
|
||||||
|
}
|
||||||
|
}, [themeName]);
|
||||||
|
return <>{children}</>
|
||||||
|
};
|
||||||
|
|
||||||
|
export const parameters = {
|
||||||
|
actions: { argTypesRegex: "^on[A-Z].*" },
|
||||||
|
themes: {
|
||||||
|
Decorator,
|
||||||
|
clearable: false,
|
||||||
|
default: "light",
|
||||||
|
list: [
|
||||||
|
{ name: "light", color: "#fff" },
|
||||||
|
{ name: "highcontrast", color: "#050514" },
|
||||||
|
{ name: "dark", color: "#121212" },
|
||||||
|
],
|
||||||
|
}
|
||||||
|
};
|
||||||
33
scm-ui/ui-buttons/.storybook/tailwind.config.js
Normal file
33
scm-ui/ui-buttons/.storybook/tailwind.config.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
// eslint-disable-next-line global-require,import/no-extraneous-dependencies
|
||||||
|
require("@scm-manager/ui-scripts/src/tailwind.config"),
|
||||||
|
],
|
||||||
|
content: [path.join(__dirname, "../{src,docs}/**/*.{tsx,mdx}")],
|
||||||
|
};
|
||||||
45
scm-ui/ui-buttons/.storybook/withApiProvider.js
Normal file
45
scm-ui/ui-buttons/.storybook/withApiProvider.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
import * as React from "react";
|
||||||
|
import { ApiProvider } from "@scm-manager/ui-api";
|
||||||
|
|
||||||
|
const withApiProvider = (storyFn) => {
|
||||||
|
return React.createElement(ApiProvider, {
|
||||||
|
index: {
|
||||||
|
version: "x.y.z",
|
||||||
|
_links: {}
|
||||||
|
},
|
||||||
|
me: {
|
||||||
|
name: "trillian",
|
||||||
|
displayName: "Trillian McMillan",
|
||||||
|
mail: "trillian@hitchhiker.com",
|
||||||
|
groups: [],
|
||||||
|
_links: {}
|
||||||
|
},
|
||||||
|
devtools: false,
|
||||||
|
children: storyFn()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withApiProvider;
|
||||||
64
scm-ui/ui-buttons/docs/introduction.stories.mdx
Normal file
64
scm-ui/ui-buttons/docs/introduction.stories.mdx
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { Meta } from "@storybook/addon-docs";
|
||||||
|
import { Button } from "../src";
|
||||||
|
|
||||||
|
<Meta title="Introduction"/>
|
||||||
|
|
||||||
|
# Buttons
|
||||||
|
|
||||||
|
The `@scm-manager/ui-buttons` library provides [atoms](https://atomicdesign.bradfrost.com/chapter-2/#atoms) implemented
|
||||||
|
as minimal wrappers around native html elements styled to match the general SCM-Manager aesthetic.
|
||||||
|
|
||||||
|
## Components
|
||||||
|
|
||||||
|
There are three actionable components available. Styling is consistent amongst them and all have the required `variant` property.
|
||||||
|
|
||||||
|
1. [Button](?path=/story/components--button)
|
||||||
|
2. [Link Button](?path=/story/components--link-button)
|
||||||
|
3. [External Link Button](?path=/story/components--external-link-button)
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Actionable components serve a dedicated purpose. It is therefore important to know when and how to use them.
|
||||||
|
|
||||||
|
### Variants
|
||||||
|
|
||||||
|
There are four variants available to each of the three button types, varying in importance.
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Emphasis</th>
|
||||||
|
<th>Button Variant</th>
|
||||||
|
<th>Usage Examples</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Very High</td>
|
||||||
|
<td><Button variant="signal" className="w-full">Signal</Button></td>
|
||||||
|
<td>Destructive actions</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>High</td>
|
||||||
|
<td><Button variant="primary" className="w-full">Primary</Button></td>
|
||||||
|
<td>Form submit</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Normal</td>
|
||||||
|
<td><Button variant="secondary" className="w-full">Secondary</Button></td>
|
||||||
|
<td>Cancel action in dialog</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Low</td>
|
||||||
|
<td><Button variant="tertiary" className="w-full">Tertiary</Button></td>
|
||||||
|
<td>Circumstantially relevant action on page with many actionable elements</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
## Content
|
||||||
|
|
||||||
|
Buttons exclusively contain text and no icons. Icons tend to be ambiguous and not always applicable which leads to inconsistent
|
||||||
|
and cluttered layouts.
|
||||||
|
|
||||||
|
Button text should be short, concise and describe the action performed.
|
||||||
22
scm-ui/ui-buttons/docs/usage.stories.mdx
Normal file
22
scm-ui/ui-buttons/docs/usage.stories.mdx
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { Meta, Story } from "@storybook/addon-docs";
|
||||||
|
import { Button } from "../src";
|
||||||
|
|
||||||
|
<Meta title="Usage" parameters={{
|
||||||
|
storyshots: { disable: true }
|
||||||
|
}} />
|
||||||
|
|
||||||
|
In confirmation dialogs, there are two actions.<br/>
|
||||||
|
One to cancel the current process and one to confirm it.<br/>
|
||||||
|
Aborting is always the secondary action, confirmation always the primary.
|
||||||
|
Focus is always on the cancelling action.
|
||||||
|
|
||||||
|
<Story name="Confirmation Dialog">
|
||||||
|
<div className="max-w-2xl rounded border p-4">
|
||||||
|
<h4 className="mb-2 font-bold">Delete User</h4>
|
||||||
|
<p>Do you really want to delete this user ?</p>
|
||||||
|
<div className="flex justify-end gap-2">
|
||||||
|
<Button variant="secondary">Cancel</Button>
|
||||||
|
<Button variant="primary">Delete</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Story>
|
||||||
85
scm-ui/ui-buttons/package.json
Normal file
85
scm-ui/ui-buttons/package.json
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
{
|
||||||
|
"name": "@scm-manager/ui-buttons",
|
||||||
|
"version": "2.37.3-SNAPSHOT",
|
||||||
|
"private": true,
|
||||||
|
"main": "build/index.js",
|
||||||
|
"module": "build/index.mjs",
|
||||||
|
"types": "build/index.d.ts",
|
||||||
|
"files": [
|
||||||
|
"build"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsup ./src/index.ts -d build --format esm,cjs --dts",
|
||||||
|
"dev": "tsup ./src/index.ts -d build --format esm,cjs --dts --watch",
|
||||||
|
"lint": "eslint src",
|
||||||
|
"typecheck": "tsc",
|
||||||
|
"storybook": "start-storybook -p 6006 -s ../ui-webapp/public",
|
||||||
|
"build-storybook": "build-storybook",
|
||||||
|
"image-snapshots": "jest \"image-snapshot.test.ts\"",
|
||||||
|
"a11y-check": "jest \"a11y.test.ts\"",
|
||||||
|
"depcheck": "depcheck --ignores=@scm-manager/prettier-config,@scm-manager/tsconfig,@babel/core,sass-loader,autoprefixer,babel-loader,postcss-loader,tailwindcss,storybook-addon-*,@storybook/*,webpack"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^17.0.1",
|
||||||
|
"react-dom": "^17.0.1",
|
||||||
|
"react-router-dom": "^5.3.1",
|
||||||
|
"classnames": "^2.2.6"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@scm-manager/ui-scripts": "2.37.3-SNAPSHOT",
|
||||||
|
"@scm-manager/ui-styles": "2.37.3-SNAPSHOT",
|
||||||
|
"@scm-manager/ui-api": "2.37.3-SNAPSHOT",
|
||||||
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
|
"@babel/core": "^7.17.8",
|
||||||
|
"@scm-manager/tsconfig": "^2.12.0",
|
||||||
|
"@storybook/addon-essentials": "^6.4.20",
|
||||||
|
"@storybook/addon-interactions": "^6.4.20",
|
||||||
|
"@storybook/addon-a11y": "^6.4.20",
|
||||||
|
"@storybook/addon-links": "^6.4.20",
|
||||||
|
"@storybook/builder-webpack5": "^6.4.20",
|
||||||
|
"@storybook/manager-webpack5": "^6.4.20",
|
||||||
|
"@storybook/react": "^6.4.20",
|
||||||
|
"@storybook/addon-storyshots-puppeteer": "^6.4.20",
|
||||||
|
"@storybook/addon-storyshots": "^6.4.20",
|
||||||
|
"@storybook/testing-library": "^0.0.9",
|
||||||
|
"jest-transform-css": "^4.0.1",
|
||||||
|
"puppeteer": "^15.5.0",
|
||||||
|
"storybook-addon-pseudo-states": "^1.15.1",
|
||||||
|
"storybook-react-router": "^1.0.8",
|
||||||
|
"@types/storybook-react-router": "^1.0.2",
|
||||||
|
"sass-loader": "^12.3.0",
|
||||||
|
"storybook-addon-themes": "^6.1.0",
|
||||||
|
"autoprefixer": "^10.4.4",
|
||||||
|
"babel-loader": "^8.2.4",
|
||||||
|
"postcss": "^8.4.12",
|
||||||
|
"postcss-loader": "^6.2.1",
|
||||||
|
"tailwindcss": "^3.0.23",
|
||||||
|
"webpack": "5",
|
||||||
|
"tsup": "^6.1.2",
|
||||||
|
"mini-css-extract-plugin": "^1.6.2",
|
||||||
|
"html-webpack-plugin": "^5.5.0",
|
||||||
|
"react-query": "^3.25.1",
|
||||||
|
"i18next": "^19.9.2",
|
||||||
|
"react-i18next": "^10.13.2",
|
||||||
|
"i18next-fetch-backend": "^2.3.1"
|
||||||
|
},
|
||||||
|
"babel": {
|
||||||
|
"presets": [
|
||||||
|
"@scm-manager/babel-preset"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"jest": {
|
||||||
|
"transform": {
|
||||||
|
"^.+\\.[tj]sx?$": "babel-jest",
|
||||||
|
"^.+\\.(css|less|scss)$": "jest-transform-css",
|
||||||
|
"^.+\\.mdx?$": "@storybook/addon-docs/jest-transform-mdx"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"prettier": "@scm-manager/prettier-config",
|
||||||
|
"eslintConfig": {
|
||||||
|
"extends": "@scm-manager/eslint-config"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "restricted"
|
||||||
|
}
|
||||||
|
}
|
||||||
30
scm-ui/ui-buttons/postcss.config.js
Normal file
30
scm-ui/ui-buttons/postcss.config.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
|
},
|
||||||
|
};
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
34
scm-ui/ui-buttons/src/a11y.test.ts
Normal file
34
scm-ui/ui-buttons/src/a11y.test.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
import initStoryshots from "@storybook/addon-storyshots";
|
||||||
|
import { axeTest } from "@storybook/addon-storyshots-puppeteer";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
|
initStoryshots({
|
||||||
|
suite: "A11y checks",
|
||||||
|
test: axeTest({
|
||||||
|
storybookUrl: `file://${path.resolve(__dirname, "../storybook-static")}`,
|
||||||
|
}),
|
||||||
|
storyNameRegex: /High-Contrast States/,
|
||||||
|
});
|
||||||
91
scm-ui/ui-buttons/src/button.stories.tsx
Normal file
91
scm-ui/ui-buttons/src/button.stories.tsx
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Button as ButtonComponent,
|
||||||
|
ButtonVariantList,
|
||||||
|
ButtonVariants,
|
||||||
|
ExternalLinkButton as ExternalLinkButtonComponent,
|
||||||
|
LinkButton as LinkButtonComponent,
|
||||||
|
} from "./button";
|
||||||
|
import StoryRouter from "storybook-react-router";
|
||||||
|
import { StoryFn } from "@storybook/react";
|
||||||
|
|
||||||
|
type ExtractProps<T> = T extends React.ComponentType<infer U> ? U : never;
|
||||||
|
|
||||||
|
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
||||||
|
export default {
|
||||||
|
title: "Components",
|
||||||
|
component: null,
|
||||||
|
subcomponents: {
|
||||||
|
Button: ButtonComponent,
|
||||||
|
LinkButton: LinkButtonComponent,
|
||||||
|
ExternalLinkButton: ExternalLinkButtonComponent,
|
||||||
|
},
|
||||||
|
argTypes: {
|
||||||
|
variant: {
|
||||||
|
options: ButtonVariantList,
|
||||||
|
control: { type: "select" },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
decorators: [StoryRouter()],
|
||||||
|
parameters: {
|
||||||
|
storyshots: { disable: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
|
||||||
|
const ButtonTemplate: StoryFn<ExtractProps<typeof ButtonComponent>> = (args) => <ButtonComponent {...args} />;
|
||||||
|
const LinkButtonTemplate: StoryFn<ExtractProps<typeof LinkButtonComponent>> = (args) => (
|
||||||
|
<LinkButtonComponent {...args} />
|
||||||
|
);
|
||||||
|
const ExternalLinkButtonTemplate: StoryFn<ExtractProps<typeof ExternalLinkButtonComponent>> = (args) => (
|
||||||
|
<ExternalLinkButtonComponent {...args} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Button = ButtonTemplate.bind({});
|
||||||
|
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||||
|
Button.args = {
|
||||||
|
children: "Button",
|
||||||
|
variant: ButtonVariants.PRIMARY,
|
||||||
|
disabled: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const LinkButton = LinkButtonTemplate.bind({});
|
||||||
|
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||||
|
LinkButton.args = {
|
||||||
|
children: "Link Button",
|
||||||
|
to: "/repos",
|
||||||
|
variant: ButtonVariants.PRIMARY,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const ExternalLinkButton = ExternalLinkButtonTemplate.bind({});
|
||||||
|
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||||
|
ExternalLinkButton.args = {
|
||||||
|
children: "External Link Button",
|
||||||
|
href: "https://scm-manager.org",
|
||||||
|
variant: ButtonVariants.PRIMARY,
|
||||||
|
};
|
||||||
73
scm-ui/ui-buttons/src/button.test.stories.mdx
Normal file
73
scm-ui/ui-buttons/src/button.test.stories.mdx
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
import { Meta, Story } from "@storybook/addon-docs";
|
||||||
|
import { Button, ButtonVariantList } from "./button";
|
||||||
|
|
||||||
|
<Meta title="Tests"/>
|
||||||
|
|
||||||
|
<Story name="Light States" parameters={{
|
||||||
|
pseudo: {
|
||||||
|
hover: ButtonVariantList.map(variant => `#${variant}-Hover`),
|
||||||
|
focus: ButtonVariantList.map(variant => `#${variant}-Focus`),
|
||||||
|
active: ButtonVariantList.map(variant => `#${variant}-Active`),
|
||||||
|
},
|
||||||
|
themes: {
|
||||||
|
default: 'light',
|
||||||
|
},
|
||||||
|
}}>
|
||||||
|
<table className="border-separate border-spacing-4">
|
||||||
|
<tr>
|
||||||
|
<th>STATE</th>
|
||||||
|
{ButtonVariantList.map(variant => <th>{variant.toUpperCase()}</th>)}
|
||||||
|
</tr>
|
||||||
|
{["Normal", "Hover", "Active", "Focus", "Disabled"].map(state => <tr>
|
||||||
|
<td>{state}</td>
|
||||||
|
{ButtonVariantList.map(variant => <td><Button id={`${variant}-${state}`} disabled={state === "Disabled"}
|
||||||
|
variant={variant}>Button</Button></td>)}
|
||||||
|
</tr>)}
|
||||||
|
</table>
|
||||||
|
</Story>
|
||||||
|
|
||||||
|
<Story name="Dark States" parameters={{
|
||||||
|
pseudo: {
|
||||||
|
hover: ButtonVariantList.map(variant => `#${variant}-Hover`),
|
||||||
|
focus: ButtonVariantList.map(variant => `#${variant}-Focus`),
|
||||||
|
active: ButtonVariantList.map(variant => `#${variant}-Active`),
|
||||||
|
},
|
||||||
|
themes: {
|
||||||
|
default: 'dark',
|
||||||
|
},
|
||||||
|
}}>
|
||||||
|
<table className="border-separate border-spacing-4">
|
||||||
|
<tr>
|
||||||
|
<th>STATE</th>
|
||||||
|
{ButtonVariantList.map(variant => <th>{variant.toUpperCase()}</th>)}
|
||||||
|
</tr>
|
||||||
|
{["Normal", "Hover", "Active", "Focus", "Disabled"].map(state => <tr>
|
||||||
|
<td>{state}</td>
|
||||||
|
{ButtonVariantList.map(variant => <td><Button id={`${variant}-${state}`} disabled={state === "Disabled"}
|
||||||
|
variant={variant}>Button</Button></td>)}
|
||||||
|
</tr>)}
|
||||||
|
</table>
|
||||||
|
</Story>
|
||||||
|
|
||||||
|
<Story name="High-Contrast States" parameters={{
|
||||||
|
pseudo: {
|
||||||
|
hover: ButtonVariantList.map(variant => `#${variant}-Hover`),
|
||||||
|
focus: ButtonVariantList.map(variant => `#${variant}-Focus`),
|
||||||
|
active: ButtonVariantList.map(variant => `#${variant}-Active`),
|
||||||
|
},
|
||||||
|
themes: {
|
||||||
|
default: 'highcontrast',
|
||||||
|
},
|
||||||
|
}}>
|
||||||
|
<table className="border-separate border-spacing-4">
|
||||||
|
<tr>
|
||||||
|
<th>STATE</th>
|
||||||
|
{ButtonVariantList.map(variant => <th>{variant.toUpperCase()}</th>)}
|
||||||
|
</tr>
|
||||||
|
{["Normal", "Hover", "Active", "Focus", "Disabled"].map(state => <tr>
|
||||||
|
<td>{state}</td>
|
||||||
|
{ButtonVariantList.map(variant => <td><Button id={`${variant}-${state}`} disabled={state === "Disabled"}
|
||||||
|
variant={variant}>Button</Button></td>)}
|
||||||
|
</tr>)}
|
||||||
|
</table>
|
||||||
|
</Story>
|
||||||
109
scm-ui/ui-buttons/src/button.tsx
Normal file
109
scm-ui/ui-buttons/src/button.tsx
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React, { AnchorHTMLAttributes, ButtonHTMLAttributes } from "react";
|
||||||
|
import { Link as ReactRouterLink, LinkProps as ReactRouterLinkProps } from "react-router-dom";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
|
export const ButtonVariants = {
|
||||||
|
PRIMARY: "primary",
|
||||||
|
SECONDARY: "secondary",
|
||||||
|
TERTIARY: "tertiary",
|
||||||
|
SIGNAL: "signal",
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const ButtonVariantList = Object.values(ButtonVariants);
|
||||||
|
|
||||||
|
type ButtonVariant = typeof ButtonVariants[keyof typeof ButtonVariants];
|
||||||
|
|
||||||
|
const BASE_BUTTON_CLASSES = classNames(
|
||||||
|
"inline-block whitespace-nowrap rounded border py-2 px-6 text-center font-semibold focus:z-10 focus:outline focus:outline-offset-2 focus:outline-purple-500 disabled:cursor-not-allowed"
|
||||||
|
);
|
||||||
|
const DEFAULT_BUTTON_CLASSES = classNames(
|
||||||
|
"border-gray-200 hover:border-gray-400 active:shadow-inner disabled:hover:border-gray-200 disabled:active:shadow-none"
|
||||||
|
);
|
||||||
|
const PRIMARY_BUTTON_CLASSES = classNames(
|
||||||
|
"border-transparent bg-primary text-primary-contrast hover:bg-primary-hover active:bg-primary-active disabled:bg-primary-disabled disabled:text-primary-disabled-contrast "
|
||||||
|
);
|
||||||
|
const SECONDARY_BUTTON_CLASSES = classNames(
|
||||||
|
"border-primary text-primary hover:border-primary-hover hover:text-primary-hover active:border-primary-active active:text-primary-active disabled:border-primary-disabled disabled:text-primary-disabled"
|
||||||
|
);
|
||||||
|
const TERTIARY_BUTTON_CLASSES = classNames(
|
||||||
|
"border-transparent text-primary hover:text-primary-hover active:text-primary-active disabled:text-primary-disabled"
|
||||||
|
);
|
||||||
|
const SIGNAL_BUTTON_CLASSES = classNames(
|
||||||
|
"border-transparent bg-signal text-signal-contrast hover:bg-signal-hover hover:text-signal-hover-contrast active:bg-signal-active active:text-signal-active-contrast disabled:bg-signal-disabled disabled:text-signal-disabled-contrast"
|
||||||
|
);
|
||||||
|
|
||||||
|
const createButtonClasses = (variant?: ButtonVariant) =>
|
||||||
|
classNames(BASE_BUTTON_CLASSES, {
|
||||||
|
[DEFAULT_BUTTON_CLASSES]: !variant,
|
||||||
|
[PRIMARY_BUTTON_CLASSES]: variant === "primary",
|
||||||
|
[SECONDARY_BUTTON_CLASSES]: variant === "secondary",
|
||||||
|
[TERTIARY_BUTTON_CLASSES]: variant === "tertiary",
|
||||||
|
[SIGNAL_BUTTON_CLASSES]: variant === "signal",
|
||||||
|
});
|
||||||
|
|
||||||
|
type BaseButtonProps = {
|
||||||
|
variant: ButtonVariant;
|
||||||
|
};
|
||||||
|
|
||||||
|
type ButtonProps = BaseButtonProps & ButtonHTMLAttributes<HTMLButtonElement>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Styled html button
|
||||||
|
*/
|
||||||
|
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
|
({ className, variant, children, ...props }, ref) => (
|
||||||
|
<button {...props} className={classNames(createButtonClasses(variant), className)} ref={ref}>
|
||||||
|
{children}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
type LinkButtonProps = BaseButtonProps & ReactRouterLinkProps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Styled react router link
|
||||||
|
*/
|
||||||
|
export const LinkButton = React.forwardRef<HTMLAnchorElement, LinkButtonProps>(
|
||||||
|
({ className, variant, children, ...props }, ref) => (
|
||||||
|
<ReactRouterLink {...props} className={classNames(createButtonClasses(variant), className)} ref={ref}>
|
||||||
|
{children}
|
||||||
|
</ReactRouterLink>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
type ExternalLinkButtonProps = BaseButtonProps & AnchorHTMLAttributes<HTMLAnchorElement>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Styled html anchor
|
||||||
|
*/
|
||||||
|
export const ExternalLinkButton = React.forwardRef<HTMLAnchorElement, ExternalLinkButtonProps>(
|
||||||
|
({ className, variant, children, ...props }, ref) => (
|
||||||
|
<a {...props} className={classNames(createButtonClasses(variant), className)} ref={ref}>
|
||||||
|
{children}
|
||||||
|
</a>
|
||||||
|
)
|
||||||
|
);
|
||||||
33
scm-ui/ui-buttons/src/image-snapshot.test.ts
Normal file
33
scm-ui/ui-buttons/src/image-snapshot.test.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
import path from "path";
|
||||||
|
import initStoryshots from "@storybook/addon-storyshots";
|
||||||
|
import { imageSnapshot } from "@storybook/addon-storyshots-puppeteer";
|
||||||
|
|
||||||
|
initStoryshots({
|
||||||
|
suite: "Image snapshots",
|
||||||
|
test: imageSnapshot({
|
||||||
|
storybookUrl: `file://${path.resolve(__dirname, "../storybook-static")}`,
|
||||||
|
})
|
||||||
|
});
|
||||||
26
scm-ui/ui-buttons/src/index.css
Normal file
26
scm-ui/ui-buttons/src/index.css
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
27
scm-ui/ui-buttons/src/index.ts
Normal file
27
scm-ui/ui-buttons/src/index.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import "./index.css";
|
||||||
|
|
||||||
|
export { Button, LinkButton, ExternalLinkButton, ButtonVariants } from "./button";
|
||||||
34
scm-ui/ui-buttons/tailwind.config.js
Normal file
34
scm-ui/ui-buttons/tailwind.config.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
// eslint-disable-next-line global-require,import/no-extraneous-dependencies
|
||||||
|
require("@scm-manager/ui-styles/src/tailwind.config.preset"),
|
||||||
|
],
|
||||||
|
content: [path.join(__dirname, "src/**/*.tsx")],
|
||||||
|
important: true,
|
||||||
|
};
|
||||||
7
scm-ui/ui-buttons/tsconfig.json
Normal file
7
scm-ui/ui-buttons/tsconfig.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"extends": "@scm-manager/tsconfig",
|
||||||
|
"include": [
|
||||||
|
"./src",
|
||||||
|
"./docs"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/prettier-config": "^2.10.1",
|
"@scm-manager/prettier-config": "^2.10.1",
|
||||||
"@scm-manager/tsconfig": "^2.13.0",
|
"@scm-manager/tsconfig": "^2.13.0",
|
||||||
@@ -109,4 +109,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,10 @@
|
|||||||
*/
|
*/
|
||||||
import React, { FC, useState } from "react";
|
import React, { FC, useState } from "react";
|
||||||
import { useHistory, useLocation } from "react-router-dom";
|
import { useHistory, useLocation } from "react-router-dom";
|
||||||
import classNames from "classnames";
|
import { urls } from "./index";
|
||||||
import { Button, urls } from "./index";
|
|
||||||
import { FilterInput, Select } from "./forms";
|
import { FilterInput, Select } from "./forms";
|
||||||
|
import { ButtonVariants, LinkButton } from "@scm-manager/ui-buttons";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
showCreateButton: boolean;
|
showCreateButton: boolean;
|
||||||
@@ -54,7 +55,7 @@ const OverviewPageActions: FC<Props> = ({
|
|||||||
label,
|
label,
|
||||||
testId,
|
testId,
|
||||||
searchPlaceholder,
|
searchPlaceholder,
|
||||||
groupAriaLabelledby
|
groupAriaLabelledby,
|
||||||
}) => {
|
}) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -66,7 +67,7 @@ const OverviewPageActions: FC<Props> = ({
|
|||||||
<Select
|
<Select
|
||||||
ariaLabelledby={groupAriaLabelledby}
|
ariaLabelledby={groupAriaLabelledby}
|
||||||
className="is-fullwidth"
|
className="is-fullwidth"
|
||||||
options={groups.map(g => ({ value: g, label: g }))}
|
options={groups.map((g) => ({ value: g, label: g }))}
|
||||||
value={currentGroup}
|
value={currentGroup}
|
||||||
onChange={groupSelected}
|
onChange={groupSelected}
|
||||||
/>
|
/>
|
||||||
@@ -76,8 +77,10 @@ const OverviewPageActions: FC<Props> = ({
|
|||||||
const renderCreateButton = () => {
|
const renderCreateButton = () => {
|
||||||
if (showCreateButton) {
|
if (showCreateButton) {
|
||||||
return (
|
return (
|
||||||
<div className={classNames("input-button", "control", "column")}>
|
<div className={classNames("control", "column")}>
|
||||||
<Button label={label} link={createLink || `${link}create/`} color="primary" />
|
<LinkButton variant={ButtonVariants.PRIMARY} to={createLink || `${link}create/`}>
|
||||||
|
{label}
|
||||||
|
</LinkButton>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,6 @@ import Button from "../buttons/Button";
|
|||||||
import { MemoryRouter } from "react-router-dom";
|
import { MemoryRouter } from "react-router-dom";
|
||||||
import { useForm } from "react-hook-form";
|
import { useForm } from "react-hook-form";
|
||||||
import { SubmitButton } from "../buttons";
|
import { SubmitButton } from "../buttons";
|
||||||
import { Person } from "@scm-manager/ui-types";
|
|
||||||
|
|
||||||
const Decorator = styled.div`
|
const Decorator = styled.div`
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
@@ -74,9 +73,9 @@ const ReactHookForm: FC = () => {
|
|||||||
handleSubmit,
|
handleSubmit,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
} = useForm<Name>();
|
} = useForm<Name>();
|
||||||
const [stored, setStored] = useState<Person>();
|
const [stored, setStored] = useState<Name>();
|
||||||
|
|
||||||
const onSubmit = (person: Person) => {
|
const onSubmit = (person: Name) => {
|
||||||
setStored(person);
|
setStored(person);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
import { nameRegex } from "../validation";
|
import { nameRegex } from "../validation";
|
||||||
import { TFunction } from "i18next";
|
import { TFunction } from "i18next";
|
||||||
import { AstPlugin } from "./PluginApi";
|
import { AstPlugin } from "./PluginApi";
|
||||||
import { Node, Parent } from "unist";
|
import { Literal, Node, Parent } from "unist";
|
||||||
|
|
||||||
const namePartRegex = nameRegex.source.substring(1, nameRegex.source.length - 1).replace(/\[\^([^\]s]+)\]/, "[^$1\\s]");
|
const namePartRegex = nameRegex.source.substring(1, nameRegex.source.length - 1).replace(/\[\^([^\]s]+)\]/, "[^$1\\s]");
|
||||||
|
|
||||||
@@ -45,11 +45,11 @@ function match(value: string): RegExpMatchArray[] {
|
|||||||
export const createTransformer = (t: TFunction): AstPlugin => {
|
export const createTransformer = (t: TFunction): AstPlugin => {
|
||||||
return ({ visit }) => {
|
return ({ visit }) => {
|
||||||
visit("text", (node: Node, index: number, parent?: Parent) => {
|
visit("text", (node: Node, index: number, parent?: Parent) => {
|
||||||
if (!parent || parent.type === "link" || !node.value) {
|
if (!parent || parent.type === "link" || !(node as Literal).value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let nodeText = node.value as string;
|
let nodeText = (node as Literal).value as string;
|
||||||
const matches = match(nodeText);
|
const matches = match(nodeText);
|
||||||
|
|
||||||
if (matches.length > 0) {
|
if (matches.length > 0) {
|
||||||
@@ -92,7 +92,7 @@ export const createTransformer = (t: TFunction): AstPlugin => {
|
|||||||
parent.children[index] = {
|
parent.children[index] = {
|
||||||
type: "text",
|
type: "text",
|
||||||
children,
|
children,
|
||||||
};
|
} as Node;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { AstPlugin } from "./PluginApi";
|
import { AstPlugin } from "./PluginApi";
|
||||||
import { Node, Parent } from "unist";
|
import { Literal, Node, Parent } from "unist";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Some existing remark plugins (e.g. changesetShortLinkParser or the plugin for issue tracker links) create
|
* Some existing remark plugins (e.g. changesetShortLinkParser or the plugin for issue tracker links) create
|
||||||
@@ -54,8 +54,8 @@ import { Node, Parent } from "unist";
|
|||||||
export const createTransformer = (): AstPlugin => {
|
export const createTransformer = (): AstPlugin => {
|
||||||
return ({ visit }) => {
|
return ({ visit }) => {
|
||||||
visit("text", (node: Node, index: number, parent?: Parent) => {
|
visit("text", (node: Node, index: number, parent?: Parent) => {
|
||||||
if (node.value === undefined && Array.isArray(node.children) && node.children.length > 0) {
|
if ((node as Literal).value === undefined && Array.isArray((node as Parent).children) && (node as Parent).children.length > 0) {
|
||||||
const children = node.children;
|
const children = (node as Parent).children;
|
||||||
const preChildren = parent?.children.slice(0, index) || [];
|
const preChildren = parent?.children.slice(0, index) || [];
|
||||||
const postChildren = parent?.children.slice(index + 1) || [];
|
const postChildren = parent?.children.slice(index + 1) || [];
|
||||||
parent!.children = [...preChildren, ...children, ...postChildren];
|
parent!.children = [...preChildren, ...children, ...postChildren];
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ const Table: FC<Props> = ({ data, sortable, children, emptyMessage, className })
|
|||||||
|
|
||||||
const sortFunctions: Comparator | undefined[] = [];
|
const sortFunctions: Comparator | undefined[] = [];
|
||||||
React.Children.forEach(children, (child, index) => {
|
React.Children.forEach(children, (child, index) => {
|
||||||
if (child && isSortable(child)) {
|
if (child && isSortable(child as ReactElement)) {
|
||||||
sortFunctions.push(child.props.createComparator(child.props, index));
|
sortFunctions.push((child as ReactElement).props.createComparator((child as ReactElement).props, index));
|
||||||
} else {
|
} else {
|
||||||
sortFunctions.push(undefined);
|
sortFunctions.push(undefined);
|
||||||
}
|
}
|
||||||
@@ -61,9 +61,9 @@ const Table: FC<Props> = ({ data, sortable, children, emptyMessage, className })
|
|||||||
return (
|
return (
|
||||||
<tr key={rowIndex}>
|
<tr key={rowIndex}>
|
||||||
{React.Children.map(children, (child, columnIndex) => {
|
{React.Children.map(children, (child, columnIndex) => {
|
||||||
const { className: columnClassName, ...childProperties } = child.props;
|
const { className: columnClassName, ...childProperties } = (child as ReactElement).props;
|
||||||
return (
|
return (
|
||||||
<td className={columnClassName}>{React.cloneElement(child, { ...childProperties, columnIndex, row })}</td>
|
<td className={columnClassName}>{React.cloneElement((child as ReactElement), { ...childProperties, columnIndex, row })}</td>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</tr>
|
</tr>
|
||||||
@@ -112,14 +112,14 @@ const Table: FC<Props> = ({ data, sortable, children, emptyMessage, className })
|
|||||||
<tr>
|
<tr>
|
||||||
{React.Children.map(children, (child, index) => (
|
{React.Children.map(children, (child, index) => (
|
||||||
<th
|
<th
|
||||||
className={isSortable(child) && "is-clickable"}
|
className={isSortable((child as ReactElement)) && "is-clickable"}
|
||||||
onClick={isSortable(child) ? () => tableSort(index) : undefined}
|
onClick={isSortable((child as ReactElement)) ? () => tableSort(index) : undefined}
|
||||||
onMouseEnter={() => setHoveredColumnIndex(index)}
|
onMouseEnter={() => setHoveredColumnIndex(index)}
|
||||||
onMouseLeave={() => setHoveredColumnIndex(undefined)}
|
onMouseLeave={() => setHoveredColumnIndex(undefined)}
|
||||||
key={index}
|
key={index}
|
||||||
>
|
>
|
||||||
{child.props.header}
|
{(child as ReactElement).props.header}
|
||||||
{isSortable(child) && renderSortIcon(child, ascending, shouldShowIcon(index))}
|
{isSortable((child as ReactElement)) && renderSortIcon((child as ReactElement), ascending, shouldShowIcon(index))}
|
||||||
</th>
|
</th>
|
||||||
))}
|
))}
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/prettier-config": "^2.10.1",
|
"@scm-manager/prettier-config": "^2.10.1",
|
||||||
"@scm-manager/tsconfig": "^2.13.0",
|
"@scm-manager/tsconfig": "^2.13.0",
|
||||||
@@ -46,4 +46,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/prettier-config": "^2.10.1",
|
"@scm-manager/prettier-config": "^2.10.1",
|
||||||
"@types/react": "^17.0.1",
|
"@types/react": "^17.0.1",
|
||||||
@@ -43,4 +43,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/prettier-config": "^2.10.1",
|
"@scm-manager/prettier-config": "^2.10.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"tsup": "^5.12.6"
|
"tsup": "^5.12.6"
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
@@ -36,4 +36,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/plugin-scripts": "^1.2.2",
|
"@scm-manager/plugin-scripts": "^1.2.2",
|
||||||
"@scm-manager/prettier-config": "^2.10.1",
|
"@scm-manager/prettier-config": "^2.10.1",
|
||||||
@@ -43,4 +43,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"ui-scripts": "./bin/ui-scripts.js"
|
"ui-scripts": "./bin/ui-scripts.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@scm-manager/ui-styles": "2.37.3-SNAPSHOT",
|
||||||
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.5",
|
||||||
"babel-loader": "^8.2.3",
|
"babel-loader": "^8.2.3",
|
||||||
"css-loader": "^6.5.0",
|
"css-loader": "^6.5.0",
|
||||||
@@ -24,11 +25,15 @@
|
|||||||
"style-loader": "^3.3.1",
|
"style-loader": "^3.3.1",
|
||||||
"webpack": "^5.60.0",
|
"webpack": "^5.60.0",
|
||||||
"webpack-cli": "^4.9.1",
|
"webpack-cli": "^4.9.1",
|
||||||
"webpack-dev-server": "^4.4.0"
|
"webpack-dev-server": "^4.4.0",
|
||||||
|
"tailwindcss": "^3.0.23",
|
||||||
|
"postcss": "^8.4.12",
|
||||||
|
"postcss-loader": "^6.2.1",
|
||||||
|
"autoprefixer": "^10.4.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/prettier-config": "^2.10.1",
|
"@scm-manager/prettier-config": "^2.10.1",
|
||||||
"webpack-bundle-analyzer": "^4.5.0"
|
"webpack-bundle-analyzer": "^4.5.0"
|
||||||
},
|
},
|
||||||
@@ -41,4 +46,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
41
scm-ui/ui-scripts/src/tailwind.config.js
Normal file
41
scm-ui/ui-scripts/src/tailwind.config.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const root = path.resolve(process.cwd(), "scm-ui");
|
||||||
|
|
||||||
|
const sizes = [0, 1, 2, 3, 4, 5, 6, "auto"];
|
||||||
|
const helpers = ["m", "p"];
|
||||||
|
const variants = ["", "x", "y", "t", "r", "l", "b"];
|
||||||
|
const bulmaHelpers = helpers
|
||||||
|
.map((helper) => sizes.map((size) => variants.map((variant) => `${helper}${variant}-${size}`)))
|
||||||
|
.flat(3);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
// eslint-disable-next-line global-require
|
||||||
|
presets: [require("@scm-manager/ui-styles/src/tailwind.config.preset")],
|
||||||
|
content: [path.join(root, "ui-webapp", "src", "**", "*.tsx")],
|
||||||
|
safelist: bulmaHelpers,
|
||||||
|
};
|
||||||
27
scm-ui/ui-scripts/src/tailwind.css
Normal file
27
scm-ui/ui-scripts/src/tailwind.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
@@ -33,7 +33,13 @@ const isDevelopment = process.env.NODE_ENV === "development";
|
|||||||
const root = path.resolve(process.cwd(), "..");
|
const root = path.resolve(process.cwd(), "..");
|
||||||
|
|
||||||
const babelPlugins = [];
|
const babelPlugins = [];
|
||||||
const webpackPlugins = [];
|
const webpackPlugins = [
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
|
filename: "webapp.tailwind.css",
|
||||||
|
chunkFilename: "webapp.tailwind.css",
|
||||||
|
ignoreOrder: false,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
if (process.env.ANALYZE_BUNDLES === "true") {
|
if (process.env.ANALYZE_BUNDLES === "true") {
|
||||||
// it is ok to use require here, because we want to load the package conditionally
|
// it is ok to use require here, because we want to load the package conditionally
|
||||||
@@ -82,6 +88,7 @@ module.exports = [
|
|||||||
// enable async/await
|
// enable async/await
|
||||||
"regenerator-runtime/runtime",
|
"regenerator-runtime/runtime",
|
||||||
"./ui-webapp/src/index.tsx",
|
"./ui-webapp/src/index.tsx",
|
||||||
|
"./ui-scripts/src/tailwind.css",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
devtool: "eval-cheap-module-source-map",
|
devtool: "eval-cheap-module-source-map",
|
||||||
@@ -101,8 +108,40 @@ module.exports = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
test: /tailwind\.css$/i,
|
||||||
|
exclude: /node_modules/,
|
||||||
|
use: [
|
||||||
|
{
|
||||||
|
loader: MiniCssExtractPlugin.loader,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: "css-loader",
|
||||||
|
options: {
|
||||||
|
importLoaders: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: "postcss-loader",
|
||||||
|
options: {
|
||||||
|
postcssOptions: {
|
||||||
|
plugins: [
|
||||||
|
[
|
||||||
|
"tailwindcss",
|
||||||
|
{
|
||||||
|
config: path.join(root, "ui-scripts", "src", "tailwind.config.js"),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
["autoprefixer", {}],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /\.(css|scss|sass)$/i,
|
test: /\.(css|scss|sass)$/i,
|
||||||
|
exclude: /tailwind\.css$/i,
|
||||||
use: [
|
use: [
|
||||||
// Creates `style` nodes from JS strings
|
// Creates `style` nodes from JS strings
|
||||||
"style-loader",
|
"style-loader",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"react-diff-view": "^2.4.10"
|
"react-diff-view": "^2.4.10"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/prettier-config": "^2.11.1",
|
"@scm-manager/prettier-config": "^2.11.1",
|
||||||
"css-loader": "^6.5.0",
|
"css-loader": "^6.5.0",
|
||||||
"html-webpack-plugin": "^5.5.0",
|
"html-webpack-plugin": "^5.5.0",
|
||||||
@@ -31,4 +31,4 @@
|
|||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "@scm-manager/eslint-config"
|
"extends": "@scm-manager/eslint-config"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,6 +229,23 @@ $danger-25: scale-color($danger, $lightness: -75%);
|
|||||||
--diff-code-delete-edit-background-color: #{desaturate(#000, 20%)};
|
--diff-code-delete-edit-background-color: #{desaturate(#000, 20%)};
|
||||||
--diff-code-selected-background-color: #{desaturate(#fffce0, 20%)};
|
--diff-code-selected-background-color: #{desaturate(#fffce0, 20%)};
|
||||||
--diff-omit-gutter-line-color: #cb2a1d;
|
--diff-omit-gutter-line-color: #cb2a1d;
|
||||||
|
|
||||||
|
// Tailwind
|
||||||
|
--scm-primary-contrast-color: #{lighten($text-strong, 2.5%)};
|
||||||
|
--scm-primary-hover-color: #{darken($primary, 5%)};
|
||||||
|
--scm-primary-hover-contrast-color: #{lighten($text-strong, 2.5%)};
|
||||||
|
--scm-primary-active-color: #{darken($primary, 10%)};
|
||||||
|
--scm-primary-active-contrast-color: #{lighten($text-strong, 2.5%)};
|
||||||
|
--scm-primary-disabled-color: #{rgba($primary, 0.5)};
|
||||||
|
--scm-primary-disabled-contrast-color: #{rgba(lighten($text-strong, 2.5%), 0.5)};
|
||||||
|
|
||||||
|
--scm-warning-contrast-color: #88550D;
|
||||||
|
--scm-warning-hover-contrast-color: #{rgba(0,0,0,0.7)};
|
||||||
|
--scm-warning-hover-color: #{darken($warning, 10%)};
|
||||||
|
--scm-warning-active-color: #{darken($warning, 20%)};
|
||||||
|
--scm-warning-active-contrast-color: #{rgba(0,0,0,0.7)};
|
||||||
|
--scm-warning-disabled-color: #{rgba($warning, 0.5)};
|
||||||
|
--scm-warning-disabled-contrast-color: #{rgba(0,0,0,0.7)};
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-list {
|
.menu-list {
|
||||||
|
|||||||
@@ -127,6 +127,23 @@ $tooltip-color: $scheme-main;
|
|||||||
--diff-code-delete-edit-background-color: #000;
|
--diff-code-delete-edit-background-color: #000;
|
||||||
--diff-code-selected-background-color: #fffce0;
|
--diff-code-selected-background-color: #fffce0;
|
||||||
--diff-omit-gutter-line-color: #cb2a1d;
|
--diff-omit-gutter-line-color: #cb2a1d;
|
||||||
|
|
||||||
|
// Tailwind
|
||||||
|
--scm-primary-contrast-color: #{$black-ter};
|
||||||
|
--scm-primary-hover-color: #{darken($primary, 5%)};
|
||||||
|
--scm-primary-hover-contrast-color: #{$black-ter};
|
||||||
|
--scm-primary-active-color: #{darken($primary, 10%)};
|
||||||
|
--scm-primary-active-contrast-color: #{$black-ter};
|
||||||
|
--scm-primary-disabled-color: #006970;
|
||||||
|
--scm-primary-disabled-contrast-color: #{$black-ter};
|
||||||
|
|
||||||
|
--scm-warning-contrast-color: #{rgba(0,0,0,0.7)};
|
||||||
|
--scm-warning-hover-contrast-color: #{rgba(0,0,0,0.7)};
|
||||||
|
--scm-warning-hover-color: #{darken($warning, 5%)};
|
||||||
|
--scm-warning-active-color: #{darken($warning, 10%)};
|
||||||
|
--scm-warning-active-contrast-color: #{rgba(0,0,0,0.7)};
|
||||||
|
--scm-warning-disabled-color: #{darken($warning, 50%)};
|
||||||
|
--scm-warning-disabled-contrast-color: #{rgba(0,0,0,0.7)};
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
|
|||||||
@@ -78,6 +78,23 @@ $popover-background-color: $grey-light;
|
|||||||
--sh-selected-color: #{$warning-25};
|
--sh-selected-color: #{$warning-25};
|
||||||
--sh-highlight-background: #f5f5f5;
|
--sh-highlight-background: #f5f5f5;
|
||||||
--sh-highlight-accent: #99d8f3;
|
--sh-highlight-accent: #99d8f3;
|
||||||
|
|
||||||
|
// Tailwind
|
||||||
|
--scm-primary-contrast-color: #{$white};
|
||||||
|
--scm-primary-hover-color: #{darken($primary, 10%)};
|
||||||
|
--scm-primary-hover-contrast-color: #{$white};
|
||||||
|
--scm-primary-active-color: #{darken($primary, 20%)};
|
||||||
|
--scm-primary-active-contrast-color: #{$white};
|
||||||
|
--scm-primary-disabled-color: #bff3f7;
|
||||||
|
--scm-primary-disabled-contrast-color: #{$white};
|
||||||
|
|
||||||
|
--scm-warning-contrast-color: #88550D;
|
||||||
|
--scm-warning-hover-contrast-color: #{rgba(0,0,0,0.7)};
|
||||||
|
--scm-warning-hover-color: #{darken($warning, 10%)};
|
||||||
|
--scm-warning-active-color: #{darken($warning, 20%)};
|
||||||
|
--scm-warning-active-contrast-color: #{rgba(0,0,0,0.7)};
|
||||||
|
--scm-warning-disabled-color: #fff6d5;
|
||||||
|
--scm-warning-disabled-contrast-color: #e1d4c2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
|
|||||||
55
scm-ui/ui-styles/src/tailwind.config.preset.js
Normal file
55
scm-ui/ui-styles/src/tailwind.config.preset.js
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
module.exports = {
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
primary: {
|
||||||
|
DEFAULT: "var(--scm-primary-color)",
|
||||||
|
contrast: "var(--scm-primary-contrast-color)",
|
||||||
|
hover: "var(--scm-primary-hover-color)",
|
||||||
|
"hover-contrast": "var(--scm-primary-hover-contrast-color)",
|
||||||
|
active: "var(--scm-primary-active-color)",
|
||||||
|
"active-contrast": "var(--scm-primary-active-contrast-color)",
|
||||||
|
disabled: "var(--scm-primary-disabled-color)",
|
||||||
|
"disabled-contrast": "var(--scm-primary-disabled-contrast-color)",
|
||||||
|
},
|
||||||
|
signal: {
|
||||||
|
DEFAULT: "var(--scm-warning-color)",
|
||||||
|
contrast: "var(--scm-warning-contrast-color)",
|
||||||
|
hover: "var(--scm-warning-hover-color)",
|
||||||
|
"hover-contrast": "var(--scm-warning-hover-contrast-color)",
|
||||||
|
active: "var(--scm-warning-active-color)",
|
||||||
|
"active-contrast": "var(--scm-warning-active-contrast-color)",
|
||||||
|
disabled: "var(--scm-warning-disabled-color)",
|
||||||
|
"disabled-contrast": "var(--scm-warning-disabled-contrast-color)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
important: true,
|
||||||
|
corePlugins: {
|
||||||
|
preflight: false,
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -21,7 +21,21 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
@import "bulma/bulma";
|
@import "bulma/sass/utilities/_all";
|
||||||
|
@import "bulma/sass/base/_all";
|
||||||
|
@import "bulma/sass/elements/_all";
|
||||||
|
@import "bulma/sass/form/_all";
|
||||||
|
@import "bulma/sass/components/_all";
|
||||||
|
@import "bulma/sass/grid/_all";
|
||||||
|
@import "bulma/sass/helpers/color";
|
||||||
|
@import "bulma/sass/helpers/flexbox";
|
||||||
|
@import "bulma/sass/helpers/float";
|
||||||
|
@import "bulma/sass/helpers/other";
|
||||||
|
@import "bulma/sass/helpers/overflow";
|
||||||
|
@import "bulma/sass/helpers/position";
|
||||||
|
@import "bulma/sass/helpers/typography";
|
||||||
|
@import "bulma/sass/helpers/visibility";
|
||||||
|
@import "bulma/sass/layout/_all";
|
||||||
@import "../variables/_derived.scss";
|
@import "../variables/_derived.scss";
|
||||||
@import "bulma-popover/css/bulma-popover";
|
@import "bulma-popover/css/bulma-popover";
|
||||||
@import "../components/_main.scss";
|
@import "../components/_main.scss";
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/prettier-config": "^2.10.1",
|
"@scm-manager/prettier-config": "^2.10.1",
|
||||||
"@scm-manager/tsconfig": "^2.13.0",
|
"@scm-manager/tsconfig": "^2.13.0",
|
||||||
@@ -54,4 +54,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "restricted"
|
"access": "restricted"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import type {
|
|||||||
TokenizeSuccessResponse,
|
TokenizeSuccessResponse,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import { isRefractorElement } from "../types";
|
import { isRefractorElement } from "../types";
|
||||||
|
import type { RefractorElement } from "refractor";
|
||||||
|
|
||||||
// the WorkerGlobalScope is assigned to self
|
// the WorkerGlobalScope is assigned to self
|
||||||
// see https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/self
|
// see https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/self
|
||||||
@@ -91,7 +92,7 @@ const countChildrenAndApplyMarkers = (node: RefractorNode, markedTexts?: string[
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (newChildren.length > 0) {
|
if (newChildren.length > 0) {
|
||||||
const el = node as RefractorNode;
|
const el = node as unknown as RefractorElement;
|
||||||
el.type = "element";
|
el.type = "element";
|
||||||
el.tagName = "span";
|
el.tagName = "span";
|
||||||
el.children = newChildren;
|
el.children = newChildren;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/babel-preset": "^2.13.1",
|
"@scm-manager/babel-preset": "^2.13.1",
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/prettier-config": "^2.10.1",
|
"@scm-manager/prettier-config": "^2.10.1",
|
||||||
"@scm-manager/tsconfig": "^2.13.0",
|
"@scm-manager/tsconfig": "^2.13.0",
|
||||||
@@ -51,4 +51,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "restricted"
|
"access": "restricted"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"lint": "eslint src"
|
"lint": "eslint src"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/tsconfig": "^2.13.0"
|
"@scm-manager/tsconfig": "^2.13.0"
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
@@ -30,4 +30,4 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
"@scm-manager/ui-modules": "2.37.3-SNAPSHOT",
|
"@scm-manager/ui-modules": "2.37.3-SNAPSHOT",
|
||||||
"@scm-manager/ui-syntaxhighlighting": "2.37.3-SNAPSHOT",
|
"@scm-manager/ui-syntaxhighlighting": "2.37.3-SNAPSHOT",
|
||||||
"@scm-manager/ui-text": "2.37.3-SNAPSHOT",
|
"@scm-manager/ui-text": "2.37.3-SNAPSHOT",
|
||||||
|
"@scm-manager/ui-buttons": "2.37.3-SNAPSHOT",
|
||||||
"@scm-manager/ui-legacy": "2.37.3-SNAPSHOT",
|
"@scm-manager/ui-legacy": "2.37.3-SNAPSHOT",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"history": "^4.10.1",
|
"history": "^4.10.1",
|
||||||
@@ -35,7 +36,7 @@
|
|||||||
"build": "webpack-cli --mode=production --config=../ui-scripts/src/webpack.config.js"
|
"build": "webpack-cli --mode=production --config=../ui-scripts/src/webpack.config.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@scm-manager/eslint-config": "^2.15.1",
|
"@scm-manager/eslint-config": "^2.16.0",
|
||||||
"@scm-manager/jest-preset": "^2.13.0",
|
"@scm-manager/jest-preset": "^2.13.0",
|
||||||
"@scm-manager/ui-tests": "2.37.3-SNAPSHOT",
|
"@scm-manager/ui-tests": "2.37.3-SNAPSHOT",
|
||||||
"@testing-library/react": "^12.1.5",
|
"@testing-library/react": "^12.1.5",
|
||||||
@@ -49,7 +50,8 @@
|
|||||||
"@types/styled-components": "^5.1.25",
|
"@types/styled-components": "^5.1.25",
|
||||||
"@types/systemjs": "^0.20.6",
|
"@types/systemjs": "^0.20.6",
|
||||||
"fetch-mock": "^7.5.1",
|
"fetch-mock": "^7.5.1",
|
||||||
"react-test-renderer": "^17.0.1"
|
"react-test-renderer": "^17.0.1",
|
||||||
|
"tailwindcss": "^3.0.23"
|
||||||
},
|
},
|
||||||
"babel": {
|
"babel": {
|
||||||
"presets": [
|
"presets": [
|
||||||
@@ -66,4 +68,5 @@
|
|||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
}
|
}
|
||||||
document.head.appendChild(linkElement);
|
document.head.appendChild(linkElement);
|
||||||
</script>
|
</script>
|
||||||
|
<link rel="stylesheet" href="{{ contextPath }}/styles.bundle.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<noscript>
|
||||||
|
|||||||
@@ -37,6 +37,9 @@ import ChangesetShortLink from "./repos/components/changesets/ChangesetShortLink
|
|||||||
import "./tokenExpired";
|
import "./tokenExpired";
|
||||||
import { ApiProvider } from "@scm-manager/ui-api";
|
import { ApiProvider } from "@scm-manager/ui-api";
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-restricted-imports
|
||||||
|
import "@scm-manager/ui-buttons/build/index.css";
|
||||||
|
|
||||||
binder.bind<extensionPoints.ChangesetDescriptionTokens>("changeset.description.tokens", ChangesetShortLink);
|
binder.bind<extensionPoints.ChangesetDescriptionTokens>("changeset.description.tokens", ChangesetShortLink);
|
||||||
|
|
||||||
const root = document.getElementById("root");
|
const root = document.getElementById("root");
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ com.cloudogu.legman.support:micrometer:2.0.0=compileClasspath,compileClasspathCo
|
|||||||
com.cloudogu.legman.support:shiro:2.0.0=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.cloudogu.legman.support:shiro:2.0.0=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.cloudogu.legman:core:2.0.0=annotationProcessor,annotationProcessorCopy,compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.cloudogu.legman:core:2.0.0=annotationProcessor,annotationProcessorCopy,compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.cloudogu.spotter:spotter-core:4.0.0=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.cloudogu.spotter:spotter-core:4.0.0=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.cronutils:cron-utils:9.1.6=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.cronutils:cron-utils:9.1.6=default
|
||||||
|
com.cronutils:cron-utils:9.1.8=compileClasspath,compileClasspathCopy,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.damnhandy:handy-uri-templates:2.1.7=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
com.damnhandy:handy-uri-templates:2.1.7=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
com.fasterxml.jackson.core:jackson-annotations:2.12.1=swaggerDeps,swaggerDepsCopy
|
com.fasterxml.jackson.core:jackson-annotations:2.12.1=swaggerDeps,swaggerDepsCopy
|
||||||
com.fasterxml.jackson.core:jackson-annotations:2.12.3=default
|
com.fasterxml.jackson.core:jackson-annotations:2.12.3=default
|
||||||
@@ -146,7 +147,8 @@ org.checkerframework:checker-qual:3.5.0=annotationProcessor,annotationProcessorC
|
|||||||
org.eclipse.microprofile.config:microprofile-config-api:2.0=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.eclipse.microprofile.config:microprofile-config-api:2.0=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.glassfish.jaxb:jaxb-runtime:2.3.3=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.glassfish.jaxb:jaxb-runtime:2.3.3=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.glassfish.jaxb:txw2:2.3.3=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.glassfish.jaxb:txw2:2.3.3=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.glassfish:javax.el:3.0.1-b11=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.glassfish:jakarta.el:3.0.4=compileClasspath,compileClasspathCopy,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
|
org.glassfish:javax.el:3.0.1-b11=default,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.hamcrest:hamcrest-core:2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.hamcrest:hamcrest-core:2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.hamcrest:hamcrest-library:2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.hamcrest:hamcrest-library:2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.hamcrest:hamcrest:2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.hamcrest:hamcrest:2.1=testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
@@ -156,8 +158,8 @@ org.jacoco:org.jacoco.agent:0.8.7=jacocoAgentCopy,jacocoAntCopy
|
|||||||
org.jacoco:org.jacoco.ant:0.8.7=jacocoAntCopy
|
org.jacoco:org.jacoco.ant:0.8.7=jacocoAntCopy
|
||||||
org.jacoco:org.jacoco.core:0.8.7=jacocoAntCopy
|
org.jacoco:org.jacoco.core:0.8.7=jacocoAntCopy
|
||||||
org.jacoco:org.jacoco.report:0.8.7=jacocoAntCopy
|
org.jacoco:org.jacoco.report:0.8.7=jacocoAntCopy
|
||||||
org.javassist:javassist:3.25.0-GA=swaggerDeps,swaggerDepsCopy
|
org.javassist:javassist:3.25.0-GA=compileClasspath,compileClasspathCopy,swaggerDeps,swaggerDepsCopy
|
||||||
org.javassist:javassist:3.27.0-GA=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.javassist:javassist:3.27.0-GA=default
|
||||||
org.jboss.logging:jboss-logging:3.4.2.Final=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.jboss.logging:jboss-logging:3.4.2.Final=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.jboss.resteasy:resteasy-client-api:4.7.5.Final=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.jboss.resteasy:resteasy-client-api:4.7.5.Final=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
org.jboss.resteasy:resteasy-client:4.7.5.Final=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
org.jboss.resteasy:resteasy-client:4.7.5.Final=compileClasspath,compileClasspathCopy,default,defaultCopy,runtimeClasspath,runtimeClasspathCopy,testCompileClasspath,testCompileClasspathCopy,testRuntimeClasspath,testRuntimeClasspathCopy
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import javax.inject.Provider;
|
|||||||
public class PushStateDispatcherProvider implements Provider<PushStateDispatcher> {
|
public class PushStateDispatcherProvider implements Provider<PushStateDispatcher> {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final String PROPERTY_TARGET = "sonia.scm.ui.proxy";
|
public static final String PROPERTY_TARGET = "sonia.scm.ui.proxy";
|
||||||
|
|
||||||
private Provider<TemplatingPushStateDispatcher> templatingPushStateDispatcherProvider;
|
private Provider<TemplatingPushStateDispatcher> templatingPushStateDispatcherProvider;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package sonia.scm.web.tailwind;
|
||||||
|
|
||||||
|
import com.github.sdorra.webresources.CacheControl;
|
||||||
|
import com.github.sdorra.webresources.WebResourceSender;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import sonia.scm.filter.WebElement;
|
||||||
|
import sonia.scm.plugin.PluginLoader;
|
||||||
|
import sonia.scm.plugin.UberWebResourceLoader;
|
||||||
|
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServlet;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import static sonia.scm.PushStateDispatcherProvider.PROPERTY_TARGET;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@WebElement(value = "/styles.bundle.css")
|
||||||
|
public class StylesServlet extends HttpServlet {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(StylesServlet.class);
|
||||||
|
private final UberWebResourceLoader webResourceLoader;
|
||||||
|
private final String target = System.getProperty(PROPERTY_TARGET);
|
||||||
|
|
||||||
|
private final WebResourceSender sender = WebResourceSender.create()
|
||||||
|
.withGZIP()
|
||||||
|
.withGZIPMinLength(512)
|
||||||
|
.withBufferSize(16384)
|
||||||
|
.withCacheControl(CacheControl.create().noCache());
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public StylesServlet(PluginLoader pluginLoader) {
|
||||||
|
this.webResourceLoader = pluginLoader.getUberWebResourceLoader();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
|
try {
|
||||||
|
URL url = webResourceLoader.getResource("/assets/webapp.tailwind.css");
|
||||||
|
if (url != null) {
|
||||||
|
// TODO: Merge css
|
||||||
|
sender.resource(url).get(request, response);
|
||||||
|
} else {
|
||||||
|
getLocally(createProxyUrl("/assets/webapp.tailwind.css"), request, response);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOG.error("Error on getting the tailwind stylesheet", ex);
|
||||||
|
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getLocally(URL url, HttpServletRequest request, HttpServletResponse response) throws IOException {
|
||||||
|
HttpURLConnection connection = openConnection(url);
|
||||||
|
connection.setRequestMethod(request.getMethod());
|
||||||
|
|
||||||
|
int responseCode = connection.getResponseCode();
|
||||||
|
response.setStatus(responseCode);
|
||||||
|
try (InputStream input = getConnectionInput(connection); OutputStream output = response.getOutputStream()) {
|
||||||
|
ByteStreams.copy(input, output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream getConnectionInput(HttpURLConnection connection) throws IOException {
|
||||||
|
if (connection.getErrorStream() != null) {
|
||||||
|
return connection.getErrorStream();
|
||||||
|
}
|
||||||
|
return connection.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
private URL createProxyUrl(String uri) throws MalformedURLException {
|
||||||
|
return new URL(target + uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HttpURLConnection openConnection(URL url) throws IOException {
|
||||||
|
return (HttpURLConnection) url.openConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user