react-admin-base-bootstrap 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.yarnrc +1 -0
- package/assets/main.css +63 -0
- package/lib/esm/Components/ApiSelect.d.ts +3 -0
- package/lib/esm/Components/ApiSelect.js +82 -0
- package/lib/esm/Components/BootstrapDataTable.d.ts +12 -0
- package/lib/esm/Components/BootstrapDataTable.js +141 -0
- package/lib/esm/Components/BootstrapPagination.d.ts +9 -0
- package/lib/esm/Components/BootstrapPagination.js +13 -0
- package/lib/esm/Components/CRUD.d.ts +20 -0
- package/lib/esm/Components/CRUD.js +88 -0
- package/lib/esm/Components/CheckBox.d.ts +2 -0
- package/lib/esm/Components/CheckBox.js +7 -0
- package/lib/esm/Components/EntityEditor.d.ts +11 -0
- package/lib/esm/Components/EntityEditor.js +61 -0
- package/lib/esm/Components/ErrorBoundary.d.ts +12 -0
- package/lib/esm/Components/ErrorBoundary.js +25 -0
- package/lib/esm/Components/ExcelExportButton.d.ts +8 -0
- package/lib/esm/Components/ExcelExportButton.js +8 -0
- package/lib/esm/Components/ExternalLoginButton.d.ts +7 -0
- package/lib/esm/Components/ExternalLoginButton.js +12 -0
- package/lib/esm/Components/FilePickerCore.d.ts +16 -0
- package/lib/esm/Components/FilePickerCore.js +82 -0
- package/lib/esm/Components/GoToTop.d.ts +11 -0
- package/lib/esm/Components/GoToTop.js +34 -0
- package/lib/esm/Components/ImagePicker.d.ts +2 -0
- package/lib/esm/Components/ImagePicker.js +22 -0
- package/lib/esm/Components/LanguageProvider.d.ts +8 -0
- package/lib/esm/Components/LanguageProvider.js +42 -0
- package/lib/esm/Components/LoadingButton.d.ts +2 -0
- package/lib/esm/Components/LoadingButton.js +6 -0
- package/lib/esm/Components/MenuState.d.ts +3 -0
- package/lib/esm/Components/MenuState.js +20 -0
- package/lib/esm/Components/MultiFilePicker.d.ts +11 -0
- package/lib/esm/Components/MultiFilePicker.js +22 -0
- package/lib/esm/Components/SingleFilePicker.d.ts +12 -0
- package/lib/esm/Components/SingleFilePicker.js +20 -0
- package/lib/esm/Components/TopProgressBar.d.ts +3 -0
- package/lib/esm/Components/TopProgressBar.js +10 -0
- package/lib/esm/Components/Validator.d.ts +16 -0
- package/lib/esm/Components/Validator.js +33 -0
- package/lib/esm/i18n/de.json +34 -0
- package/lib/esm/i18n/en.json +35 -0
- package/lib/esm/i18n/tr.json +35 -0
- package/lib/esm/index.d.ts +19 -0
- package/lib/esm/index.js +19 -0
- package/package.json +55 -0
- package/src/Components/ApiSelect.tsx +122 -0
- package/src/Components/BootstrapDataTable.tsx +160 -0
- package/src/Components/BootstrapPagination.tsx +35 -0
- package/src/Components/CRUD.tsx +117 -0
- package/src/Components/CheckBox.tsx +9 -0
- package/src/Components/EntityEditor.tsx +67 -0
- package/src/Components/ErrorBoundary.tsx +29 -0
- package/src/Components/ExcelExportButton.tsx +11 -0
- package/src/Components/ExternalLoginButton.tsx +14 -0
- package/src/Components/FilePickerCore.tsx +87 -0
- package/src/Components/GoToTop.tsx +41 -0
- package/src/Components/ImagePicker.tsx +26 -0
- package/src/Components/LanguageProvider.tsx +61 -0
- package/src/Components/LoadingButton.tsx +7 -0
- package/src/Components/MenuState.tsx +24 -0
- package/src/Components/MultiFilePicker.tsx +43 -0
- package/src/Components/SingleFilePicker.tsx +40 -0
- package/src/Components/TopProgressBar.tsx +13 -0
- package/src/Components/Validator.tsx +55 -0
- package/src/i18n/de.json +34 -0
- package/src/i18n/en.json +35 -0
- package/src/i18n/tr.json +35 -0
- package/src/index.ts +42 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import prettysize from 'prettysize';
|
|
3
|
+
import { Button } from "reactstrap";
|
|
4
|
+
import { useApp, useFilePicker, usePreviewComponent } from "react-admin-base";
|
|
5
|
+
import { FormattedMessage } from "react-intl";
|
|
6
|
+
var photo_ext = ["png", "jpg", "jpeg", "svg"];
|
|
7
|
+
function is_photo(name) {
|
|
8
|
+
return photo_ext.indexOf(name.split('.')[1]) !== -1;
|
|
9
|
+
}
|
|
10
|
+
function is_absolute(url) {
|
|
11
|
+
if (url.indexOf("blob:") === 0)
|
|
12
|
+
return false;
|
|
13
|
+
var pat = /^https?:\/\//i;
|
|
14
|
+
return !pat.test(url);
|
|
15
|
+
}
|
|
16
|
+
export function Relative({ children }) {
|
|
17
|
+
const app = useApp();
|
|
18
|
+
if (!children)
|
|
19
|
+
return null;
|
|
20
|
+
const { src, href } = children.props;
|
|
21
|
+
return React.cloneElement(children, {
|
|
22
|
+
src: src && (is_absolute(src) ? app.endpoint.replace(/\/$/, "") + src : src),
|
|
23
|
+
href: href && (is_absolute(href) ? app.endpoint.replace(/\/$/, "") + href : href)
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export function Preview({ value }) {
|
|
27
|
+
var name = value.$name;
|
|
28
|
+
var src = value.$blob_url || value.$src;
|
|
29
|
+
if (is_photo(name)) {
|
|
30
|
+
return React.createElement("div", { className: "mt-2" },
|
|
31
|
+
React.createElement(Relative, null,
|
|
32
|
+
React.createElement("img", { src: src, style: { maxHeight: '150px', maxWidth: '100%' }, alt: name })));
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
export default function FilePickerCore({ disabled, className, accepts, value, onNotify, children, transform }) {
|
|
37
|
+
const [uc, cancel, pick] = useFilePicker(value, onNotify);
|
|
38
|
+
const CustomPreview = usePreviewComponent() || Preview;
|
|
39
|
+
const chooseFile = useCallback(function (e) {
|
|
40
|
+
e.preventDefault();
|
|
41
|
+
pick(accepts, transform);
|
|
42
|
+
}, [pick, accepts, transform]);
|
|
43
|
+
if (uc.$state === 1) { // dosya sec
|
|
44
|
+
return React.createElement("div", { className: className },
|
|
45
|
+
React.createElement(Button, { color: "primary", size: "sm", onClick: chooseFile, disabled: disabled },
|
|
46
|
+
React.createElement("i", { className: "fa fa-upload" }),
|
|
47
|
+
" ",
|
|
48
|
+
React.createElement(FormattedMessage, { id: "CHOOSE_FILE" })),
|
|
49
|
+
children && children(null));
|
|
50
|
+
}
|
|
51
|
+
else if (uc.$state === 2) { // yukleniyor
|
|
52
|
+
return React.createElement("div", { className: className },
|
|
53
|
+
React.createElement(Button, { color: "danger", outline: true, size: "sm", onClick: cancel },
|
|
54
|
+
React.createElement("i", { className: "fa fa-times-circle" })),
|
|
55
|
+
' ',
|
|
56
|
+
React.createElement(Button, { disabled: true, size: "sm", outline: true, color: "dark" },
|
|
57
|
+
React.createElement("i", { className: "fa fa-spinner fa-spin" }),
|
|
58
|
+
React.createElement("span", { style: { width: '35px', display: 'inline-block' } },
|
|
59
|
+
Math.round(uc.$pr * 1000) / 10,
|
|
60
|
+
"%"),
|
|
61
|
+
uc.name),
|
|
62
|
+
children && children(uc));
|
|
63
|
+
}
|
|
64
|
+
else if (uc.$state === 3) { // yuklendi
|
|
65
|
+
return React.createElement("div", { className: className },
|
|
66
|
+
!disabled && React.createElement(Button, { color: "danger", outline: true, size: "sm", onClick: cancel },
|
|
67
|
+
React.createElement("i", { className: "fa fa-trash" })),
|
|
68
|
+
"\u00A0",
|
|
69
|
+
React.createElement(Relative, null,
|
|
70
|
+
React.createElement("a", { href: uc.$src, target: "_blank", className: "btn btn-sm btn-outline-primary" },
|
|
71
|
+
React.createElement("i", { className: "fa fa-download" }),
|
|
72
|
+
" ",
|
|
73
|
+
uc.name)),
|
|
74
|
+
React.createElement("span", null,
|
|
75
|
+
"\u00A0(",
|
|
76
|
+
prettysize(uc.$size),
|
|
77
|
+
")"),
|
|
78
|
+
React.createElement(CustomPreview, { value: uc }),
|
|
79
|
+
children && children(uc));
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export default class GoToTop extends React.Component {
|
|
3
|
+
state: {
|
|
4
|
+
show: boolean;
|
|
5
|
+
};
|
|
6
|
+
scrollTop(e: any): void;
|
|
7
|
+
handleScroll(e: any): void;
|
|
8
|
+
componentDidMount(): void;
|
|
9
|
+
componentWillUnmount(): void;
|
|
10
|
+
render(): JSX.Element | null;
|
|
11
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { FormattedMessage } from "react-intl";
|
|
3
|
+
export default class GoToTop extends React.Component {
|
|
4
|
+
constructor() {
|
|
5
|
+
super(...arguments);
|
|
6
|
+
this.state = { show: false };
|
|
7
|
+
}
|
|
8
|
+
scrollTop(e) {
|
|
9
|
+
e.preventDefault();
|
|
10
|
+
window.scrollTo(0, 0);
|
|
11
|
+
}
|
|
12
|
+
handleScroll(e) {
|
|
13
|
+
var newShow = window.scrollY > 100;
|
|
14
|
+
if (newShow !== this.state.show) {
|
|
15
|
+
this.setState({ show: newShow });
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
componentDidMount() {
|
|
19
|
+
this.handleScroll = this.handleScroll.bind(this);
|
|
20
|
+
window.addEventListener('scroll', this.handleScroll);
|
|
21
|
+
}
|
|
22
|
+
componentWillUnmount() {
|
|
23
|
+
window.removeEventListener('scroll', this.handleScroll);
|
|
24
|
+
}
|
|
25
|
+
render() {
|
|
26
|
+
if (!this.state.show) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return React.createElement("div", { onClick: this.scrollTop, className: "back-btn-shown" },
|
|
30
|
+
React.createElement("span", null,
|
|
31
|
+
React.createElement(FormattedMessage, { id: "GO_TOP" })),
|
|
32
|
+
React.createElement("i", { className: "fa fa-angle-up", title: "Go top" }));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import React, { useCallback } from 'react';
|
|
11
|
+
import SingleFilePicker from './SingleFilePicker';
|
|
12
|
+
export default function ImagePicker(props) {
|
|
13
|
+
const { width, height, type, exact } = props;
|
|
14
|
+
const transform = useCallback(function (file) {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
const modalCropper = yield import('modal-cropper');
|
|
17
|
+
const modalCropperFnc = modalCropper.default || modalCropper;
|
|
18
|
+
return yield modalCropperFnc(file, width, height, type, exact);
|
|
19
|
+
});
|
|
20
|
+
}, [width, height, type, exact]);
|
|
21
|
+
return React.createElement(SingleFilePicker, Object.assign({}, props, { transform: transform, accepts: "image/png, image/jpeg" }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
export declare function useLanguage(): any;
|
|
3
|
+
export default function LanguageProvider({ defaultLanguage, languages, children }: {
|
|
4
|
+
defaultLanguage: any;
|
|
5
|
+
languages: any;
|
|
6
|
+
children: any;
|
|
7
|
+
}): JSX.Element;
|
|
8
|
+
export declare function LanguageSwitcher(): JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import React, { useContext, useReducer, useMemo, useState } from 'react';
|
|
2
|
+
import { useApp } from 'react-admin-base';
|
|
3
|
+
import { IntlProvider } from 'react-intl';
|
|
4
|
+
import { Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
|
|
5
|
+
import enMessages from '../i18n/en.json';
|
|
6
|
+
import deMessages from '../i18n/de.json';
|
|
7
|
+
import trMessages from '../i18n/tr.json';
|
|
8
|
+
const _languages = {
|
|
9
|
+
'en': enMessages,
|
|
10
|
+
'de': deMessages,
|
|
11
|
+
'tr': trMessages
|
|
12
|
+
};
|
|
13
|
+
const LanguageContext = React.createContext(null);
|
|
14
|
+
export function useLanguage() {
|
|
15
|
+
return useContext(LanguageContext);
|
|
16
|
+
}
|
|
17
|
+
export default function LanguageProvider({ defaultLanguage, languages, children }) {
|
|
18
|
+
const app = useApp();
|
|
19
|
+
const preferredLanguage = (navigator.languages && navigator.languages[0]) ||
|
|
20
|
+
navigator.language;
|
|
21
|
+
const [lang, setLang] = useReducer((oldValue, newValue) => {
|
|
22
|
+
localStorage.setItem(app.id + "_" + 'language', newValue);
|
|
23
|
+
return newValue;
|
|
24
|
+
}, localStorage.getItem(app.id + "_" + 'language') || null);
|
|
25
|
+
const activeLanguageKey = (!!lang && languages[lang] && lang) || (languages[preferredLanguage] && preferredLanguage) || (languages[defaultLanguage] && defaultLanguage);
|
|
26
|
+
const activeLanguage = languages[activeLanguageKey];
|
|
27
|
+
const messages = useMemo(() => (Object.assign(Object.assign({}, (_languages[activeLanguageKey] || _languages.en)), activeLanguage.messages)), [activeLanguage]);
|
|
28
|
+
const value = useMemo(() => [activeLanguage, languages, setLang], [activeLanguage, languages, setLang]);
|
|
29
|
+
return React.createElement(IntlProvider, { locale: activeLanguageKey, messages: messages },
|
|
30
|
+
React.createElement(LanguageContext.Provider, { value: value }, children));
|
|
31
|
+
}
|
|
32
|
+
export function LanguageSwitcher() {
|
|
33
|
+
const [show, setShow] = useState(false);
|
|
34
|
+
const [activeLang, languages, setLanguage] = useLanguage();
|
|
35
|
+
return React.createElement(Dropdown, { isOpen: show, toggle: () => setShow(!show) },
|
|
36
|
+
React.createElement(DropdownToggle, { className: "nav-flag dropdown-toggle show", nav: true, caret: true },
|
|
37
|
+
React.createElement("img", { width: "20", src: activeLang.icon, alt: activeLang.name })),
|
|
38
|
+
React.createElement(DropdownMenu, { end: true }, Object.entries(languages).map(([key, value]) => React.createElement(DropdownItem, { key: key, active: activeLang === value, onClick: () => setLanguage(key) },
|
|
39
|
+
React.createElement("img", { width: "20", src: value.icon, alt: value.name }),
|
|
40
|
+
" ",
|
|
41
|
+
React.createElement("span", { className: "align-middle" }, value.name)))));
|
|
42
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button } from 'reactstrap';
|
|
3
|
+
export default function LoadingButton(props) {
|
|
4
|
+
return props.loading ? React.createElement(Button, Object.assign({}, props, { loading: undefined, disabled: true }),
|
|
5
|
+
React.createElement("i", { className: "fas fa-spin fa-circle-notch" })) : React.createElement(Button, Object.assign({}, props, { loading: undefined }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { useEffect, useReducer } from 'react';
|
|
2
|
+
import { useMediaQuery } from 'react-responsive';
|
|
3
|
+
import { useHistory } from "react-router-dom";
|
|
4
|
+
export function useIsMobile() {
|
|
5
|
+
return useMediaQuery({ query: '(max-width: 992px)' });
|
|
6
|
+
}
|
|
7
|
+
export function useMenuState() {
|
|
8
|
+
const isMobile = useIsMobile();
|
|
9
|
+
const state = useReducer(a => !a, !isMobile);
|
|
10
|
+
const [isOpen, toggleOpen] = state;
|
|
11
|
+
const history = useHistory();
|
|
12
|
+
useEffect(function () {
|
|
13
|
+
if (isMobile && isOpen) {
|
|
14
|
+
return history.listen(function () {
|
|
15
|
+
toggleOpen();
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}, [isMobile, isOpen, history]);
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare type MultiFilePickerProps = {
|
|
3
|
+
disabled?: boolean;
|
|
4
|
+
className?: string;
|
|
5
|
+
accepts?: string;
|
|
6
|
+
value: any;
|
|
7
|
+
onChange: (value: any) => void;
|
|
8
|
+
children?: (value: any) => React.ReactNode;
|
|
9
|
+
};
|
|
10
|
+
export default function MultiFilePicker({ disabled, className, accepts, value, onChange, children }: MultiFilePickerProps): JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { useMultiFilePicker } from "react-admin-base";
|
|
3
|
+
import { FormattedMessage } from "react-intl";
|
|
4
|
+
import { Button } from "reactstrap";
|
|
5
|
+
import FilePickerCore from "./FilePickerCore";
|
|
6
|
+
export default function MultiFilePicker({ disabled, className, accepts, value, onChange, children }) {
|
|
7
|
+
const uniqueIdList = useMemo(() => [], []);
|
|
8
|
+
const [controllers, _onChange, chooseFile] = useMultiFilePicker(value, onChange);
|
|
9
|
+
function getConstantUniqueIdFor(element) {
|
|
10
|
+
if (uniqueIdList.indexOf(element) < 0) {
|
|
11
|
+
uniqueIdList.push(element);
|
|
12
|
+
}
|
|
13
|
+
return uniqueIdList.indexOf(element);
|
|
14
|
+
}
|
|
15
|
+
return React.createElement("div", null,
|
|
16
|
+
React.createElement(Button, { color: "primary", size: "sm", disabled: !!disabled, outline: true, onClick: chooseFile.bind(null, accepts) },
|
|
17
|
+
React.createElement("i", { className: "fa fa-upload" }),
|
|
18
|
+
" ",
|
|
19
|
+
React.createElement(FormattedMessage, { id: "CHOOSE_FILE" })),
|
|
20
|
+
children && children(null),
|
|
21
|
+
controllers.map((a, i) => React.createElement(FilePickerCore, { key: getConstantUniqueIdFor(a), disabled: !!disabled, className: "mt-2", accepts: accepts, value: a, onNotify: _onChange.bind(null, a) }, children)));
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
declare type SingleFilePickerProps = {
|
|
3
|
+
disabled?: boolean;
|
|
4
|
+
className?: string;
|
|
5
|
+
accepts?: string;
|
|
6
|
+
value: any;
|
|
7
|
+
onChange: (value: any) => void;
|
|
8
|
+
children?: (value: any) => React.ReactNode;
|
|
9
|
+
transform?: any;
|
|
10
|
+
};
|
|
11
|
+
export default function SingleFilePicker({ disabled, className, accepts, value, onChange, transform, children }: SingleFilePickerProps): JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React, { useCallback, useMemo } from 'react';
|
|
2
|
+
import { useUploadController } from "react-admin-base";
|
|
3
|
+
import FilePickerCore from "./FilePickerCore";
|
|
4
|
+
export default function SingleFilePicker({ disabled, className, accepts, value, onChange, transform, children }) {
|
|
5
|
+
const uploadController = useUploadController();
|
|
6
|
+
const controller = useMemo(() => uploadController(value), [uploadController, value]);
|
|
7
|
+
const _onChange = useCallback(function () {
|
|
8
|
+
if (controller.$state === 3) {
|
|
9
|
+
if (value !== controller) {
|
|
10
|
+
onChange(controller);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
if (!!value) {
|
|
15
|
+
onChange(null);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}, [value, controller, onChange]);
|
|
19
|
+
return React.createElement(FilePickerCore, { disabled: !!disabled, className: className, accepts: accepts, value: controller, onNotify: _onChange, transform: transform }, children);
|
|
20
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import NProgress from 'nprogress';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { useAuth } from "react-admin-base";
|
|
4
|
+
export default function TopProgressBar({ children }) {
|
|
5
|
+
const [api] = useAuth();
|
|
6
|
+
useEffect(function () {
|
|
7
|
+
return api.set_hook(() => NProgress.start(), () => NProgress.done());
|
|
8
|
+
}, [api.set_hook]);
|
|
9
|
+
return children;
|
|
10
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
declare type ValidatorProps = {
|
|
3
|
+
name: string;
|
|
4
|
+
type: any;
|
|
5
|
+
children: any;
|
|
6
|
+
};
|
|
7
|
+
export declare function Validator({ name, type, children }: ValidatorProps): JSX.Element;
|
|
8
|
+
declare type ValueValidatorProps = {
|
|
9
|
+
name: string;
|
|
10
|
+
type: any;
|
|
11
|
+
value: any;
|
|
12
|
+
children: any;
|
|
13
|
+
};
|
|
14
|
+
export declare function ValueValidator({ name, value, type, children }: ValueValidatorProps): JSX.Element;
|
|
15
|
+
export declare function ValidationErrors(): JSX.Element | null;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useValidate, useValidator } from 'react-admin-base';
|
|
3
|
+
import { FormattedMessage } from "react-intl";
|
|
4
|
+
import { Alert, FormFeedback } from "reactstrap";
|
|
5
|
+
function ValidatorCore(name, value, type, children) {
|
|
6
|
+
const error = useValidate(name || '', value, type);
|
|
7
|
+
return React.createElement(React.Fragment, null,
|
|
8
|
+
(error
|
|
9
|
+
&& React.cloneElement(children, { invalid: !!error, className: (children.props.className || '') + (!!error ? ' is-invalid' : '') })) || children,
|
|
10
|
+
error && React.createElement(FormFeedback, { className: "d-block" }, error));
|
|
11
|
+
}
|
|
12
|
+
export function Validator({ name, type, children }) {
|
|
13
|
+
return ValidatorCore(name, children.props.value || children.props.checked, type, children);
|
|
14
|
+
}
|
|
15
|
+
export function ValueValidator({ name, value, type, children }) {
|
|
16
|
+
return ValidatorCore(name, value, type, children);
|
|
17
|
+
}
|
|
18
|
+
export function ValidationErrors() {
|
|
19
|
+
const validator = useValidator();
|
|
20
|
+
if (validator.messagesShown) {
|
|
21
|
+
let errors = Object.values(validator.getErrorMessages()).filter(a => !!a);
|
|
22
|
+
if (!!errors.length) {
|
|
23
|
+
return React.createElement(Alert, { color: "danger", toggle: () => validator.hideMessages() },
|
|
24
|
+
React.createElement("p", null,
|
|
25
|
+
React.createElement("i", { className: "fas fa-exclamation-circle" }),
|
|
26
|
+
" ",
|
|
27
|
+
React.createElement("b", null,
|
|
28
|
+
React.createElement(FormattedMessage, { id: "VALIDATION.ERROR" }))),
|
|
29
|
+
React.createElement("ol", { className: "mb-0" }, errors.map(value => React.createElement("li", null, value))));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ENTITY.SAVE": "Speichern",
|
|
3
|
+
"ENTITY.CANCEL": "Abbrechen",
|
|
4
|
+
"USERNAME": "Benutzername",
|
|
5
|
+
"PASSWORD": "Passwort",
|
|
6
|
+
"FORGOT_PASSWORD": "Ich habe mein Passwort vergessen",
|
|
7
|
+
"LOGIN": "Einloggen",
|
|
8
|
+
"LOGIN_HEAD": "Anmeldebereich",
|
|
9
|
+
"SUBMIT": "Absenden",
|
|
10
|
+
"SIGN_IN_USING": "Mit anmelden",
|
|
11
|
+
"RESET_PASSWORD": "Passwort zurücksetzen",
|
|
12
|
+
"EMAIL": "Email",
|
|
13
|
+
"AUTH_CODE": "Autorisierungscode",
|
|
14
|
+
"ENTER_AUTH_CODE": "Bitte geben Sie den Bestätigungscode ein, an den wir gesendet haben",
|
|
15
|
+
"CHANGE_EMAIL": "An eine neue E-Mail-Adresse gesendet.",
|
|
16
|
+
"PASSWORD_REPEAT": "Passwort (wieder)",
|
|
17
|
+
"VALIDATION.ERROR": "Entität hat folgende Fehler:",
|
|
18
|
+
"ENTITY.SAVED": "Änderungen werden gespeichert.",
|
|
19
|
+
"CHOOSE_FILE": "Datei aussuchen",
|
|
20
|
+
"OR": "ODER",
|
|
21
|
+
"NEW_ACCOUNT": "Registrieren Sie ein neues Konto",
|
|
22
|
+
"GO_TOP": "Oben",
|
|
23
|
+
"INVALID_PASSWORD": "Ungültiger Benutzername oder Passwort",
|
|
24
|
+
"ALL": "Alles",
|
|
25
|
+
"SEARCH": "Suche...",
|
|
26
|
+
"NO_DATA_IS_AVAILABLE": "Es sind keine Daten verfügbar.",
|
|
27
|
+
"SELECT": "Auswählen",
|
|
28
|
+
"BACK": "Zurück",
|
|
29
|
+
"ACTIONS.DELETE.TITLE": "Bist du sicher?",
|
|
30
|
+
"ACTIONS.DELETE.TEXT": "Diese Aktion ist nicht umkehrbar!",
|
|
31
|
+
"ACTIONS.DELETE.CONFIRM": "Ja, löschen!",
|
|
32
|
+
"PLEASE_WAIT": "Warten Sie mal.",
|
|
33
|
+
"AUTHORIZATION_CODE": "Zugangscode"
|
|
34
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ENTITY.SAVE": "Save",
|
|
3
|
+
"ENTITY.CANCEL": "Cancel",
|
|
4
|
+
"USERNAME": "Username",
|
|
5
|
+
"PASSWORD": "Password",
|
|
6
|
+
"FORGOT_PASSWORD": "I forgot my password",
|
|
7
|
+
"LOGIN": "Login",
|
|
8
|
+
"LOGIN_HEAD": "Login Area",
|
|
9
|
+
"SUBMIT": "Submit",
|
|
10
|
+
"SIGN_IN_USING": "Sign in using {provider}",
|
|
11
|
+
"RESET_PASSWORD": "Reset Password",
|
|
12
|
+
"EMAIL": "Email",
|
|
13
|
+
"AUTH_CODE": "Authorization Code",
|
|
14
|
+
"ENTER_AUTH_CODE": "Please enter the verification code that we sent to {email}.",
|
|
15
|
+
"CHANGE_EMAIL": "Not your e-mail? <1>Sent to a new email address</1>.",
|
|
16
|
+
"PASSWORD_REPEAT": "Password (again)",
|
|
17
|
+
"VALIDATION.ERROR": "Entity has following errors:",
|
|
18
|
+
"ENTITY.SAVED": "Changes are saved.",
|
|
19
|
+
"CHOOSE_FILE": "Choose file",
|
|
20
|
+
"OR": "OR",
|
|
21
|
+
"NEW_ACCOUNT": "Register a new account",
|
|
22
|
+
"GO_TOP": "Go Top",
|
|
23
|
+
"CREATE_VALUE": "Create \"{text}\"",
|
|
24
|
+
"INVALID_PASSWORD": "Invalid username or password",
|
|
25
|
+
"ALL": "All",
|
|
26
|
+
"SEARCH": "Search...",
|
|
27
|
+
"NO_DATA_IS_AVAILABLE": "No data is available.",
|
|
28
|
+
"SELECT": "Please Select",
|
|
29
|
+
"BACK": "Back",
|
|
30
|
+
"ACTIONS.DELETE.TITLE": "Are you sure?",
|
|
31
|
+
"ACTIONS.DELETE.TEXT": "You won't be able to revert this!",
|
|
32
|
+
"ACTIONS.DELETE.CONFIRM": "Yes, delete it!",
|
|
33
|
+
"PLEASE_WAIT": "Please wait.",
|
|
34
|
+
"AUTHORIZATION_CODE": "Authorization Code"
|
|
35
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"ENTITY.SAVE": "Kaydet",
|
|
3
|
+
"ENTITY.CANCEL": "İptal",
|
|
4
|
+
"USERNAME": "Kullanıcı Adı",
|
|
5
|
+
"PASSWORD": "Şifre",
|
|
6
|
+
"FORGOT_PASSWORD": "Şifremi unuttum",
|
|
7
|
+
"SUBMIT": "Gönder",
|
|
8
|
+
"LOGIN": "Giriş",
|
|
9
|
+
"LOGIN_HEAD": "Oturum Açma Alanı",
|
|
10
|
+
"SIGN_IN_USING": "Kullanarak oturum açın",
|
|
11
|
+
"RESET_PASSWORD": "Şifreyi Sıfırla",
|
|
12
|
+
"EMAIL": "E-Posta",
|
|
13
|
+
"AUTH_CODE": "Yetki Kodu",
|
|
14
|
+
"ENTER_AUTH_CODE": "Lütfen gönderdiğimiz doğrulama kodunu giriniz.",
|
|
15
|
+
"CHANGE_EMAIL": "Yeni bir e-posta adresine gönderildi.",
|
|
16
|
+
"PASSWORD_REPEAT": "Şifre (tekrar)",
|
|
17
|
+
"VALIDATION.ERROR": "Aşağıdaki hatalar mevcut:",
|
|
18
|
+
"ENTITY.SAVED": "Değişiklikler kaydedildi.",
|
|
19
|
+
"CHOOSE_FILE": "Dosya Seçin",
|
|
20
|
+
"OR": "Veya",
|
|
21
|
+
"NEW_ACCOUNT": "Yeni bir hesap açın",
|
|
22
|
+
"GO_TOP": "Yukarı",
|
|
23
|
+
"CREATE_VALUE": "Oluştur \"{text}\"",
|
|
24
|
+
"INVALID_PASSWORD": "Kullanıcı adı veya şifre hatalı",
|
|
25
|
+
"ALL": "Hepsi",
|
|
26
|
+
"SEARCH": "Arama...",
|
|
27
|
+
"NO_DATA_IS_AVAILABLE": "Veri bulunmamaktadır.",
|
|
28
|
+
"SELECT": "Seçiniz",
|
|
29
|
+
"BACK": "Geri",
|
|
30
|
+
"ACTIONS.DELETE.TITLE": "Emin misiniz?",
|
|
31
|
+
"ACTIONS.DELETE.TEXT": "Bu işlem geri alınamaz!",
|
|
32
|
+
"ACTIONS.DELETE.CONFIRM": "Evet, sil!",
|
|
33
|
+
"PLEASE_WAIT": "Lütfen bekleyiniz.",
|
|
34
|
+
"AUTHORIZATION_CODE": "Yetki Kodu"
|
|
35
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import BootstrapTable, { Actions, ActionsColumn, Column, default as BootstrapDataTable, IdColumn, useDataTableContext } from './Components/BootstrapDataTable';
|
|
2
|
+
import CRUD, { CRUDActions, ModalEntityEditor } from './Components/CRUD';
|
|
3
|
+
import EntityEditor from "./Components/EntityEditor";
|
|
4
|
+
import ExcelExportButton from './Components/ExcelExportButton';
|
|
5
|
+
import ExternalLoginButton from './Components/ExternalLoginButton';
|
|
6
|
+
import GoToTop from "./Components/GoToTop";
|
|
7
|
+
import { ValidationErrors, Validator, ValueValidator } from "./Components/Validator";
|
|
8
|
+
import ApiSelect from "./Components/ApiSelect";
|
|
9
|
+
import { Preview, Relative } from './Components/FilePickerCore';
|
|
10
|
+
import ImagePicker from './Components/ImagePicker';
|
|
11
|
+
import LoadingButton from './Components/LoadingButton';
|
|
12
|
+
import MultiFilePicker from "./Components/MultiFilePicker";
|
|
13
|
+
import SingleFilePicker from "./Components/SingleFilePicker";
|
|
14
|
+
import LanguageProvider, { LanguageSwitcher, useLanguage } from "./Components/LanguageProvider";
|
|
15
|
+
import CheckBox from './Components/CheckBox';
|
|
16
|
+
import ErrorBoundary from './Components/ErrorBoundary';
|
|
17
|
+
import { useMenuState, useIsMobile } from './Components/MenuState';
|
|
18
|
+
import TopProgressBar from './Components/TopProgressBar';
|
|
19
|
+
export { useIsMobile, useMenuState, TopProgressBar, CRUD, ModalEntityEditor, CRUDActions, Relative, ApiSelect, Preview, ExcelExportButton, ExternalLoginButton, SingleFilePicker, MultiFilePicker, ImagePicker, BootstrapTable, EntityEditor, GoToTop, Validator, ValueValidator, ValidationErrors, LoadingButton, BootstrapDataTable, IdColumn, Column, ActionsColumn, Actions, useDataTableContext, LanguageProvider, useLanguage, LanguageSwitcher, ErrorBoundary, CheckBox };
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import BootstrapTable, { Actions, ActionsColumn, Column, default as BootstrapDataTable, IdColumn, useDataTableContext } from './Components/BootstrapDataTable';
|
|
2
|
+
import CRUD, { CRUDActions, ModalEntityEditor } from './Components/CRUD';
|
|
3
|
+
import EntityEditor from "./Components/EntityEditor";
|
|
4
|
+
import ExcelExportButton from './Components/ExcelExportButton';
|
|
5
|
+
import ExternalLoginButton from './Components/ExternalLoginButton';
|
|
6
|
+
import GoToTop from "./Components/GoToTop";
|
|
7
|
+
import { ValidationErrors, Validator, ValueValidator } from "./Components/Validator";
|
|
8
|
+
import ApiSelect from "./Components/ApiSelect";
|
|
9
|
+
import { Preview, Relative } from './Components/FilePickerCore';
|
|
10
|
+
import ImagePicker from './Components/ImagePicker';
|
|
11
|
+
import LoadingButton from './Components/LoadingButton';
|
|
12
|
+
import MultiFilePicker from "./Components/MultiFilePicker";
|
|
13
|
+
import SingleFilePicker from "./Components/SingleFilePicker";
|
|
14
|
+
import LanguageProvider, { LanguageSwitcher, useLanguage } from "./Components/LanguageProvider";
|
|
15
|
+
import CheckBox from './Components/CheckBox';
|
|
16
|
+
import ErrorBoundary from './Components/ErrorBoundary';
|
|
17
|
+
import { useMenuState, useIsMobile } from './Components/MenuState';
|
|
18
|
+
import TopProgressBar from './Components/TopProgressBar';
|
|
19
|
+
export { useIsMobile, useMenuState, TopProgressBar, CRUD, ModalEntityEditor, CRUDActions, Relative, ApiSelect, Preview, ExcelExportButton, ExternalLoginButton, SingleFilePicker, MultiFilePicker, ImagePicker, BootstrapTable, EntityEditor, GoToTop, Validator, ValueValidator, ValidationErrors, LoadingButton, BootstrapDataTable, IdColumn, Column, ActionsColumn, Actions, useDataTableContext, LanguageProvider, useLanguage, LanguageSwitcher, ErrorBoundary, CheckBox };
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-admin-base-bootstrap",
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
7
|
+
"build": "tsc",
|
|
8
|
+
"watch": "nodemon --exec npm run build"
|
|
9
|
+
},
|
|
10
|
+
"main": "lib/esm/index.js",
|
|
11
|
+
"jsnext:main": "lib/esm/index.js",
|
|
12
|
+
"module": "lib/esm/index.js",
|
|
13
|
+
"keywords": [],
|
|
14
|
+
"author": "",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"eslintConfig": {
|
|
17
|
+
"extends": [
|
|
18
|
+
"react-app"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
"nodemonConfig": {
|
|
22
|
+
"ignore": [
|
|
23
|
+
"lib/**"
|
|
24
|
+
],
|
|
25
|
+
"delay": "100"
|
|
26
|
+
},
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"react": "^17.0.2",
|
|
29
|
+
"react-dom": "^17.0.2",
|
|
30
|
+
"react-router-dom": "^5.3.0",
|
|
31
|
+
"react-intl": "^5.21.0"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@emotion/react": "^11.5.0",
|
|
35
|
+
"@fortawesome/fontawesome-free": "^5.15.4",
|
|
36
|
+
"bootstrap": "^5.1.3",
|
|
37
|
+
"file-dialog": "^0.0.8",
|
|
38
|
+
"modal-cropper": "^1.2.3",
|
|
39
|
+
"nprogress": "^0.2.0",
|
|
40
|
+
"prettysize": "^2.0.0",
|
|
41
|
+
"react-admin-base": "^0.4.3",
|
|
42
|
+
"react-responsive": "^8.2.0",
|
|
43
|
+
"react-select": "^5.2.1",
|
|
44
|
+
"reactstrap": "^9.0.0",
|
|
45
|
+
"sweetalert2": "^11.1.9"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/react": "^17.0.34",
|
|
49
|
+
"@types/react-router-dom": "^5.3.2",
|
|
50
|
+
"react-intl": "^5.21.0",
|
|
51
|
+
"cross-env": "^7.0.3",
|
|
52
|
+
"nodemon": "^2.0.14",
|
|
53
|
+
"typescript": "^4.4.4"
|
|
54
|
+
}
|
|
55
|
+
}
|