mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Scraper and plugin manager (#4242)
* Add package manager * Add SettingModal validate * Reverse modal button order * Add plugin package management * Refactor ClearableInput
This commit is contained in:
33
ui/v2.5/src/components/Shared/Alert.tsx
Normal file
33
ui/v2.5/src/components/Shared/Alert.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import React from "react";
|
||||
import { Button, Modal } from "react-bootstrap";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
|
||||
export interface IAlertModalProps {
|
||||
text: JSX.Element | string;
|
||||
show?: boolean;
|
||||
confirmButtonText?: string;
|
||||
onConfirm: () => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
export const AlertModal: React.FC<IAlertModalProps> = ({
|
||||
text,
|
||||
show,
|
||||
confirmButtonText,
|
||||
onConfirm,
|
||||
onCancel,
|
||||
}) => {
|
||||
return (
|
||||
<Modal show={show}>
|
||||
<Modal.Body>{text}</Modal.Body>
|
||||
<Modal.Footer>
|
||||
<Button variant="danger" onClick={() => onConfirm()}>
|
||||
{confirmButtonText ?? <FormattedMessage id="actions.confirm" />}
|
||||
</Button>
|
||||
<Button variant="secondary" onClick={() => onCancel()}>
|
||||
<FormattedMessage id="actions.cancel" />
|
||||
</Button>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
@@ -8,17 +8,23 @@ import useFocus from "src/utils/focus";
|
||||
interface IClearableInput {
|
||||
value: string;
|
||||
setValue: (value: string) => void;
|
||||
focus: ReturnType<typeof useFocus>;
|
||||
focus?: ReturnType<typeof useFocus>;
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
export const ClearableInput: React.FC<IClearableInput> = ({
|
||||
value,
|
||||
setValue,
|
||||
focus,
|
||||
placeholder,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const [queryRef, setQueryFocus] = focus;
|
||||
const [defaultQueryRef, setQueryFocusDefault] = useFocus();
|
||||
const [queryRef, setQueryFocus] = focus || [
|
||||
defaultQueryRef,
|
||||
setQueryFocusDefault,
|
||||
];
|
||||
const queryClearShowing = !!value;
|
||||
|
||||
function onChangeQuery(event: React.FormEvent<HTMLInputElement>) {
|
||||
@@ -34,7 +40,7 @@ export const ClearableInput: React.FC<IClearableInput> = ({
|
||||
<div className="clearable-input-group">
|
||||
<FormControl
|
||||
ref={queryRef}
|
||||
placeholder={`${intl.formatMessage({ id: "actions.search" })}…`}
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onInput={onChangeQuery}
|
||||
className="clearable-text-field"
|
||||
|
||||
@@ -13,7 +13,7 @@ interface IButton {
|
||||
interface IModal {
|
||||
show: boolean;
|
||||
onHide?: () => void;
|
||||
header?: string;
|
||||
header?: JSX.Element | string;
|
||||
icon?: IconDefinition;
|
||||
cancel?: IButton;
|
||||
accept?: IButton;
|
||||
@@ -59,24 +59,6 @@ export const ModalComponent: React.FC<IModal> = ({
|
||||
<div>{leftFooterButtons}</div>
|
||||
<div>
|
||||
{footerButtons}
|
||||
{cancel ? (
|
||||
<Button
|
||||
disabled={isRunning}
|
||||
variant={cancel.variant ?? "primary"}
|
||||
onClick={cancel.onClick}
|
||||
className="ml-2"
|
||||
>
|
||||
{cancel.text ?? (
|
||||
<FormattedMessage
|
||||
id="actions.cancel"
|
||||
defaultMessage="Cancel"
|
||||
description="Cancels the current action and dismisses the modal."
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
<Button
|
||||
disabled={isRunning || disabled}
|
||||
variant={accept?.variant ?? "primary"}
|
||||
@@ -95,6 +77,24 @@ export const ModalComponent: React.FC<IModal> = ({
|
||||
)
|
||||
)}
|
||||
</Button>
|
||||
{cancel ? (
|
||||
<Button
|
||||
disabled={isRunning}
|
||||
variant={cancel.variant ?? "primary"}
|
||||
onClick={cancel.onClick}
|
||||
className="ml-2"
|
||||
>
|
||||
{cancel.text ?? (
|
||||
<FormattedMessage
|
||||
id="actions.cancel"
|
||||
defaultMessage="Cancel"
|
||||
description="Cancels the current action and dismisses the modal."
|
||||
/>
|
||||
)}
|
||||
</Button>
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
</div>
|
||||
</Modal.Footer>
|
||||
</Modal>
|
||||
|
||||
1002
ui/v2.5/src/components/Shared/PackageManager/PackageManager.tsx
Normal file
1002
ui/v2.5/src/components/Shared/PackageManager/PackageManager.tsx
Normal file
File diff suppressed because it is too large
Load Diff
100
ui/v2.5/src/components/Shared/PackageManager/styles.scss
Normal file
100
ui/v2.5/src/components/Shared/PackageManager/styles.scss
Normal file
@@ -0,0 +1,100 @@
|
||||
.package-manager {
|
||||
padding: 1em;
|
||||
|
||||
.package-source {
|
||||
font-weight: bold;
|
||||
|
||||
.source-controls {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: end;
|
||||
}
|
||||
}
|
||||
|
||||
.package-cell,
|
||||
.package-source {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.package-collapse-button {
|
||||
color: $text-color;
|
||||
}
|
||||
|
||||
.package-manager-table-container {
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
table thead {
|
||||
background-color: $card-bg;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
|
||||
.button-cell {
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
table td {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.package-version,
|
||||
.package-date,
|
||||
.package-name,
|
||||
.package-id {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.package-date,
|
||||
.package-id {
|
||||
color: $muted-gray;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.package-manager-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.package-required-by {
|
||||
color: $warning;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.LoadingIndicator-message {
|
||||
display: inline-block;
|
||||
font-size: 1rem;
|
||||
margin-left: 0.5em;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.source-error {
|
||||
& > .fa-icon {
|
||||
color: $warning;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.package-manager-no-results {
|
||||
color: $text-muted;
|
||||
padding: 1em;
|
||||
text-align: center;
|
||||
|
||||
.btn {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
}
|
||||
@@ -457,21 +457,31 @@ div.react-datepicker {
|
||||
.clearable-text-field,
|
||||
.clearable-text-field:active,
|
||||
.clearable-text-field:focus {
|
||||
background-color: #394b59;
|
||||
background-color: $secondary;
|
||||
border: 0;
|
||||
border-color: #394b59;
|
||||
border-color: $secondary;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.clearable-text-field-clear {
|
||||
background-color: #394b59;
|
||||
color: #bfccd6;
|
||||
background-color: $secondary;
|
||||
color: $muted-gray;
|
||||
font-size: 0.875rem;
|
||||
margin: 0.375rem 0.75rem;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
z-index: 4;
|
||||
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active,
|
||||
&:not(:disabled):not(.disabled):active,
|
||||
&:not(:disabled):not(.disabled):active:focus {
|
||||
background-color: $secondary;
|
||||
border-color: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
.string-list-row .input-group {
|
||||
|
||||
Reference in New Issue
Block a user