Line data Source code
1 : /*
2 : * Copyright (C) 2023 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 15 : import cockpit from 'cockpit';
7 15 : import React from 'react';
8 : import { Form, FormGroup } from "@patternfly/react-core/dist/esm/components/Form/index.js";
9 : import { HelperText, HelperTextItem } from "@patternfly/react-core/dist/esm/components/HelperText/index.js";
10 : import { TextInput } from "@patternfly/react-core/dist/esm/components/TextInput/index.js";
11 :
12 : import { apply_modal_dialog, show_modal_dialog } from "cockpit-components-dialog.jsx";
13 : import { FormHelper } from "cockpit-components-form-helper";
14 : import { has_errors, is_valid_char_name } from "./dialog-utils.js";
15 :
16 15 : const _ = cockpit.gettext;
17 :
18 1 : function RenameGroupDialogBody({ state, errors, change }) {
19 1 : const { name } = state;
20 :
21 1 : return (
22 1 : <Form isHorizontal onSubmit={apply_modal_dialog}>
23 1 : <FormGroup fieldId="group-name" label={_("New name")}>
24 1 : <TextInput id="group-name"
25 1 : validated={(errors?.name) ? "error" : "default"}
26 1 : onChange={(_event, val) => change("name", val)} value={name} />
27 1 : <FormHelper fieldId="group-name" helperTextInvalid={errors?.name} />
28 1 : </FormGroup>
29 1 : <HelperText>
30 1 : <HelperTextItem variant="warning">{_("Renaming a group may affect sudo and similar rules")}</HelperTextItem>
31 1 : </HelperText>
32 1 : </Form>
33 : );
34 1 : }
35 :
36 1 : function validate_name(name) {
37 1 : if (!name)
38 1 : return _("Group name cannot be empty");
39 :
40 1 : for (let i = 0; i < name.length; i++) {
41 1 : if (!is_valid_char_name(name[i]))
42 1 : return _("Group name can only consist of letters, digits, dots, dashes, and underscores");
43 1 : }
44 :
45 1 : return null;
46 1 : }
47 :
48 1 : export function rename_group_dialog(group) {
49 1 : let dlg = null;
50 :
51 1 : const state = {
52 1 : name: group
53 1 : };
54 1 : let errors = { };
55 :
56 1 : function change(field, value) {
57 1 : state[field] = value;
58 1 : errors = { };
59 1 : update();
60 1 : }
61 :
62 1 : function update() {
63 1 : const props = {
64 1 : id: "group-confirm-rename-dialog",
65 1 : title: cockpit.format(_("Rename group $0"), group),
66 1 : body: <RenameGroupDialogBody state={state} errors={errors} change={change} />,
67 1 : variant: 'small',
68 1 : };
69 :
70 1 : const footer = {
71 1 : actions: [
72 1 : {
73 1 : caption: _("Rename"),
74 1 : style: "primary",
75 1 : clicked: () => {
76 1 : errors.name = validate_name(state.name);
77 1 : if (has_errors(errors)) {
78 1 : update();
79 1 : return Promise.reject();
80 1 : }
81 1 : return cockpit.spawn(["groupmod", group, "--new-name", state.name], { superuser: "require", err: "message" }).then(dlg.close);
82 1 : }
83 1 : }
84 1 : ]
85 1 : };
86 :
87 1 : if (!dlg)
88 1 : dlg = show_modal_dialog(props, footer);
89 1 : else {
90 1 : dlg.setProps(props);
91 1 : dlg.setFooterProps(footer);
92 1 : }
93 1 : }
94 :
95 1 : update();
96 1 : }
|