Merge branch 'main' into application-wizard-2
* main: web/flows: fix identification stage band color (#6489) providers/proxy: only intercept auth header when a value is set (#6488) web: bump @goauthentik/api from 2023.6.1-1691242648 to 2023.6.1-1691266058 in /web (#6486) providers/proxy: set outpost session cookie to httponly and secure wh… (#6482) web: bump @esbuild/linux-arm64 from 0.18.17 to 0.18.18 in /web (#6483) web/admin: fix user sorting by active field (#6485) web: bump @esbuild/darwin-arm64 from 0.18.17 to 0.18.18 in /web (#6484) web: bump storybook (#6481) web: bump the sentry group in /web with 2 updates (#6480) web: bump API Client version (#6479) api: optimise pagination in API schema (#6478) website/dev-docs: tweaks to template (#6474) website: bump react-tooltip from 5.19.0 to 5.20.0 in /website (#6471) website: bump prettier from 3.0.0 to 3.0.1 in /website (#6472)
This commit is contained in:
commit
fa0a9166d1
|
@ -2,6 +2,43 @@
|
|||
from rest_framework import pagination
|
||||
from rest_framework.response import Response
|
||||
|
||||
PAGINATION_COMPONENT_NAME = "Pagination"
|
||||
PAGINATION_SCHEMA = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"next": {
|
||||
"type": "number",
|
||||
},
|
||||
"previous": {
|
||||
"type": "number",
|
||||
},
|
||||
"count": {
|
||||
"type": "number",
|
||||
},
|
||||
"current": {
|
||||
"type": "number",
|
||||
},
|
||||
"total_pages": {
|
||||
"type": "number",
|
||||
},
|
||||
"start_index": {
|
||||
"type": "number",
|
||||
},
|
||||
"end_index": {
|
||||
"type": "number",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"next",
|
||||
"previous",
|
||||
"count",
|
||||
"current",
|
||||
"total_pages",
|
||||
"start_index",
|
||||
"end_index",
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
class Pagination(pagination.PageNumberPagination):
|
||||
"""Pagination which includes total pages and current page"""
|
||||
|
@ -35,41 +72,7 @@ class Pagination(pagination.PageNumberPagination):
|
|||
return {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"pagination": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"next": {
|
||||
"type": "number",
|
||||
},
|
||||
"previous": {
|
||||
"type": "number",
|
||||
},
|
||||
"count": {
|
||||
"type": "number",
|
||||
},
|
||||
"current": {
|
||||
"type": "number",
|
||||
},
|
||||
"total_pages": {
|
||||
"type": "number",
|
||||
},
|
||||
"start_index": {
|
||||
"type": "number",
|
||||
},
|
||||
"end_index": {
|
||||
"type": "number",
|
||||
},
|
||||
},
|
||||
"required": [
|
||||
"next",
|
||||
"previous",
|
||||
"count",
|
||||
"current",
|
||||
"total_pages",
|
||||
"start_index",
|
||||
"end_index",
|
||||
],
|
||||
},
|
||||
"pagination": {"$ref": f"#/components/schemas/{PAGINATION_COMPONENT_NAME}"},
|
||||
"results": schema,
|
||||
},
|
||||
"required": ["pagination", "results"],
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
"""Error Response schema, from https://github.com/axnsan12/drf-yasg/issues/224"""
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from drf_spectacular.generators import SchemaGenerator
|
||||
from drf_spectacular.plumbing import (
|
||||
ResolvedComponent,
|
||||
build_array_type,
|
||||
|
@ -9,6 +10,8 @@ from drf_spectacular.plumbing import (
|
|||
from drf_spectacular.settings import spectacular_settings
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
|
||||
from authentik.api.pagination import PAGINATION_COMPONENT_NAME, PAGINATION_SCHEMA
|
||||
|
||||
|
||||
def build_standard_type(obj, **kwargs):
|
||||
"""Build a basic type with optional add owns."""
|
||||
|
@ -36,15 +39,7 @@ VALIDATION_ERROR = build_object_type(
|
|||
)
|
||||
|
||||
|
||||
def postprocess_schema_responses(result, generator, **kwargs): # noqa: W0613
|
||||
"""Workaround to set a default response for endpoints.
|
||||
Workaround suggested at
|
||||
<https://github.com/tfranzel/drf-spectacular/issues/119#issuecomment-656970357>
|
||||
for the missing drf-spectacular feature discussed in
|
||||
<https://github.com/tfranzel/drf-spectacular/issues/101>.
|
||||
"""
|
||||
|
||||
def create_component(name, schema, type_=ResolvedComponent.SCHEMA):
|
||||
def create_component(generator: SchemaGenerator, name, schema, type_=ResolvedComponent.SCHEMA):
|
||||
"""Register a component and return a reference to it."""
|
||||
component = ResolvedComponent(
|
||||
name=name,
|
||||
|
@ -55,8 +50,19 @@ def postprocess_schema_responses(result, generator, **kwargs): # noqa: W0613
|
|||
generator.registry.register_on_missing(component)
|
||||
return component
|
||||
|
||||
generic_error = create_component("GenericError", GENERIC_ERROR)
|
||||
validation_error = create_component("ValidationError", VALIDATION_ERROR)
|
||||
|
||||
def postprocess_schema_responses(result, generator: SchemaGenerator, **kwargs): # noqa: W0613
|
||||
"""Workaround to set a default response for endpoints.
|
||||
Workaround suggested at
|
||||
<https://github.com/tfranzel/drf-spectacular/issues/119#issuecomment-656970357>
|
||||
for the missing drf-spectacular feature discussed in
|
||||
<https://github.com/tfranzel/drf-spectacular/issues/101>.
|
||||
"""
|
||||
|
||||
create_component(generator, PAGINATION_COMPONENT_NAME, PAGINATION_SCHEMA)
|
||||
|
||||
generic_error = create_component(generator, "GenericError", GENERIC_ERROR)
|
||||
validation_error = create_component(generator, "ValidationError", VALIDATION_ERROR)
|
||||
|
||||
for path in result["paths"].values():
|
||||
for method in path.values():
|
||||
|
|
|
@ -15,7 +15,13 @@ from django.utils.http import urlencode
|
|||
from django.utils.text import slugify
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext as _
|
||||
from django_filters.filters import BooleanFilter, CharFilter, ModelMultipleChoiceFilter, UUIDFilter
|
||||
from django_filters.filters import (
|
||||
BooleanFilter,
|
||||
CharFilter,
|
||||
ModelMultipleChoiceFilter,
|
||||
MultipleChoiceFilter,
|
||||
UUIDFilter,
|
||||
)
|
||||
from django_filters.filterset import FilterSet
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import (
|
||||
|
@ -300,11 +306,11 @@ class UsersFilter(FilterSet):
|
|||
is_superuser = BooleanFilter(field_name="ak_groups", lookup_expr="is_superuser")
|
||||
uuid = UUIDFilter(field_name="uuid")
|
||||
|
||||
path = CharFilter(
|
||||
field_name="path",
|
||||
)
|
||||
path = CharFilter(field_name="path")
|
||||
path_startswith = CharFilter(field_name="path", lookup_expr="startswith")
|
||||
|
||||
type = MultipleChoiceFilter(field_name="type")
|
||||
|
||||
groups_by_name = ModelMultipleChoiceFilter(
|
||||
field_name="ak_groups__name",
|
||||
to_field_name="name",
|
||||
|
|
|
@ -13,6 +13,30 @@ import (
|
|||
"goauthentik.io/internal/constants"
|
||||
)
|
||||
|
||||
// Attempt to set basic auth based on user's attributes
|
||||
func (a *Application) setAuthorizationHeader(headers http.Header, c *Claims) {
|
||||
if !*a.proxyConfig.BasicAuthEnabled {
|
||||
return
|
||||
}
|
||||
userAttributes := c.Proxy.UserAttributes
|
||||
var ok bool
|
||||
var password string
|
||||
if password, ok = userAttributes[*a.proxyConfig.BasicAuthPasswordAttribute].(string); !ok {
|
||||
password = ""
|
||||
}
|
||||
// Check if we should use email or a custom attribute as username
|
||||
var username string
|
||||
if username, ok = userAttributes[*a.proxyConfig.BasicAuthUserAttribute].(string); !ok {
|
||||
username = c.Email
|
||||
}
|
||||
if username == "" && password == "" {
|
||||
return
|
||||
}
|
||||
authVal := base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
|
||||
a.log.WithField("username", username).Trace("setting http basic auth")
|
||||
headers.Set("Authorization", fmt.Sprintf("Basic %s", authVal))
|
||||
}
|
||||
|
||||
func (a *Application) addHeaders(headers http.Header, c *Claims) {
|
||||
// https://goauthentik.io/docs/providers/proxy/proxy
|
||||
headers.Set("X-authentik-username", c.PreferredUsername)
|
||||
|
@ -33,22 +57,7 @@ func (a *Application) addHeaders(headers http.Header, c *Claims) {
|
|||
return
|
||||
}
|
||||
userAttributes := c.Proxy.UserAttributes
|
||||
// Attempt to set basic auth based on user's attributes
|
||||
if *a.proxyConfig.BasicAuthEnabled {
|
||||
var ok bool
|
||||
var password string
|
||||
if password, ok = userAttributes[*a.proxyConfig.BasicAuthPasswordAttribute].(string); !ok {
|
||||
password = ""
|
||||
}
|
||||
// Check if we should use email or a custom attribute as username
|
||||
var username string
|
||||
if username, ok = userAttributes[*a.proxyConfig.BasicAuthUserAttribute].(string); !ok {
|
||||
username = c.Email
|
||||
}
|
||||
authVal := base64.StdEncoding.EncodeToString([]byte(username + ":" + password))
|
||||
a.log.WithField("username", username).Trace("setting http basic auth")
|
||||
headers.Set("Authorization", fmt.Sprintf("Basic %s", authVal))
|
||||
}
|
||||
a.setAuthorizationHeader(headers, c)
|
||||
// Check if user has additional headers set that we should sent
|
||||
if additionalHeaders, ok := userAttributes["additionalHeaders"].(map[string]interface{}); ok {
|
||||
a.log.WithField("headers", additionalHeaders).Trace("setting additional headers")
|
||||
|
|
|
@ -3,6 +3,7 @@ package application
|
|||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
|
@ -37,7 +38,12 @@ func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL)
|
|||
rs.SetMaxLength(math.MaxInt)
|
||||
rs.SetKeyPrefix(RedisKeyPrefix)
|
||||
|
||||
rs.Options.HttpOnly = true
|
||||
if strings.ToLower(externalHost.Scheme) == "https" {
|
||||
rs.Options.Secure = true
|
||||
}
|
||||
rs.Options.Domain = *p.CookieDomain
|
||||
rs.Options.SameSite = http.SameSiteLaxMode
|
||||
a.log.Trace("using redis session backend")
|
||||
return rs
|
||||
}
|
||||
|
@ -51,7 +57,12 @@ func (a *Application) getStore(p api.ProxyOutpostConfig, externalHost *url.URL)
|
|||
|
||||
// Note, when using the FilesystemStore only the session.ID is written to a browser cookie, so this is explicit for the storage on disk
|
||||
cs.MaxLength(math.MaxInt)
|
||||
cs.Options.HttpOnly = true
|
||||
if strings.ToLower(externalHost.Scheme) == "https" {
|
||||
cs.Options.Secure = true
|
||||
}
|
||||
cs.Options.Domain = *p.CookieDomain
|
||||
cs.Options.SameSite = http.SameSiteLaxMode
|
||||
a.log.WithField("dir", dir).Trace("using filesystem session backend")
|
||||
return cs
|
||||
}
|
||||
|
|
2071
schema.yml
2071
schema.yml
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -23,7 +23,7 @@
|
|||
"tsc:execute": "tsc --noEmit -p .",
|
||||
"tsc": "run-s build-locales tsc:execute",
|
||||
"storybook": "storybook dev -p 6006",
|
||||
"storybook:build": "storybook build",
|
||||
"storybook:build": "node --max-old-space-size=4096 ./node_modules/.bin/storybook build",
|
||||
"background-image": "sharp resize 2650 --mozjpeg -i src/assets/images/flow_background.jpg -o src/assets/images/flow_background.jpg"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -35,14 +35,14 @@
|
|||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@formatjs/intl-listformat": "^7.4.0",
|
||||
"@fortawesome/fontawesome-free": "^6.4.2",
|
||||
"@goauthentik/api": "^2023.6.1-1690455444",
|
||||
"@goauthentik/api": "^2023.6.1-1691266058",
|
||||
"@lit-labs/context": "^0.3.3",
|
||||
"@lit-labs/task": "^3.0.0",
|
||||
"@lit/localize": "^0.11.4",
|
||||
"@patternfly/elements": "^2.3.2",
|
||||
"@patternfly/patternfly": "^4.224.2",
|
||||
"@sentry/browser": "^7.61.0",
|
||||
"@sentry/tracing": "^7.61.0",
|
||||
"@sentry/browser": "^7.61.1",
|
||||
"@sentry/tracing": "^7.61.1",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.3.3",
|
||||
|
@ -77,11 +77,11 @@
|
|||
"@rollup/plugin-node-resolve": "^15.0.2",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@rollup/plugin-typescript": "^11.1.2",
|
||||
"@storybook/addon-essentials": "^7.1.1",
|
||||
"@storybook/addon-links": "^7.1.1",
|
||||
"@storybook/addon-essentials": "^7.2.1",
|
||||
"@storybook/addon-links": "^7.2.1",
|
||||
"@storybook/blocks": "^7.1.1",
|
||||
"@storybook/web-components": "^7.1.0",
|
||||
"@storybook/web-components-vite": "^7.1.1",
|
||||
"@storybook/web-components": "^7.2.1",
|
||||
"@storybook/web-components-vite": "^7.2.1",
|
||||
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
|
||||
"@types/chart.js": "^2.9.37",
|
||||
"@types/codemirror": "5.60.8",
|
||||
|
@ -108,7 +108,7 @@
|
|||
"rollup-plugin-postcss-lit": "^2.1.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"sharp-cli": "^4.1.1",
|
||||
"storybook": "^7.1.1",
|
||||
"storybook": "^7.2.1",
|
||||
"storybook-addon-mock": "^4.1.0",
|
||||
"ts-lit-plugin": "^1.2.1",
|
||||
"tslib": "^2.6.1",
|
||||
|
@ -117,8 +117,8 @@
|
|||
"vite-tsconfig-paths": "^4.2.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/darwin-arm64": "^0.18.17",
|
||||
"@esbuild/darwin-arm64": "^0.18.18",
|
||||
"@esbuild/linux-amd64": "^0.18.11",
|
||||
"@esbuild/linux-arm64": "^0.18.17"
|
||||
"@esbuild/linux-arm64": "^0.18.18"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ export class MemberSelectTable extends TableModal<User> {
|
|||
columns(): TableColumn[] {
|
||||
return [
|
||||
new TableColumn(msg("Name"), "username"),
|
||||
new TableColumn(msg("Active"), "active"),
|
||||
new TableColumn(msg("Active"), "is_active"),
|
||||
new TableColumn(msg("Last login"), "last_login"),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ export class SystemTaskListPage extends TablePage<Task> {
|
|||
startIndex: 1,
|
||||
endIndex: tasks.length,
|
||||
current: page,
|
||||
next: 0,
|
||||
previous: 0,
|
||||
},
|
||||
results: tasks,
|
||||
};
|
||||
|
|
|
@ -31,7 +31,14 @@ import PFAlert from "@patternfly/patternfly/components/Alert/alert.css";
|
|||
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
|
||||
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
|
||||
|
||||
import { CapabilitiesEnum, CoreApi, Group, ResponseError, User } from "@goauthentik/api";
|
||||
import {
|
||||
CapabilitiesEnum,
|
||||
CoreApi,
|
||||
CoreUsersListTypeEnum,
|
||||
Group,
|
||||
ResponseError,
|
||||
User,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-user-related-add")
|
||||
export class RelatedUserAdd extends Form<{ users: number[] }> {
|
||||
|
@ -127,10 +134,8 @@ export class RelatedUserList extends Table<User> {
|
|||
pageSize: (await uiConfig()).pagination.perPage,
|
||||
search: this.search || "",
|
||||
groupsByPk: this.targetGroup ? [this.targetGroup.pk] : [],
|
||||
attributes: this.hideServiceAccounts
|
||||
? JSON.stringify({
|
||||
"goauthentik.io/user/service-account__isnull": true,
|
||||
})
|
||||
type: this.hideServiceAccounts
|
||||
? [CoreUsersListTypeEnum.External, CoreUsersListTypeEnum.Internal]
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
@ -138,7 +143,7 @@ export class RelatedUserList extends Table<User> {
|
|||
columns(): TableColumn[] {
|
||||
return [
|
||||
new TableColumn(msg("Name"), "username"),
|
||||
new TableColumn(msg("Active"), "active"),
|
||||
new TableColumn(msg("Active"), "is_active"),
|
||||
new TableColumn(msg("Last login"), "last_login"),
|
||||
new TableColumn(msg("Actions")),
|
||||
];
|
||||
|
|
|
@ -94,7 +94,7 @@ export class UserListPage extends TablePage<User> {
|
|||
columns(): TableColumn[] {
|
||||
return [
|
||||
new TableColumn(msg("Name"), "username"),
|
||||
new TableColumn(msg("Active"), "active"),
|
||||
new TableColumn(msg("Active"), "is_active"),
|
||||
new TableColumn(msg("Last login"), "last_login"),
|
||||
new TableColumn(msg("Actions")),
|
||||
];
|
||||
|
|
|
@ -264,7 +264,7 @@ select[multiple] option:checked {
|
|||
filter: invert(1);
|
||||
}
|
||||
.pf-c-login__main-footer-band {
|
||||
background-color: var(--ak-dark-background-lighter);
|
||||
--pf-c-login__main-footer-band--BackgroundColor: var(--ak-dark-background-lighter);
|
||||
color: var(--ak-dark-foreground);
|
||||
}
|
||||
.form-control-static {
|
||||
|
|
|
@ -47,6 +47,8 @@ export class DeleteObjectsTable<T> extends Table<T> {
|
|||
totalPages: 1,
|
||||
startIndex: 1,
|
||||
endIndex: this.objects.length,
|
||||
next: 0,
|
||||
previous: 0,
|
||||
},
|
||||
results: this.objects,
|
||||
});
|
||||
|
|
|
@ -7,7 +7,6 @@ import "@goauthentik/elements/chips/Chip";
|
|||
import "@goauthentik/elements/chips/ChipGroup";
|
||||
import { getURLParam, updateURLParams } from "@goauthentik/elements/router/RouteMatch";
|
||||
import "@goauthentik/elements/table/TablePagination";
|
||||
import { Pagination } from "@goauthentik/elements/table/TablePagination";
|
||||
import "@goauthentik/elements/table/TableSearch";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
|
@ -24,6 +23,8 @@ import PFToolbar from "@patternfly/patternfly/components/Toolbar/toolbar.css";
|
|||
import PFBullseye from "@patternfly/patternfly/layouts/Bullseye/bullseye.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import { Pagination } from "@goauthentik/api";
|
||||
|
||||
export class TableColumn {
|
||||
title: string;
|
||||
orderBy?: string;
|
||||
|
|
|
@ -8,17 +8,7 @@ import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
|||
import PFPagination from "@patternfly/patternfly/components/Pagination/pagination.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
export interface Pagination {
|
||||
next?: number;
|
||||
previous?: number;
|
||||
|
||||
count: number;
|
||||
current: number;
|
||||
totalPages: number;
|
||||
|
||||
startIndex: number;
|
||||
endIndex: number;
|
||||
}
|
||||
import { Pagination } from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-table-pagination")
|
||||
export class TablePagination extends AKElement {
|
||||
|
|
|
@ -28,6 +28,8 @@ export class UserDeviceList extends MFADevicesPage {
|
|||
totalPages: 1,
|
||||
startIndex: 1,
|
||||
endIndex: res.length,
|
||||
next: 0,
|
||||
previous: 0,
|
||||
},
|
||||
results: res,
|
||||
};
|
||||
|
|
|
@ -49,6 +49,8 @@ export class MFADevicesPage extends Table<Device> {
|
|||
totalPages: 1,
|
||||
startIndex: 1,
|
||||
endIndex: devices.length,
|
||||
next: 0,
|
||||
previous: 0,
|
||||
},
|
||||
results: devices,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,7 @@ The most common types are:
|
|||
|
||||
- [**Procedural**](./procedural.md): these are How To docs, the HOW information, with step-by-step instructions for accomplishing a task. This is what most people are looking for when they open the docs... and best practice is to separate the procedural docs from long, lengthy conceptual or reference docs.
|
||||
|
||||
- **Conceptual**: these docs provide the WHY information, and explain when to use a feature (or when not to!), and general concepts behind the fature or functioanlity.
|
||||
- **Conceptual**: these docs provide the WHY information, and explain when to use a feature (or when not to!), and general concepts behind the feature or functioanlity.
|
||||
|
||||
- **Reference**: this is typically tables or lists of reference information, such as configuration values, or most commmonly APIs.
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
title: "Procedural topic"
|
||||
---
|
||||
|
||||
Use a title that focuses on the task you are writing about... for example, "Add a new Group" or "Edit user profiles". For procedural docs, there should be a verb in the tilte, and usually the noun (the thing you are working on). For the title (and all headings) use the infinitive form of the verb (i.e. "add") not the gerund form (i.e. "adding").
|
||||
Use a title that focuses on the task you are writing about... for example, "Add a new Group" or "Edit user profiles". For procedural docs, there should be a verb in the title, and usually the noun (the component or object you are working on). For the title (and all headings) use the infinitive form of the verb (i.e. "add") not the gerund form (i.e. "adding").
|
||||
|
||||
In this first section write one or two sentences about the task. Keep it brief; if it goes on too long, then create a separate conceptual topic, in a separate `.md` file. We don't want readers to have to scroll through paragraphs of conceptual info before they get to Step 1.
|
||||
In this first section, right after the title, write one or two sentences about the task. Keep it brief; if it goes on too long, then create a separate conceptual topic, in a separate `.md` file. We don't want readers to have to scroll through paragraphs of conceptual info before they get to Step 1.
|
||||
|
||||
## Prerequisites (optional section)
|
||||
|
||||
|
@ -16,7 +16,7 @@ If the task is quite long or complex, it might be good to add a bullet list of t
|
|||
|
||||
## first several group steps
|
||||
|
||||
If the task involves a lot of steps, try to group them into simalr steps and have a Head3 or Hedad4 title for each group.
|
||||
If the task involves a lot of steps, try to group them into similar steps and have a Head3 or Head4 title for each group.
|
||||
|
||||
In this section, help the reader get oriented... where do they need to be (i.e. in the GUI, on a CLI, etc).
|
||||
|
||||
|
@ -34,4 +34,4 @@ Use screenshots sparingly, only for complex UIs where it is difficult to describ
|
|||
|
||||
## verify the steps
|
||||
|
||||
Whenever possible, it is useful to add verification steps at the end of a procedural topic. For example, if the procedural was about installing a product, use this section to tell them how they can verify that the install was successful
|
||||
Whenever possible, it is useful to add verification steps at the end of a procedural topic. For example, if the procedural was about installing a product, use this section to tell them how they can verify that the install was successful.
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
"react-dom": "^17.0.2",
|
||||
"react-feather": "^2.0.10",
|
||||
"react-toggle": "^4.1.3",
|
||||
"react-tooltip": "^5.19.0",
|
||||
"react-tooltip": "^5.20.0",
|
||||
"remark-github": "^11.2.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "3.0.0"
|
||||
"prettier": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@algolia/autocomplete-core": {
|
||||
|
@ -10008,9 +10008,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz",
|
||||
"integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz",
|
||||
"integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
|
@ -10591,9 +10591,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/react-tooltip": {
|
||||
"version": "5.19.0",
|
||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.19.0.tgz",
|
||||
"integrity": "sha512-NSUk77GMpxYKHFKJVNHL++QQXRuH2QW1qDrXPtJnp2s/MJvUnU73N5TTADwDyrO2+xGlr0xHhjvQphkF60cMEA==",
|
||||
"version": "5.20.0",
|
||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.20.0.tgz",
|
||||
"integrity": "sha512-LWBIHEZjwDW9ZJ/Dn2xeZrsz+WKMii61CIsx2XPfs1IiIRnWyvKJXrgy6uEGOXYvrnCd4jiEvurn8Y+zJ1bw5Q==",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.0.0",
|
||||
"classnames": "^2.3.0"
|
||||
|
@ -20927,9 +20927,9 @@
|
|||
"integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA=="
|
||||
},
|
||||
"prettier": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz",
|
||||
"integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.1.tgz",
|
||||
"integrity": "sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==",
|
||||
"dev": true
|
||||
},
|
||||
"pretty-error": {
|
||||
|
@ -21361,9 +21361,9 @@
|
|||
}
|
||||
},
|
||||
"react-tooltip": {
|
||||
"version": "5.19.0",
|
||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.19.0.tgz",
|
||||
"integrity": "sha512-NSUk77GMpxYKHFKJVNHL++QQXRuH2QW1qDrXPtJnp2s/MJvUnU73N5TTADwDyrO2+xGlr0xHhjvQphkF60cMEA==",
|
||||
"version": "5.20.0",
|
||||
"resolved": "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.20.0.tgz",
|
||||
"integrity": "sha512-LWBIHEZjwDW9ZJ/Dn2xeZrsz+WKMii61CIsx2XPfs1IiIRnWyvKJXrgy6uEGOXYvrnCd4jiEvurn8Y+zJ1bw5Q==",
|
||||
"requires": {
|
||||
"@floating-ui/dom": "^1.0.0",
|
||||
"classnames": "^2.3.0"
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
"react-dom": "^17.0.2",
|
||||
"react-feather": "^2.0.10",
|
||||
"react-toggle": "^4.1.3",
|
||||
"react-tooltip": "^5.19.0",
|
||||
"react-tooltip": "^5.20.0",
|
||||
"remark-github": "^11.2.4"
|
||||
},
|
||||
"browserslist": {
|
||||
|
@ -45,6 +45,6 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "3.0.0"
|
||||
"prettier": "3.0.1"
|
||||
}
|
||||
}
|
||||
|
|
Reference in New Issue