Add FieldUmask and use for `newFileMode` (#214)
parent
af764380a6
commit
b904fb9f17
@ -0,0 +1,79 @@
|
||||
import { FieldBase } from './base';
|
||||
|
||||
const PERM_MAP: Record<number, string> = {
|
||||
0: '---',
|
||||
1: '--x',
|
||||
2: '-w-',
|
||||
3: '-wx',
|
||||
4: 'r--',
|
||||
5: 'r-x',
|
||||
6: 'rw-',
|
||||
7: 'rwx',
|
||||
};
|
||||
|
||||
export class FieldUmask extends FieldBase<number | undefined> {
|
||||
protected getValueClassName() {
|
||||
return super.getValueClassName() + ' checkbox-box checkbox-small';
|
||||
}
|
||||
public renderInput() {
|
||||
const value = this.getValue() || 0;
|
||||
console.log(this.state.newValue, '=>', value);
|
||||
const cell = (target: number, permission: number) => {
|
||||
const shifted = permission * target;
|
||||
const checked = (value & shifted) > 0;
|
||||
return <td className="checkbox">
|
||||
<div className="checkbox-box">
|
||||
<div className={`checkbox ${checked ? 'checked' : ''}`}
|
||||
onClick={() => this.setPart(shifted, !checked)} />
|
||||
</div>
|
||||
</td>;
|
||||
};
|
||||
const row = (target: number, name: string) => <tr>
|
||||
<th scope="row">{name}</th>
|
||||
{cell(target, 4)}
|
||||
{cell(target, 2)}
|
||||
{cell(target, 1)}
|
||||
</tr>;
|
||||
return <>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><th /><th>Read</th><th>Write</th><th>Execute</th></tr>
|
||||
{row(0o100, 'Owner')}
|
||||
{row(0o010, 'Group')}
|
||||
{row(0o001, 'Other')}
|
||||
</tbody>
|
||||
</table>
|
||||
<span>
|
||||
Resulting mask:{" "}
|
||||
<code>
|
||||
{PERM_MAP[(value / 0o100) & 0o7]}
|
||||
{PERM_MAP[(value / 0o010) & 0o7]}
|
||||
{PERM_MAP[(value / 0o001) & 0o7]}
|
||||
</code>
|
||||
</span>
|
||||
</>;
|
||||
}
|
||||
public getError() {
|
||||
const { newValue } = this.state;
|
||||
const { validator, optional } = this.props;
|
||||
if (newValue === undefined) {
|
||||
if (optional) return null;
|
||||
return 'No value given';
|
||||
} else if (Number.isNaN(Number(newValue))) {
|
||||
return 'Not a number';
|
||||
}
|
||||
return validator ? validator(newValue!) : null;
|
||||
}
|
||||
public getValue(): number | undefined {
|
||||
const { newValue, oldValue } = this.state;
|
||||
if (newValue === undefined) {
|
||||
return this.props.optional ? newValue : Number(oldValue);
|
||||
}
|
||||
return typeof newValue === 'number' ? newValue : (Number(newValue) || undefined);
|
||||
}
|
||||
public setPart(part: number, checked: boolean): void {
|
||||
this.setState(({ newValue }) => ({
|
||||
newValue: checked ? (newValue || 0) | part : (newValue || 0) & ~part
|
||||
}), () => this.props.onChange(this.getValue()));
|
||||
}
|
||||
}
|
Loading…
Reference in new issue