Added missing inventory features
Smaller changes: - Optimized a few SCSS files
This commit is contained in:
Vendored
+1568
-10356
File diff suppressed because it is too large
Load Diff
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-1
File diff suppressed because one or more lines are too long
BIN
Binary file not shown.
+2373
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 275 KiB |
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
+147
@@ -0,0 +1,147 @@
|
||||
# Material icon sprites
|
||||
|
||||
Sprite images allow you to use images more efficiently.
|
||||
Our recommended way to use sprites is to create a single SVG file with the subset of icons needed for the project compiled as symbols.
|
||||
This will keep the file small and allow for the greatest flexibility in referencing each icon.
|
||||
It will also allow you to include any other svgs in the project, like a logo, in a single reference file.
|
||||
|
||||
Note that symbol files must be `<use>`ed or opened in an editor in order to be viewed, while sprite sheets can be opened and previewed directly.
|
||||
|
||||
## Creating your own sprites
|
||||
|
||||
While PNG and SVG icon images can be combined manually in an editor, using a processor to combine them automatically and generate any needed companion files is definitely the most convenient.
|
||||
Here are three good options for creating your own CSS and SVG sprites.
|
||||
|
||||
* [Sprity](https://www.npmjs.com/package/sprity) (previously css-sprite) for PNG sprites with CSS sprite sheets.
|
||||
* [svg-sprite](https://www.npmjs.com/package/svg-sprite) for SVG sprites with CSS sprite sheets.
|
||||
* [svgstore](https://github.com/w0rm/gulp-svgstore) for SVG symbol sprites.
|
||||
|
||||
When creating a project, there are many similar and extended processors that can be for compilers such as gulp.
|
||||
|
||||
## Using the provided sprites
|
||||
|
||||
Material design icons come with CSS sprite sheets and SVG symbol sprites for each category of icon we include.
|
||||
The icon sprites can be found in the `sprites` directory under `css-sprite` for png image sprites and `svg-sprite` for the various svg sprite techniques—including symbols.
|
||||
Symbol sprites in the `svg-sprite` folder have an additional `-symbol` marker after their name.
|
||||
If you are considering using svg sprites, you are encouraged to `<use>` the symbol sprites rather than traditional sprite sheets as they reduce the size of the files and the complexity and redundancy of using them.
|
||||
|
||||
|
||||
## Using SVG symbol sprites
|
||||
|
||||
To add an icon using symbol sprites, you will need to add an svg element that `<use>`es the reference file with a link to the specific icon you want.
|
||||
Since the icons are stored as `<symbol>`s, the viewbox is already set up and can be scaled relatively without needing to keep adjacent symbols in mind. You will only need set the size of the icon using CSS:
|
||||
|
||||
```CSS
|
||||
.svg-24px {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
```
|
||||
|
||||
Then reference the id for the icon you need:
|
||||
|
||||
```HTML
|
||||
<svg class="svg-24px">
|
||||
<use xlink:href="MaterialIcons.svg#ic_face_24px"></use>
|
||||
</svg>
|
||||
```
|
||||
|
||||
The HTML can also be simplified further by targeting all svg tags, and then overriding the size for individual classes and IDs.
|
||||
While you will need to be careful not to let this hamper your layout, this kind of sizing is generally a matter of course.
|
||||
To make 24px the default for `<svg>` tags, add the tag properties in css:
|
||||
|
||||
```CSS
|
||||
svg {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
```
|
||||
|
||||
Then reference the icon:
|
||||
|
||||
```HTML
|
||||
<svg><use xlink:href="MaterialIcons.svg#ic_face_24px"></use></svg>
|
||||
```
|
||||
|
||||
### Stacking symbol sprite icons
|
||||
|
||||
Using symbol sprites, icons can also easily be stacked on top of each other by including them in a single svg `<use>` statement.
|
||||
Each icon can then be referenced using ids and classes and likewise handled using javascript.
|
||||
E.g. To add a blue checkmark on top of a checkbox outline than can then be hidden when needed, first add the fill property in CSS:
|
||||
|
||||
```CSS
|
||||
.svg-24px {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
}
|
||||
.check {
|
||||
fill: blue;
|
||||
}
|
||||
```
|
||||
|
||||
Then add the check after the outline icon together with an id for the SVG tag (for targeting) and the check class for the checkmark:
|
||||
|
||||
```HTML
|
||||
<svg class="svg-24px" id="checkbox-1">
|
||||
<use xlink:href="MaterialIcons.svg#ic_check_box_outline_blank"></use>
|
||||
<use class="check" xlink:href="MaterialIcons.svg#ic_check_box"></use>
|
||||
</svg>
|
||||
|
||||
```
|
||||
|
||||
### External SVG symbols
|
||||
|
||||
The benefits to referencing an external svg come in the form of caching, as the same map file can be reused across the site and on subsequent visits.
|
||||
|
||||
Unfortunately, Internet Explorer, Edge, and older Android and iOS browsers cannot `<use>` external svg files.
|
||||
Besides copying the svg file contents directly into each html file you need them in, there are two good ways to handle this:
|
||||
|
||||
1. Use the [svg4everybody polyfill](https://github.com/jonathantneal/svg4everybody) (this is the preferred method)
|
||||
2. Use a simple AJAX call to include the symbol sprites in the document for all browsers, and then reference the svg directly wherever it is `<use>´d rather than the external file
|
||||
|
||||
### CSS Selectors, Transformation and the Shadow DOM
|
||||
|
||||
For some projects, parts of individual icons may be required to change or animate in some way relative to the icon, rather than as a whole. For example, an icon where the top part flies away or two parts are given separate colors. This is the power given to inline svg, as opposed to a simple image file.
|
||||
|
||||
Browser support for the `<use>` element, however, is still not good enough to properly allow the targeting of its shadow DOM. While not impossible, it can make selecting individual paths on a page very tricky.
|
||||
|
||||
In projects where individual paths need to be targeted, it is best to copy them inline or inject the paths into the html at build or load time, regardless of browser, to prevent issues that may arise due to the shadow DOM nature of the `<use>` element. There are two ways to handle this depending on the project:
|
||||
1. The recommended way to do this is automatically using a build script or with a tool like [gulp-inject](https://github.com/klei/gulp-inject) that can reference individual icons, as that will keep the html files small and prevent having to make an href request.
|
||||
2. If the project is designed to generate all pages dynamically using very few static elements, or none at all, the svg elements can instead be pulled in using javascript ajax calls. In this case, a purely concatenated xml file containing the individual icons required would work better and be easier to target than a symbol map.
|
||||
|
||||
## Using CSS sprite sheets
|
||||
|
||||
To use a CSS sprite sheet, reference the stylesheet for the icon category you wish to use, then include the icon definition in your markup.
|
||||
E.g. using one of the play icons in `css-sprite-av`...
|
||||
|
||||
Reference the stylesheet:
|
||||
|
||||
```html
|
||||
<link href="png/sprite-av-black.css" rel="stylesheet">
|
||||
```
|
||||
|
||||
Create an element which will use the icon as a background, and include that icon as a class.
|
||||
The example class here references the `icon` sprite sheet and specific `icon-ic_play_circle_outline_black_24dp` icon, which you can get from the above stylesheet.
|
||||
|
||||
```html
|
||||
<div class="icon icon-ic_play_circle_outline_black_24dp"></div>
|
||||
```
|
||||
|
||||
That's it! Well, for PNG sprites anyway.
|
||||
|
||||
If you are using svg sprites by referencing `svg/sprite-av-black.css` in this example instead, you will also need to set a dimension for the icon.
|
||||
This can either be done inline or via a generic size class or a specific class such as this one:
|
||||
|
||||
```html
|
||||
<style>
|
||||
.svg-ic_play_circle_outline_black_24dp-dims { width: 24px; height: 24px; }
|
||||
</style>
|
||||
```
|
||||
|
||||
Then, make sure you set the dimension for the specific icon, `svg-ic_play_circle_outline_black_24dp`, which you can get from the svg stylesheet.
|
||||
|
||||
```html
|
||||
<div class="svg-ic_play_circle_outline_black_24dp svg-ic_play_circle_outline_black_24dp-dims"></div>
|
||||
```
|
||||
|
||||
Don't forget to publish the corresponding CSS and SVG/PNG files when deploying your project.
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
@font-face {
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(MaterialIcons-Regular.eot); /* For IE6-8 */
|
||||
src: local('Material Icons'),
|
||||
local('MaterialIcons-Regular'),
|
||||
url(MaterialIcons-Regular.woff2) format('woff2'),
|
||||
url(MaterialIcons-Regular.woff) format('woff'),
|
||||
url(MaterialIcons-Regular.ttf) format('truetype');
|
||||
}
|
||||
|
||||
.material-icons {
|
||||
font-family: 'Material Icons';
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-size: 24px; /* Preferred icon size */
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
text-transform: none;
|
||||
letter-spacing: normal;
|
||||
word-wrap: normal;
|
||||
white-space: nowrap;
|
||||
direction: ltr;
|
||||
|
||||
/* Support for all WebKit browsers. */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
/* Support for Safari and Chrome. */
|
||||
text-rendering: optimizeLegibility;
|
||||
|
||||
/* Support for Firefox. */
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
|
||||
/* Support for IE. */
|
||||
font-feature-settings: 'liga';
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
@include font-face('C5AUI', 'fonts/Cha5App UI/Cha5App-UI', normal, normal, $file-formats: ttf);
|
||||
@include font-face('Material', 'fonts/Material/Material', normal, normal, $file-formats: ttf);
|
||||
@include font-face('Material', 'fonts/Material/MaterialIcons-Regular', normal, normal, $file-formats: ttf);
|
||||
|
||||
@include font-face('Alegreya', 'fonts/Alegreya-Bold', 700, normal, $file-formats: ttf);
|
||||
@include font-face('Alegreya', 'fonts/Alegreya-BoldItalic', 700, italic, $file-formats: ttf);
|
||||
|
||||
@@ -15,6 +15,8 @@ $color6: #cdbe91;
|
||||
$color7: #c89b3c;
|
||||
$color8: #463714;
|
||||
$color9: #1e282d;
|
||||
$color10: #3c3732;
|
||||
$color11: #31353a;
|
||||
|
||||
$link-color1: #0080b9;
|
||||
$link-color2: #52abd1;
|
||||
|
||||
@@ -22,5 +22,23 @@ export default {
|
||||
},
|
||||
showItemEditor: function(item) {
|
||||
createOverlay(<ItemEditor item={item} />);
|
||||
},
|
||||
addToList: function(item) {
|
||||
AppDispatcher.dispatch({
|
||||
actionType: ActionTypes.ADD_ITEM,
|
||||
item
|
||||
});
|
||||
},
|
||||
saveItem: function(item) {
|
||||
AppDispatcher.dispatch({
|
||||
actionType: ActionTypes.SAVE_ITEM,
|
||||
item
|
||||
});
|
||||
},
|
||||
removeFromList: function(id) {
|
||||
AppDispatcher.dispatch({
|
||||
actionType: ActionTypes.REMOVE_ITEM,
|
||||
id
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import GeminiScrollbar from 'react-gemini-scrollbar';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import GeminiScrollbar from 'react-gemini-scrollbar';
|
||||
import Label from './Label';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
export default class Dropdown extends Component {
|
||||
|
||||
@@ -86,7 +87,7 @@ export default class Dropdown extends Component {
|
||||
const classNameInner = classNames( option[1] === this.props.value && 'active' );
|
||||
|
||||
return (
|
||||
<div className={classNameInner} key={option[1]} onClick={this.onChange.bind(null, option[1])}>
|
||||
<div className={classNameInner} key={option[1]} onClick={this.props.disabled ? null : this.onChange.bind(null, option[1])}>
|
||||
{option[0]}
|
||||
</div>
|
||||
);
|
||||
@@ -99,7 +100,7 @@ export default class Dropdown extends Component {
|
||||
|
||||
return (
|
||||
<div className={className} ref="container">
|
||||
{labelTextELement}
|
||||
<Label text={this.props.label} disabled={this.props.disabled}></Label>
|
||||
<div onMouseDown={this.insideFocus} onMouseUp={this.insideBlur} onTouchStart={this.insideFocus} onTouchEnd={this.insideBlur}>
|
||||
{this.state.position === 'top' && this.state.isOpen ? downElement : <div style={{height:0}}></div>}
|
||||
<div onClick={this.switch} className="value">{valueText}</div>
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
width: 280px;
|
||||
margin: 10px 0;
|
||||
font: 500 13px/30px Alegreya Sans;
|
||||
|
||||
@extend %label;
|
||||
|
||||
> div {
|
||||
position: relative;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
hr {
|
||||
margin: 15px 0 5px;
|
||||
border: none;
|
||||
height: 1px;
|
||||
background: $color9;
|
||||
}
|
||||
@@ -1,17 +1,20 @@
|
||||
import classNames from 'classnames';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
export default class Label extends Component {
|
||||
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
text: PropTypes.string
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
let { text } = this.props;
|
||||
let { className, disabled, text, ...other } = this.props;
|
||||
|
||||
return text ? (
|
||||
<label>{text}</label>
|
||||
<label {...other} className={classNames(className, disabled && 'disabled')}>{text}</label>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,4 +4,8 @@ label {
|
||||
display: block;
|
||||
font: 500 12px/1 Alegreya Sans;
|
||||
padding-bottom: 6px;
|
||||
|
||||
&.disabled {
|
||||
color: $color11;
|
||||
}
|
||||
}
|
||||
+22
-14
@@ -3,13 +3,15 @@
|
||||
border: 2px solid $color8;
|
||||
background: $background2;
|
||||
color: $color2;
|
||||
box-shadow: 0 0 0 1px transparentiz(black, .6);
|
||||
z-index: 2000;
|
||||
|
||||
> div {
|
||||
padding: 21px 14px 18px;
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font: bold 14px/14px Alegreya SC;
|
||||
font: bold 14px/18px Alegreya SC;
|
||||
text-transform: uppercase;
|
||||
color: $color1;
|
||||
display: flex;
|
||||
@@ -19,18 +21,15 @@
|
||||
span:last-child {
|
||||
color: $color2;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
font: 500 12px/18px Alegreya Sans;
|
||||
font: 500 12px/16px Alegreya Sans;
|
||||
letter-spacing: 0.05em;
|
||||
margin-top: 16px;
|
||||
|
||||
&:not(:nth-child(2)) {
|
||||
margin-top: 0;
|
||||
&:last-child {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,14 +45,23 @@
|
||||
transform: rotate(45deg);
|
||||
@include calc(left, "50% - 8px");
|
||||
bottom: -8px;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
> .calc-attr-overlay {
|
||||
width: 280px;
|
||||
|
||||
p.calc-text {
|
||||
font-style: italic;
|
||||
&.overlay-bottom {
|
||||
&:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@include size(12px);
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-color: transparent $color8 $color8 transparent;
|
||||
background: $background2;
|
||||
transform: rotate(-135deg);
|
||||
@include calc(left, "50% - 8px");
|
||||
top: -8px;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
+59
-59
@@ -115,79 +115,79 @@
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-list {
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
white-space: nowrap;
|
||||
// .scroll-list {
|
||||
// table {
|
||||
// width: 100%;
|
||||
// border-collapse: collapse;
|
||||
// white-space: nowrap;
|
||||
|
||||
td {
|
||||
padding: 5px 5px 5px 11px;
|
||||
// td {
|
||||
// padding: 5px 5px 5px 11px;
|
||||
|
||||
&.name {
|
||||
width: 100%;
|
||||
}
|
||||
// &.name {
|
||||
// width: 100%;
|
||||
// }
|
||||
|
||||
&.name, &.fw {
|
||||
color: #f0e6d2;
|
||||
}
|
||||
}
|
||||
// &.name, &.fw {
|
||||
// color: #f0e6d2;
|
||||
// }
|
||||
// }
|
||||
|
||||
thead {
|
||||
font: bold 13px/22px Alegreya SC;
|
||||
// thead {
|
||||
// font: bold 13px/22px Alegreya SC;
|
||||
|
||||
tr td {
|
||||
border-bottom: 1px solid transparentize(white, .925);
|
||||
}
|
||||
}
|
||||
// tr td {
|
||||
// border-bottom: 1px solid transparentize(white, .925);
|
||||
// }
|
||||
// }
|
||||
|
||||
tbody {
|
||||
tr {
|
||||
&:not(:last-child) td {
|
||||
height: 36px;
|
||||
border-bottom: 1px solid transparentize(white, .925);
|
||||
}
|
||||
// tbody {
|
||||
// tr {
|
||||
// &:not(:last-child) td {
|
||||
// height: 36px;
|
||||
// border-bottom: 1px solid transparentize(white, .925);
|
||||
// }
|
||||
|
||||
&:hover {
|
||||
background: transparentize(white, .975);
|
||||
}
|
||||
// &:hover {
|
||||
// background: transparentize(white, .975);
|
||||
// }
|
||||
|
||||
td {
|
||||
height: 36px;
|
||||
// td {
|
||||
// height: 36px;
|
||||
|
||||
&.name {
|
||||
vertical-align: middle;
|
||||
// &.name {
|
||||
// vertical-align: middle;
|
||||
|
||||
h2 {
|
||||
font: 500 15px/15px Alegreya Sans;
|
||||
text-transform: none;
|
||||
color: #f0e6d2;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
// h2 {
|
||||
// font: 500 15px/15px Alegreya Sans;
|
||||
// text-transform: none;
|
||||
// color: #f0e6d2;
|
||||
// display: inline-block;
|
||||
// }
|
||||
// }
|
||||
|
||||
&.check, &.skt {
|
||||
font: 13px/13px Alegreya SC;
|
||||
}
|
||||
// &.check, &.skt {
|
||||
// font: 13px/13px Alegreya SC;
|
||||
// }
|
||||
|
||||
&.inc {
|
||||
font-weight: 500;
|
||||
// &.inc {
|
||||
// font-weight: 500;
|
||||
|
||||
.btn {
|
||||
padding: 0 14px 3px;
|
||||
min-width: auto;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
// .btn {
|
||||
// padding: 0 14px 3px;
|
||||
// min-width: auto;
|
||||
// font-size: 16px;
|
||||
// }
|
||||
// }
|
||||
|
||||
.textfield, .dropdown {
|
||||
width: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// .textfield, .dropdown {
|
||||
// width: 200px;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
h4 {
|
||||
font-size: 13px;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import RadioButtonGroup from './RadioButtonGroup';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
const SORT_NAMES = {
|
||||
name: 'Alphabetisch',
|
||||
group: 'Nach Gruppe',
|
||||
groupname: 'Nach Gruppe',
|
||||
where: 'Nach Trageort'
|
||||
};
|
||||
|
||||
export default class SortOptions extends Component {
|
||||
|
||||
static propTypes = {
|
||||
options: PropTypes.array.isRequired,
|
||||
sort: PropTypes.func.isRequired,
|
||||
sortOrder: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const { options, sort, sortOrder, ...other } = this.props;
|
||||
|
||||
return (
|
||||
<RadioButtonGroup
|
||||
{...other}
|
||||
active={sortOrder}
|
||||
onClick={sort}
|
||||
array={options.map(e => ({ name: SORT_NAMES[e], value: e }))}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
+50
-37
@@ -6,7 +6,9 @@ table {
|
||||
table-layout: auto;
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
table.list {
|
||||
td {
|
||||
padding: 5px 5px 5px 11px;
|
||||
|
||||
@@ -22,7 +24,7 @@ table {
|
||||
thead {
|
||||
font: bold 13px/22px Alegreya SC;
|
||||
|
||||
tr td {
|
||||
td {
|
||||
border-bottom: 1px solid transparentize(white, .925);
|
||||
}
|
||||
}
|
||||
@@ -30,58 +32,69 @@ table {
|
||||
tbody {
|
||||
tr {
|
||||
&:not(:last-child) td {
|
||||
height: 36px;
|
||||
border-bottom: 1px solid transparentize(white, .925);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: transparentize(white, .975);
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
height: 36px;
|
||||
|
||||
&.name h2, &.fw {
|
||||
font: 500 15px/15px Alegreya Sans;
|
||||
text-transform: none;
|
||||
color: #f0e6d2;
|
||||
}
|
||||
td {
|
||||
height: 36px;
|
||||
|
||||
&.name h2, &.fw {
|
||||
font: 500 15px/15px Alegreya Sans;
|
||||
text-transform: none;
|
||||
color: #f0e6d2;
|
||||
}
|
||||
|
||||
&.check, &.skt {
|
||||
font: 13px/13px Alegreya SC;
|
||||
}
|
||||
&.check, &.skt {
|
||||
font: 13px/13px Alegreya SC;
|
||||
}
|
||||
|
||||
&.inc {
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
&.inc {
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
.btn {
|
||||
height: 26px;
|
||||
padding: 0 14px 3px;
|
||||
min-width: auto;
|
||||
font-size: 16px;
|
||||
flex: none;
|
||||
.btn {
|
||||
height: 26px;
|
||||
padding: 0 14px 3px;
|
||||
min-width: auto;
|
||||
font-size: 16px;
|
||||
flex: none;
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-left: 4px;
|
||||
}
|
||||
&:nth-child(2) {
|
||||
margin-left: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// &.min {
|
||||
// td {
|
||||
// color: transparentize(#878683, .4);
|
||||
&.large-list tbody td {
|
||||
height: 42px;
|
||||
|
||||
// &.name h2, &.fw {
|
||||
// font: 500 15px/15px Alegreya Sans;
|
||||
// text-transform: none;
|
||||
// color: transparentize(#f0e6d2, .4);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
&.name {
|
||||
> div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> h2, > div {
|
||||
flex: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> div {
|
||||
margin-left: 14px;
|
||||
|
||||
&.tiers {
|
||||
width: 65px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,8 +56,9 @@ export default class TextField extends Component {
|
||||
<input
|
||||
type={type}
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
onKeyPress={onKeyDown}
|
||||
onChange={disabled ? null : onChange}
|
||||
onKeyPress={disabled ? null : onKeyDown}
|
||||
readOnly={disabled}
|
||||
ref='inputElement'
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -17,8 +17,6 @@
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@extend %label;
|
||||
|
||||
input, textarea {
|
||||
width: 100%;
|
||||
|
||||
@@ -2,12 +2,18 @@ import classNames from 'classnames';
|
||||
import createOverlay, { close } from '../utils/createOverlay';
|
||||
import Overlay from './Overlay';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
export default class Tooltip extends Component {
|
||||
|
||||
static propTypes = {
|
||||
content: PropTypes.node,
|
||||
margin: PropTypes.number
|
||||
margin: PropTypes.number,
|
||||
position: PropTypes.string
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
position: 'top'
|
||||
};
|
||||
|
||||
state = {
|
||||
@@ -17,26 +23,38 @@ export default class Tooltip extends Component {
|
||||
triggerRef;
|
||||
node;
|
||||
|
||||
componentDidMount() {
|
||||
this.triggerRef = this.refs.trigger;
|
||||
componentWillUnmount() {
|
||||
if (this.node) {
|
||||
close(this.node);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open = () => {
|
||||
const { content, margin } = this.props;
|
||||
this.node = createOverlay(<Overlay className="tooltip" position="top" trigger={this.triggerRef} margin={margin}>
|
||||
const { content, margin, position } = this.props;
|
||||
this.node = createOverlay(<Overlay className="tooltip" position={position} trigger={this.triggerRef} margin={margin}>
|
||||
{content}
|
||||
</Overlay>);
|
||||
};
|
||||
close = () => close(this.node);
|
||||
close = () => {
|
||||
close(this.node);
|
||||
this.node = undefined;
|
||||
};
|
||||
|
||||
render() {
|
||||
|
||||
const { children } = this.props;
|
||||
|
||||
const only = React.cloneElement(React.Children.only(children), {
|
||||
onMouseEnter: this.open,
|
||||
onMouseLeave: this.close,
|
||||
ref: 'trigger'
|
||||
onMouseOver: this.open,
|
||||
onMouseOut: this.close,
|
||||
ref: (node) => {
|
||||
if (node !== null && node.nodeType !== 1) {
|
||||
this.triggerRef = ReactDOM.findDOMNode(node);
|
||||
}
|
||||
else {
|
||||
this.triggerRef = node;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return only;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
@import "Checkbox";
|
||||
@import "Dialog";
|
||||
@import "Dropdown";
|
||||
@import "Hr";
|
||||
@import "IconButton";
|
||||
@import "Label";
|
||||
@import "LabelBox";
|
||||
|
||||
@@ -18,6 +18,7 @@ import TitleBarLeft from './TitleBarLeft';
|
||||
import TitleBarRight from './TitleBarRight';
|
||||
import TitleBarTabs from './TitleBarTabs';
|
||||
import TitleBarWrapper from './TitleBarWrapper';
|
||||
import TooltipToggle from '../TooltipToggle';
|
||||
|
||||
export default class TitleBar extends Component {
|
||||
|
||||
@@ -72,7 +73,7 @@ export default class TitleBar extends Component {
|
||||
render() {
|
||||
|
||||
const { currentSection, currentTab } = this.props;
|
||||
const { account, ap: { total, spent }, avatar, isUndoAvailable, phase } = this.state;
|
||||
const { account, ap: { total, spent, adv, disadv }, avatar, isUndoAvailable, phase } = this.state;
|
||||
|
||||
switch (currentSection) {
|
||||
case 'main': {
|
||||
@@ -97,6 +98,10 @@ export default class TitleBar extends Component {
|
||||
primary
|
||||
disabled
|
||||
/>
|
||||
<IconButton
|
||||
icon=""
|
||||
disabled
|
||||
/>
|
||||
</TitleBarRight>
|
||||
</TitleBarWrapper>
|
||||
);
|
||||
@@ -115,6 +120,10 @@ export default class TitleBar extends Component {
|
||||
{ label: account.name, tag: 'account' }
|
||||
]} />
|
||||
<BorderButton label="Abmelden" onClick={this.logout} disabled />
|
||||
<IconButton
|
||||
icon=""
|
||||
disabled
|
||||
/>
|
||||
</TitleBarRight>
|
||||
</TitleBarWrapper>
|
||||
);
|
||||
@@ -153,7 +162,30 @@ export default class TitleBar extends Component {
|
||||
<TitleBarTabs active={currentTab} tabs={tabs} />
|
||||
</TitleBarLeft>
|
||||
<TitleBarRight>
|
||||
<Text className="collected-ap">{total - spent} AP</Text>
|
||||
<TooltipToggle
|
||||
position="bottom"
|
||||
margin={12}
|
||||
content={
|
||||
<div className="ap-details">
|
||||
<h4>Abenteuerpunkte</h4>
|
||||
<p className="general">
|
||||
{total} AP gesamt<br/>
|
||||
{spent} AP verwendet
|
||||
</p>
|
||||
<hr />
|
||||
<p>
|
||||
{adv[0]} / 80 AP für Vorteile<br/>
|
||||
{adv[1] > 0 ? `${adv[1]} / 50 für magische Vorteile` : null}
|
||||
{adv[2] > 0 ? `${adv[2]} / 50 für karmale Vorteile` : null}
|
||||
{disadv[0]} / 80 AP für Nachteile<br/>
|
||||
{disadv[1] > 0 ? `${disadv[1]} / 50 für magische Nachteile` : null}
|
||||
{disadv[2] > 0 ? `${disadv[2]} / 50 für karmale Nachteile` : null}
|
||||
</p>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Text className="collected-ap">{total - spent} AP</Text>
|
||||
</TooltipToggle>
|
||||
<IconButton
|
||||
icon=""
|
||||
onClick={this.undo}
|
||||
@@ -187,18 +219,3 @@ export default class TitleBar extends Component {
|
||||
}
|
||||
}
|
||||
}
|
||||
// <div className="details">
|
||||
// <div className="all"><span>{this.state.ap}</span> AP gesamt</div>
|
||||
// <div className="used"><span>{this.state.used}</span> AP verwendet</div>
|
||||
// <hr />
|
||||
// <div className="adv">
|
||||
// <span>{this.state.disadv.adv[0]} / 80</span> AP für Vorteile
|
||||
// {this.state.disadv.adv[1] > 0 ? ` (davon ${this.state.disadv.adv[1]} für magische)`:null}
|
||||
// {this.state.disadv.adv[2] > 0 ? ` (davon ${this.state.disadv.adv[2]} für karmale)`:null}
|
||||
// </div>
|
||||
// <div className="disadv">
|
||||
// <span>{this.state.disadv.disadv[0]} / 80</span> AP für Nachteile
|
||||
// {this.state.disadv.disadv[1] > 0 ? `(davon ${this.state.disadv.disadv[1]} für magische)`:null}
|
||||
// {this.state.disadv.disadv[2] > 0 ? `(davon ${this.state.disadv.disadv[2]} für karmale)`:null}
|
||||
// </div>
|
||||
// </div>
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
padding-left: 4px;
|
||||
|
||||
+ div {
|
||||
margin-left: 20px;
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
|
||||
@@ -22,81 +22,17 @@
|
||||
|
||||
.btn {
|
||||
margin-left: 11px;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.collected-ap {
|
||||
color: #a19b8f;
|
||||
flex: 1 0 auto;
|
||||
font: bold 15px/#{$titlebar-height} Alegreya SC;
|
||||
font: bold 15px/32px Alegreya SC;
|
||||
height: 32px;
|
||||
letter-spacing: 0.1em;
|
||||
margin: 0 11px 0 35px;
|
||||
text-transform: uppercase;
|
||||
color: #a19b8f;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
// .ap:hover + .details {
|
||||
// visibility: visible;
|
||||
// }
|
||||
|
||||
// .details {
|
||||
// background: #010a13;
|
||||
// border: 1px solid #785a28;
|
||||
// position: absolute;
|
||||
// font: 500 12px/18px Alegreya Sans;
|
||||
// letter-spacing: 0.05em;
|
||||
// color: #878683;
|
||||
// padding: 13px 0;
|
||||
// top: $titlebar-height - 12px;
|
||||
// // right: 112px;
|
||||
// white-space: nowrap;
|
||||
// // width: 2px;
|
||||
// visibility: hidden;
|
||||
// // transition: all 0.2s cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||
// // min-width: 150px;
|
||||
// right: 16px;
|
||||
// padding: 13px 18px;
|
||||
// box-shadow: 0 0 18px 4px black;
|
||||
|
||||
// &:before, &:after {
|
||||
// position: absolute;
|
||||
// display: block;
|
||||
// content: "";
|
||||
// @include calc(width, '100% - 10px');
|
||||
// height: 2px;
|
||||
// left: 4px;
|
||||
// background: #785a28;
|
||||
// }
|
||||
|
||||
// &:before {
|
||||
// top: -5px;
|
||||
// }
|
||||
|
||||
// &:after {
|
||||
// bottom: -5px;
|
||||
// }
|
||||
|
||||
// div {
|
||||
// overflow: hidden;
|
||||
// }
|
||||
|
||||
// hr {
|
||||
// margin: 10px 0;
|
||||
// padding: 0;
|
||||
// background: #1f282d;
|
||||
// height: 1px;
|
||||
// }
|
||||
|
||||
// span {
|
||||
// color: #f1e6d4;
|
||||
// }
|
||||
// }
|
||||
|
||||
.menu-button {
|
||||
flex: 1 0 auto;
|
||||
font: 24px/#{$titlebar-height} Material;
|
||||
width: $titlebar-height;
|
||||
text-align: center;
|
||||
display: none;
|
||||
color: #f1e6d4;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,6 +143,9 @@ export default keyMirror({
|
||||
// InventoryStore
|
||||
FILTER_ITEMS: null,
|
||||
SORT_ITEMS: null,
|
||||
ADD_ITEM: null,
|
||||
SAVE_ITEM: null,
|
||||
REMOVE_ITEM: null,
|
||||
|
||||
// GroupsStore
|
||||
SHOW_MASTER_REQUESTED_LIST: null,
|
||||
|
||||
@@ -8,7 +8,7 @@ var _heroes = {
|
||||
date: new Date('2016-10-18T16:18:28.420Z'),
|
||||
player: ['U_1', 'schuchi'],
|
||||
id: 'H_1',
|
||||
phase: 2,
|
||||
phase: 3,
|
||||
name: 'Shimo ibn Rashdul',
|
||||
avatar: 'images/portrait.png',
|
||||
ap: {
|
||||
|
||||
+160
-2
@@ -1,12 +1,99 @@
|
||||
import AppDispatcher from '../dispatcher/AppDispatcher';
|
||||
import Store from './Store';
|
||||
import ActionTypes from '../constants/ActionTypes';
|
||||
import { Item } from '../utils/DataUtils';
|
||||
|
||||
var _itemsById = {};
|
||||
var _items = [];
|
||||
var _itemsById = {
|
||||
ITEM_1: new Item({
|
||||
id: 'ITEM_1',
|
||||
name: 'Mörderstorchsäbel',
|
||||
price: 100,
|
||||
weight: 1.2,
|
||||
number: 1,
|
||||
where: 'Gürtel',
|
||||
gr: 1,
|
||||
combattechnique: 'CT_12',
|
||||
damageDiceNumber: 1,
|
||||
damageDiceSides: 6,
|
||||
damageFlat: 6,
|
||||
damageBonus: 14,
|
||||
at: -1,
|
||||
pa: 0,
|
||||
reach: 2,
|
||||
length: 76,
|
||||
stp: 0,
|
||||
range: [0, 0, 0],
|
||||
reloadtime: 0,
|
||||
ammunition: null,
|
||||
pro: 0,
|
||||
enc: 0,
|
||||
addpenalties: false
|
||||
}),
|
||||
ITEM_2: new Item({
|
||||
id: 'ITEM_2',
|
||||
name: 'Bogen des Rakorium Muntagonus',
|
||||
price: 1234,
|
||||
weight: 0.9,
|
||||
number: 1,
|
||||
where: 'Fliegt',
|
||||
gr: 2,
|
||||
combattechnique: 'CT_2',
|
||||
damageDiceNumber: 2,
|
||||
damageDiceSides: 6,
|
||||
damageFlat: 0,
|
||||
damageBonus: 0,
|
||||
at: 0,
|
||||
pa: 0,
|
||||
reach: 0,
|
||||
length: 123,
|
||||
stp: 0,
|
||||
range: [90, 60, 90],
|
||||
reloadtime: 1,
|
||||
ammunition: null,
|
||||
pro: 0,
|
||||
enc: 0,
|
||||
addpenalties: false
|
||||
}),
|
||||
ITEM_3: new Item({
|
||||
id: 'ITEM_3',
|
||||
name: 'Rüstung des Widderhorns',
|
||||
price: 30,
|
||||
weight: 4,
|
||||
number: 1,
|
||||
where: '',
|
||||
gr: 3,
|
||||
combattechnique: '',
|
||||
damageDiceNumber: 0,
|
||||
damageDiceSides: 6,
|
||||
damageFlat: 0,
|
||||
damageBonus: 0,
|
||||
at: 0,
|
||||
pa: 0,
|
||||
reach: 0,
|
||||
length: 123,
|
||||
stp: 0,
|
||||
range: [90, 60, 90],
|
||||
reloadtime: 1,
|
||||
ammunition: null,
|
||||
pro: 4,
|
||||
enc: 2,
|
||||
addpenalties: true
|
||||
})
|
||||
};
|
||||
var _items = ['ITEM_1','ITEM_2','ITEM_3'];
|
||||
var _itemTemplatesById = {};
|
||||
var _itemTemplates = [];
|
||||
var _filterText = '';
|
||||
var _sortOrder = 'name';
|
||||
|
||||
function _init(raw) {
|
||||
for (const id in raw) {
|
||||
_itemTemplatesById[id] = new Item({ ...raw[id], isTemplateLocked: true });
|
||||
_itemTemplates.push(id);
|
||||
}
|
||||
console.log(_itemTemplatesById[_itemTemplates[0]]);
|
||||
}
|
||||
|
||||
function _updateFilterText(text) {
|
||||
_filterText = text;
|
||||
}
|
||||
@@ -15,6 +102,49 @@ function _updateSortOrder(option) {
|
||||
_sortOrder = option;
|
||||
}
|
||||
|
||||
function _addItem(raw, id) {
|
||||
// if ([1,2].includes(data.gr)) {
|
||||
// data.ddn = parseInt(data.ddn) || 0;
|
||||
// data.df = parseInt(data.df) || 0;
|
||||
// data.length = parseInt(data.length) || 0;
|
||||
// }
|
||||
// if (data.gr === 1) {
|
||||
// data.db = parseInt(data.db) || 0;
|
||||
// data.at = parseInt(data.at) || 0;
|
||||
// data.pa = parseInt(data.pa) || 0;
|
||||
// data.reach = parseInt(data.reach) || 0;
|
||||
// data.stp = parseInt(data.stp) || 0;
|
||||
// }
|
||||
// else if (data.gr === 2) {
|
||||
// data.rb1 = parseInt(data.rb1) || 0;
|
||||
// data.rb2 = parseInt(data.rb2) || 0;
|
||||
// data.rb3 = parseInt(data.rb3) || 0;
|
||||
// data.range = [ data.rb1, data.rb2, data.rb3 ];
|
||||
// data.rt = parseInt(data.rt) || 0;
|
||||
// }
|
||||
// else if (data.gr === 3) {
|
||||
// data.pro = parseInt(data.pro) || 0;
|
||||
// data.enc = parseInt(data.enc) || 0;
|
||||
// }
|
||||
_itemsById[id] = new Item({ ...Item.prepareDataForStore(raw), id });
|
||||
_items.push(id);
|
||||
}
|
||||
|
||||
function _saveItem(raw) {
|
||||
_itemsById[raw.id] = new Item(Item.prepareDataForStore(raw));
|
||||
}
|
||||
|
||||
function _removeItem(id) {
|
||||
delete _itemsById[id];
|
||||
_items.some((e,i) => {
|
||||
if (e === id) {
|
||||
_items.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
class _InventoryStore extends Store {
|
||||
|
||||
get(id) {
|
||||
@@ -25,6 +155,14 @@ class _InventoryStore extends Store {
|
||||
return _items.map(e => _itemsById[e]);
|
||||
}
|
||||
|
||||
getTemplate(id) {
|
||||
return _itemTemplatesById[id];
|
||||
}
|
||||
|
||||
getAllTemplates() {
|
||||
return _itemTemplates.map(e => _itemTemplatesById[e]);
|
||||
}
|
||||
|
||||
getFilterText() {
|
||||
return _filterText;
|
||||
}
|
||||
@@ -33,6 +171,10 @@ class _InventoryStore extends Store {
|
||||
return _sortOrder;
|
||||
}
|
||||
|
||||
getForEditor(id) {
|
||||
return Item.prepareDataForEditor(_itemsById[id]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const InventoryStore = new _InventoryStore();
|
||||
@@ -49,6 +191,22 @@ InventoryStore.dispatchToken = AppDispatcher.register(payload => {
|
||||
_updateSortOrder(payload.option);
|
||||
break;
|
||||
|
||||
case ActionTypes.ADD_ITEM:
|
||||
_addItem(payload.item, 'ITEM_' + (_items[_items.length - 1] ? _items[_items.length - 1].split('_')[1] + 1 : 1));
|
||||
break;
|
||||
|
||||
case ActionTypes.SAVE_ITEM:
|
||||
_saveItem(payload.item);
|
||||
break;
|
||||
|
||||
case ActionTypes.REMOVE_ITEM:
|
||||
_removeItem(payload.id);
|
||||
break;
|
||||
|
||||
case ActionTypes.RECEIVE_RAW_LISTS:
|
||||
_init(payload.items);
|
||||
break;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
+22
-3
@@ -24,6 +24,14 @@ export const sortByCostSex = (a,b) => a.ap < b.ap ? -1 : a.ap > b.ap ? 1 : sortB
|
||||
|
||||
export const sortByGroup = (a,b) => a.gr < b.gr ? -1 : a.gr > b.gr ? 1 : sortByName(a,b);
|
||||
|
||||
var GROUPS;
|
||||
|
||||
export const sortByGroupName = (a,b) => {
|
||||
let agr = GROUPS[a.gr - 1];
|
||||
let bgr = GROUPS[b.gr - 1];
|
||||
return agr < bgr ? -1 : agr > bgr ? 1 : sortByName(a,b);
|
||||
};
|
||||
|
||||
export const sortByIC = (a,b) => a.ic < b.ic ? -1 : a.ic > b.ic ? 1 : sortByName(a,b);
|
||||
|
||||
export const sortByProperty = (a,b) => {
|
||||
@@ -41,6 +49,8 @@ export const sortByPrice = (a,b) => a.price < b.price ? -1 : a.price > b.price ?
|
||||
|
||||
export const sortByWeight = (a,b) => a.weight < b.weight ? -1 : a.weight > b.weight ? 1 : sortByName(a,b);
|
||||
|
||||
export const sortByWhere = (a,b) => a.where < b.where ? -1 : a.where > b.where ? 1 : sortByName(a,b);
|
||||
|
||||
export const sort = (list, sortOrder) => {
|
||||
let sort;
|
||||
switch (sortOrder) {
|
||||
@@ -53,6 +63,9 @@ export const sort = (list, sortOrder) => {
|
||||
case 'group':
|
||||
sort = sortByGroup;
|
||||
break;
|
||||
case 'groupname':
|
||||
sort = sortByGroupName;
|
||||
break;
|
||||
case 'ic':
|
||||
sort = sortByIC;
|
||||
break;
|
||||
@@ -68,6 +81,9 @@ export const sort = (list, sortOrder) => {
|
||||
case 'weight':
|
||||
sort = sortByWeight;
|
||||
break;
|
||||
case 'where':
|
||||
sort = sortByWhere;
|
||||
break;
|
||||
|
||||
default:
|
||||
return list;
|
||||
@@ -92,9 +108,12 @@ export const sortSex = (list, sortOrder, sex) => {
|
||||
return list.sort(sort);
|
||||
};
|
||||
|
||||
export const filterAndSort = (list, filterText, sortOrder, sex) => {
|
||||
if (sex) {
|
||||
return sortSex(filter(list, filterText), sortOrder, sex);
|
||||
export const filterAndSort = (list, filterText, sortOrder, option) => {
|
||||
if (Array.isArray(option)) {
|
||||
GROUPS = option;
|
||||
}
|
||||
else if (option) {
|
||||
return sortSex(filter(list, filterText), sortOrder, option);
|
||||
}
|
||||
return sort(filter(list, filterText), sortOrder);
|
||||
};
|
||||
|
||||
+55
-41
@@ -1,6 +1,5 @@
|
||||
import AuthStore from '../stores/AuthStore';
|
||||
import ProfileStore from '../stores/ProfileStore';
|
||||
import { get, post } from './request';
|
||||
import ServerActions from '../actions/ServerActions';
|
||||
|
||||
export default {
|
||||
@@ -10,7 +9,8 @@ export default {
|
||||
|
||||
getAllData: async function() {
|
||||
try {
|
||||
let result = await get('data/DSA5.json', 'json');
|
||||
let response = await fetch('data/DSA5.json');
|
||||
let result = await response.json();
|
||||
ServerActions.receiveLists(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -19,7 +19,8 @@ export default {
|
||||
register: async function(email, username, displayname, password) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let result = await get('data/register.php?email=' + email + '&name=' + username + '&display=' + displayname + '&password=' + password);
|
||||
let response = await fetch('data/register.php?email=' + email + '&name=' + username + '&display=' + displayname + '&password=' + password);
|
||||
let result = await response.text();
|
||||
ServerActions.registrationSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -27,7 +28,8 @@ export default {
|
||||
},
|
||||
checkEmail: async function(email) {
|
||||
try {
|
||||
let result = await get('data/checkemail.php?e=' + email);
|
||||
let response = await fetch('data/checkemail.php?e=' + email);
|
||||
let result = await response.text();
|
||||
return result;
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -35,7 +37,8 @@ export default {
|
||||
},
|
||||
checkUsername: async function(username) {
|
||||
try {
|
||||
let result = await get('data/checkuser.php?e=' + username);
|
||||
let response = await fetch('data/checkuser.php?e=' + username);
|
||||
let result = await response.text();
|
||||
return result;
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -44,7 +47,8 @@ export default {
|
||||
sendPasswordCode: async function(email) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let result = await get('php/forgetpw.php?e=' + email);
|
||||
let response = await fetch('php/forgetpw.php?e=' + email);
|
||||
let result = await response.text();
|
||||
ServerActions.forgotPasswordSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -53,7 +57,8 @@ export default {
|
||||
sendUsername: async function(email) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let result = await get('php/forgetusername.php?e=' + email);
|
||||
let response = await fetch('php/forgetusername.php?e=' + email);
|
||||
let result = await response.text();
|
||||
ServerActions.forgotUsernameSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -62,7 +67,8 @@ export default {
|
||||
resendActivation: async function(email) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let result = await get('php/regmailagain.php?e=' + email);
|
||||
let response = await fetch('php/regmailagain.php?e=' + email);
|
||||
let result = await response.text();
|
||||
ServerActions.resendActivationSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -71,7 +77,8 @@ export default {
|
||||
login: async function(username, password) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let result = await get('php/login.php?u=' + username + '&p=' + password);
|
||||
let response = await fetch('php/login.php?u=' + username + '&p=' + password);
|
||||
let result = await response.text();
|
||||
ServerActions.receiveAccount(result, username);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -83,7 +90,8 @@ export default {
|
||||
// logout: async function() {
|
||||
// try {
|
||||
// ServerActions.startLoading();
|
||||
// let result = await get('php/logout.php?uid=' + AuthStore.getID());
|
||||
// let response = await fetch('php/logout.php?uid=' + AuthStore.getID());
|
||||
// let result = await response.text();
|
||||
// ServerActions.logoutSuccess(result);
|
||||
// } catch(e) {
|
||||
// ServerActions.connectionError(e);
|
||||
@@ -92,9 +100,8 @@ export default {
|
||||
setNewUsername: async function(name) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let userID = AuthStore.getID();
|
||||
let url = 'php/changeaccount.php?uid=' + userID + '&src=username&v=' + name;
|
||||
let result = await get(url);
|
||||
let response = await fetch('php/changeaccount.php?uid=' + AuthStore.getID() + '&src=username&v=' + name);
|
||||
let result = await response.text();
|
||||
ServerActions.changeUsernameSuccess(result, name);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -103,9 +110,8 @@ export default {
|
||||
setNewPassword: async function(password) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let userID = AuthStore.getID();
|
||||
let url = 'php/changeaccount.php?uid=' + userID + '&src=password&v=' + password;
|
||||
let result = await get(url);
|
||||
let response = await fetch('php/changeaccount.php?uid=' + AuthStore.getID() + '&src=password&v=' + password);
|
||||
let result = await response.text();
|
||||
ServerActions.changePasswordSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -114,7 +120,8 @@ export default {
|
||||
deleteAccount: async function() {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let result = await get('php/deleteaccount.php?uid=' + AuthStore.getID());
|
||||
let response = await fetch('php/deleteaccount.php?uid=' + AuthStore.getID());
|
||||
let result = await response.text();
|
||||
ServerActions.deleteAccountSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -123,7 +130,8 @@ export default {
|
||||
getHeroes: async function() {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let result = await get('php/getherolist.php?uid=' + AuthStore.getID());
|
||||
let response = await fetch('php/getherolist.php?uid=' + AuthStore.getID());
|
||||
let result = await response.text();
|
||||
ServerActions.herolistRefreshSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -193,7 +201,8 @@ export default {
|
||||
// loadHero: async function(id) {
|
||||
// try {
|
||||
// ServerActions.startLoading();
|
||||
// let result = await get('php/gethero.php?hid=' + id);
|
||||
// let response = await fetch('php/gethero.php?hid=' + id);
|
||||
// let result = await response.text();
|
||||
// ServerActions.loadHeroSuccess(id, result);
|
||||
// } catch(e) {
|
||||
// ServerActions.connectionError(e);
|
||||
@@ -202,35 +211,40 @@ export default {
|
||||
createNewHero: async function(heroname) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let url = 'php/newhero.php?uid=' + AuthStore.getID() + '&n=' + heroname;
|
||||
let result = await get(url);
|
||||
let response = await fetch('php/newhero.php?uid=' + AuthStore.getID() + '&n=' + heroname);
|
||||
let result = await response.text();
|
||||
ServerActions.createNewHeroSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
}
|
||||
},
|
||||
saveHero: function(data) {
|
||||
ServerActions.startLoading();
|
||||
var blob = new Blob([data], { type: "application/json" });
|
||||
var url = window.URL.createObjectURL(blob);
|
||||
window.open(url);
|
||||
},
|
||||
// saveHero: async function(data) {
|
||||
// try {
|
||||
// ServerActions.startLoading();
|
||||
// let url = 'php/save.php?short=' + data[0] + '&full=' + data[1];
|
||||
// let result = await get(url);
|
||||
// ServerActions.saveHeroSuccess(result);
|
||||
// } catch(e) {
|
||||
// ServerActions.connectionError(e);
|
||||
// }
|
||||
// saveHero: function(data) {
|
||||
// ServerActions.startLoading();
|
||||
// var blob = new Blob([data], { type: "application/json" });
|
||||
// var url = window.URL.createObjectURL(blob);
|
||||
// window.open(url);
|
||||
// },
|
||||
saveHero: async function(data) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let response = await fetch('php/save.php?short=' + data[0] + '&full=' + data[1], {
|
||||
method: 'post',
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
let result = await response.text();
|
||||
ServerActions.saveHeroSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
}
|
||||
},
|
||||
changeHeroAvatar: async function(type, data) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
var finalData = new FormData(data);
|
||||
let url = 'php/uploadheropic.php?hid=' + ProfileStore.getID();
|
||||
let result = await post(url, finalData);
|
||||
let response = await fetch('php/uploadheropic.php?hid=' + ProfileStore.getID(), {
|
||||
method: 'post',
|
||||
body: new FormData(data)
|
||||
});
|
||||
let result = await response.text();
|
||||
ServerActions.changeHeroAvatarSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
@@ -239,8 +253,8 @@ export default {
|
||||
deleteHero: async function(heroid) {
|
||||
try {
|
||||
ServerActions.startLoading();
|
||||
let url = 'php/deletehero.php?uid=' + AuthStore.getID() + '&hid=' + heroid;
|
||||
let result = await get(url);
|
||||
let response = await fetch('php/deletehero.php?uid=' + AuthStore.getID() + '&hid=' + heroid);
|
||||
let result = await response.text();
|
||||
ServerActions.deleteHeroSuccess(result);
|
||||
} catch(e) {
|
||||
ServerActions.connectionError(e);
|
||||
|
||||
+79
-21
@@ -7,48 +7,106 @@ export default class Item extends Core {
|
||||
let {
|
||||
price,
|
||||
weight,
|
||||
number,
|
||||
where,
|
||||
gr,
|
||||
ct,
|
||||
ddn,
|
||||
dds,
|
||||
df,
|
||||
db,
|
||||
combattechnique,
|
||||
damageDiceNumber,
|
||||
damageDiceSides,
|
||||
damageFlat,
|
||||
damageBonus,
|
||||
at,
|
||||
pa,
|
||||
re,
|
||||
reach,
|
||||
length,
|
||||
stp,
|
||||
range,
|
||||
rt,
|
||||
am,
|
||||
reloadtime,
|
||||
ammunition,
|
||||
pro,
|
||||
enc,
|
||||
addp
|
||||
addpenalties,
|
||||
template,
|
||||
isTemplateLocked
|
||||
} = args;
|
||||
|
||||
this.price = price;
|
||||
this.weight = weight;
|
||||
this.number = number;
|
||||
this.gr = gr;
|
||||
|
||||
this.combattechnique = ct;
|
||||
this.damageDiceNumber = ddn;
|
||||
this.damageDiceSides = dds;
|
||||
this.damageFlat = df;
|
||||
this.damageBonus = db;
|
||||
this.combattechnique = combattechnique;
|
||||
this.damageDiceNumber = damageDiceNumber;
|
||||
this.damageDiceSides = damageDiceSides;
|
||||
this.damageFlat = damageFlat;
|
||||
this.damageBonus = damageBonus;
|
||||
this.at = at;
|
||||
this.pa = pa;
|
||||
this.reach = re;
|
||||
this.reach = reach;
|
||||
this.length = length;
|
||||
this.stp = stp;
|
||||
this.range = range;
|
||||
this.reloadtime = rt;
|
||||
this.ammunition = am;
|
||||
this.reloadtime = reloadtime;
|
||||
this.ammunition = ammunition;
|
||||
this.pro = pro;
|
||||
this.enc = enc;
|
||||
this.addpenalties = addp;
|
||||
this.addpenalties = addpenalties;
|
||||
|
||||
this.number = 1;
|
||||
this.where = '';
|
||||
this.template = 'ITEMTPL_0';
|
||||
this.where = where;
|
||||
this.template = template;
|
||||
this.isTemplateLocked = isTemplateLocked || false;
|
||||
}
|
||||
|
||||
static prepareDataForStore(target) {
|
||||
target.range = [];
|
||||
for (const name in target) {
|
||||
const value = target[name];
|
||||
switch (name) {
|
||||
case 'price':
|
||||
case 'weight':
|
||||
target[name] = value ? (typeof value === 'number' ? value : parseInt(value.replace(',','.'))) : value;
|
||||
break;
|
||||
|
||||
case 'number':
|
||||
target[name] = value ? (typeof value === 'number' ? value : parseInt(value)) : value;
|
||||
break;
|
||||
|
||||
case 'damageDiceNumber':
|
||||
case 'damageFlat':
|
||||
case 'damageBonus':
|
||||
case 'length':
|
||||
case 'at':
|
||||
case 'pa':
|
||||
case 'stp':
|
||||
case 'reloadtime':
|
||||
case 'pro':
|
||||
case 'enc':
|
||||
target[name] = value ? parseInt(value) : value;
|
||||
break;
|
||||
|
||||
case 'range1':
|
||||
target.range[0] = value;
|
||||
break;
|
||||
|
||||
case 'range2':
|
||||
target.range[1] = value;
|
||||
break;
|
||||
|
||||
case 'range3':
|
||||
target.range[2] = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
target[name] = value;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
static prepareDataForEditor(target) {
|
||||
target.range1 = target.range[0];
|
||||
target.range2 = target.range[1];
|
||||
target.range3 = target.range[2];
|
||||
return target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
@include calc(width, "100% - 70px");
|
||||
height: 1px;
|
||||
content: "";
|
||||
background: #3c3732;
|
||||
background: $color10;
|
||||
// background: #3a322b;
|
||||
// background: #1f282d;
|
||||
top: 0;
|
||||
@@ -55,6 +55,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
@at-root .overlay > .calc-attr-overlay {
|
||||
width: 280px;
|
||||
|
||||
p.calc-text {
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
|
||||
> .btn-round {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
@@ -33,8 +33,10 @@ export default class AttributeCalcItem extends Component {
|
||||
<AttributeBorder label={short} value={value} tooltip={<div className="calc-attr-overlay">
|
||||
<h4><span>{label}</span><span>{value}</span></h4>
|
||||
<p className="calc-text">{calc} = {value || '-'}</p>
|
||||
{ mod || mod === 0 ? <p className="mod">Modifikator: {mod}</p> : null}
|
||||
{ (currentAdd || currentAdd === 0) && phase > 2 ? <p className="add">Gekauft: {currentAdd} / {maxAdd || '-'}</p> : null}
|
||||
{ mod || mod === 0 || ((currentAdd || currentAdd === 0) && phase > 2) ? <p>
|
||||
{ mod || mod === 0 ? <span className="mod">Modifikator: {mod}<br/></span> : null}
|
||||
{ (currentAdd || currentAdd === 0) && phase > 2 ? <span className="add">Gekauft: {currentAdd} / {maxAdd || '-'}</span> : null}
|
||||
</p> : null}
|
||||
</div>} tooltipMargin={7}>
|
||||
{ phase > 2 && maxAdd ? <NumberBox current={currentAdd} max={maxAdd} /> : null }
|
||||
{increaseElement}
|
||||
|
||||
@@ -20,7 +20,7 @@ export default class DisAdvList extends Component {
|
||||
|
||||
return (
|
||||
<Scroll className="list">
|
||||
<table>
|
||||
<table className="list large-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="name">{type === 'ADV' ? 'Vorteil' : 'Nachteil'}</td>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
@include calc(width, "100% - 70px");
|
||||
height: 1px;
|
||||
content: "";
|
||||
background: #3c3732;
|
||||
background: $color10;
|
||||
// background: #3a322b;
|
||||
// background: #1f282d;
|
||||
top: $titlebar-height;
|
||||
|
||||
+42
-15
@@ -1,12 +1,16 @@
|
||||
import { filterAndSort } from '../../utils/ListUtils';
|
||||
import BorderButton from '../../components/BorderButton';
|
||||
import InventoryActions from '../../actions/InventoryActions';
|
||||
import InventoryListItem from './InventoryListItem';
|
||||
import InventoryStore from '../../stores/InventoryStore';
|
||||
import RadioButtonGroup from '../../components/RadioButtonGroup';
|
||||
import SortOptions from '../../components/SortOptions';
|
||||
import React, { Component } from 'react';
|
||||
import Scroll from '../../components/Scroll';
|
||||
import Slidein from '../../components/Slidein';
|
||||
import TextField from '../../components/TextField';
|
||||
|
||||
const GROUPS = ['Nahkampfwaffen', 'Fernkampfwaffen', 'Rüstungen', 'Munition', 'Waffenzubehör', 'Kleidung', 'Reisebedarf und Werkzeuge', 'Beleuchtung', 'Verbandzeug und Heilmittel', 'Behältnisse', 'Seile und Ketten', 'Diebeswerkzeug', 'Handwerkszeug', 'Orientierungshilfen', 'Schmuck', 'Edelsteine und Feingestein', 'Schreibwaren', 'Bücher', 'Magische Artefakte', 'Alchimica', 'Gifte', 'Heilkräuter', 'Musikinstrumente', 'Genussmittel und Luxus', 'Tiere', 'Tierbedarf', 'Forbewegungsmittel'];
|
||||
|
||||
const getInventoryStore = () => ({
|
||||
items: InventoryStore.getAll(),
|
||||
filterText: InventoryStore.getFilterText(),
|
||||
@@ -15,7 +19,10 @@ const getInventoryStore = () => ({
|
||||
|
||||
export default class Inventory extends Component {
|
||||
|
||||
state = getInventoryStore();
|
||||
state = {
|
||||
...getInventoryStore(),
|
||||
templates: InventoryStore.getAllTemplates()
|
||||
};
|
||||
|
||||
_updateInventoryStore = () => this.setState(getInventoryStore());
|
||||
|
||||
@@ -31,30 +38,50 @@ export default class Inventory extends Component {
|
||||
}
|
||||
|
||||
showItemCreation = () => InventoryActions.showItemCreation();
|
||||
showAddSlidein = () => this.setState({ showAddSlidein: true });
|
||||
hideAddSlidein = () => this.setState({ showAddSlidein: false });
|
||||
|
||||
render() {
|
||||
|
||||
const { filterText, items, sortOrder } = this.state;
|
||||
const { filterText, items, showAddSlidein, sortOrder, templates } = this.state;
|
||||
|
||||
const list = filterAndSort(items, filterText, sortOrder);
|
||||
const list = filterAndSort(items, filterText, sortOrder, GROUPS);
|
||||
const templateList = filterAndSort(templates, filterText, 'name');
|
||||
|
||||
return (
|
||||
<div className="page" id="inventory">
|
||||
<Slidein isOpen={showAddSlidein} close={this.hideAddSlidein}>
|
||||
<div className="options">
|
||||
<TextField hint="Suchen" value={filterText} onChange={this.filter} fullWidth />
|
||||
</div>
|
||||
<Scroll className="list">
|
||||
<table className="list large-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="name">Gegenstand</td>
|
||||
<td className="inc"></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
templateList.map(obj => <InventoryListItem key={obj.id} data={obj} add />)
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</Scroll>
|
||||
</Slidein>
|
||||
<div className="options">
|
||||
<TextField hint="Suchen" value={filterText} onChange={this.filter} fullWidth />
|
||||
<RadioButtonGroup
|
||||
active={sortOrder}
|
||||
onClick={this.sort}
|
||||
array={[
|
||||
{ name: 'Alphabetisch', value: 'name' },
|
||||
{ name: 'Gruppen', value: 'group' }
|
||||
]}
|
||||
<SortOptions
|
||||
options={[ 'name', 'groupname', 'where' ]}
|
||||
sortOrder={sortOrder}
|
||||
sort={this.sort}
|
||||
/>
|
||||
<BorderButton label="Hinzufügen" disabled />
|
||||
<BorderButton label="Erstellen" onClick={this.showItemCreation} />
|
||||
<BorderButton label="Hinzufügen" onClick={this.showAddSlidein} />
|
||||
<BorderButton label="Erstellen" onClick={this.showItemCreation} />
|
||||
</div>
|
||||
<Scroll className="list">
|
||||
<table>
|
||||
<table className="list large-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="type">Gruppe</td>
|
||||
@@ -68,7 +95,7 @@ export default class Inventory extends Component {
|
||||
</thead>
|
||||
<tbody>
|
||||
{
|
||||
list
|
||||
list.map(obj => <InventoryListItem key={obj.id} data={obj} />)
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
import IconButton from '../../components/IconButton';
|
||||
import { Item } from '../../utils/DataUtils';
|
||||
import { get } from '../../stores/ListStore';
|
||||
import InventoryActions from '../../actions/InventoryActions';
|
||||
import InventoryStore from '../../stores/InventoryStore';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import TooltipToggle from '../../components/TooltipToggle';
|
||||
|
||||
const GROUPS = ['Nahkampfwaffen', 'Fernkampfwaffen', 'Rüstungen', 'Munition', 'Waffenzubehör', 'Kleidung', 'Reisebedarf und Werkzeuge', 'Beleuchtung', 'Verbandzeug und Heilmittel', 'Behältnisse', 'Seile und Ketten', 'Diebeswerkzeug', 'Handwerkszeug', 'Orientierungshilfen', 'Schmuck', 'Edelsteine und Feingestein', 'Schreibwaren', 'Bücher', 'Magische Artefakte', 'Alchimica', 'Gifte', 'Heilkräuter', 'Musikinstrumente', 'Genussmittel und Luxus', 'Tiere', 'Tierbedarf', 'Forbewegungsmittel'];
|
||||
|
||||
export default class InventoryListItem extends Component {
|
||||
|
||||
static propTypes = {
|
||||
add: PropTypes.bool,
|
||||
data: PropTypes.instanceOf(Item).isRequired,
|
||||
};
|
||||
|
||||
edit = () => InventoryActions.showItemEditor(InventoryStore.get(this.props.data.id));
|
||||
delete = () => InventoryActions.removeFromList(this.props.data.id);
|
||||
add = () => InventoryActions.addToList(this.props.data);
|
||||
|
||||
render() {
|
||||
|
||||
const { add, data: { gr, name, number, price, weight, where, combattechnique, damageDiceNumber, damageDiceSides, damageFlat, damageBonus, at, pa, reach, length, reloadtime, range, ammunition, pro, enc, addpenalties } } = this.props;
|
||||
|
||||
const numberValue = number > 1 ? number : null;
|
||||
|
||||
return (
|
||||
<TooltipToggle content={
|
||||
<div className="inventory-item">
|
||||
<h4><span>{name}</span><span>{numberValue}</span></h4>
|
||||
{ gr === 4 ? <p className="ammunition">Munition</p> : null}
|
||||
{ [4,5].includes(gr) ? <table className="melee">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Gewicht</td>
|
||||
<td>{weight} Stn</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Preis</td>
|
||||
<td>{price} S</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table> : null}
|
||||
{ gr === 1 ? <table className="melee">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Kampftechnik</td>
|
||||
<td>{get(combattechnique).name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TP</td>
|
||||
<td>{damageDiceNumber}W{damageDiceSides}{damageFlat > 0 ? '+' : null}{damageFlat !== 0 ? damageFlat : null}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>L+S</td>
|
||||
<td>{get(combattechnique).primary.map(attr => get(attr).short).join('/')} {damageBonus}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>AT/PA-Mod</td>
|
||||
<td>{at > 0 ? '+' : null}{at}/{pa > 0 ? '+' : null}{pa}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RW</td>
|
||||
<td>{['Kurz','Mittel','Lang'][reach - 1]}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gewicht</td>
|
||||
<td>{weight} Stn</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Länge</td>
|
||||
<td>{length} HF</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Preis</td>
|
||||
<td>{price} S</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table> : null}
|
||||
{ gr === 2 ? <table className="ranged">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Kampftechnik</td>
|
||||
<td>{get(combattechnique).name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TP</td>
|
||||
<td>{damageDiceNumber}W{damageDiceSides}{damageFlat > 0 ? '+' : null}{damageFlat !== 0 ? damageFlat : null}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>LZ</td>
|
||||
<td>{reloadtime}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>RW</td>
|
||||
<td>{range.join('/')}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Munitionstyp</td>
|
||||
<td>{(InventoryStore.get(ammunition) || {}).name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gewicht</td>
|
||||
<td>{weight} Stn</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Länge</td>
|
||||
<td>{length} HF</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Preis</td>
|
||||
<td>{price} S</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table> : null}
|
||||
{ gr === 3 ? <table className="armor">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>RS</td>
|
||||
<td>{pro}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>BE</td>
|
||||
<td>{enc}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Gewicht</td>
|
||||
<td>{weight} Stn</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Preis</td>
|
||||
<td>{price} S</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table> : null}
|
||||
{ gr === 3 ? <p className="armor">
|
||||
Zus. Abzüge: {addpenalties ? '-1 GS, -1 INI' : '-'}
|
||||
</p> : null}
|
||||
</div>
|
||||
} margin={11}>
|
||||
{add ? (
|
||||
<tr>
|
||||
<td className="name">{name}</td>
|
||||
<td className="inc">
|
||||
<IconButton
|
||||
icon=""
|
||||
onClick={this.add}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
):(
|
||||
<tr>
|
||||
<td className="type">{GROUPS[gr - 1]}</td>
|
||||
<td className="number">{numberValue}</td>
|
||||
<td className="name">{name}</td>
|
||||
<td className="price">{price} S</td>
|
||||
<td className="weight">{weight} Stn</td>
|
||||
<td className="where">{where}</td>
|
||||
<td className="inc">
|
||||
<IconButton
|
||||
icon=""
|
||||
onClick={this.edit}
|
||||
/>
|
||||
<IconButton
|
||||
icon=""
|
||||
onClick={this.delete}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</TooltipToggle>
|
||||
);
|
||||
}
|
||||
}
|
||||
+135
-86
@@ -4,10 +4,17 @@ import Dialog from '../../components/Dialog';
|
||||
import Dropdown from '../../components/Dropdown';
|
||||
import Hr from '../../components/Hr';
|
||||
import IconButton from '../../components/IconButton';
|
||||
import InventoryActions from '../../actions/InventoryActions';
|
||||
import InventoryStore from '../../stores/InventoryStore';
|
||||
import Label from '../../components/Label';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
import TextField from '../../components/TextField';
|
||||
|
||||
const GROUPS = ['Nahkampfwaffen', 'Fernkampfwaffen', 'Rüstungen', 'Munition', 'Waffenzubehör', 'Kleidung', 'Reisebedarf und Werkzeuge', 'Beleuchtung', 'Verbandzeug und Heilmittel', 'Behältnisse', 'Seile und Ketten', 'Diebeswerkzeug', 'Handwerkszeug', 'Orientierungshilfen', 'Schmuck', 'Edelsteine und Feingestein', 'Schreibwaren', 'Bücher', 'Magische Artefakte', 'Alchimica', 'Gifte', 'Heilkräuter', 'Musikinstrumente', 'Genussmittel und Luxus', 'Tiere', 'Tierbedarf', 'Forbewegungsmittel'];
|
||||
|
||||
const GROUPS_SELECTION = GROUPS.map((e,i) => [ e, i + 1 ]);
|
||||
// const GROUPS_SELECTION = GROUPS.map((e,i) => [ e, i + 1 ]).sort((a,b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0);
|
||||
|
||||
export default class ItemEditor extends Component {
|
||||
|
||||
static propTypes = {
|
||||
@@ -16,43 +23,53 @@ export default class ItemEditor extends Component {
|
||||
node: PropTypes.any
|
||||
};
|
||||
|
||||
state = {
|
||||
state = this.props.item || {
|
||||
id: '',
|
||||
name: '',
|
||||
price: '',
|
||||
weight: '',
|
||||
amount: '1',
|
||||
number: '',
|
||||
where: '',
|
||||
gr: 5,
|
||||
tpl: 'ITEMTPL_0',
|
||||
|
||||
ct: 'CT_0', // Combat Technique
|
||||
dpdn: '', // Number of dices
|
||||
dpds: null, // Amount of sides per dice
|
||||
dpf: '', // Flat damage
|
||||
dpb: '', // Damage bonus with primary attribute
|
||||
at: '', // AT mod
|
||||
pa: '', // PA mod
|
||||
re: 0,
|
||||
gr: 0,
|
||||
template: 'ITEMTPL_0',
|
||||
isTemplateLocked: false,
|
||||
combattechnique: 'CT_0',
|
||||
damageDiceNumber: '',
|
||||
damageDiceSides: null,
|
||||
damageFlat: '',
|
||||
damageBonus: '',
|
||||
at: '',
|
||||
pa: '',
|
||||
reach: '',
|
||||
length: '',
|
||||
stp: '',
|
||||
rb1: '', // Range brackets
|
||||
rb2: '', // Range brackets
|
||||
rb3: '', // Range brackets
|
||||
rt: '', // Reload time
|
||||
am: null, // Ammunition type
|
||||
pro: '', // Protection
|
||||
range1: '',
|
||||
range2: '',
|
||||
range3: '',
|
||||
reloadtime: '',
|
||||
ammunition: null,
|
||||
pro: '',
|
||||
enc: '',
|
||||
addp: false // Add. penalties
|
||||
addpenalties: false
|
||||
};
|
||||
|
||||
onEvent = (prop, e) => this.setState({ [prop]: e.target.value });
|
||||
onSwitch = prop => this.setState({ [prop]: !this.state[prop] });
|
||||
onValue = (prop, value) => this.setState({ [prop]: value });
|
||||
|
||||
applyTemplate = () => this.state.template !== 'ITEMTPL_0' && this.setState({ ...InventoryStore.getTemplate(this.state.template), id: this.state.id, isTemplateLocked: false });
|
||||
lockTemplate = () => this.state.template !== 'ITEMTPL_0' && this.setState({ ...InventoryStore.getTemplate(this.state.template), id: this.state.id });
|
||||
unlockTemplate = () => this.setState({ isTemplateLocked: false });
|
||||
|
||||
addItem = () => InventoryActions.addToList(this.state);
|
||||
saveItem = () => InventoryActions.saveItem(this.state);
|
||||
|
||||
render() {
|
||||
|
||||
const { create, node } = this.props;
|
||||
const { addp, am, amount, at, ct, dpb, dpdn, dpds, dpf, enc, gr, length, name, pa, price, pro, rb1, rb2, rb3, re, rt, stp, tpl, weight, where } = this.state;
|
||||
const { addpenalties, ammunition, number, at, combattechnique, damageBonus, damageDiceNumber, damageDiceSides, damageFlat, enc, gr, isTemplateLocked: locked, length, name, pa, price, pro, range1, range2, range3, reach, reloadtime, stp, template, weight, where } = this.state;
|
||||
|
||||
const TEMPLATES = [['Keine Vorlage', 'ITEMTPL_0']].concat(InventoryStore.getAllTemplates().map(e => [e.name, e.id]).sort((a,b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0));
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
@@ -62,9 +79,9 @@ export default class ItemEditor extends Component {
|
||||
buttons={[
|
||||
{
|
||||
label: 'Speichern',
|
||||
onClick: null,
|
||||
onClick: create ? this.addItem : this.saveItem,
|
||||
autoWidth: true,
|
||||
disabled: true
|
||||
disabled: name === '' || gr === 0
|
||||
}
|
||||
]}>
|
||||
<div className="main">
|
||||
@@ -72,14 +89,16 @@ export default class ItemEditor extends Component {
|
||||
<TextField
|
||||
className="number"
|
||||
label="Menge"
|
||||
value={amount}
|
||||
onChange={this.onEvent.bind(null, 'amount')}
|
||||
value={number}
|
||||
onChange={this.onEvent.bind(null, 'number')}
|
||||
/>
|
||||
<TextField
|
||||
className="name"
|
||||
label="Name"
|
||||
value={name}
|
||||
onChange={this.onEvent.bind(null, 'name')}
|
||||
autoFocus={create}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
@@ -88,12 +107,14 @@ export default class ItemEditor extends Component {
|
||||
label="Preis in S"
|
||||
value={price}
|
||||
onChange={this.onEvent.bind(null, 'price')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<TextField
|
||||
className="weight"
|
||||
label="Gewicht in St"
|
||||
value={weight}
|
||||
onChange={this.onEvent.bind(null, 'weight')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<TextField
|
||||
className="where"
|
||||
@@ -106,106 +127,120 @@ export default class ItemEditor extends Component {
|
||||
<Dropdown
|
||||
className="gr"
|
||||
label="Art"
|
||||
hint="Wähle den Typ des Gegenstands aus"
|
||||
value={gr}
|
||||
options={[
|
||||
['Allgemein',5],
|
||||
['Nahkampfwaffe',1],
|
||||
['Fernkampfwaffe',2],
|
||||
['Rüstung',3],
|
||||
['Munition',4]
|
||||
]}
|
||||
options={GROUPS_SELECTION}
|
||||
onChange={this.onValue.bind(null, 'gr')}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
<Hr />
|
||||
<div className="row">
|
||||
<Dropdown
|
||||
className="tpl"
|
||||
className="template"
|
||||
label="Vorlage"
|
||||
hint="Keine"
|
||||
value={tpl}
|
||||
options={[]}
|
||||
onChange={this.onValue.bind(null, 'tpl')}
|
||||
value={template}
|
||||
options={TEMPLATES}
|
||||
onChange={this.onValue.bind(null, 'template')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<IconButton
|
||||
icon=""
|
||||
disabled
|
||||
/>
|
||||
<IconButton
|
||||
icon=""
|
||||
disabled
|
||||
onClick={this.applyTemplate}
|
||||
disabled={template === 'ITEMTPL_0' || locked}
|
||||
/>
|
||||
{locked ? (
|
||||
<IconButton
|
||||
icon=""
|
||||
onClick={this.unlockTemplate}
|
||||
/>
|
||||
) : (
|
||||
<IconButton
|
||||
icon=""
|
||||
onClick={this.lockTemplate}
|
||||
disabled={template === 'ITEMTPL_0'}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{ gr === 1 ? ( <div className="melee">
|
||||
<Hr />
|
||||
<div className="row">
|
||||
<Dropdown
|
||||
className="ct"
|
||||
className="combattechnique"
|
||||
label="Kampftechnik"
|
||||
hint="Keine"
|
||||
value={ct}
|
||||
value={combattechnique}
|
||||
options={CombatTechniquesStore.getAll().filter(e => e.gr === 1).map(e => [e.name, e.id])}
|
||||
onChange={this.onValue.bind(null, 'ct')}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
<TextField
|
||||
className="db"
|
||||
className="damage-bonus"
|
||||
label="Schadensb."
|
||||
value={dpb}
|
||||
onChange={this.onEvent.bind(null, 'dpb')}
|
||||
value={damageBonus}
|
||||
onChange={this.onEvent.bind(null, 'db')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<div className="container">
|
||||
<Label text="Schaden" />
|
||||
<Label text="Schaden" disabled={locked} />
|
||||
<TextField
|
||||
className="ddn"
|
||||
value={dpdn}
|
||||
onChange={this.onEvent.bind(null, 'dpdn')}
|
||||
className="damage-dice-number"
|
||||
value={damageDiceNumber}
|
||||
onChange={this.onEvent.bind(null, 'ddn')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<Dropdown
|
||||
className="dds"
|
||||
className="damage-dice-sides"
|
||||
hint="W"
|
||||
value={dpds}
|
||||
value={damageDiceSides}
|
||||
options={[['W3',3],['W6',6],['W20',20]]}
|
||||
onChange={this.onValue.bind(null, 'dpds')}
|
||||
onChange={this.onValue.bind(null, 'dds')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<TextField
|
||||
className="df"
|
||||
value={dpf}
|
||||
onChange={this.onEvent.bind(null, 'dpf')}
|
||||
className="damage-flat"
|
||||
value={damageFlat}
|
||||
onChange={this.onEvent.bind(null, 'df')}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<Dropdown
|
||||
className="re"
|
||||
className="reach"
|
||||
label="Reichweite"
|
||||
hint="Auswählen"
|
||||
value={re}
|
||||
value={reach}
|
||||
options={[['Kurz',1],['Mittel',2],['Lang',3]]}
|
||||
onChange={this.onValue.bind(null, 're')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<div className="container">
|
||||
<Label text="AT/PA-Mod" />
|
||||
<Label text="AT/PA-Mod" disabled={locked} />
|
||||
<TextField
|
||||
className="at"
|
||||
value={at}
|
||||
onChange={this.onEvent.bind(null, 'at')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<TextField
|
||||
className="pa"
|
||||
value={pa}
|
||||
onChange={this.onEvent.bind(null, 'pa')}
|
||||
disabled={ct === 'CT_6'}
|
||||
disabled={locked || combattechnique === 'CT_6'}
|
||||
/>
|
||||
</div>
|
||||
{ ct === 'CT_10' ? (
|
||||
{ combattechnique === 'CT_10' ? (
|
||||
<TextField
|
||||
className="stp"
|
||||
label="Strukturp."
|
||||
value={stp}
|
||||
onChange={this.onEvent.bind(null, 'length')}
|
||||
disabled={locked}
|
||||
/>
|
||||
) : (
|
||||
<TextField
|
||||
@@ -213,6 +248,7 @@ export default class ItemEditor extends Component {
|
||||
label="Länge in Hf."
|
||||
value={length}
|
||||
onChange={this.onEvent.bind(null, 'length')}
|
||||
disabled={locked}
|
||||
/>
|
||||
) }
|
||||
</div>
|
||||
@@ -221,78 +257,88 @@ export default class ItemEditor extends Component {
|
||||
<Hr />
|
||||
<div className="row">
|
||||
<Dropdown
|
||||
className="ct"
|
||||
className="combattechnique"
|
||||
label="Kampftechnik"
|
||||
hint="Keine"
|
||||
value={ct}
|
||||
value={combattechnique}
|
||||
options={CombatTechniquesStore.getAll().filter(e => e.gr === 2).map(e => [e.name, e.id])}
|
||||
onChange={this.onValue.bind(null, 'ct')}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
<div className="row">
|
||||
<TextField
|
||||
className="rt"
|
||||
className="reloadtime"
|
||||
label="Ladezeiten"
|
||||
value={rt}
|
||||
value={reloadtime}
|
||||
onChange={this.onEvent.bind(null, 'rt')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<div className="container">
|
||||
<Label text="Schaden" />
|
||||
<Label text="Schaden" disabled={locked} />
|
||||
<TextField
|
||||
className="ddn"
|
||||
value={dpdn}
|
||||
onChange={this.onEvent.bind(null, 'dpdn')}
|
||||
className="damage-dice-number"
|
||||
value={damageDiceNumber}
|
||||
onChange={this.onEvent.bind(null, 'ddn')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<Dropdown
|
||||
className="dds"
|
||||
className="damage-dice-sides"
|
||||
hint="W"
|
||||
value={dpds}
|
||||
value={damageDiceSides}
|
||||
options={[['W3',3],['W6',6],['W20',20]]}
|
||||
onChange={this.onValue.bind(null, 'dpds')}
|
||||
onChange={this.onValue.bind(null, 'dds')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<TextField
|
||||
className="df"
|
||||
value={dpf}
|
||||
onChange={this.onEvent.bind(null, 'dpf')}
|
||||
className="damage-flat"
|
||||
value={damageFlat}
|
||||
onChange={this.onEvent.bind(null, 'df')}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="container">
|
||||
<TextField
|
||||
className="rb1"
|
||||
className="range1"
|
||||
label="Nah"
|
||||
value={rb1}
|
||||
value={range1}
|
||||
onChange={this.onValue.bind(null, 'rb1')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<TextField
|
||||
className="rb2"
|
||||
className="range2"
|
||||
label="Mittel"
|
||||
value={rb2}
|
||||
value={range2}
|
||||
onChange={this.onValue.bind(null, 'rb2')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<TextField
|
||||
className="rb3"
|
||||
className="range3"
|
||||
label="Weit"
|
||||
value={rb3}
|
||||
value={range3}
|
||||
onChange={this.onValue.bind(null, 'rb3')}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
<Dropdown
|
||||
className="am"
|
||||
className="ammunition"
|
||||
label="Munition"
|
||||
hint="Keine"
|
||||
value={am}
|
||||
value={ammunition}
|
||||
options={[
|
||||
['Keine',null]
|
||||
]}
|
||||
onChange={this.onValue.bind(null, 'am')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<TextField
|
||||
className="length"
|
||||
label="Länge in Hf."
|
||||
value={length}
|
||||
onChange={this.onEvent.bind(null, 'length')}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
</div> ) : null }
|
||||
@@ -305,19 +351,22 @@ export default class ItemEditor extends Component {
|
||||
label="RS"
|
||||
value={pro}
|
||||
onChange={this.onEvent.bind(null, 'pro')}
|
||||
disabled={locked}
|
||||
/>
|
||||
<TextField
|
||||
className="enc"
|
||||
label="BE"
|
||||
value={enc}
|
||||
onChange={this.onEvent.bind(null, 'enc')}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
<Checkbox
|
||||
className="addp"
|
||||
className="addpenalties"
|
||||
label="Zusätzliche Abzüge"
|
||||
checked={addp}
|
||||
onClick={this.onSwitch.bind(null, 'addp')}
|
||||
checked={addpenalties}
|
||||
onClick={this.onSwitch.bind(null, 'addpenalties')}
|
||||
disabled={locked}
|
||||
/>
|
||||
</div>
|
||||
</div> ) : null }
|
||||
|
||||
@@ -76,15 +76,15 @@
|
||||
}
|
||||
|
||||
> div.container > div {
|
||||
&.ddn, &.dds, &.df, &.at, &.pa, &.rb1, &.rb2, &.rb3, &.pro, &.enc {
|
||||
&.damage-dice-number, &.damage-dice-sides, &.damage-flat, &.at, &.pa, &.range1, &.range2, &.range3, &.pro, &.enc {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
&.dds {
|
||||
&.damage-dice-sides {
|
||||
width: 65px;
|
||||
}
|
||||
|
||||
&.ddn, &.df, &.at, &.pa, &.rb1, &.rb2, &.rb3, &.pro, &.enc {
|
||||
&.damage-dice-sides, &.damage-flat, &.at, &.pa, &.range1, &.range2, &.range3, &.pro, &.enc {
|
||||
width: 40px;
|
||||
|
||||
input {
|
||||
@@ -95,15 +95,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 15px 0 5px;
|
||||
border: none;
|
||||
height: 1px;
|
||||
background: $color9;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 5px;
|
||||
}
|
||||
hr:first-child {
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1,61 @@
|
||||
@import "ItemEditor";
|
||||
@import "ItemEditor";
|
||||
|
||||
.page {
|
||||
&#inventory {
|
||||
tbody {
|
||||
td:last-child {
|
||||
padding-right: 11px;
|
||||
}
|
||||
|
||||
td.inc > .btn {
|
||||
height: 32px;
|
||||
padding: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overlay > .inventory-item {
|
||||
max-width: 280px;
|
||||
|
||||
h4 {
|
||||
span:first-child {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
margin-top: 15px;
|
||||
font: 500 13px/22px Alegreya Sans;
|
||||
letter-spacing: 0.05em;
|
||||
|
||||
td {
|
||||
padding: 0;
|
||||
border: none;
|
||||
height: auto;
|
||||
|
||||
&:first-child {
|
||||
color: $color2;
|
||||
padding-right: 15px;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
color: $color1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p.ammunition {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
p.armor {
|
||||
margin-top: 10px;
|
||||
font: 500 13px/22px Alegreya Sans;
|
||||
color: $color1;
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ export default class CombatTechniques extends Component {
|
||||
]} />
|
||||
</div>
|
||||
<Scroll>
|
||||
<table>
|
||||
<table className="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="type">Gruppe</td>
|
||||
|
||||
@@ -87,7 +87,7 @@ export default class Liturgies extends Component {
|
||||
/>
|
||||
</div>
|
||||
<Scroll className="list">
|
||||
<table>
|
||||
<table className="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="type">Gruppe</td>
|
||||
@@ -146,7 +146,7 @@ export default class Liturgies extends Component {
|
||||
/>
|
||||
</div>
|
||||
<Scroll className="list">
|
||||
<table>
|
||||
<table className="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="type">Gruppe</td>
|
||||
|
||||
@@ -69,7 +69,7 @@ export default class SpecialAbilities extends Component {
|
||||
/>
|
||||
</div>
|
||||
<Scroll className="list">
|
||||
<table>
|
||||
<table className="list large-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="type">Gruppe</td>
|
||||
@@ -96,7 +96,7 @@ export default class SpecialAbilities extends Component {
|
||||
<BorderButton label="Hinzufügen" onClick={this.showAddSlidein} />
|
||||
</div>
|
||||
<Scroll className="list">
|
||||
<table>
|
||||
<table className="list large-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="type">Gruppe</td>
|
||||
|
||||
@@ -96,7 +96,7 @@ export default class Spells extends Component {
|
||||
/>
|
||||
</div>
|
||||
<Scroll className="list">
|
||||
<table>
|
||||
<table className="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="type">Gruppe</td>
|
||||
@@ -156,7 +156,7 @@ export default class Spells extends Component {
|
||||
/>
|
||||
</div>
|
||||
<Scroll className="list">
|
||||
<table>
|
||||
<table className="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="type">Gruppe</td>
|
||||
|
||||
@@ -62,7 +62,7 @@ export default class Talents extends Component {
|
||||
<Checkbox checked={talentRating} onClick={this.changeTalentRating}>Wertung durch Kultur anzeigen</Checkbox>
|
||||
</div>
|
||||
<Scroll className="list">
|
||||
<table>
|
||||
<table className="list">
|
||||
<thead>
|
||||
<tr>
|
||||
<td className="type">Gruppe</td>
|
||||
|
||||
Reference in New Issue
Block a user