diff --git a/frontend/components/Spinner/_styles.scss b/frontend/components/Spinner/_styles.scss
index f11ae4b31..b056f7963 100644
--- a/frontend/components/Spinner/_styles.scss
+++ b/frontend/components/Spinner/_styles.scss
@@ -25,29 +25,13 @@
width: 32px;
height: 32px;
margin: -4px;
- border: 4px solid $core-white;
+ border: 4px solid;
border-radius: 50%;
animation: ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: $ui-vibrant-blue-25 transparent transparent transparent;
}
}
- &__ring-for-button {
- margin-right: $pad-small;
- width: 16px;
- height: 16px;
- border-width: 3px;
- border-color: rgba(255,255,255,0.25);
-
- div {
- margin: -3px;
- width: 16px;
- height: 16px;
- border-width: 3px;
- border-color: $core-white transparent transparent transparent;
- }
- }
-
div:nth-child(1) {
animation-delay: -0.45s;
}
@@ -61,6 +45,38 @@
}
}
+.loading-spinner.small {
+ background: none;
+ box-shadow: none;
+ height: auto;
+ margin: 0;
+ transform: scale(0.7);
+}
+
+button {
+ position: relative;
+ .loading-spinner {
+ background: none;
+ box-shadow: none;
+ margin: 0;
+ transform: scale(0.7);
+ position: absolute;
+ &__ring {
+ border-color: $core-white;
+
+ div {
+ border-color: $core-vibrant-blue transparent transparent transparent;
+ width: 32px;
+ height: 32px;
+ }
+ }
+ }
+}
+
+.spinner-wrap {
+ display: flex;
+}
+
@keyframes ring {
0% {
transform: rotate(0deg);
diff --git a/frontend/pages/policies/PolicyPage/_styles.scss b/frontend/pages/policies/PolicyPage/_styles.scss
index 50a75dc6a..183da66e7 100644
--- a/frontend/pages/policies/PolicyPage/_styles.scss
+++ b/frontend/pages/policies/PolicyPage/_styles.scss
@@ -157,6 +157,11 @@
margin-left: 16px;
font-size: $x-small;
display: flex;
+ align-items: center;
+
+ .loading-spinner {
+ margin-left: -12px;
+ }
span {
font-weight: 700;
diff --git a/frontend/pages/policies/PolicyPage/components/NewPolicyModal/NewPolicyModal.tsx b/frontend/pages/policies/PolicyPage/components/NewPolicyModal/NewPolicyModal.tsx
index 68b165ecb..ffb684ab3 100644
--- a/frontend/pages/policies/PolicyPage/components/NewPolicyModal/NewPolicyModal.tsx
+++ b/frontend/pages/policies/PolicyPage/components/NewPolicyModal/NewPolicyModal.tsx
@@ -102,84 +102,80 @@ const NewPolicyModal = ({
return (
setIsNewPolicyModalOpen(false)}>
<>
- {policyIsLoading ? (
-
- ) : (
-
>
);
diff --git a/frontend/pages/policies/PolicyPage/components/PolicyForm/PolicyForm.tsx b/frontend/pages/policies/PolicyPage/components/PolicyForm/PolicyForm.tsx
index 76bcfe38b..48711460b 100644
--- a/frontend/pages/policies/PolicyPage/components/PolicyForm/PolicyForm.tsx
+++ b/frontend/pages/policies/PolicyPage/components/PolicyForm/PolicyForm.tsx
@@ -37,6 +37,7 @@ interface IPolicyFormProps {
storedPolicy: IPolicy | undefined;
isStoredPolicyLoading: boolean;
isCreatingNewPolicy: boolean;
+ isUpdatingPolicy: boolean;
onCreatePolicy: (formData: IPolicyFormData) => void;
onOsqueryTableSelect: (tableName: string) => void;
goToSelectTargets: () => void;
@@ -64,6 +65,7 @@ const PolicyForm = ({
storedPolicy,
isStoredPolicyLoading,
isCreatingNewPolicy,
+ isUpdatingPolicy,
onCreatePolicy,
onOsqueryTableSelect,
goToSelectTargets,
@@ -84,6 +86,7 @@ const PolicyForm = ({
const [isEditingResolution, setIsEditingResolution] = useState
(
false
);
+ const [isPolicySaving, setIsPolicySaving] = useState(false);
// Note: The PolicyContext values should always be used for any mutable policy data such as query name
// The storedPolicy prop should only be used to access immutable metadata such as author id
@@ -486,7 +489,7 @@ const PolicyForm = ({
onClick={promptSavePolicy()}
disabled={isEditMode && !isAnyPlatformSelected}
>
- <>{!isEditMode ? "Save policy" : "Save"}>
+ <>{isUpdatingPolicy ? : "Save"}>
)}
);
diff --git a/frontend/pages/policies/PolicyPage/screens/QueryEditor.tsx b/frontend/pages/policies/PolicyPage/screens/QueryEditor.tsx
index 58556f657..dc0f496f9 100644
--- a/frontend/pages/policies/PolicyPage/screens/QueryEditor.tsx
+++ b/frontend/pages/policies/PolicyPage/screens/QueryEditor.tsx
@@ -70,6 +70,7 @@ const QueryEditor = ({
const [isCreatingNewPolicy, setIsCreatingNewPolicy] = useState